import {BehaviorSubject, Observable, Subject, Subscription} from "rxjs"; import express from "express"; import http from "http"; import {Server, Socket} from "socket.io"; export type Func0 = () => R | Promise; export type Func1 = (a0: A0) => R | Promise; export type Func2 = (a0: A0, a1: A1) => R | Promise; export type Func3 = (a0: A0, a1: A1, a2: A2) => R | Promise; export type Func4 = (a0: A0, a1: A1, a2: A2, a3: A3) => R | Promise; export interface Event { readonly __type: "Event"; readonly __name: string; readonly create: (app: AppContext | SessionContext) => void; readonly destroy: (app: AppContext | SessionContext) => void; } export interface RefParam { readonly __type: "StateRefParam" | "EventRefParam" | "TaskRefParam"; readonly ref: State | Event | Task; } export interface StateRef { readonly __type: "StateRef"; readonly _next: (v: V) => void; readonly _getValue: () => V; } export interface EventRef { readonly __type: "EventRef"; readonly _next: () => void; } export interface TaskRef { readonly __type: "TaskRef"; readonly _next: () => void; readonly _getValue: () => V; } export interface State { readonly __type: "State"; readonly __name: string; readonly create: (app: AppContext | SessionContext) => void; readonly destroy: (app: AppContext | SessionContext) => void; } export interface Operator { (app: AppContext, session: SessionContext, context: OperatorContext): Promise; readonly __name: string; readonly __type: string; readonly _suboperators: Operator[]; readonly _subgraph: Graph | null; readonly _stateInputs: State[]; readonly _taskInputs: Task[]; } export interface TriggerOperator extends Operator { readonly __type: "TriggerOperator"; } export interface TaskOptions { readonly name: string; readonly triggers?: (State | Event | Task | "self" | "stateChanges")[]; } export interface QueryOptions { readonly name?: string; readonly triggers?: (State | Event | Task | "self" | "deps")[]; readonly onSuccess?: (Event | Query)[]; } export type Query = Task export interface EffectOptions { readonly name?: string; readonly triggers?: (State | Event | Task | "self" | "deps")[]; readonly onSuccess?: (Event | Query)[]; } export type Effect = Task export interface Task { __type: string; __name: string; _operators: Operator[]; _input: string; _output: string; _outputState: State; _trigger: Event | null; _triggers: (Event | State | Task)[]; _inputs: State[]; _state: State; create: (context: AppContext, session: SessionContext) => void; destroy: (context: AppContext, session: SessionContext) => void; } export interface OperatorContext { readonly graph: string; readonly data: Record; readonly state: Record>; } export interface Graph { (a: A): Promise; readonly __type: string; readonly __name: string; readonly _operators: Operator[]; readonly _input: string; readonly _output: string; } export interface OperatorJSON { readonly name: string; readonly type: string; readonly suboperators: OperatorJSON[]; readonly subgraph: string | null; } export interface TriggerJSON { readonly name: string; } export interface InputJSON { readonly name: string; } export interface GraphJSON { readonly name: string; readonly operators: OperatorJSON[]; readonly triggers?: TriggerJSON[]; readonly inputs?: InputJSON[]; } interface StateJSON { readonly name: string; } interface EventJSON { readonly name: string; } export interface SheetJSON { name: string, graphs: GraphJSON[] states?: StateJSON[]; events?: EventJSON[]; } export interface SlimSheetJSON { readonly name: string; } export interface AppContext { readonly __id: string; readonly __connectionId: string; readonly __name: string; readonly __state: Record>; readonly __events: Record>; readonly __tasks: Record>; readonly __requests$: Subject; __requestSubscription?: Subscription; __lastRequestId: number; __lastResponseId: number; } export interface BlueprintRequest { readonly __type: "event" | "state" | "task"; readonly name: string; readonly payload: any; readonly id: number; readonly count: number; } export interface SessionContext { readonly __id: string; readonly __connectionId: string; readonly __name: string; readonly __state: Record>; readonly __events: Record>; readonly __tasks: Record>; readonly __requests$: Subject } export interface AppBlueprint { readonly name: string; state?: State[]; events?: Event[]; tasks?: Task[]; queries?: Query[]; effects?: Effect[]; } export interface Session { readonly state: Record>; readonly events: Record; readonly tasks: Record>; } export interface ServerSentEventsConnection { __type: "ServerSentEvents"; res: express.Response; } export interface WebSocketConnection { __type: "WebSocket" socket: Socket; } export type BlueprintConnection = ServerSentEventsConnection | WebSocketConnection; type ConnectionType = "ServerSentEvents" | "WebSocket"; export interface BlueprintServer { options: ServerOptions; readonly connectionType: ConnectionType; readonly connections: Record; readonly routes: {readonly post: Record;}; readonly sessions: Record; readonly apps: Record; } export interface App { readonly __app: AppBlueprint; readonly __sheet: SheetJSON; readonly create: (connectionId: string) => void; readonly destroy: (connectionId: string) => void; } export interface ServerOptions { readonly cors: Cors; readonly port: number; readonly connectionType: ConnectionType; } export interface Cors { readonly origin?: string; } export interface BlueprintExpress { readonly path: string; readonly app: express.Application; readonly serve: (options?: ServerOptions) => http.Server; } export interface BlueprintIO { readonly namespace: string; readonly onConnection: (socket: Socket) => void; readonly serve: (server: http.Server, options?: ServerOptions) => Server; } export interface Servers { readonly expressServer: http.Server; readonly ioServer: Server | null; } export interface Blueprint { readonly express: BlueprintExpress; readonly io: BlueprintIO; readonly serve: (options?: ServerOptions) => Servers; } export interface Serialized { readonly name: string; readonly sheets: SheetJSON[]; readonly slimSheets: SlimSheetJSON[]; }