@swirls/looms 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +190 -0
- package/README.md +9 -0
- package/dist/actor/cell.d.ts +27 -0
- package/dist/actor/cell.js +41 -0
- package/dist/actor/host.d.ts +27 -0
- package/dist/actor/host.js +82 -0
- package/dist/actor/index.d.ts +3 -0
- package/dist/actor/index.js +3 -0
- package/dist/actor/routing.d.ts +15 -0
- package/dist/actor/routing.js +80 -0
- package/dist/agent/definitions-store.d.ts +11 -0
- package/dist/agent/definitions-store.js +10 -0
- package/dist/agent/definitions.d.ts +152 -0
- package/dist/agent/definitions.js +74 -0
- package/dist/agent/effects.d.ts +425 -0
- package/dist/agent/effects.js +318 -0
- package/dist/agent/events.d.ts +170 -0
- package/dist/agent/events.js +61 -0
- package/dist/agent/index.d.ts +13 -0
- package/dist/agent/index.js +13 -0
- package/dist/agent/llm.d.ts +35 -0
- package/dist/agent/llm.js +48 -0
- package/dist/agent/module.d.ts +1037 -0
- package/dist/agent/module.js +27 -0
- package/dist/agent/projections.d.ts +17 -0
- package/dist/agent/projections.js +81 -0
- package/dist/agent/scope.d.ts +171 -0
- package/dist/agent/scope.js +7 -0
- package/dist/agent/signals.d.ts +17 -0
- package/dist/agent/signals.js +19 -0
- package/dist/agent/stop-when.d.ts +12 -0
- package/dist/agent/stop-when.js +6 -0
- package/dist/agent/threads.d.ts +34 -0
- package/dist/agent/threads.js +407 -0
- package/dist/agent/tool-schema.d.ts +21 -0
- package/dist/agent/tool-schema.js +67 -0
- package/dist/agent/types.d.ts +87 -0
- package/dist/agent/types.js +32 -0
- package/dist/ai-vercel/index.d.ts +2 -0
- package/dist/ai-vercel/index.js +2 -0
- package/dist/ai-vercel/messages.d.ts +9 -0
- package/dist/ai-vercel/messages.js +68 -0
- package/dist/ai-vercel/vercel-llm.d.ts +8 -0
- package/dist/ai-vercel/vercel-llm.js +98 -0
- package/dist/approval/effects.d.ts +133 -0
- package/dist/approval/effects.js +13 -0
- package/dist/approval/events.d.ts +52 -0
- package/dist/approval/events.js +28 -0
- package/dist/approval/index.d.ts +6 -0
- package/dist/approval/index.js +6 -0
- package/dist/approval/module.d.ts +342 -0
- package/dist/approval/module.js +10 -0
- package/dist/approval/projections.d.ts +42 -0
- package/dist/approval/projections.js +57 -0
- package/dist/approval/scope.d.ts +45 -0
- package/dist/approval/scope.js +7 -0
- package/dist/approval/signals.d.ts +19 -0
- package/dist/approval/signals.js +34 -0
- package/dist/cli/cli.d.ts +2 -0
- package/dist/cli/cli.js +6 -0
- package/dist/cli/commands.d.ts +13 -0
- package/dist/cli/commands.js +133 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +1 -0
- package/dist/client/client.d.ts +69 -0
- package/dist/client/client.js +179 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.js +2 -0
- package/dist/client/sse.d.ts +10 -0
- package/dist/client/sse.js +103 -0
- package/dist/cloudflare/alarm-scheduler.d.ts +9 -0
- package/dist/cloudflare/alarm-scheduler.js +13 -0
- package/dist/cloudflare/durable-object.d.ts +24 -0
- package/dist/cloudflare/durable-object.js +43 -0
- package/dist/cloudflare/event-store.d.ts +10 -0
- package/dist/cloudflare/event-store.js +18 -0
- package/dist/cloudflare/index.d.ts +4 -0
- package/dist/cloudflare/index.js +4 -0
- package/dist/cloudflare/router.d.ts +12 -0
- package/dist/cloudflare/router.js +26 -0
- package/dist/core/bun-sqlite.d.ts +13 -0
- package/dist/core/bun-sqlite.js +19 -0
- package/dist/core/catalog.d.ts +49 -0
- package/dist/core/catalog.js +39 -0
- package/dist/core/coalesce.d.ts +21 -0
- package/dist/core/coalesce.js +178 -0
- package/dist/core/compose.d.ts +59 -0
- package/dist/core/compose.js +97 -0
- package/dist/core/cursor.d.ts +16 -0
- package/dist/core/cursor.js +46 -0
- package/dist/core/effects.d.ts +110 -0
- package/dist/core/effects.js +99 -0
- package/dist/core/envelope.d.ts +79 -0
- package/dist/core/envelope.js +68 -0
- package/dist/core/event-codec.d.ts +8 -0
- package/dist/core/event-codec.js +82 -0
- package/dist/core/event-index.d.ts +28 -0
- package/dist/core/event-index.js +86 -0
- package/dist/core/fold.d.ts +19 -0
- package/dist/core/fold.js +362 -0
- package/dist/core/ids.d.ts +11 -0
- package/dist/core/ids.js +47 -0
- package/dist/core/index.d.ts +26 -0
- package/dist/core/index.js +25 -0
- package/dist/core/match.d.ts +8 -0
- package/dist/core/match.js +58 -0
- package/dist/core/module-scope.d.ts +99 -0
- package/dist/core/module-scope.js +72 -0
- package/dist/core/module.d.ts +74 -0
- package/dist/core/module.js +3 -0
- package/dist/core/projection.d.ts +83 -0
- package/dist/core/projection.js +241 -0
- package/dist/core/protocol.d.ts +99 -0
- package/dist/core/protocol.js +101 -0
- package/dist/core/replay.d.ts +13 -0
- package/dist/core/replay.js +34 -0
- package/dist/core/schema.d.ts +35 -0
- package/dist/core/schema.js +130 -0
- package/dist/core/serialize.d.ts +14 -0
- package/dist/core/serialize.js +42 -0
- package/dist/core/snapshot-store.d.ts +39 -0
- package/dist/core/snapshot-store.js +53 -0
- package/dist/core/snapshots.d.ts +26 -0
- package/dist/core/snapshots.js +100 -0
- package/dist/core/sqlite-store.d.ts +31 -0
- package/dist/core/sqlite-store.js +328 -0
- package/dist/core/state.d.ts +43 -0
- package/dist/core/state.js +31 -0
- package/dist/core/store.d.ts +146 -0
- package/dist/core/store.js +229 -0
- package/dist/core/thread.d.ts +41 -0
- package/dist/core/thread.js +13 -0
- package/dist/core/types.d.ts +27 -0
- package/dist/core/types.js +42 -0
- package/dist/core/validate-event.d.ts +19 -0
- package/dist/core/validate-event.js +42 -0
- package/dist/debugger/components/debugger-split.d.ts +23 -0
- package/dist/debugger/components/debugger-split.js +25 -0
- package/dist/debugger/components/event-inspector.d.ts +5 -0
- package/dist/debugger/components/event-inspector.js +38 -0
- package/dist/debugger/components/event-stream.d.ts +13 -0
- package/dist/debugger/components/event-stream.js +119 -0
- package/dist/debugger/components/json-view.d.ts +5 -0
- package/dist/debugger/components/json-view.js +5 -0
- package/dist/debugger/components/run-tree.d.ts +14 -0
- package/dist/debugger/components/run-tree.js +38 -0
- package/dist/debugger/components/status-dot.d.ts +3 -0
- package/dist/debugger/components/status-dot.js +5 -0
- package/dist/debugger/contracts.d.ts +22 -0
- package/dist/debugger/contracts.js +1 -0
- package/dist/debugger/events/catalog.d.ts +6 -0
- package/dist/debugger/events/catalog.js +27 -0
- package/dist/debugger/events/domain-summarize.d.ts +3 -0
- package/dist/debugger/events/domain-summarize.js +107 -0
- package/dist/debugger/events/family.d.ts +8 -0
- package/dist/debugger/events/family.js +44 -0
- package/dist/debugger/events/protocol-summarize.d.ts +3 -0
- package/dist/debugger/events/protocol-summarize.js +70 -0
- package/dist/debugger/index.d.ts +17 -0
- package/dist/debugger/index.js +16 -0
- package/dist/debugger/lib/cn.d.ts +5 -0
- package/dist/debugger/lib/cn.js +17 -0
- package/dist/debugger/lib/event-counts.d.ts +5 -0
- package/dist/debugger/lib/event-counts.js +23 -0
- package/dist/debugger/lib/event-meta.d.ts +8 -0
- package/dist/debugger/lib/event-meta.js +20 -0
- package/dist/debugger/lib/project-run.d.ts +9 -0
- package/dist/debugger/lib/project-run.js +14 -0
- package/dist/debugger/lib/status.d.ts +3 -0
- package/dist/debugger/lib/status.js +31 -0
- package/dist/debugger/lib/visible-events.d.ts +8 -0
- package/dist/debugger/lib/visible-events.js +21 -0
- package/dist/debugger/styles.css +71 -0
- package/dist/debugger/ui/checkbox.d.ts +4 -0
- package/dist/debugger/ui/checkbox.js +9 -0
- package/dist/debugger/ui/input.d.ts +3 -0
- package/dist/debugger/ui/input.js +7 -0
- package/dist/debugger/ui/scroll-area.d.ts +9 -0
- package/dist/debugger/ui/scroll-area.js +10 -0
- package/dist/debugger/ui/tabs.d.ts +7 -0
- package/dist/debugger/ui/tabs.js +17 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/projectors/index-model.d.ts +56 -0
- package/dist/projectors/index-model.js +117 -0
- package/dist/projectors/index.d.ts +4 -0
- package/dist/projectors/index.js +3 -0
- package/dist/projectors/memory.d.ts +5 -0
- package/dist/projectors/memory.js +77 -0
- package/dist/projectors/postgres.d.ts +9 -0
- package/dist/projectors/postgres.js +108 -0
- package/dist/projectors/projector.d.ts +11 -0
- package/dist/projectors/projector.js +1 -0
- package/dist/projectors/schema.d.ts +5 -0
- package/dist/projectors/schema.js +43 -0
- package/dist/projectors/sqlite.d.ts +9 -0
- package/dist/projectors/sqlite.js +103 -0
- package/dist/projectors/with-projectors.d.ts +17 -0
- package/dist/projectors/with-projectors.js +55 -0
- package/dist/react/derived.d.ts +19 -0
- package/dist/react/derived.js +50 -0
- package/dist/react/index.d.ts +6 -0
- package/dist/react/index.js +5 -0
- package/dist/react/materialize.d.ts +3 -0
- package/dist/react/materialize.js +86 -0
- package/dist/react/notify.d.ts +18 -0
- package/dist/react/notify.js +80 -0
- package/dist/react/react.d.ts +61 -0
- package/dist/react/react.js +187 -0
- package/dist/react/register.d.ts +31 -0
- package/dist/react/register.js +1 -0
- package/dist/react/sse.d.ts +1 -0
- package/dist/react/sse.js +1 -0
- package/dist/react/store.d.ts +56 -0
- package/dist/react/store.js +340 -0
- package/dist/react/tables.d.ts +21 -0
- package/dist/react/tables.js +6 -0
- package/dist/runtime/dispatch-effect.d.ts +3 -0
- package/dist/runtime/dispatch-effect.js +113 -0
- package/dist/runtime/events-api.d.ts +4 -0
- package/dist/runtime/events-api.js +84 -0
- package/dist/runtime/index.d.ts +5 -0
- package/dist/runtime/index.js +5 -0
- package/dist/runtime/looms.d.ts +74 -0
- package/dist/runtime/looms.js +109 -0
- package/dist/runtime/runtime-helpers.d.ts +51 -0
- package/dist/runtime/runtime-helpers.js +230 -0
- package/dist/runtime/runtime.d.ts +91 -0
- package/dist/runtime/runtime.js +531 -0
- package/dist/runtime/server.d.ts +17 -0
- package/dist/runtime/server.js +226 -0
- package/dist/runtime/sse.d.ts +15 -0
- package/dist/runtime/sse.js +96 -0
- package/dist/runtime/wake-scheduler.d.ts +8 -0
- package/dist/runtime/wake-scheduler.js +38 -0
- package/dist/s2/config.d.ts +27 -0
- package/dist/s2/config.js +54 -0
- package/dist/s2/index.d.ts +6 -0
- package/dist/s2/index.js +6 -0
- package/dist/s2/lite.d.ts +26 -0
- package/dist/s2/lite.js +150 -0
- package/dist/s2/projector.d.ts +8 -0
- package/dist/s2/projector.js +28 -0
- package/dist/s2/serialize.d.ts +1 -0
- package/dist/s2/serialize.js +1 -0
- package/dist/s2/snapshot-store.d.ts +17 -0
- package/dist/s2/snapshot-store.js +320 -0
- package/dist/s2/store.d.ts +35 -0
- package/dist/s2/store.js +337 -0
- package/dist/testing/index.d.ts +11 -0
- package/dist/testing/index.js +63 -0
- package/dist/workflow/definitions-store.d.ts +11 -0
- package/dist/workflow/definitions-store.js +8 -0
- package/dist/workflow/definitions.d.ts +82 -0
- package/dist/workflow/definitions.js +32 -0
- package/dist/workflow/effects.d.ts +305 -0
- package/dist/workflow/effects.js +208 -0
- package/dist/workflow/events.d.ts +60 -0
- package/dist/workflow/events.js +39 -0
- package/dist/workflow/index.d.ts +8 -0
- package/dist/workflow/index.js +8 -0
- package/dist/workflow/module.d.ts +926 -0
- package/dist/workflow/module.js +19 -0
- package/dist/workflow/projections.d.ts +30 -0
- package/dist/workflow/projections.js +43 -0
- package/dist/workflow/scope.d.ts +61 -0
- package/dist/workflow/scope.js +7 -0
- package/dist/workflow/threads.d.ts +171 -0
- package/dist/workflow/threads.js +287 -0
- package/package.json +183 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { defineEventCatalog, } from './catalog.js';
|
|
2
|
+
import { emit, defineEffect, } from './effects.js';
|
|
3
|
+
import {} from './module.js';
|
|
4
|
+
import { defineProjection } from './projection.js';
|
|
5
|
+
import { defineThread, } from './thread.js';
|
|
6
|
+
import { asJson } from './types.js';
|
|
7
|
+
function buildScopeInput(namespace, events, key, payload, meta) {
|
|
8
|
+
if (events) {
|
|
9
|
+
// SAFETY: catalog input produces typed EventInput for the catalog entry.
|
|
10
|
+
return events.input(key, payload, meta);
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
...meta,
|
|
14
|
+
type: `${namespace}.${key}`,
|
|
15
|
+
payload: asJson(payload),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function createModuleScope(options) {
|
|
19
|
+
const { namespace, protocolVersion, events, observes, dependencies } = options;
|
|
20
|
+
const scope = {
|
|
21
|
+
namespace,
|
|
22
|
+
protocolVersion,
|
|
23
|
+
events,
|
|
24
|
+
observes,
|
|
25
|
+
dependencies,
|
|
26
|
+
thread(def) {
|
|
27
|
+
return defineThread(def);
|
|
28
|
+
},
|
|
29
|
+
projection(def) {
|
|
30
|
+
return defineProjection(def);
|
|
31
|
+
},
|
|
32
|
+
effect(def) {
|
|
33
|
+
return defineEffect(def);
|
|
34
|
+
},
|
|
35
|
+
input(key, payload, meta) {
|
|
36
|
+
return buildScopeInput(namespace, events, key, payload, meta);
|
|
37
|
+
},
|
|
38
|
+
emit(key, payload, meta) {
|
|
39
|
+
return emit(buildScopeInput(namespace, events, key, payload, meta));
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
return scope;
|
|
43
|
+
}
|
|
44
|
+
/** Construct a complete module. Only members returned by setup are installed. */
|
|
45
|
+
/* oxlint-disable anti-slop/no-runtime-typeof, anti-slop/no-chained-type-assertions, anti-slop/no-conditional-empty-object-spread, anti-slop/require-safety-comment-for-type-assertion -- This compatibility boundary normalizes either a module builder or its finished catalog while preserving its generic member types. */
|
|
46
|
+
export function defineModule(options, setup) {
|
|
47
|
+
const source = options.events;
|
|
48
|
+
// SAFETY: catalogs have an input builder; inline entries are normalized once here.
|
|
49
|
+
const events = (source &&
|
|
50
|
+
(typeof source.input === 'function'
|
|
51
|
+
? source
|
|
52
|
+
: defineEventCatalog(options.namespace, source)));
|
|
53
|
+
const scope = typeof options.effect === 'function'
|
|
54
|
+
? options
|
|
55
|
+
: createModuleScope({ ...options, events });
|
|
56
|
+
const members = setup(scope);
|
|
57
|
+
return {
|
|
58
|
+
namespace: options.namespace,
|
|
59
|
+
protocolVersion: options.protocolVersion,
|
|
60
|
+
events: events,
|
|
61
|
+
...(options.observes ? { observes: options.observes } : {}),
|
|
62
|
+
...(options.dependencies ? { dependencies: options.dependencies } : {}),
|
|
63
|
+
...(members.definitions ? { definitions: members.definitions } : {}),
|
|
64
|
+
...(members.middleware ? { middleware: members.middleware } : {}),
|
|
65
|
+
...(members.services ? { services: members.services } : {}),
|
|
66
|
+
// SAFETY: absent member bags use the corresponding empty-object generic defaults.
|
|
67
|
+
effects: (members.effects ?? {}),
|
|
68
|
+
threads: (members.threads ?? {}),
|
|
69
|
+
projections: (members.projections ?? {}),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/* oxlint-enable anti-slop/no-runtime-typeof, anti-slop/no-chained-type-assertions, anti-slop/no-conditional-empty-object-spread, anti-slop/require-safety-comment-for-type-assertion */
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { Effect, Layer } from 'effect';
|
|
2
|
+
import type { EventCatalog } from './catalog';
|
|
3
|
+
import type { EffectContext, EffectDefinition, RuntimeEffect } from './effects';
|
|
4
|
+
import type { EventInput } from './envelope';
|
|
5
|
+
import type { ProjectionDefinition } from './projection';
|
|
6
|
+
import type { InferDefinedSchema, SchemaInput } from './schema';
|
|
7
|
+
import type { ThreadDefinition } from './thread';
|
|
8
|
+
import type { JsonValue } from './types';
|
|
9
|
+
export type NextEffectHandler = (effect: RuntimeEffect, ctx: EffectContext) => Effect.Effect<ReadonlyArray<EventInput>, Error>;
|
|
10
|
+
export type EffectMiddleware = (effect: RuntimeEffect, ctx: EffectContext, next: NextEffectHandler) => Effect.Effect<ReadonlyArray<EventInput>, Error>;
|
|
11
|
+
export interface RuntimeModuleDependency {
|
|
12
|
+
readonly namespace: string;
|
|
13
|
+
readonly protocolVersion?: string;
|
|
14
|
+
}
|
|
15
|
+
/** Anything a host can start by `{ kind, name }`: an agent, a workflow, or your own kind. */
|
|
16
|
+
export interface DefinitionRef {
|
|
17
|
+
readonly kind: string;
|
|
18
|
+
readonly name: string;
|
|
19
|
+
readonly input?: SchemaInput | undefined;
|
|
20
|
+
}
|
|
21
|
+
/** A definition registered on a host, keyed by `${kind}:${name}`. */
|
|
22
|
+
export interface RegisteredDefinition {
|
|
23
|
+
readonly kind: string;
|
|
24
|
+
readonly name: string;
|
|
25
|
+
readonly input?: SchemaInput | undefined;
|
|
26
|
+
readonly value: DefinitionRef;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Input type accepted when starting a definition: inferred from the definition's
|
|
30
|
+
* `input` Standard Schema / Effect Schema, or JsonValue when it has none.
|
|
31
|
+
*/
|
|
32
|
+
export type DefinitionInput<TDef> = TDef extends {
|
|
33
|
+
readonly input?: infer S;
|
|
34
|
+
} ? InferDefinedSchema<S> : JsonValue;
|
|
35
|
+
export interface RuntimeModule<TNamespace extends string = string, TEvents extends EventCatalog = EventCatalog, TEffects extends {
|
|
36
|
+
readonly [key: string]: EffectDefinition;
|
|
37
|
+
} = {
|
|
38
|
+
readonly [key: string]: EffectDefinition;
|
|
39
|
+
}, TThreads extends {
|
|
40
|
+
readonly [key: string]: ThreadDefinition;
|
|
41
|
+
} = {
|
|
42
|
+
readonly [key: string]: ThreadDefinition;
|
|
43
|
+
}, TProjections extends {
|
|
44
|
+
readonly [key: string]: ProjectionDefinition;
|
|
45
|
+
} = {
|
|
46
|
+
readonly [key: string]: ProjectionDefinition;
|
|
47
|
+
}, TServices = any> {
|
|
48
|
+
readonly namespace: TNamespace;
|
|
49
|
+
readonly protocolVersion: string;
|
|
50
|
+
readonly events?: TEvents;
|
|
51
|
+
readonly observes?: readonly EventCatalog[];
|
|
52
|
+
readonly threads?: TThreads;
|
|
53
|
+
readonly effects?: TEffects;
|
|
54
|
+
readonly projections?: TProjections;
|
|
55
|
+
readonly definitions?: readonly DefinitionRef[];
|
|
56
|
+
readonly dependencies?: readonly RuntimeModuleDependency[];
|
|
57
|
+
readonly middleware?: readonly EffectMiddleware[];
|
|
58
|
+
/** Host-side services this module's effect handlers need (an LLM, a definition lookup, a DB pool). */
|
|
59
|
+
readonly services?: () => Layer.Layer<TServices>;
|
|
60
|
+
}
|
|
61
|
+
export declare function defineRuntimeModule<TNamespace extends string, TEvents extends EventCatalog, TEffects extends {
|
|
62
|
+
readonly [key: string]: EffectDefinition;
|
|
63
|
+
}, TThreads extends {
|
|
64
|
+
readonly [key: string]: ThreadDefinition;
|
|
65
|
+
}, TProjections extends {
|
|
66
|
+
readonly [key: string]: ProjectionDefinition;
|
|
67
|
+
}, TServices = any>(module: RuntimeModule<TNamespace, TEvents, TEffects, TThreads, TProjections, TServices>): RuntimeModule<TNamespace, TEvents, TEffects, TThreads, TProjections, TServices>;
|
|
68
|
+
export type AnyRuntimeModule = RuntimeModule<string, EventCatalog, {
|
|
69
|
+
readonly [name: string]: EffectDefinition;
|
|
70
|
+
}, {
|
|
71
|
+
readonly [kind: string]: ThreadDefinition;
|
|
72
|
+
}, {
|
|
73
|
+
readonly [name: string]: ProjectionDefinition;
|
|
74
|
+
}>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Schema, Stream, type Effect } from 'effect';
|
|
2
|
+
import type { EventEnvelope } from './envelope';
|
|
3
|
+
import type { InferSchemaOutput } from './schema';
|
|
4
|
+
import type { RunState, ThreadRecord } from './state';
|
|
5
|
+
export interface ProjectionDefinition<S = unknown> {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly shape?: unknown;
|
|
8
|
+
initialState: S;
|
|
9
|
+
reduce(state: S, event: EventEnvelope): S;
|
|
10
|
+
}
|
|
11
|
+
export declare function defineProjection<TShape>(def: {
|
|
12
|
+
readonly name: string;
|
|
13
|
+
readonly shape: TShape;
|
|
14
|
+
readonly initialState: InferSchemaOutput<TShape>;
|
|
15
|
+
reduce(state: InferSchemaOutput<TShape>, event: EventEnvelope): InferSchemaOutput<TShape>;
|
|
16
|
+
}): ProjectionDefinition<InferSchemaOutput<TShape>>;
|
|
17
|
+
export declare function defineProjection<S = unknown>(def: {
|
|
18
|
+
readonly name: string;
|
|
19
|
+
readonly shape?: unknown;
|
|
20
|
+
readonly initialState: S;
|
|
21
|
+
reduce(state: S, event: EventEnvelope): S;
|
|
22
|
+
}): ProjectionDefinition<S>;
|
|
23
|
+
export declare function foldProjection<S>(projection: ProjectionDefinition<S>, events: readonly EventEnvelope[], initial?: S): S;
|
|
24
|
+
/** Fold a projection over events, skipping ephemeral ones. */
|
|
25
|
+
export declare function project<S>(definition: ProjectionDefinition<S>, events: readonly EventEnvelope[], from?: S): S;
|
|
26
|
+
/** Fold a projection over an Effect Stream of events, skipping ephemeral ones. */
|
|
27
|
+
export declare function projectStream<S, E = never, R = never>(definition: ProjectionDefinition<S>, stream: Stream.Stream<EventEnvelope, E, R>, from?: S): Effect.Effect<S, E, R>;
|
|
28
|
+
export interface ThreadNode {
|
|
29
|
+
threadId: string;
|
|
30
|
+
kind: string;
|
|
31
|
+
definitionName: string;
|
|
32
|
+
status: ThreadRecord['status'];
|
|
33
|
+
parentThreadId: string | null;
|
|
34
|
+
children: ThreadNode[];
|
|
35
|
+
}
|
|
36
|
+
export type TreeNode = ThreadNode;
|
|
37
|
+
export interface ThreadTree {
|
|
38
|
+
runId: string;
|
|
39
|
+
root: ThreadNode | null;
|
|
40
|
+
}
|
|
41
|
+
export interface TreeBuildState {
|
|
42
|
+
runId: string;
|
|
43
|
+
records: {
|
|
44
|
+
[threadId: string]: ThreadRecord;
|
|
45
|
+
};
|
|
46
|
+
rootThreadId: string | null;
|
|
47
|
+
/** Wait ids still open for a thread (mirrors fold `state.waits`). */
|
|
48
|
+
activeWaits?: {
|
|
49
|
+
[threadId: string]: string[];
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export declare const TreeBuildStateSchema: Schema.Schema<TreeBuildState>;
|
|
53
|
+
export declare const threadTree: ProjectionDefinition<TreeBuildState>;
|
|
54
|
+
export declare function toThreadTree(state: TreeBuildState): ThreadTree;
|
|
55
|
+
export declare function treeFromRun(state: RunState): ThreadTree;
|
|
56
|
+
export declare const TimelineEntrySchema: Schema.Struct<{
|
|
57
|
+
readonly seq: Schema.Number;
|
|
58
|
+
readonly id: Schema.String;
|
|
59
|
+
readonly type: Schema.String;
|
|
60
|
+
readonly threadId: Schema.NullOr<Schema.String>;
|
|
61
|
+
readonly causationId: Schema.NullOr<Schema.String>;
|
|
62
|
+
readonly effectId: Schema.NullOr<Schema.String>;
|
|
63
|
+
readonly ts: Schema.Number;
|
|
64
|
+
}>;
|
|
65
|
+
export type TimelineEntry = Schema.Schema.Type<typeof TimelineEntrySchema>;
|
|
66
|
+
export declare const TimelineSchema: Schema.mutable<Schema.$Array<Schema.Struct<{
|
|
67
|
+
readonly seq: Schema.Number;
|
|
68
|
+
readonly id: Schema.String;
|
|
69
|
+
readonly type: Schema.String;
|
|
70
|
+
readonly threadId: Schema.NullOr<Schema.String>;
|
|
71
|
+
readonly causationId: Schema.NullOr<Schema.String>;
|
|
72
|
+
readonly effectId: Schema.NullOr<Schema.String>;
|
|
73
|
+
readonly ts: Schema.Number;
|
|
74
|
+
}>>>;
|
|
75
|
+
export declare const timeline: ProjectionDefinition<{
|
|
76
|
+
readonly seq: number;
|
|
77
|
+
readonly id: string;
|
|
78
|
+
readonly type: string;
|
|
79
|
+
readonly threadId: string | null;
|
|
80
|
+
readonly causationId: string | null;
|
|
81
|
+
readonly effectId: string | null;
|
|
82
|
+
readonly ts: number;
|
|
83
|
+
}[]>;
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { Predicate, Schema, Stream } from 'effect';
|
|
2
|
+
import { isTerminalStatus } from './thread.js';
|
|
3
|
+
export function defineProjection(def) {
|
|
4
|
+
return def;
|
|
5
|
+
}
|
|
6
|
+
export function foldProjection(projection, events, initial) {
|
|
7
|
+
let state = initial !== undefined ? initial : projection.initialState;
|
|
8
|
+
for (const event of events) {
|
|
9
|
+
state = projection.reduce(state, event);
|
|
10
|
+
}
|
|
11
|
+
return state;
|
|
12
|
+
}
|
|
13
|
+
/** Fold a projection over events, skipping ephemeral ones. */
|
|
14
|
+
export function project(definition, events, from) {
|
|
15
|
+
let state = from ?? definition.initialState;
|
|
16
|
+
for (const event of events) {
|
|
17
|
+
if (event.ephemeral) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
state = definition.reduce(state, event);
|
|
21
|
+
}
|
|
22
|
+
return state;
|
|
23
|
+
}
|
|
24
|
+
/** Fold a projection over an Effect Stream of events, skipping ephemeral ones. */
|
|
25
|
+
export function projectStream(definition, stream, from) {
|
|
26
|
+
const getInitial = () => (from !== undefined ? from : definition.initialState);
|
|
27
|
+
return Stream.runFold(stream, getInitial, (state, event) => event.ephemeral ? state : definition.reduce(state, event));
|
|
28
|
+
}
|
|
29
|
+
// SAFETY: TreeBuildState is folded by reducers; Schema.Unknown is a typed placeholder, not a decoder.
|
|
30
|
+
export const TreeBuildStateSchema = Schema.Unknown;
|
|
31
|
+
function readPayload(event) {
|
|
32
|
+
if (!Predicate.isObject(event.payload)) {
|
|
33
|
+
return {};
|
|
34
|
+
}
|
|
35
|
+
return event.payload;
|
|
36
|
+
}
|
|
37
|
+
function readString(obj, key) {
|
|
38
|
+
const value = obj[key];
|
|
39
|
+
return Predicate.isString(value) ? value : undefined;
|
|
40
|
+
}
|
|
41
|
+
export const threadTree = defineProjection({
|
|
42
|
+
name: 'threadTree',
|
|
43
|
+
shape: TreeBuildStateSchema,
|
|
44
|
+
initialState: { runId: '', records: {}, rootThreadId: null },
|
|
45
|
+
reduce(state, event) {
|
|
46
|
+
const payload = readPayload(event);
|
|
47
|
+
switch (event.type) {
|
|
48
|
+
case 'runtime.run.started': {
|
|
49
|
+
const rootThreadId = readString(payload, 'rootThreadId') ?? state.rootThreadId;
|
|
50
|
+
return {
|
|
51
|
+
...state,
|
|
52
|
+
runId: event.runId,
|
|
53
|
+
rootThreadId,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
case 'runtime.thread.started': {
|
|
57
|
+
const threadId = readString(payload, 'threadId') ?? event.threadId;
|
|
58
|
+
const kind = readString(payload, 'kind');
|
|
59
|
+
const definitionName = readString(payload, 'definitionName');
|
|
60
|
+
if (!threadId || !kind || !definitionName) {
|
|
61
|
+
return { ...state, runId: event.runId };
|
|
62
|
+
}
|
|
63
|
+
const parent = payload.parentThreadId;
|
|
64
|
+
const parentThreadId = parent === null || Predicate.isString(parent) ? parent : null;
|
|
65
|
+
const record = {
|
|
66
|
+
threadId,
|
|
67
|
+
kind,
|
|
68
|
+
definitionName,
|
|
69
|
+
parentThreadId,
|
|
70
|
+
status: 'running',
|
|
71
|
+
input: payload.input ?? null,
|
|
72
|
+
output: null,
|
|
73
|
+
error: null,
|
|
74
|
+
state: {},
|
|
75
|
+
};
|
|
76
|
+
const rootThreadId = state.rootThreadId ?? threadId;
|
|
77
|
+
return {
|
|
78
|
+
...state,
|
|
79
|
+
runId: event.runId,
|
|
80
|
+
rootThreadId,
|
|
81
|
+
records: { ...state.records, [threadId]: record },
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
case 'runtime.thread.completed':
|
|
85
|
+
case 'runtime.thread.failed':
|
|
86
|
+
case 'runtime.thread.cancelled': {
|
|
87
|
+
const threadId = readString(payload, 'threadId') ?? event.threadId;
|
|
88
|
+
if (!threadId) {
|
|
89
|
+
return { ...state, runId: event.runId };
|
|
90
|
+
}
|
|
91
|
+
const existing = state.records[threadId];
|
|
92
|
+
if (!existing) {
|
|
93
|
+
return { ...state, runId: event.runId };
|
|
94
|
+
}
|
|
95
|
+
const status = event.type === 'runtime.thread.completed'
|
|
96
|
+
? 'completed'
|
|
97
|
+
: event.type === 'runtime.thread.failed'
|
|
98
|
+
? 'failed'
|
|
99
|
+
: 'cancelled';
|
|
100
|
+
return {
|
|
101
|
+
...state,
|
|
102
|
+
runId: event.runId,
|
|
103
|
+
records: {
|
|
104
|
+
...state.records,
|
|
105
|
+
[threadId]: {
|
|
106
|
+
...existing,
|
|
107
|
+
status,
|
|
108
|
+
output: payload.output ?? existing.output,
|
|
109
|
+
error: readString(payload, 'error') ?? existing.error,
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
case 'runtime.wait.registered': {
|
|
115
|
+
const threadId = event.threadId ?? readString(payload, 'threadId');
|
|
116
|
+
const waitId = readString(payload, 'waitId');
|
|
117
|
+
if (!threadId || !waitId) {
|
|
118
|
+
return { ...state, runId: event.runId };
|
|
119
|
+
}
|
|
120
|
+
const existing = state.records[threadId];
|
|
121
|
+
if (!existing || isTerminalStatus(existing.status)) {
|
|
122
|
+
return { ...state, runId: event.runId };
|
|
123
|
+
}
|
|
124
|
+
const currentWaits = state.activeWaits?.[threadId] ?? [];
|
|
125
|
+
const nextWaits = currentWaits.includes(waitId) ? currentWaits : [...currentWaits, waitId];
|
|
126
|
+
return {
|
|
127
|
+
...state,
|
|
128
|
+
runId: event.runId,
|
|
129
|
+
activeWaits: { ...state.activeWaits, [threadId]: nextWaits },
|
|
130
|
+
records: {
|
|
131
|
+
...state.records,
|
|
132
|
+
[threadId]: {
|
|
133
|
+
...existing,
|
|
134
|
+
status: 'waiting',
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
case 'runtime.wait.satisfied': {
|
|
140
|
+
const threadId = event.threadId ?? readString(payload, 'threadId');
|
|
141
|
+
const waitId = readString(payload, 'waitId');
|
|
142
|
+
if (!threadId) {
|
|
143
|
+
return { ...state, runId: event.runId };
|
|
144
|
+
}
|
|
145
|
+
const existing = state.records[threadId];
|
|
146
|
+
if (!existing || isTerminalStatus(existing.status)) {
|
|
147
|
+
return { ...state, runId: event.runId };
|
|
148
|
+
}
|
|
149
|
+
const currentWaits = waitId
|
|
150
|
+
? (state.activeWaits?.[threadId] ?? []).filter((id) => id !== waitId)
|
|
151
|
+
: [];
|
|
152
|
+
const nextStatus = currentWaits.length > 0 ? 'waiting' : 'running';
|
|
153
|
+
return {
|
|
154
|
+
...state,
|
|
155
|
+
runId: event.runId,
|
|
156
|
+
activeWaits: { ...state.activeWaits, [threadId]: currentWaits },
|
|
157
|
+
records: {
|
|
158
|
+
...state.records,
|
|
159
|
+
[threadId]: {
|
|
160
|
+
...existing,
|
|
161
|
+
status: nextStatus,
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
default:
|
|
167
|
+
return state.runId === event.runId ? state : { ...state, runId: event.runId };
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
export function toThreadTree(state) {
|
|
172
|
+
return treeFromRun({
|
|
173
|
+
runId: state.runId,
|
|
174
|
+
status: 'running',
|
|
175
|
+
rootThreadId: state.rootThreadId,
|
|
176
|
+
threads: state.records,
|
|
177
|
+
waits: {},
|
|
178
|
+
outstandingEffects: [],
|
|
179
|
+
completedEffectIds: [],
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
export function treeFromRun(state) {
|
|
183
|
+
const records = Object.values(state.threads);
|
|
184
|
+
const waitingThreadIds = new Set(Object.values(state.waits).map((w) => w.threadId));
|
|
185
|
+
const byParent = new Map();
|
|
186
|
+
for (const record of records) {
|
|
187
|
+
const key = record.parentThreadId;
|
|
188
|
+
const list = byParent.get(key) ?? [];
|
|
189
|
+
list.push(record);
|
|
190
|
+
byParent.set(key, list);
|
|
191
|
+
}
|
|
192
|
+
const toNode = (record) => {
|
|
193
|
+
const isWaiting = !isTerminalStatus(record.status) &&
|
|
194
|
+
(record.status === 'waiting' || waitingThreadIds.has(record.threadId));
|
|
195
|
+
return {
|
|
196
|
+
threadId: record.threadId,
|
|
197
|
+
kind: record.kind,
|
|
198
|
+
definitionName: record.definitionName,
|
|
199
|
+
status: isWaiting ? 'waiting' : record.status,
|
|
200
|
+
parentThreadId: record.parentThreadId,
|
|
201
|
+
children: (byParent.get(record.threadId) ?? []).map(toNode),
|
|
202
|
+
};
|
|
203
|
+
};
|
|
204
|
+
const rootRecord = state.rootThreadId
|
|
205
|
+
? state.threads[state.rootThreadId]
|
|
206
|
+
: records.find((r) => r.parentThreadId === null);
|
|
207
|
+
return {
|
|
208
|
+
runId: state.runId,
|
|
209
|
+
root: rootRecord ? toNode(rootRecord) : null,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
export const TimelineEntrySchema = Schema.Struct({
|
|
213
|
+
seq: Schema.Number,
|
|
214
|
+
id: Schema.String,
|
|
215
|
+
type: Schema.String,
|
|
216
|
+
threadId: Schema.NullOr(Schema.String),
|
|
217
|
+
causationId: Schema.NullOr(Schema.String),
|
|
218
|
+
effectId: Schema.NullOr(Schema.String),
|
|
219
|
+
ts: Schema.Number,
|
|
220
|
+
});
|
|
221
|
+
export const TimelineSchema = Schema.mutable(Schema.Array(TimelineEntrySchema));
|
|
222
|
+
export const timeline = defineProjection({
|
|
223
|
+
name: 'timeline',
|
|
224
|
+
shape: TimelineSchema,
|
|
225
|
+
initialState: [],
|
|
226
|
+
reduce(state, event) {
|
|
227
|
+
const threadId = event.threadId ?? null;
|
|
228
|
+
return [
|
|
229
|
+
...state,
|
|
230
|
+
{
|
|
231
|
+
seq: event.seq,
|
|
232
|
+
id: event.id,
|
|
233
|
+
type: event.type,
|
|
234
|
+
threadId,
|
|
235
|
+
causationId: event.causationId ?? null,
|
|
236
|
+
effectId: event.effectId ?? null,
|
|
237
|
+
ts: event.ts,
|
|
238
|
+
},
|
|
239
|
+
];
|
|
240
|
+
},
|
|
241
|
+
});
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Schema } from 'effect';
|
|
2
|
+
import { type EventInputOf, type EventsOfCatalog } from './catalog';
|
|
3
|
+
import type { WaitCondition } from './effects';
|
|
4
|
+
export declare const WaitConditionSchema: Schema.Union<readonly [Schema.Struct<{
|
|
5
|
+
readonly type: Schema.Union<readonly [Schema.String, Schema.$Array<Schema.String>]>;
|
|
6
|
+
readonly match: Schema.optional<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
7
|
+
}>, Schema.Struct<{
|
|
8
|
+
readonly timerAt: Schema.Number;
|
|
9
|
+
}>]>;
|
|
10
|
+
export declare const protocolCatalog: import("./catalog").EventCatalog<"runtime", {
|
|
11
|
+
'run.started': Schema.Struct<{
|
|
12
|
+
readonly rootThreadId: Schema.optional<Schema.String>;
|
|
13
|
+
readonly kind: Schema.String;
|
|
14
|
+
readonly definitionName: Schema.String;
|
|
15
|
+
readonly input: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
16
|
+
}>;
|
|
17
|
+
'run.completed': Schema.Struct<{
|
|
18
|
+
readonly output: Schema.NullOr<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
19
|
+
readonly error: Schema.NullOr<Schema.String>;
|
|
20
|
+
}>;
|
|
21
|
+
'thread.started': Schema.Struct<{
|
|
22
|
+
readonly threadId: Schema.String;
|
|
23
|
+
readonly kind: Schema.String;
|
|
24
|
+
readonly definitionName: Schema.String;
|
|
25
|
+
readonly input: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
26
|
+
readonly parentThreadId: Schema.NullOr<Schema.String>;
|
|
27
|
+
}>;
|
|
28
|
+
'thread.completed': Schema.Struct<{
|
|
29
|
+
readonly threadId: Schema.String;
|
|
30
|
+
readonly output: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
31
|
+
}>;
|
|
32
|
+
'thread.failed': Schema.Struct<{
|
|
33
|
+
readonly threadId: Schema.String;
|
|
34
|
+
readonly error: Schema.String;
|
|
35
|
+
}>;
|
|
36
|
+
'thread.cancelled': Schema.Struct<{
|
|
37
|
+
readonly threadId: Schema.String;
|
|
38
|
+
readonly reason: Schema.optional<Schema.String>;
|
|
39
|
+
}>;
|
|
40
|
+
'wait.registered': Schema.Struct<{
|
|
41
|
+
readonly waitId: Schema.String;
|
|
42
|
+
readonly threadId: Schema.optional<Schema.String>;
|
|
43
|
+
readonly on: Schema.Union<readonly [Schema.Struct<{
|
|
44
|
+
readonly type: Schema.Union<readonly [Schema.String, Schema.$Array<Schema.String>]>;
|
|
45
|
+
readonly match: Schema.optional<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
46
|
+
}>, Schema.Struct<{
|
|
47
|
+
readonly timerAt: Schema.Number;
|
|
48
|
+
}>]>;
|
|
49
|
+
readonly tag: Schema.optional<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
50
|
+
}>;
|
|
51
|
+
'wait.satisfied': Schema.Struct<{
|
|
52
|
+
readonly waitId: Schema.String;
|
|
53
|
+
readonly tag: Schema.optional<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
54
|
+
readonly event: Schema.Struct<{
|
|
55
|
+
readonly id: Schema.String;
|
|
56
|
+
readonly type: Schema.String;
|
|
57
|
+
readonly payload: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
58
|
+
}>;
|
|
59
|
+
}>;
|
|
60
|
+
'timer.set': Schema.Struct<{
|
|
61
|
+
readonly timerId: Schema.String;
|
|
62
|
+
readonly waitId: Schema.String;
|
|
63
|
+
readonly wakeAt: Schema.Number;
|
|
64
|
+
}>;
|
|
65
|
+
'timer.fired': Schema.Struct<{
|
|
66
|
+
readonly timerId: Schema.String;
|
|
67
|
+
readonly waitId: Schema.String;
|
|
68
|
+
}>;
|
|
69
|
+
'effect.failed': Schema.Struct<{
|
|
70
|
+
readonly effectId: Schema.String;
|
|
71
|
+
readonly error: Schema.String;
|
|
72
|
+
}>;
|
|
73
|
+
'snapshot.taken': Schema.Struct<{
|
|
74
|
+
readonly seq: Schema.Number;
|
|
75
|
+
readonly stateHash: Schema.String;
|
|
76
|
+
readonly state: Schema.optional<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
77
|
+
}>;
|
|
78
|
+
'signal.received': Schema.Struct<{
|
|
79
|
+
readonly signalType: Schema.String;
|
|
80
|
+
}>;
|
|
81
|
+
}>;
|
|
82
|
+
export type ProtocolEvent = EventsOfCatalog<typeof protocolCatalog>;
|
|
83
|
+
export type ProtocolEventInput = EventInputOf<typeof protocolCatalog>;
|
|
84
|
+
export declare const PROTOCOL_TYPES: readonly ['runtime.run.started', 'runtime.run.completed', 'runtime.thread.started', 'runtime.thread.completed', 'runtime.thread.failed', 'runtime.thread.cancelled', 'runtime.wait.registered', 'runtime.wait.satisfied', 'runtime.timer.set', 'runtime.timer.fired', 'runtime.effect.failed', 'runtime.snapshot.taken', 'runtime.signal.received'];
|
|
85
|
+
export type ProtocolEventType = (typeof PROTOCOL_TYPES)[number];
|
|
86
|
+
export declare function isProtocolType(type: string): type is ProtocolEventType;
|
|
87
|
+
export type RunStartedPayload = Schema.Schema.Type<(typeof protocolCatalog.entries)['run.started']>;
|
|
88
|
+
export type RunCompletedPayload = Schema.Schema.Type<(typeof protocolCatalog.entries)['run.completed']>;
|
|
89
|
+
export type ThreadStartedPayload = Schema.Schema.Type<(typeof protocolCatalog.entries)['thread.started']>;
|
|
90
|
+
export type ThreadCompletedPayload = Schema.Schema.Type<(typeof protocolCatalog.entries)['thread.completed']>;
|
|
91
|
+
export type ThreadFailedPayload = Schema.Schema.Type<(typeof protocolCatalog.entries)['thread.failed']>;
|
|
92
|
+
export type ThreadCancelledPayload = Schema.Schema.Type<(typeof protocolCatalog.entries)['thread.cancelled']>;
|
|
93
|
+
export type WaitRegisteredPayload = Schema.Schema.Type<(typeof protocolCatalog.entries)['wait.registered']>;
|
|
94
|
+
export type WaitSatisfiedPayload = Schema.Schema.Type<(typeof protocolCatalog.entries)['wait.satisfied']>;
|
|
95
|
+
export type TimerSetPayload = Schema.Schema.Type<(typeof protocolCatalog.entries)['timer.set']>;
|
|
96
|
+
export type TimerFiredPayload = Schema.Schema.Type<(typeof protocolCatalog.entries)['timer.fired']>;
|
|
97
|
+
export type EffectFailedPayload = Schema.Schema.Type<(typeof protocolCatalog.entries)['effect.failed']>;
|
|
98
|
+
export type SnapshotTakenPayload = Schema.Schema.Type<(typeof protocolCatalog.entries)['snapshot.taken']>;
|
|
99
|
+
export declare function asWaitCondition(value: Schema.Schema.Type<typeof WaitConditionSchema>): WaitCondition;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Schema } from 'effect';
|
|
2
|
+
import { defineEventCatalog } from './catalog.js';
|
|
3
|
+
import { JsonValueSchema } from './envelope.js';
|
|
4
|
+
const WaitOnEventSchema = Schema.Struct({
|
|
5
|
+
type: Schema.Union([Schema.String, Schema.Array(Schema.String)]),
|
|
6
|
+
match: Schema.optional(JsonValueSchema),
|
|
7
|
+
});
|
|
8
|
+
const WaitOnTimerSchema = Schema.Struct({
|
|
9
|
+
timerAt: Schema.Number,
|
|
10
|
+
});
|
|
11
|
+
export const WaitConditionSchema = Schema.Union([WaitOnEventSchema, WaitOnTimerSchema]);
|
|
12
|
+
export const protocolCatalog = defineEventCatalog('runtime', {
|
|
13
|
+
'run.started': Schema.Struct({
|
|
14
|
+
rootThreadId: Schema.optional(Schema.String),
|
|
15
|
+
kind: Schema.String,
|
|
16
|
+
definitionName: Schema.String,
|
|
17
|
+
input: JsonValueSchema,
|
|
18
|
+
}),
|
|
19
|
+
'run.completed': Schema.Struct({
|
|
20
|
+
output: Schema.NullOr(JsonValueSchema),
|
|
21
|
+
error: Schema.NullOr(Schema.String),
|
|
22
|
+
}),
|
|
23
|
+
'thread.started': Schema.Struct({
|
|
24
|
+
threadId: Schema.String,
|
|
25
|
+
kind: Schema.String,
|
|
26
|
+
definitionName: Schema.String,
|
|
27
|
+
input: JsonValueSchema,
|
|
28
|
+
parentThreadId: Schema.NullOr(Schema.String),
|
|
29
|
+
}),
|
|
30
|
+
'thread.completed': Schema.Struct({
|
|
31
|
+
threadId: Schema.String,
|
|
32
|
+
output: JsonValueSchema,
|
|
33
|
+
}),
|
|
34
|
+
'thread.failed': Schema.Struct({
|
|
35
|
+
threadId: Schema.String,
|
|
36
|
+
error: Schema.String,
|
|
37
|
+
}),
|
|
38
|
+
'thread.cancelled': Schema.Struct({
|
|
39
|
+
threadId: Schema.String,
|
|
40
|
+
reason: Schema.optional(Schema.String),
|
|
41
|
+
}),
|
|
42
|
+
'wait.registered': Schema.Struct({
|
|
43
|
+
waitId: Schema.String,
|
|
44
|
+
threadId: Schema.optional(Schema.String),
|
|
45
|
+
on: WaitConditionSchema,
|
|
46
|
+
tag: Schema.optional(JsonValueSchema),
|
|
47
|
+
}),
|
|
48
|
+
'wait.satisfied': Schema.Struct({
|
|
49
|
+
waitId: Schema.String,
|
|
50
|
+
tag: Schema.optional(JsonValueSchema),
|
|
51
|
+
event: Schema.Struct({
|
|
52
|
+
id: Schema.String,
|
|
53
|
+
type: Schema.String,
|
|
54
|
+
payload: JsonValueSchema,
|
|
55
|
+
}),
|
|
56
|
+
}),
|
|
57
|
+
'timer.set': Schema.Struct({
|
|
58
|
+
timerId: Schema.String,
|
|
59
|
+
waitId: Schema.String,
|
|
60
|
+
wakeAt: Schema.Number,
|
|
61
|
+
}),
|
|
62
|
+
'timer.fired': Schema.Struct({
|
|
63
|
+
timerId: Schema.String,
|
|
64
|
+
waitId: Schema.String,
|
|
65
|
+
}),
|
|
66
|
+
'effect.failed': Schema.Struct({
|
|
67
|
+
effectId: Schema.String,
|
|
68
|
+
error: Schema.String,
|
|
69
|
+
}),
|
|
70
|
+
'snapshot.taken': Schema.Struct({
|
|
71
|
+
seq: Schema.Number,
|
|
72
|
+
stateHash: Schema.String,
|
|
73
|
+
state: Schema.optional(JsonValueSchema),
|
|
74
|
+
}),
|
|
75
|
+
'signal.received': Schema.Struct({
|
|
76
|
+
signalType: Schema.String,
|
|
77
|
+
}),
|
|
78
|
+
});
|
|
79
|
+
export const PROTOCOL_TYPES = [
|
|
80
|
+
'runtime.run.started',
|
|
81
|
+
'runtime.run.completed',
|
|
82
|
+
'runtime.thread.started',
|
|
83
|
+
'runtime.thread.completed',
|
|
84
|
+
'runtime.thread.failed',
|
|
85
|
+
'runtime.thread.cancelled',
|
|
86
|
+
'runtime.wait.registered',
|
|
87
|
+
'runtime.wait.satisfied',
|
|
88
|
+
'runtime.timer.set',
|
|
89
|
+
'runtime.timer.fired',
|
|
90
|
+
'runtime.effect.failed',
|
|
91
|
+
'runtime.snapshot.taken',
|
|
92
|
+
'runtime.signal.received',
|
|
93
|
+
];
|
|
94
|
+
export function isProtocolType(type) {
|
|
95
|
+
// SAFETY: PROTOCOL_TYPES is the closed list of runtime.* event names.
|
|
96
|
+
const names = PROTOCOL_TYPES;
|
|
97
|
+
return names.includes(type);
|
|
98
|
+
}
|
|
99
|
+
export function asWaitCondition(value) {
|
|
100
|
+
return value;
|
|
101
|
+
}
|