Skip to content

TypeScript Analysis Service SDK ​

The @dxworks/scriptbee-analysis-sdk package is the TypeScript implementation of the Analysis Service SDK. It lets you build a fully-featured Analysis Service in TypeScript using Hono without writing HTTP boilerplate.

Installation ​

bash
npm install @dxworks/scriptbee-analysis-sdk hono zod

What the SDK provides ​

LayerWhat's included
EndpointsAll REST routes pre-wired with correct HTTP verbs, paths, and status codes
ContractsWeb* Zod schemas and request/response models matching the REST API
ValidatorsZod validation for all request payloads
AbstractionsType-safe interfaces your service implements
UtilitiesFileBundler for packaging binary file streams for loader plugins
RegistrationcreateAnalysisSdkRouter() to mount everything into a Hono application

Architecture ​

┌────────────────┐   REST API    ┌────────────────────────────────────┐
│   Gateway      │ ─────────────▶│    Your Hono Analysis Service      │
│ (ScriptBee)    │               │                                    │
└────────────────┘               │  createAnalysisSdkRouter()         │
                                 │  ┌────────────────────────────┐    │
                                 │  │  Your AnalysisSdkContainer │    │
                                 │  │  (10 use-case properties)  │    │
                                 │  └────────────────────────────┘    │
                                 └────────────────────────────────────┘

Implementing the use cases ​

Implement each use case interface from @dxworks/scriptbee-analysis-sdk and expose them through an object conforming to AnalysisSdkContainer.

InterfaceResponsibility
RunAnalysisUseCaseExecute a script against the loaded context
GetContextUseCaseReturn current context slices
GetContextGraphUseCaseReturn context as a graph (nodes + edges)
LoadContextUseCaseLoad files into context via a loader plugin
LinkContextUseCaseLink loaded context via a linker plugin
ClearContextUseCaseClear all loaded context
GenerateClassesUseCaseStream generated model class files
GetInstalledPluginsUseCaseList installed plugins
InstallPluginUseCaseInstall a plugin by id
UninstallPluginUseCaseUninstall a plugin by id

Example implementation ​

typescript
import type {
  AnalysisInfo,
  RunAnalysisCommand,
  RunAnalysisUseCase,
} from '@dxworks/scriptbee-analysis-sdk';

export class Neo4jRunAnalysisService implements RunAnalysisUseCase {
  constructor(private readonly session: unknown) {}

  async run(command: RunAnalysisCommand): Promise<AnalysisInfo> {
    return {
      id: { value: 'analysis-1' },
      projectId: command.projectId,
      scriptId: command.scriptId,
      status: { value: 'Running' },
      creationDate: new Date(),
    };
  }
}

Registration ​

Create a container implementing AnalysisSdkContainer, then call createAnalysisSdkRouter() to get a pre-configured Hono app:

typescript
import { Hono } from 'hono';
import { serve } from '@hono/node-server';
import {
  createAnalysisSdkRouter,
  type AnalysisSdkContainer,
} from '@dxworks/scriptbee-analysis-sdk';

class AppContainer implements AnalysisSdkContainer {
  readonly runAnalysis = new Neo4jRunAnalysisService(null);
  readonly getContext = new Neo4jGetContextService();
  readonly loadContext = new Neo4jLoadContextService();
  readonly linkContext = new Neo4jLinkContextService();
  readonly clearContext = new Neo4jClearContextService();
  readonly getContextGraph = new Neo4jContextGraphService();
  readonly generateClasses = new Neo4jGenerateClassesService();
  readonly getInstalledPlugins = new Neo4jInstalledPluginsService();
  readonly installPlugin = new Neo4jInstallPluginService();
  readonly uninstallPlugin = new Neo4jUninstallPluginService();
}

const app = new Hono();
app.route('/', createAnalysisSdkRouter(new AppContainer()));

serve({
  fetch: app.fetch,
  port: 5000,
});

createAnalysisSdkRouter() registers all endpoints under /api/ and routes each request to the corresponding use case in the container.

Container interface ​

The AnalysisSdkContainer interface defines all 10 use-case properties:

typescript
export interface AnalysisSdkContainer {
  readonly runAnalysis: RunAnalysisUseCase;
  readonly getContext: GetContextUseCase;
  readonly loadContext: LoadContextUseCase;
  readonly linkContext: LinkContextUseCase;
  readonly clearContext: ClearContextUseCase;
  readonly getContextGraph: GetContextGraphUseCase;
  readonly generateClasses: GenerateClassesUseCase;
  readonly getInstalledPlugins: GetInstalledPluginsUseCase;
  readonly installPlugin: InstallPluginUseCase;
  readonly uninstallPlugin: UninstallPluginUseCase;
}

FileBundler ​

The FileBundler utility serialises a list of SampleCodeFile objects into the binary format consumed by the Gateway for the generate-classes endpoint.

typescript
import { FileBundler } from '@dxworks/scriptbee-analysis-sdk';

const bundler = new FileBundler();
const buffer = bundler.writeToBuffer([{ name: 'Model.ts', content: 'export interface Model {}' }]);

The wire format matches the Gateway expectation: for each file, a big-endian uint32 path length, the UTF-8 encoded path, a big-endian uint64 content length, and the UTF-8 encoded content bytes, terminated by a uint32 of 0.

Domain types ​

All domain models are exported from the root barrel:

ModuleTypes
projectProjectId, ScriptId, FileId, InstanceId
contextContextSlice, ContextGraphNode, ContextGraphEdge, ContextGraphResult
analysisAnalysisId, AnalysisStatus, AnalysisInfo
code-generationSampleCodeFile
pluginsPluginId, PluginKind, PluginManifest, Plugin, PluginExtensionPoint

Results SDK ​

The DefaultAnalysisResultService lets analysis logic emit typed results (files, console output, errors, or custom types) without managing file IDs, byte encoding, or low-level storage.

Storage Decoupling ​

The SDK deliberately does not provide any in-memory or built-in storage implementation. The SDK only defines the basic abstractions — concrete storage is something that the concrete implementer offers by implementing ScriptResultsStore (backed by e.g. S3, disk, blob storage, or a database).

Interfaces ​

typescript
export interface ScriptResultsStore {
  uploadFile(fileId: string, content: Uint8Array, metadata?: Record<string, string>): Promise<void>;
}

export interface AnalysisResultService {
  addFile(name: string, content: string | Uint8Array, resultType?: string): Promise<ResultId>;
  addConsole(content: string, name?: string): Promise<ResultId>;
  addError(message: string, name?: string): Promise<ResultId>;
  addResult(name: string, resultType: string, content: string | Uint8Array): Promise<ResultId>;
}

Usage ​

typescript
import {
  DefaultAnalysisResultService,
  ResultType,
  type ScriptResultsStore,
} from '@dxworks/scriptbee-analysis-sdk';

class FileSystemResultsStore implements ScriptResultsStore {
  async uploadFile(
    fileId: string,
    content: Uint8Array,
    metadata?: Record<string, string>,
  ): Promise<void> {
    // concrete storage implementation (e.g. S3, disk, blob storage)
  }
}

const store = new FileSystemResultsStore();
const results = new DefaultAnalysisResultService({ store });

// emit a file result
const resultId = await results.addFile('summary.json', '{"count": 42}');

// emit console output
await results.addConsole('Analysis started');

// emit an error
await results.addError('Script timed out');

// emit a custom result type
await results.addResult('chart.svg', 'Chart', svgBytes);

Result types ​

Built-in type constants:

ConstantValue
ResultType.FILE"File"
ResultType.CONSOLE"Console"
ResultType.RUN_ERROR"RunError"

Callback hook ​

DefaultAnalysisResultService accepts an optional onResultAdded callback in its constructor options:

typescript
const summaries: ResultSummary[] = [];
const results = new DefaultAnalysisResultService({
  store,
  onResultAdded: summary => summaries.push(summary),
});

Versioning & Changelog ​

The SDK follows Semantic Versioning. Releases are tagged @dxworks/scriptbee-analysis-sdk@<version>. See the shared CHANGELOG.md for details.

Released under the MIT License.