TypeScript SDK (@industream/flowmaker-sdk)

Package: sdk/typescript.

Overview

The TypeScript SDK provides the runtime infrastructure for building FlowBox workers—stateless or stateful components that process data streams in the FlowMaker platform.

[INFO!hub/SDK SCOPE] This SDK handles the runtime loop, serialization, and logging. Your FlowBox implementations focus on business logic: transforming data, calling external APIs, or managing state.

Documentation Index

Getting Started

Implementation Guides


Runtime Architecture & Data Flow

[NOTE!lightbulb/DIAGRAM CONTEXT] This diagram shows a typical three-stage pipeline. Data flows down (Source → Pipe → Sink) via ZMQ frames with headers. Logs flow right to the Logger via Socket.IO. Control events flow to the Scheduler via ZMQ.

{ val, $$meta, $$timestamp }header: Msgpack{ transformedVal , $$meta, $$timestamp }header: Msgpackemit(log)SourcemethodsonOutputReady(id, hdr, cb)PipemethodsonInputReceived(id, hdr, data)onOutputReady(id, hdr, cb)SinkmethodsonInputReceived(id, hdr, data)LoggerserverSocket.IO serverSchedulereventsZMQ Events
ZMQ/Frames
Socket.IO Events

How data flows:

  1. Source initiates data by calling onOutputReady(), pushing { val, $$meta, $$timestamp } with a MessagePack header
  2. Pipe receives via onInputReceived(), transforms, and pushes downstream with the same header format
  3. Sink receives final data, processes it (e.g., saves to database), and acknowledges
  4. Logger receives log events via Socket.IO (dashed lines), displays in the frontend
  5. Scheduler manages lifecycle (init, destroy, heartbeat) via ZMQ control events (dotted lines)

Data Shape Convention

All FlowBox integrations should use this standard data shape for compatibility with DataCatalog and metadata-aware processing:

{
  "temperature": 21.7,
  "pressure": 1.8,
  "$$meta": {
    "temperature": { "entryId": "dc-entry-temp" },
    "pressure": { "entryId": "dc-entry-pressure" }
  },
  "$$timestamp": "2026-04-10T16:00:00.000Z"
}
  • $$meta: Per-field metadata (e.g., DataCatalog entry references)
  • $$timestamp: ISO 8601 timestamp of data creation

[NOTE!lightbulb/META PROPERTY CONTRACT] The $$meta object must have field names as keys matching the data properties. Mismatched keys will cause DataCatalog auto-fetchers to skip enrichment.

[WARNING!shield/RESERVED PREFIX] Properties starting with $$ are reserved for runtime metadata. Do not use this prefix for application data—it may be overwritten or stripped by SDK components.


Quick Start

A minimal worker entrypoint:

// src/index.ts
import { FlowBoxEventLoopHandler, FlowBoxFactory } from "@industream/flowmaker-sdk";
import { MyPipe } from "./my-pipe";

const handler = new FlowBoxEventLoopHandler(
  process.env.FM_ROUTER_TRANSPORT_ADDRESS || 'tcp://*:5560',
  process.env.FM_RUNTIME_HTTP_ADDRESS || 'http://localhost:3100',
  new FlowBoxFactory([MyPipe])
);

await handler.run();

A minimal pipe implementation:

// src/my-pipe.ts
import { FlowBoxCore, FlowBoxRegistration, flowBoxSerializer } from "@industream/flowmaker-sdk";

@FlowBoxRegistration({
  id: "myorg/my-pipe",
  displayName: "My Pipe",
  currentVersion: "1.0.0",
  type: "pipe",
  icon: "transform",
  stateless: true,
  agent: "flowmaker-node/1.0.0",
  workerId: process.env.FM_WORKER_ID!,
  workerDataConnectionString: process.env.FM_WORKER_TRANSPORT_ADV_ADDRESS!,
  ioInterfaces: {
    inputs: [{ name: "input", supportedFormats: ["msgpack"] }],
    outputs: [{ name: "output", supportedFormats: ["msgpack"] }]
  },
  uiConfig: { defaultOptions: {}, implementation: null }
})
export class MyPipe extends FlowBoxCore {
  protected async onInput(inputId: Buffer, header: Buffer, data: Buffer): Promise<void> {
    const input = flowBoxSerializer.unpack(header, data);
    await this.push("output", flowBoxSerializer.pack(header, { ...input, processed: true }), header);
  }
}

[INFO!info/RUNTIME INITIALIZATION] The run() method starts an infinite async dispatch loop. The process won't exit naturally—use SIGINT/SIGTERM for shutdown.

Build Commands

From sdk/typescript:

pnpm install
pnpm build