@swirls/looms 0.0.2 → 0.2.0
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/CHANGELOG.md +24 -2
- package/dist/actor/cell.d.ts +9 -4
- package/dist/actor/cell.js +7 -11
- package/dist/actor/host.d.ts +7 -3
- package/dist/actor/host.js +57 -33
- package/dist/actor/index.d.ts +1 -1
- package/dist/actor/index.js +1 -1
- package/dist/actor/routing.d.ts +12 -1
- package/dist/actor/routing.js +57 -51
- package/dist/agent/agent-session.d.ts +5 -0
- package/dist/agent/agent-session.js +270 -0
- package/dist/agent/debugger/agent-chat.d.ts +2 -0
- package/dist/agent/debugger/agent-chat.js +176 -0
- package/dist/agent/debugger/index.d.ts +5 -0
- package/dist/agent/debugger/index.js +19 -0
- package/dist/agent/debugger/summarize.d.ts +2 -0
- package/dist/agent/debugger/summarize.js +51 -0
- package/dist/agent/debugger/token-usage.d.ts +3 -0
- package/dist/agent/debugger/token-usage.js +11 -0
- package/dist/agent/definitions-store.d.ts +2 -3
- package/dist/agent/definitions-store.js +2 -4
- package/dist/agent/definitions.d.ts +47 -29
- package/dist/agent/definitions.js +39 -12
- package/dist/agent/effects.d.ts +359 -2
- package/dist/agent/effects.js +60 -34
- package/dist/agent/events.d.ts +175 -19
- package/dist/agent/events.js +45 -10
- package/dist/agent/index.d.ts +1 -0
- package/dist/agent/index.js +1 -0
- package/dist/agent/llm.d.ts +11 -2
- package/dist/agent/llm.js +13 -3
- package/dist/agent/module.d.ts +812 -78
- package/dist/agent/module.js +16 -4
- package/dist/agent/scope.d.ts +174 -18
- package/dist/agent/signals.d.ts +26 -1
- package/dist/agent/signals.js +79 -0
- package/dist/agent/threads.d.ts +3 -33
- package/dist/agent/threads.js +20 -25
- package/dist/agent/tool-schema.d.ts +1 -17
- package/dist/agent/tool-schema.js +3 -43
- package/dist/agent/types.d.ts +49 -4
- package/dist/agent/types.js +5 -5
- package/dist/ai-vercel/index.d.ts +1 -0
- package/dist/ai-vercel/index.js +1 -0
- package/dist/ai-vercel/messages.js +22 -7
- package/dist/ai-vercel/vercel-evaluator.d.ts +36 -0
- package/dist/ai-vercel/vercel-evaluator.js +73 -0
- package/dist/ai-vercel/vercel-llm.js +64 -44
- package/dist/approval/debugger/approvals-view.d.ts +3 -0
- package/dist/approval/debugger/approvals-view.js +16 -0
- package/dist/approval/debugger/index.d.ts +4 -0
- package/dist/approval/debugger/index.js +11 -0
- package/dist/approval/debugger/summarize.d.ts +2 -0
- package/dist/approval/debugger/summarize.js +17 -0
- package/dist/approval/effects.d.ts +89 -0
- package/dist/approval/module.d.ts +179 -29
- package/dist/approval/projections.d.ts +0 -14
- package/dist/approval/projections.js +20 -3
- package/dist/approval/signals.d.ts +2 -0
- package/dist/approval/signals.js +18 -2
- package/dist/cli/cli.js +2 -0
- package/dist/cli/commands.js +12 -16
- package/dist/client/client.d.ts +1213 -18
- package/dist/client/client.js +120 -120
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/sse.d.ts +13 -0
- package/dist/client/sse.js +38 -44
- package/dist/cloudflare/alarm-scheduler.d.ts +12 -2
- package/dist/cloudflare/alarm-scheduler.js +34 -7
- package/dist/cloudflare/durable-object.d.ts +10 -2
- package/dist/cloudflare/durable-object.js +59 -28
- package/dist/cloudflare/event-store.d.ts +7 -2
- package/dist/cloudflare/event-store.js +8 -7
- package/dist/cloudflare/index.d.ts +2 -2
- package/dist/cloudflare/index.js +2 -2
- package/dist/cloudflare/router.d.ts +1 -1
- package/dist/cloudflare/router.js +15 -16
- package/dist/core/catalog.d.ts +3 -3
- package/dist/core/catalog.js +2 -5
- package/dist/core/coalesce.js +5 -3
- package/dist/core/compose.d.ts +2 -1
- package/dist/core/compose.js +19 -2
- package/dist/core/debugger-host.d.ts +16 -0
- package/dist/core/debugger-host.js +1 -0
- package/dist/core/definition-store.d.ts +11 -0
- package/dist/core/definition-store.js +6 -0
- package/dist/core/effects.d.ts +127 -15
- package/dist/core/effects.js +89 -17
- package/dist/core/envelope.d.ts +27 -7
- package/dist/core/envelope.js +20 -6
- package/dist/core/event-codec.d.ts +4 -2
- package/dist/core/event-codec.js +10 -5
- package/dist/core/event-index.js +1 -3
- package/dist/core/fold.d.ts +3 -0
- package/dist/core/fold.js +171 -24
- package/dist/core/ids.d.ts +5 -0
- package/dist/core/ids.js +35 -2
- package/dist/core/index.d.ts +7 -1
- package/dist/core/index.js +6 -1
- package/dist/core/kind.d.ts +22 -0
- package/dist/core/kind.js +17 -0
- package/dist/core/limits.d.ts +34 -0
- package/dist/core/limits.js +46 -0
- package/dist/core/match.d.ts +1 -0
- package/dist/core/match.js +10 -1
- package/dist/core/module-scope.d.ts +22 -20
- package/dist/core/module-scope.js +38 -28
- package/dist/core/module.d.ts +18 -5
- package/dist/core/module.js +4 -0
- package/dist/core/projection.d.ts +13 -13
- package/dist/core/projection.js +9 -5
- package/dist/core/protocol.d.ts +68 -11
- package/dist/core/protocol.js +82 -11
- package/dist/core/published.d.ts +43 -0
- package/dist/core/published.js +44 -0
- package/dist/core/replay.d.ts +312 -3
- package/dist/core/replay.js +11 -1
- package/dist/core/schema.d.ts +11 -20
- package/dist/core/schema.js +63 -80
- package/dist/core/serialize.js +2 -4
- package/dist/core/snapshot-store.d.ts +6 -1
- package/dist/core/snapshot-store.js +15 -2
- package/dist/core/snapshots.d.ts +5 -1
- package/dist/core/snapshots.js +10 -15
- package/dist/core/sqlite-store.js +95 -11
- package/dist/core/state.d.ts +142 -4
- package/dist/core/state.js +78 -0
- package/dist/core/store.d.ts +38 -3
- package/dist/core/store.js +77 -22
- package/dist/core/thread.d.ts +10 -9
- package/dist/core/types.d.ts +5 -8
- package/dist/core/types.js +28 -24
- package/dist/core/validate-event.js +14 -4
- package/dist/core/worker-callback.d.ts +17 -0
- package/dist/core/worker-callback.js +1 -0
- package/dist/debugger/app/assets/index-B3Ah8WAE.css +2 -0
- package/dist/debugger/app/assets/index-Qb371t_O.js +22 -0
- package/dist/debugger/app/assets/rolldown-runtime-CbXtAM7H.js +1 -0
- package/dist/debugger/app/assets/routes-CjtEHgPQ.js +47 -0
- package/dist/debugger/app/index.html +14 -0
- package/dist/debugger/components/composer.d.ts +17 -0
- package/dist/debugger/components/composer.js +25 -0
- package/dist/debugger/components/debugger-split.d.ts +2 -1
- package/dist/debugger/components/debugger-split.js +2 -2
- package/dist/debugger/components/event-inspector.d.ts +2 -1
- package/dist/debugger/components/event-inspector.js +25 -16
- package/dist/debugger/components/event-stream.d.ts +2 -1
- package/dist/debugger/components/event-stream.js +14 -74
- package/dist/debugger/components/follow-list.d.ts +19 -0
- package/dist/debugger/components/follow-list.js +96 -0
- package/dist/debugger/components/json-tree.d.ts +11 -0
- package/dist/debugger/components/json-tree.js +120 -0
- package/dist/debugger/components/json-view.js +2 -2
- package/dist/debugger/components/run-tree.js +53 -20
- package/dist/debugger/components/status-dot.d.ts +4 -0
- package/dist/debugger/components/status-dot.js +6 -2
- package/dist/debugger/context.d.ts +14 -0
- package/dist/debugger/context.js +17 -0
- package/dist/debugger/contracts.d.ts +7 -4
- package/dist/debugger/events/builtin-families.d.ts +3 -0
- package/dist/debugger/events/builtin-families.js +9 -0
- package/dist/debugger/events/catalog.d.ts +3 -4
- package/dist/debugger/events/catalog.js +27 -17
- package/dist/debugger/events/protocol-summarize.d.ts +1 -2
- package/dist/debugger/events/protocol-summarize.js +42 -24
- package/dist/debugger/index.d.ts +20 -6
- package/dist/debugger/index.js +19 -5
- package/dist/debugger/lib/cn.d.ts +1 -0
- package/dist/debugger/lib/cn.js +3 -0
- package/dist/debugger/lib/event-meta.d.ts +2 -3
- package/dist/debugger/lib/event-meta.js +6 -12
- package/dist/debugger/lib/json.d.ts +25 -0
- package/dist/debugger/lib/json.js +87 -0
- package/dist/debugger/lib/payload.d.ts +7 -0
- package/dist/debugger/lib/payload.js +11 -0
- package/dist/debugger/lib/time.d.ts +3 -0
- package/dist/debugger/lib/time.js +24 -0
- package/dist/debugger/plugin.d.ts +36 -0
- package/dist/debugger/plugin.js +14 -0
- package/dist/debugger/server/index.d.ts +14 -0
- package/dist/debugger/server/index.js +114 -0
- package/dist/debugger/shell/debugger-shell.d.ts +15 -0
- package/dist/debugger/shell/debugger-shell.js +43 -0
- package/dist/debugger/shell/definition-key.d.ts +3 -0
- package/dist/debugger/shell/definition-key.js +4 -0
- package/dist/debugger/shell/events-pane.d.ts +12 -0
- package/dist/debugger/shell/events-pane.js +25 -0
- package/dist/debugger/shell/projections-panel.d.ts +4 -0
- package/dist/debugger/shell/projections-panel.js +59 -0
- package/dist/debugger/shell/run-controls.d.ts +4 -0
- package/dist/debugger/shell/run-controls.js +72 -0
- package/dist/debugger/shell/run-search.d.ts +6 -0
- package/dist/debugger/shell/run-search.js +102 -0
- package/dist/debugger/shell/run-type-menu.d.ts +6 -0
- package/dist/debugger/shell/run-type-menu.js +11 -0
- package/dist/debugger/shell/schema-form.d.ts +31 -0
- package/dist/debugger/shell/schema-form.js +117 -0
- package/dist/debugger/shell/start-form.d.ts +3 -0
- package/dist/debugger/shell/start-form.js +75 -0
- package/dist/debugger/shell/use-start-run.d.ts +14 -0
- package/dist/debugger/shell/use-start-run.js +32 -0
- package/dist/debugger/shell/workspace.d.ts +6 -0
- package/dist/debugger/shell/workspace.js +15 -0
- package/dist/debugger/styles.css +111 -27
- package/dist/debugger/ui/button.d.ts +24 -0
- package/dist/debugger/ui/button.js +24 -0
- package/dist/debugger/ui/command.d.ts +9 -0
- package/dist/debugger/ui/command.js +24 -0
- package/dist/debugger/ui/dropdown-menu.d.ts +13 -0
- package/dist/debugger/ui/dropdown-menu.js +37 -0
- package/dist/debugger/ui/panel.d.ts +14 -0
- package/dist/debugger/ui/panel.js +16 -0
- package/dist/debugger/ui/popover.d.ts +7 -0
- package/dist/debugger/ui/popover.js +17 -0
- package/dist/debugger/ui/resizable.d.ts +7 -0
- package/dist/debugger/ui/resizable.js +14 -0
- package/dist/debugger/ui/scroll-area.d.ts +2 -1
- package/dist/debugger/ui/scroll-area.js +5 -3
- package/dist/debugger/ui/select.d.ts +10 -0
- package/dist/debugger/ui/select.js +21 -0
- package/dist/debugger/ui/tabs.js +2 -2
- package/dist/debugger/ui/textarea.d.ts +3 -0
- package/dist/debugger/ui/textarea.js +7 -0
- package/dist/evaluator/definitions-store.d.ts +11 -0
- package/dist/evaluator/definitions-store.js +8 -0
- package/dist/evaluator/definitions.d.ts +18 -0
- package/dist/evaluator/definitions.js +4 -0
- package/dist/evaluator/effects.d.ts +226 -0
- package/dist/evaluator/effects.js +132 -0
- package/dist/evaluator/evaluator.d.ts +24 -0
- package/dist/evaluator/evaluator.js +67 -0
- package/dist/evaluator/events.d.ts +59 -0
- package/dist/evaluator/events.js +21 -0
- package/dist/evaluator/index.d.ts +11 -0
- package/dist/evaluator/index.js +11 -0
- package/dist/evaluator/module.d.ts +606 -0
- package/dist/evaluator/module.js +25 -0
- package/dist/evaluator/projections.d.ts +50 -0
- package/dist/evaluator/projections.js +20 -0
- package/dist/evaluator/scope.d.ts +59 -0
- package/dist/evaluator/scope.js +7 -0
- package/dist/evaluator/signals.d.ts +3 -0
- package/dist/evaluator/signals.js +17 -0
- package/dist/evaluator/threads.d.ts +62 -0
- package/dist/evaluator/threads.js +117 -0
- package/dist/evaluator/types.d.ts +125 -0
- package/dist/evaluator/types.js +51 -0
- package/dist/projectors/delivery.d.ts +83 -0
- package/dist/projectors/delivery.js +182 -0
- package/dist/projectors/index-model.d.ts +1 -1
- package/dist/projectors/index-model.js +4 -6
- package/dist/projectors/index.d.ts +2 -0
- package/dist/projectors/index.js +2 -0
- package/dist/projectors/memory.d.ts +1 -1
- package/dist/projectors/memory.js +10 -8
- package/dist/projectors/postgres.js +44 -58
- package/dist/projectors/projector.d.ts +17 -0
- package/dist/projectors/projector.js +26 -1
- package/dist/projectors/sqlite-delivery.d.ts +4 -0
- package/dist/projectors/sqlite-delivery.js +147 -0
- package/dist/projectors/sqlite.js +23 -23
- package/dist/projectors/with-projectors.d.ts +7 -2
- package/dist/projectors/with-projectors.js +27 -28
- package/dist/react/notify.js +11 -8
- package/dist/react/react.d.ts +2 -3
- package/dist/react/react.js +14 -30
- package/dist/react/sse.d.ts +1 -1
- package/dist/react/sse.js +1 -1
- package/dist/react/store.d.ts +3 -3
- package/dist/react/store.js +109 -119
- package/dist/runtime/cancellation.d.ts +16 -0
- package/dist/runtime/cancellation.js +129 -0
- package/dist/runtime/deadline-transition-planner.d.ts +31 -0
- package/dist/runtime/deadline-transition-planner.js +139 -0
- package/dist/runtime/dispatch-effect.d.ts +3 -2
- package/dist/runtime/dispatch-effect.js +7 -13
- package/dist/runtime/errors.d.ts +51 -0
- package/dist/runtime/errors.js +39 -0
- package/dist/runtime/{runtime-helpers.d.ts → helpers.d.ts} +24 -4
- package/dist/runtime/{runtime-helpers.js → helpers.js} +56 -19
- package/dist/runtime/index.d.ts +3 -3
- package/dist/runtime/index.js +3 -3
- package/dist/runtime/ingress.d.ts +15 -0
- package/dist/runtime/ingress.js +42 -0
- package/dist/runtime/local-effect-executor.d.ts +21 -0
- package/dist/runtime/local-effect-executor.js +137 -0
- package/dist/runtime/looms.d.ts +30 -4
- package/dist/runtime/looms.js +57 -37
- package/dist/runtime/observer.d.ts +45 -0
- package/dist/runtime/observer.js +11 -0
- package/dist/runtime/repository.d.ts +55 -0
- package/dist/runtime/repository.js +293 -0
- package/dist/runtime/retry-policy.d.ts +16 -0
- package/dist/runtime/retry-policy.js +29 -0
- package/dist/runtime/run-execution-context.d.ts +30 -0
- package/dist/runtime/run-execution-context.js +56 -0
- package/dist/runtime/run-start.d.ts +4 -0
- package/dist/runtime/run-start.js +44 -0
- package/dist/runtime/runtime.d.ts +6 -87
- package/dist/runtime/runtime.js +248 -470
- package/dist/runtime/server/auth.d.ts +41 -0
- package/dist/runtime/server/auth.js +45 -0
- package/dist/runtime/server/debugger-host.d.ts +11 -0
- package/dist/runtime/server/debugger-host.js +32 -0
- package/dist/runtime/server/fetch-handler.d.ts +18 -0
- package/dist/runtime/server/fetch-handler.js +62 -0
- package/dist/runtime/server/http.d.ts +38 -0
- package/dist/runtime/server/http.js +66 -0
- package/dist/runtime/server/route-table.d.ts +55 -0
- package/dist/runtime/server/route-table.js +74 -0
- package/dist/runtime/server/routes/definitions.d.ts +3 -0
- package/dist/runtime/server/routes/definitions.js +20 -0
- package/dist/runtime/server/routes/effects.d.ts +3 -0
- package/dist/runtime/server/routes/effects.js +59 -0
- package/dist/runtime/server/routes/operations.d.ts +3 -0
- package/dist/runtime/server/routes/operations.js +14 -0
- package/dist/runtime/server/routes/runs.d.ts +3 -0
- package/dist/runtime/server/routes/runs.js +199 -0
- package/dist/runtime/server.d.ts +4 -8
- package/dist/runtime/server.js +6 -211
- package/dist/runtime/sse.d.ts +2 -1
- package/dist/runtime/sse.js +24 -17
- package/dist/runtime/types.d.ts +117 -0
- package/dist/runtime/types.js +1 -0
- package/dist/runtime/wake-engine.d.ts +20 -0
- package/dist/runtime/wake-engine.js +311 -0
- package/dist/runtime/wake-scheduler.d.ts +3 -4
- package/dist/runtime/wake-scheduler.js +25 -31
- package/dist/runtime/worker-callbacks.d.ts +16 -0
- package/dist/runtime/worker-callbacks.js +167 -0
- package/dist/runtime/worker-effect-dispatch.d.ts +36 -0
- package/dist/runtime/worker-effect-dispatch.js +126 -0
- package/dist/s2/config.d.ts +1 -1
- package/dist/s2/config.js +1 -1
- package/dist/s2/lite.js +70 -82
- package/dist/s2/pagination.d.ts +15 -0
- package/dist/s2/pagination.js +36 -0
- package/dist/s2/projector.js +6 -5
- package/dist/s2/snapshot-store.js +188 -161
- package/dist/s2/store.d.ts +3 -21
- package/dist/s2/store.js +71 -165
- package/dist/testing/index.d.ts +15 -0
- package/dist/testing/index.js +53 -16
- package/dist/workflow/debugger/index.d.ts +4 -0
- package/dist/workflow/debugger/index.js +11 -0
- package/dist/workflow/debugger/nodes-view.d.ts +3 -0
- package/dist/workflow/debugger/nodes-view.js +13 -0
- package/dist/workflow/debugger/summarize.d.ts +2 -0
- package/dist/workflow/debugger/summarize.js +30 -0
- package/dist/workflow/definitions-store.d.ts +2 -3
- package/dist/workflow/definitions-store.js +2 -2
- package/dist/workflow/definitions.d.ts +78 -22
- package/dist/workflow/definitions.js +80 -14
- package/dist/workflow/effects.d.ts +453 -107
- package/dist/workflow/effects.js +214 -115
- package/dist/workflow/events.d.ts +149 -5
- package/dist/workflow/events.js +27 -5
- package/dist/workflow/graph.d.ts +56 -0
- package/dist/workflow/graph.js +207 -0
- package/dist/workflow/index.d.ts +1 -0
- package/dist/workflow/index.js +1 -0
- package/dist/workflow/module.d.ts +1047 -266
- package/dist/workflow/projections.d.ts +14 -12
- package/dist/workflow/projections.js +30 -8
- package/dist/workflow/scope.d.ts +146 -4
- package/dist/workflow/threads.d.ts +383 -155
- package/dist/workflow/threads.js +308 -110
- package/package.json +26 -2
- package/dist/debugger/events/domain-summarize.d.ts +0 -3
- package/dist/debugger/events/domain-summarize.js +0 -107
- package/dist/debugger/events/family.d.ts +0 -8
- package/dist/debugger/events/family.js +0 -44
- package/dist/runtime/events-api.d.ts +0 -4
- package/dist/runtime/events-api.js +0 -84
package/dist/core/snapshots.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { type RunState } from './state';
|
|
|
5
5
|
import { type JsonValue } from './types';
|
|
6
6
|
export declare const DEFAULT_SNAPSHOT_EVERY = 200;
|
|
7
7
|
export declare const SnapshotTakenPayloadSchema: Schema.Struct<{
|
|
8
|
-
readonly seq: Schema.
|
|
8
|
+
readonly seq: Schema.Finite;
|
|
9
9
|
readonly stateHash: Schema.String;
|
|
10
10
|
readonly state: Schema.optional<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
11
11
|
}>;
|
|
@@ -16,6 +16,10 @@ export declare function runStateToJson(state: RunState): JsonValue;
|
|
|
16
16
|
export declare function buildSnapshotEvent(runId: string, events: readonly EventEnvelope[], registry: FoldRegistry, options?: {
|
|
17
17
|
includeState?: boolean;
|
|
18
18
|
}): EventEnvelope;
|
|
19
|
+
/**
|
|
20
|
+
* Pointer-only snapshot marker. Inline `state` only when provided and
|
|
21
|
+
* serialized state is at most `maxInlineBytes` (default 256 KiB).
|
|
22
|
+
*/
|
|
19
23
|
export declare function buildSnapshotMarker(runId: string, cursor: number, stateHash: string, options?: {
|
|
20
24
|
state?: RunState;
|
|
21
25
|
maxInlineBytes?: number;
|
package/dist/core/snapshots.js
CHANGED
|
@@ -3,16 +3,17 @@ import { bytesToHex } from '@noble/hashes/utils.js';
|
|
|
3
3
|
import { Schema } from 'effect';
|
|
4
4
|
import { createEvent, JsonValueSchema } from './envelope.js';
|
|
5
5
|
import { foldRun } from './fold.js';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { utf8JsonBytes } from './limits.js';
|
|
7
|
+
import { emptyRunState, RunStateSchema } from './state.js';
|
|
8
|
+
import { asJson, stringifyJson } from './types.js';
|
|
8
9
|
export const DEFAULT_SNAPSHOT_EVERY = 200;
|
|
9
10
|
export const SnapshotTakenPayloadSchema = Schema.Struct({
|
|
10
|
-
seq: Schema.
|
|
11
|
+
seq: Schema.Finite,
|
|
11
12
|
stateHash: Schema.String,
|
|
12
13
|
state: Schema.optional(JsonValueSchema),
|
|
13
14
|
});
|
|
14
15
|
export function hashRunState(state) {
|
|
15
|
-
const json =
|
|
16
|
+
const json = stringifyJson(state);
|
|
16
17
|
return bytesToHex(sha256(new TextEncoder().encode(json))).slice(0, 16);
|
|
17
18
|
}
|
|
18
19
|
export function shouldTakeSnapshot(events, every = DEFAULT_SNAPSHOT_EVERY) {
|
|
@@ -33,8 +34,7 @@ export function shouldTakeSnapshot(events, every = DEFAULT_SNAPSHOT_EVERY) {
|
|
|
33
34
|
}
|
|
34
35
|
export const DEFAULT_MAX_INLINE_SNAPSHOT_BYTES = 256 * 1024;
|
|
35
36
|
export function runStateToJson(state) {
|
|
36
|
-
|
|
37
|
-
return Schema.decodeUnknownSync(JsonValueSchema)(raw);
|
|
37
|
+
return asJson(state);
|
|
38
38
|
}
|
|
39
39
|
export function buildSnapshotEvent(runId, events, registry, options) {
|
|
40
40
|
const state = foldRun(events, registry, { runId });
|
|
@@ -45,22 +45,17 @@ export function buildSnapshotEvent(runId, events, registry, options) {
|
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
47
|
* Pointer-only snapshot marker. Inline `state` only when provided and
|
|
48
|
-
*
|
|
48
|
+
* serialized state is at most `maxInlineBytes` (default 256 KiB).
|
|
49
49
|
*/
|
|
50
|
-
let warnedInlineSkip = false;
|
|
51
50
|
export function buildSnapshotMarker(runId, cursor, stateHash, options) {
|
|
52
51
|
const maxInlineBytes = options?.maxInlineBytes ?? DEFAULT_MAX_INLINE_SNAPSHOT_BYTES;
|
|
53
52
|
let payload = asJson({ seq: cursor, stateHash });
|
|
54
53
|
if (options?.state !== undefined) {
|
|
55
54
|
const encoded = runStateToJson(options.state);
|
|
56
|
-
const bytes =
|
|
55
|
+
const bytes = utf8JsonBytes(encoded);
|
|
57
56
|
if (bytes <= maxInlineBytes) {
|
|
58
57
|
payload = asJson({ seq: cursor, stateHash, state: encoded });
|
|
59
58
|
}
|
|
60
|
-
else if (!warnedInlineSkip) {
|
|
61
|
-
warnedInlineSkip = true;
|
|
62
|
-
console.warn(`[looms] snapshot state is ${bytes} bytes (limit ${maxInlineBytes}); writing a pointer-only marker`);
|
|
63
|
-
}
|
|
64
59
|
}
|
|
65
60
|
return createEvent(runId, {
|
|
66
61
|
type: 'runtime.snapshot.taken',
|
|
@@ -86,11 +81,11 @@ export function foldFromSnapshots(events, registry, options) {
|
|
|
86
81
|
if (decoded.state !== undefined) {
|
|
87
82
|
const trailing = events.filter((e) => e.seq > decoded.seq);
|
|
88
83
|
if (trailing.length === 0) {
|
|
89
|
-
return
|
|
84
|
+
return Schema.decodeUnknownSync(RunStateSchema)(decoded.state);
|
|
90
85
|
}
|
|
91
86
|
return foldRun(trailing, registry, {
|
|
92
87
|
runId,
|
|
93
|
-
initial:
|
|
88
|
+
initial: Schema.decodeUnknownSync(RunStateSchema)(decoded.state),
|
|
94
89
|
});
|
|
95
90
|
}
|
|
96
91
|
return foldRun(events, registry, { runId });
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Effect, Option, Queue, Schema, Stream } from 'effect';
|
|
2
2
|
import { EventEnvelopeSchema, fromWireEvent, withAssignedSeq } from './envelope.js';
|
|
3
|
+
import { assertEventByteLimits, assertSnapshotByteLimit, EventPayloadTooLargeError, SnapshotPayloadTooLargeError, } from './limits.js';
|
|
3
4
|
import { SnapshotStoreError, withSnapshotStore, } from './snapshot-store.js';
|
|
5
|
+
import { RunStateSchema } from './state.js';
|
|
4
6
|
import { EventStoreConflictError, EventStoreError, EventStoreFencedError, } from './store.js';
|
|
5
7
|
export const SQLITE_EVENT_STORE_SCHEMA = `
|
|
6
8
|
CREATE TABLE IF NOT EXISTS looms_streams (
|
|
@@ -25,11 +27,26 @@ CREATE TABLE IF NOT EXISTS looms_snapshots (
|
|
|
25
27
|
state TEXT NOT NULL,
|
|
26
28
|
PRIMARY KEY (run_id, cursor)
|
|
27
29
|
);
|
|
30
|
+
|
|
31
|
+
CREATE TABLE IF NOT EXISTS looms_commands (
|
|
32
|
+
run_id TEXT NOT NULL,
|
|
33
|
+
idempotency_key TEXT NOT NULL,
|
|
34
|
+
fingerprint TEXT,
|
|
35
|
+
committed_tail INTEGER NOT NULL,
|
|
36
|
+
PRIMARY KEY (run_id, idempotency_key)
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
CREATE TABLE IF NOT EXISTS looms_run_headers (
|
|
40
|
+
run_id TEXT PRIMARY KEY,
|
|
41
|
+
status TEXT NOT NULL,
|
|
42
|
+
kind TEXT,
|
|
43
|
+
definition_name TEXT
|
|
44
|
+
);
|
|
28
45
|
`.trim();
|
|
29
46
|
const StreamRowSchema = Schema.Struct({
|
|
30
47
|
run_id: Schema.String,
|
|
31
|
-
head: Schema.
|
|
32
|
-
tail: Schema.
|
|
48
|
+
head: Schema.Finite,
|
|
49
|
+
tail: Schema.Finite,
|
|
33
50
|
fence_token: Schema.NullOr(Schema.String),
|
|
34
51
|
});
|
|
35
52
|
const EventRowSchema = Schema.Struct({
|
|
@@ -37,25 +54,30 @@ const EventRowSchema = Schema.Struct({
|
|
|
37
54
|
});
|
|
38
55
|
const SnapshotRowSchema = Schema.Struct({
|
|
39
56
|
run_id: Schema.String,
|
|
40
|
-
cursor: Schema.
|
|
57
|
+
cursor: Schema.Finite,
|
|
41
58
|
state_hash: Schema.String,
|
|
42
|
-
taken_at: Schema.
|
|
59
|
+
taken_at: Schema.Finite,
|
|
43
60
|
state: Schema.String,
|
|
44
61
|
});
|
|
45
62
|
const RunIdRowSchema = Schema.Struct({
|
|
46
63
|
run_id: Schema.String,
|
|
47
64
|
});
|
|
48
65
|
const CursorRowSchema = Schema.Struct({
|
|
49
|
-
cursor: Schema.
|
|
66
|
+
cursor: Schema.Finite,
|
|
67
|
+
});
|
|
68
|
+
const CommandRowSchema = Schema.Struct({
|
|
69
|
+
fingerprint: Schema.NullOr(Schema.String),
|
|
70
|
+
committed_tail: Schema.Finite,
|
|
50
71
|
});
|
|
51
72
|
const decodeEventBody = Schema.decodeUnknownSync(Schema.fromJsonString(EventEnvelopeSchema));
|
|
52
|
-
const decodeRunState = Schema.decodeUnknownSync(Schema.fromJsonString(
|
|
73
|
+
const decodeRunState = Schema.decodeUnknownSync(Schema.fromJsonString(RunStateSchema));
|
|
53
74
|
const encodeJson = Schema.encodeSync(Schema.fromJsonString(Schema.Unknown));
|
|
54
75
|
const decodeStreamRow = Schema.decodeUnknownSync(StreamRowSchema);
|
|
55
76
|
const decodeEventRow = Schema.decodeUnknownSync(EventRowSchema);
|
|
56
77
|
const decodeSnapshotRow = Schema.decodeUnknownSync(SnapshotRowSchema);
|
|
57
78
|
const decodeRunIdRow = Schema.decodeUnknownSync(RunIdRowSchema);
|
|
58
79
|
const decodeCursorRow = Schema.decodeUnknownSync(CursorRowSchema);
|
|
80
|
+
const decodeCommandRow = Schema.decodeUnknownSync(CommandRowSchema);
|
|
59
81
|
/** Adapter for Cloudflare Durable Object `ctx.storage.sql`. */
|
|
60
82
|
export function sqlStorageExec(sql, options) {
|
|
61
83
|
return {
|
|
@@ -100,7 +122,6 @@ function parseEvent(body) {
|
|
|
100
122
|
return fromWireEvent(decodeEventBody(body));
|
|
101
123
|
}
|
|
102
124
|
function toSnapshot(row) {
|
|
103
|
-
// SAFETY: snapshot state is a JSON-encoded RunState written by this store.
|
|
104
125
|
const state = decodeRunState(row.state);
|
|
105
126
|
return {
|
|
106
127
|
runId: row.run_id,
|
|
@@ -110,6 +131,21 @@ function toSnapshot(row) {
|
|
|
110
131
|
state,
|
|
111
132
|
};
|
|
112
133
|
}
|
|
134
|
+
const HeaderRowSchema = Schema.Struct({
|
|
135
|
+
run_id: Schema.String,
|
|
136
|
+
status: RunStateSchema.fields.status,
|
|
137
|
+
kind: Schema.NullOr(Schema.String),
|
|
138
|
+
definition_name: Schema.NullOr(Schema.String),
|
|
139
|
+
});
|
|
140
|
+
const decodeHeaderRow = Schema.decodeUnknownSync(HeaderRowSchema);
|
|
141
|
+
function headerFromRow(row) {
|
|
142
|
+
return {
|
|
143
|
+
runId: row.run_id,
|
|
144
|
+
status: row.status,
|
|
145
|
+
kind: row.kind,
|
|
146
|
+
definitionName: row.definition_name,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
113
149
|
function createSqliteSnapshotStore(exec) {
|
|
114
150
|
return {
|
|
115
151
|
loadLatest: (runId) => Effect.try({
|
|
@@ -121,6 +157,7 @@ function createSqliteSnapshotStore(exec) {
|
|
|
121
157
|
}),
|
|
122
158
|
save: (snapshot) => Effect.try({
|
|
123
159
|
try: () => {
|
|
160
|
+
assertSnapshotByteLimit(snapshot);
|
|
124
161
|
exec.run(`INSERT INTO looms_snapshots (run_id, cursor, state_hash, taken_at, state)
|
|
125
162
|
VALUES (?, ?, ?, ?, ?)
|
|
126
163
|
ON CONFLICT (run_id, cursor) DO UPDATE SET
|
|
@@ -134,7 +171,9 @@ function createSqliteSnapshotStore(exec) {
|
|
|
134
171
|
encodeJson(snapshot.state),
|
|
135
172
|
]);
|
|
136
173
|
},
|
|
137
|
-
catch: (cause) =>
|
|
174
|
+
catch: (cause) => cause instanceof SnapshotPayloadTooLargeError
|
|
175
|
+
? cause
|
|
176
|
+
: new SnapshotStoreError(`Failed to save snapshot for ${snapshot.runId}`, cause),
|
|
138
177
|
}),
|
|
139
178
|
listCursors: (runId) => Effect.try({
|
|
140
179
|
try: () => exec
|
|
@@ -158,6 +197,23 @@ function createSqliteSnapshotStore(exec) {
|
|
|
158
197
|
},
|
|
159
198
|
catch: (cause) => new SnapshotStoreError(`Failed to prune snapshots for ${runId}`, cause),
|
|
160
199
|
}),
|
|
200
|
+
saveHeader: (header) => Effect.try({
|
|
201
|
+
try: () => {
|
|
202
|
+
exec.run(`INSERT INTO looms_run_headers (run_id, status, kind, definition_name)
|
|
203
|
+
VALUES (?, ?, ?, ?)
|
|
204
|
+
ON CONFLICT (run_id) DO UPDATE SET
|
|
205
|
+
status = excluded.status,
|
|
206
|
+
kind = excluded.kind,
|
|
207
|
+
definition_name = excluded.definition_name`, [header.runId, header.status, header.kind, header.definitionName]);
|
|
208
|
+
},
|
|
209
|
+
catch: (cause) => new SnapshotStoreError(`Failed to save run header for ${header.runId}`, cause),
|
|
210
|
+
}),
|
|
211
|
+
listHeaders: Effect.try({
|
|
212
|
+
try: () => exec
|
|
213
|
+
.rows('SELECT run_id, status, kind, definition_name FROM looms_run_headers')
|
|
214
|
+
.map((row) => headerFromRow(decodeHeaderRow(row))),
|
|
215
|
+
catch: (cause) => new SnapshotStoreError('Failed to list run headers', cause),
|
|
216
|
+
}),
|
|
161
217
|
};
|
|
162
218
|
}
|
|
163
219
|
function createSqliteEventStore(exec) {
|
|
@@ -194,11 +250,33 @@ function createSqliteEventStore(exec) {
|
|
|
194
250
|
const service = {
|
|
195
251
|
append: (runId, events, options) => Effect.try({
|
|
196
252
|
try: () => {
|
|
197
|
-
|
|
253
|
+
assertEventByteLimits(runId, events);
|
|
254
|
+
if (events.length === 0 &&
|
|
255
|
+
options?.fence === undefined &&
|
|
256
|
+
options?.idempotency === undefined) {
|
|
198
257
|
return { sequences: [], tail: getStream(runId).tail };
|
|
199
258
|
}
|
|
200
259
|
return runInTransaction(exec, () => {
|
|
201
260
|
const log = ensureStream(runId);
|
|
261
|
+
const idempotency = options?.idempotency;
|
|
262
|
+
if (idempotency) {
|
|
263
|
+
const [commandRow] = exec.rows(`SELECT fingerprint, committed_tail
|
|
264
|
+
FROM looms_commands
|
|
265
|
+
WHERE run_id = ? AND idempotency_key = ?`, [runId, idempotency.key]);
|
|
266
|
+
if (commandRow !== undefined) {
|
|
267
|
+
const command = decodeCommandRow(commandRow);
|
|
268
|
+
if (idempotency.fingerprint !== undefined &&
|
|
269
|
+
command.fingerprint !== null &&
|
|
270
|
+
command.fingerprint !== idempotency.fingerprint) {
|
|
271
|
+
throw new EventStoreError(`Idempotency key "${idempotency.key}" was reused with different content`);
|
|
272
|
+
}
|
|
273
|
+
return {
|
|
274
|
+
sequences: [],
|
|
275
|
+
tail: getStream(runId).tail,
|
|
276
|
+
deduplicated: true,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
}
|
|
202
280
|
if (options?.expectedTail !== undefined && log.tail !== options.expectedTail) {
|
|
203
281
|
throw new EventStoreConflictError(runId, options.expectedTail, log.tail);
|
|
204
282
|
}
|
|
@@ -231,13 +309,19 @@ function createSqliteEventStore(exec) {
|
|
|
231
309
|
ON CONFLICT (run_id) DO UPDATE SET
|
|
232
310
|
tail = excluded.tail,
|
|
233
311
|
fence_token = excluded.fence_token`, [runId, log.head, nextTail, fenceToken]);
|
|
312
|
+
if (idempotency) {
|
|
313
|
+
exec.run(`INSERT INTO looms_commands
|
|
314
|
+
(run_id, idempotency_key, fingerprint, committed_tail)
|
|
315
|
+
VALUES (?, ?, ?, ?)`, [runId, idempotency.key, idempotency.fingerprint ?? null, nextTail]);
|
|
316
|
+
}
|
|
234
317
|
notify(runId, appended);
|
|
235
318
|
return { sequences, tail: nextTail };
|
|
236
319
|
});
|
|
237
320
|
},
|
|
238
321
|
catch: (cause) => cause instanceof EventStoreConflictError ||
|
|
239
322
|
cause instanceof EventStoreFencedError ||
|
|
240
|
-
cause instanceof EventStoreError
|
|
323
|
+
cause instanceof EventStoreError ||
|
|
324
|
+
cause instanceof EventPayloadTooLargeError
|
|
241
325
|
? cause
|
|
242
326
|
: new EventStoreError(`append failed for ${runId}`, cause),
|
|
243
327
|
}),
|
|
@@ -308,7 +392,7 @@ function createSqliteEventStore(exec) {
|
|
|
308
392
|
}
|
|
309
393
|
}));
|
|
310
394
|
})),
|
|
311
|
-
listRuns:
|
|
395
|
+
listRuns: Effect.try({
|
|
312
396
|
try: () => exec
|
|
313
397
|
.rows('SELECT run_id FROM looms_streams ORDER BY run_id ASC')
|
|
314
398
|
.map((row) => decodeRunIdRow(row).run_id),
|
package/dist/core/state.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Schema } from 'effect';
|
|
2
|
+
import { type RuntimeEffect, type WaitCondition } from './effects';
|
|
2
3
|
import type { JsonValue, ThreadStatus, RunStatus } from './types';
|
|
3
4
|
export interface ThreadRecord {
|
|
4
5
|
threadId: string;
|
|
5
6
|
kind: string;
|
|
6
7
|
definitionName: string;
|
|
8
|
+
definitionVersion: string;
|
|
7
9
|
parentThreadId: string | null;
|
|
8
10
|
status: ThreadStatus;
|
|
9
11
|
input: JsonValue;
|
|
@@ -24,20 +26,156 @@ export interface OutstandingEffect {
|
|
|
24
26
|
causingEventId: string;
|
|
25
27
|
effect: RuntimeEffect;
|
|
26
28
|
}
|
|
29
|
+
export interface EffectExecutionRecord {
|
|
30
|
+
effectId: string;
|
|
31
|
+
attempt: number;
|
|
32
|
+
status: 'queued' | 'dispatched' | 'started' | 'heartbeat' | 'retry_wait' | 'cancel_requested' | 'timed_out' | 'ambiguous' | 'running';
|
|
33
|
+
nextAttemptAt: number | null;
|
|
34
|
+
deadlineAt: number | null;
|
|
35
|
+
/** When the current attempt started executing, locally or on a worker. */
|
|
36
|
+
startedAt: number | null;
|
|
37
|
+
lastHeartbeatAt: number | null;
|
|
38
|
+
lastError: string | null;
|
|
39
|
+
}
|
|
40
|
+
export interface RunStartIdentity {
|
|
41
|
+
kind: string;
|
|
42
|
+
definitionName: string;
|
|
43
|
+
definitionVersion: string;
|
|
44
|
+
input: JsonValue;
|
|
45
|
+
requestedThreadId: string | null;
|
|
46
|
+
idempotencyKey: string | null;
|
|
47
|
+
rootThreadId: string;
|
|
48
|
+
}
|
|
27
49
|
export interface RunState {
|
|
28
50
|
runId: string;
|
|
29
51
|
status: RunStatus;
|
|
30
52
|
rootThreadId: string | null;
|
|
53
|
+
startIdentity: RunStartIdentity | null;
|
|
31
54
|
threads: {
|
|
32
55
|
[threadId: string]: ThreadRecord;
|
|
33
56
|
};
|
|
34
57
|
waits: {
|
|
35
58
|
[waitId: string]: WaitRecord;
|
|
36
59
|
};
|
|
37
|
-
outstandingEffects: OutstandingEffect[];
|
|
38
|
-
|
|
39
|
-
|
|
60
|
+
outstandingEffects: readonly OutstandingEffect[];
|
|
61
|
+
effectExecutions: {
|
|
62
|
+
[effectId: string]: EffectExecutionRecord;
|
|
63
|
+
};
|
|
64
|
+
completedEffectIds: readonly string[];
|
|
65
|
+
processedIdempotencyKeys: readonly string[];
|
|
40
66
|
}
|
|
67
|
+
export declare const RunStateSchema: Schema.Struct<{
|
|
68
|
+
readonly runId: Schema.String;
|
|
69
|
+
readonly status: Schema.Union<readonly [Schema.Literal<"running">, Schema.Literal<"completed">, Schema.Literal<"failed">, Schema.Literal<"cancelled">]>;
|
|
70
|
+
readonly rootThreadId: Schema.NullOr<Schema.String>;
|
|
71
|
+
readonly startIdentity: Schema.withDecodingDefaultKey<Schema.NullOr<Schema.Struct<{
|
|
72
|
+
readonly kind: Schema.String;
|
|
73
|
+
readonly definitionName: Schema.String;
|
|
74
|
+
readonly definitionVersion: Schema.String;
|
|
75
|
+
readonly input: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
76
|
+
readonly requestedThreadId: Schema.NullOr<Schema.String>;
|
|
77
|
+
readonly idempotencyKey: Schema.NullOr<Schema.String>;
|
|
78
|
+
readonly rootThreadId: Schema.String;
|
|
79
|
+
}>>, never>;
|
|
80
|
+
readonly threads: Schema.$Record<Schema.String, Schema.Struct<{
|
|
81
|
+
readonly threadId: Schema.String;
|
|
82
|
+
readonly kind: Schema.String;
|
|
83
|
+
readonly definitionName: Schema.String;
|
|
84
|
+
readonly definitionVersion: Schema.withDecodingDefaultKey<Schema.String, never>;
|
|
85
|
+
readonly parentThreadId: Schema.NullOr<Schema.String>;
|
|
86
|
+
readonly status: Schema.Union<readonly [Schema.Literal<"running">, Schema.Literal<"waiting">, Schema.Literal<"completed">, Schema.Literal<"failed">, Schema.Literal<"cancelled">]>;
|
|
87
|
+
readonly input: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
88
|
+
readonly output: Schema.NullOr<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
89
|
+
readonly error: Schema.NullOr<Schema.String>;
|
|
90
|
+
readonly state: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
91
|
+
}>>;
|
|
92
|
+
readonly waits: Schema.$Record<Schema.String, Schema.Struct<{
|
|
93
|
+
readonly waitId: Schema.String;
|
|
94
|
+
readonly threadId: Schema.String;
|
|
95
|
+
readonly on: Schema.Union<readonly [Schema.Struct<{
|
|
96
|
+
readonly type: Schema.Union<readonly [Schema.String, Schema.$Array<Schema.String>]>;
|
|
97
|
+
readonly match: Schema.optional<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
98
|
+
}>, Schema.Struct<{
|
|
99
|
+
readonly timerAt: Schema.Finite;
|
|
100
|
+
}>]>;
|
|
101
|
+
readonly tag: Schema.optional<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
102
|
+
}>>;
|
|
103
|
+
readonly outstandingEffects: Schema.$Array<Schema.Struct<{
|
|
104
|
+
readonly effectId: Schema.String;
|
|
105
|
+
readonly threadId: Schema.String;
|
|
106
|
+
readonly causingSeq: Schema.Finite;
|
|
107
|
+
readonly causingEventId: Schema.String;
|
|
108
|
+
readonly effect: Schema.Union<readonly [Schema.Struct<{
|
|
109
|
+
readonly type: Schema.Literal<"runtime.spawn">;
|
|
110
|
+
readonly childThreadId: Schema.String;
|
|
111
|
+
readonly kind: Schema.String;
|
|
112
|
+
readonly definitionName: Schema.String;
|
|
113
|
+
readonly definitionVersion: Schema.withDecodingDefaultKey<Schema.String, never>;
|
|
114
|
+
readonly input: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
115
|
+
}>, Schema.Struct<{
|
|
116
|
+
readonly type: Schema.Literal<"runtime.wait">;
|
|
117
|
+
readonly waitId: Schema.String;
|
|
118
|
+
readonly on: Schema.Union<readonly [Schema.Struct<{
|
|
119
|
+
readonly type: Schema.Union<readonly [Schema.String, Schema.$Array<Schema.String>]>;
|
|
120
|
+
readonly match: Schema.optional<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
121
|
+
}>, Schema.Struct<{
|
|
122
|
+
readonly timerAt: Schema.Finite;
|
|
123
|
+
}>]>;
|
|
124
|
+
readonly tag: Schema.optional<Schema.Codec<Schema.Json, Schema.Json, never, never>>;
|
|
125
|
+
}>, Schema.Struct<{
|
|
126
|
+
readonly type: Schema.Literal<"runtime.emit">;
|
|
127
|
+
readonly event: Schema.Struct<{
|
|
128
|
+
readonly type: Schema.String;
|
|
129
|
+
readonly payload: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
130
|
+
readonly threadId: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
131
|
+
readonly parentThreadId: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
132
|
+
readonly causationId: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
133
|
+
readonly correlationId: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
134
|
+
readonly effectId: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
135
|
+
readonly origin: Schema.optional<Schema.Union<readonly [Schema.Struct<{
|
|
136
|
+
readonly type: Schema.Literal<"thread">;
|
|
137
|
+
readonly threadId: Schema.String;
|
|
138
|
+
}>, Schema.Struct<{
|
|
139
|
+
readonly type: Schema.Literal<"external">;
|
|
140
|
+
readonly actorId: Schema.optional<Schema.String>;
|
|
141
|
+
}>, Schema.Struct<{
|
|
142
|
+
readonly type: Schema.Literal<"system">;
|
|
143
|
+
}>]>>;
|
|
144
|
+
readonly ephemeral: Schema.optional<Schema.Boolean>;
|
|
145
|
+
readonly id: Schema.optional<Schema.String>;
|
|
146
|
+
readonly ts: Schema.optional<Schema.Finite>;
|
|
147
|
+
readonly idempotencyKey: Schema.optional<Schema.NullOr<Schema.String>>;
|
|
148
|
+
}>;
|
|
149
|
+
readonly tag: Schema.optional<Schema.String>;
|
|
150
|
+
}>, Schema.Struct<{
|
|
151
|
+
readonly type: Schema.Literal<"runtime.complete">;
|
|
152
|
+
readonly output: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
153
|
+
}>, Schema.Struct<{
|
|
154
|
+
readonly type: Schema.Literal<"runtime.fail">;
|
|
155
|
+
readonly error: Schema.String;
|
|
156
|
+
}>, Schema.Struct<{
|
|
157
|
+
readonly type: Schema.Literal<"runtime.cancel">;
|
|
158
|
+
readonly threadId: Schema.String;
|
|
159
|
+
readonly tag: Schema.optional<Schema.String>;
|
|
160
|
+
}>, Schema.Struct<{
|
|
161
|
+
readonly type: Schema.String;
|
|
162
|
+
readonly input: Schema.Codec<Schema.Json, Schema.Json, never, never>;
|
|
163
|
+
readonly tag: Schema.optional<Schema.String>;
|
|
164
|
+
}>]>;
|
|
165
|
+
}>>;
|
|
166
|
+
readonly effectExecutions: Schema.withDecodingDefaultKey<Schema.$Record<Schema.String, Schema.Struct<{
|
|
167
|
+
readonly effectId: Schema.String;
|
|
168
|
+
readonly attempt: Schema.Finite;
|
|
169
|
+
readonly status: Schema.Union<readonly [Schema.Literal<"queued">, Schema.Literal<"dispatched">, Schema.Literal<"started">, Schema.Literal<"heartbeat">, Schema.Literal<"retry_wait">, Schema.Literal<"cancel_requested">, Schema.Literal<"timed_out">, Schema.Literal<"ambiguous">, Schema.Literal<"running">]>;
|
|
170
|
+
readonly nextAttemptAt: Schema.NullOr<Schema.Finite>;
|
|
171
|
+
readonly deadlineAt: Schema.withDecodingDefaultKey<Schema.NullOr<Schema.Finite>, never>;
|
|
172
|
+
readonly startedAt: Schema.withDecodingDefaultKey<Schema.NullOr<Schema.Finite>, never>;
|
|
173
|
+
readonly lastHeartbeatAt: Schema.withDecodingDefaultKey<Schema.NullOr<Schema.Finite>, never>;
|
|
174
|
+
readonly lastError: Schema.NullOr<Schema.String>;
|
|
175
|
+
}>>, never>;
|
|
176
|
+
readonly completedEffectIds: Schema.withDecodingDefaultKey<Schema.$Array<Schema.String>, never>;
|
|
177
|
+
readonly processedIdempotencyKeys: Schema.withDecodingDefaultKey<Schema.$Array<Schema.String>, never>;
|
|
178
|
+
}>;
|
|
41
179
|
export declare function emptyRunState(runId: string): RunState;
|
|
42
180
|
export declare function isRunTerminal(state: RunState): boolean;
|
|
43
181
|
export declare function isRunParked(state: RunState): boolean;
|
package/dist/core/state.js
CHANGED
|
@@ -1,11 +1,89 @@
|
|
|
1
|
+
import { Effect, Schema } from 'effect';
|
|
2
|
+
import { RuntimeEffectSchema, WaitConditionSchema, } from './effects.js';
|
|
3
|
+
import { JsonValueSchema } from './envelope.js';
|
|
4
|
+
import { DEFAULT_DEFINITION_VERSION } from './module.js';
|
|
5
|
+
export const RunStateSchema = Schema.Struct({
|
|
6
|
+
runId: Schema.String,
|
|
7
|
+
status: Schema.Union([
|
|
8
|
+
Schema.Literal('running'),
|
|
9
|
+
Schema.Literal('completed'),
|
|
10
|
+
Schema.Literal('failed'),
|
|
11
|
+
Schema.Literal('cancelled'),
|
|
12
|
+
]),
|
|
13
|
+
rootThreadId: Schema.NullOr(Schema.String),
|
|
14
|
+
startIdentity: Schema.NullOr(Schema.Struct({
|
|
15
|
+
kind: Schema.String,
|
|
16
|
+
definitionName: Schema.String,
|
|
17
|
+
definitionVersion: Schema.String,
|
|
18
|
+
input: JsonValueSchema,
|
|
19
|
+
requestedThreadId: Schema.NullOr(Schema.String),
|
|
20
|
+
idempotencyKey: Schema.NullOr(Schema.String),
|
|
21
|
+
rootThreadId: Schema.String,
|
|
22
|
+
})).pipe(Schema.withDecodingDefaultKey(Effect.succeed(null))),
|
|
23
|
+
threads: Schema.Record(Schema.String, Schema.Struct({
|
|
24
|
+
threadId: Schema.String,
|
|
25
|
+
kind: Schema.String,
|
|
26
|
+
definitionName: Schema.String,
|
|
27
|
+
definitionVersion: Schema.String.pipe(Schema.withDecodingDefaultKey(Effect.succeed(DEFAULT_DEFINITION_VERSION))),
|
|
28
|
+
parentThreadId: Schema.NullOr(Schema.String),
|
|
29
|
+
status: Schema.Union([
|
|
30
|
+
Schema.Literal('running'),
|
|
31
|
+
Schema.Literal('waiting'),
|
|
32
|
+
Schema.Literal('completed'),
|
|
33
|
+
Schema.Literal('failed'),
|
|
34
|
+
Schema.Literal('cancelled'),
|
|
35
|
+
]),
|
|
36
|
+
input: JsonValueSchema,
|
|
37
|
+
output: Schema.NullOr(JsonValueSchema),
|
|
38
|
+
error: Schema.NullOr(Schema.String),
|
|
39
|
+
state: JsonValueSchema,
|
|
40
|
+
})),
|
|
41
|
+
waits: Schema.Record(Schema.String, Schema.Struct({
|
|
42
|
+
waitId: Schema.String,
|
|
43
|
+
threadId: Schema.String,
|
|
44
|
+
on: WaitConditionSchema,
|
|
45
|
+
tag: Schema.optional(JsonValueSchema),
|
|
46
|
+
})),
|
|
47
|
+
outstandingEffects: Schema.Array(Schema.Struct({
|
|
48
|
+
effectId: Schema.String,
|
|
49
|
+
threadId: Schema.String,
|
|
50
|
+
causingSeq: Schema.Finite,
|
|
51
|
+
causingEventId: Schema.String,
|
|
52
|
+
effect: RuntimeEffectSchema,
|
|
53
|
+
})),
|
|
54
|
+
effectExecutions: Schema.Record(Schema.String, Schema.Struct({
|
|
55
|
+
effectId: Schema.String,
|
|
56
|
+
attempt: Schema.Finite,
|
|
57
|
+
status: Schema.Union([
|
|
58
|
+
Schema.Literal('queued'),
|
|
59
|
+
Schema.Literal('dispatched'),
|
|
60
|
+
Schema.Literal('started'),
|
|
61
|
+
Schema.Literal('heartbeat'),
|
|
62
|
+
Schema.Literal('retry_wait'),
|
|
63
|
+
Schema.Literal('cancel_requested'),
|
|
64
|
+
Schema.Literal('timed_out'),
|
|
65
|
+
Schema.Literal('ambiguous'),
|
|
66
|
+
Schema.Literal('running'),
|
|
67
|
+
]),
|
|
68
|
+
nextAttemptAt: Schema.NullOr(Schema.Finite),
|
|
69
|
+
deadlineAt: Schema.NullOr(Schema.Finite).pipe(Schema.withDecodingDefaultKey(Effect.succeed(null))),
|
|
70
|
+
startedAt: Schema.NullOr(Schema.Finite).pipe(Schema.withDecodingDefaultKey(Effect.succeed(null))),
|
|
71
|
+
lastHeartbeatAt: Schema.NullOr(Schema.Finite).pipe(Schema.withDecodingDefaultKey(Effect.succeed(null))),
|
|
72
|
+
lastError: Schema.NullOr(Schema.String),
|
|
73
|
+
})).pipe(Schema.withDecodingDefaultKey(Effect.succeed({}))),
|
|
74
|
+
completedEffectIds: Schema.Array(Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed([]))),
|
|
75
|
+
processedIdempotencyKeys: Schema.Array(Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed([]))),
|
|
76
|
+
});
|
|
1
77
|
export function emptyRunState(runId) {
|
|
2
78
|
return {
|
|
3
79
|
runId,
|
|
4
80
|
status: 'running',
|
|
5
81
|
rootThreadId: null,
|
|
82
|
+
startIdentity: null,
|
|
6
83
|
threads: {},
|
|
7
84
|
waits: {},
|
|
8
85
|
outstandingEffects: [],
|
|
86
|
+
effectExecutions: {},
|
|
9
87
|
completedEffectIds: [],
|
|
10
88
|
processedIdempotencyKeys: [],
|
|
11
89
|
};
|
package/dist/core/store.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Context, Effect, Layer, Stream } from 'effect';
|
|
2
2
|
import { type AppendableEvent, type EventEnvelope } from './envelope';
|
|
3
|
+
import { EventPayloadTooLargeError } from './limits';
|
|
3
4
|
declare const EventStoreError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
4
5
|
readonly _tag: "EventStoreError";
|
|
5
6
|
} & Readonly<A>;
|
|
@@ -59,8 +60,31 @@ export declare class EventStoreFencedError extends EventStoreFencedError_base<{
|
|
|
59
60
|
}> {
|
|
60
61
|
constructor(runId: string, token: string);
|
|
61
62
|
}
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
declare const UnsafeEventStoreTrimError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
64
|
+
readonly _tag: "UnsafeEventStoreTrimError";
|
|
65
|
+
} & Readonly<A>;
|
|
66
|
+
export declare class UnsafeEventStoreTrimError extends UnsafeEventStoreTrimError_base<{
|
|
67
|
+
readonly runId: string;
|
|
68
|
+
readonly trimThrough: number;
|
|
69
|
+
readonly message: string;
|
|
70
|
+
}> {
|
|
71
|
+
constructor(runId: string, trimThrough: number);
|
|
72
|
+
}
|
|
73
|
+
export type EventStoreTrimCoverage = {
|
|
74
|
+
/** Durable archive contains every event through this sequence. */
|
|
75
|
+
readonly archiveCursor: number;
|
|
76
|
+
readonly requiredProjectors?: never;
|
|
77
|
+
readonly projectorCursors?: never;
|
|
78
|
+
} | {
|
|
79
|
+
readonly archiveCursor?: never;
|
|
80
|
+
/** Authoritative identities of every projector required before trimming. */
|
|
81
|
+
readonly requiredProjectors: readonly string[];
|
|
82
|
+
/** Durable checkpoint by projector identity. Every required projector must be present. */
|
|
83
|
+
readonly projectorCursors: Readonly<Record<string, number>>;
|
|
84
|
+
};
|
|
85
|
+
export declare function trimEventStoreSafely(store: EventStore, runId: string, beforeSeq: number, coverage: EventStoreTrimCoverage): Effect.Effect<void, EventStoreError | UnsafeEventStoreTrimError>;
|
|
86
|
+
export type EventStoreAppendError = EventStoreError | EventStoreConflictError | EventStoreFencedError | EventPayloadTooLargeError;
|
|
87
|
+
export type AnyEventStoreError = EventStoreError | EventStoreConflictError | EventStoreTruncationError | EventStoreTrimmedError | EventStoreFencedError | EventPayloadTooLargeError;
|
|
64
88
|
export declare function isEventStoreError(err: unknown): err is AnyEventStoreError;
|
|
65
89
|
export interface StreamBounds {
|
|
66
90
|
readonly head: number;
|
|
@@ -68,6 +92,16 @@ export interface StreamBounds {
|
|
|
68
92
|
}
|
|
69
93
|
export interface AppendOptions {
|
|
70
94
|
readonly expectedTail?: number;
|
|
95
|
+
/**
|
|
96
|
+
* Atomically claims an ingress command with the append. Reusing the key
|
|
97
|
+
* returns a deduplicated result without appending events. Stores without a
|
|
98
|
+
* command table may ignore this; callers must pair it with `expectedTail`
|
|
99
|
+
* so a retried command conflicts instead of appending twice.
|
|
100
|
+
*/
|
|
101
|
+
readonly idempotency?: {
|
|
102
|
+
readonly key: string;
|
|
103
|
+
readonly fingerprint?: string;
|
|
104
|
+
};
|
|
71
105
|
/** Set the stream fencing token atomically in this batch (`''` clears). */
|
|
72
106
|
readonly fence?: string;
|
|
73
107
|
/** Must match the stream's current fencing token, or the append fails. */
|
|
@@ -92,6 +126,7 @@ export declare function paginatePages<T, SCursor, E = never, R = never>(options:
|
|
|
92
126
|
export interface AppendResult {
|
|
93
127
|
sequences: number[];
|
|
94
128
|
tail: number;
|
|
129
|
+
deduplicated?: boolean;
|
|
95
130
|
}
|
|
96
131
|
export interface EventStore {
|
|
97
132
|
readonly append: (runId: string, events: ReadonlyArray<AppendableEvent>, options?: AppendOptions) => Effect.Effect<AppendResult, EventStoreAppendError>;
|
|
@@ -128,7 +163,7 @@ export interface EventStore {
|
|
|
128
163
|
readonly subscribe: (runId: string, options?: {
|
|
129
164
|
fromSeq?: number;
|
|
130
165
|
}) => Stream.Stream<EventEnvelope, EventStoreError>;
|
|
131
|
-
readonly listRuns:
|
|
166
|
+
readonly listRuns: Effect.Effect<string[], EventStoreError>;
|
|
132
167
|
}
|
|
133
168
|
/**
|
|
134
169
|
* Utility to read an EventStore as a Stream.Stream, using `store.readStream` if implemented
|