@swirls/looms 0.1.0 → 0.3.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 +37 -0
- package/dist/actor/host.js +4 -5
- package/dist/actor/index.d.ts +1 -1
- package/dist/actor/index.js +1 -1
- package/dist/actor/routing.d.ts +5 -0
- package/dist/actor/routing.js +14 -0
- package/dist/agent/agent-session.js +1 -0
- package/dist/agent/debugger/agent-chat.d.ts +2 -0
- package/dist/agent/debugger/agent-chat.js +210 -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 +53 -0
- package/dist/agent/debugger/token-usage.d.ts +3 -0
- package/dist/agent/debugger/token-usage.js +11 -0
- package/dist/agent/definitions.d.ts +3 -11
- package/dist/agent/definitions.js +5 -6
- package/dist/agent/effects.d.ts +30 -0
- package/dist/agent/events.d.ts +2 -0
- package/dist/agent/events.js +2 -0
- package/dist/agent/llm.js +1 -8
- package/dist/agent/module.d.ts +604 -534
- package/dist/agent/module.js +11 -7
- package/dist/agent/projections.d.ts +5 -0
- package/dist/agent/projections.js +43 -2
- package/dist/agent/scope.d.ts +2 -0
- package/dist/agent/signals.d.ts +7 -0
- package/dist/agent/signals.js +25 -16
- package/dist/agent/threads.js +35 -21
- package/dist/agent/tool-schema.d.ts +1 -17
- package/dist/agent/tool-schema.js +3 -42
- package/dist/agent/transcript.d.ts +7 -0
- package/dist/agent/transcript.js +19 -0
- package/dist/agent/types.d.ts +10 -0
- package/dist/agent/types.js +4 -0
- package/dist/ai-vercel/index.d.ts +1 -1
- package/dist/ai-vercel/vercel-evaluator.d.ts +21 -8
- package/dist/ai-vercel/vercel-evaluator.js +7 -2
- package/dist/approval/debugger/approvals-view.d.ts +3 -0
- package/dist/approval/debugger/approvals-view.js +18 -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 +12 -0
- package/dist/approval/module.d.ts +24 -0
- package/dist/client/client.d.ts +310 -0
- package/dist/client/client.js +20 -2
- package/dist/cloudflare/router.d.ts +1 -1
- package/dist/cloudflare/router.js +6 -8
- package/dist/core/compose.js +1 -0
- package/dist/core/debugger-host.d.ts +16 -0
- package/dist/core/debugger-host.js +1 -0
- package/dist/core/effects.d.ts +7 -0
- package/dist/core/effects.js +1 -0
- package/dist/core/fold.js +12 -6
- package/dist/core/fork.d.ts +35 -0
- package/dist/core/fork.js +129 -0
- package/dist/core/index.d.ts +3 -0
- package/dist/core/index.js +2 -0
- package/dist/core/module-scope.d.ts +1 -0
- package/dist/core/module.d.ts +4 -2
- package/dist/core/projection.js +1 -0
- package/dist/core/protocol.d.ts +10 -1
- package/dist/core/protocol.js +11 -0
- package/dist/core/published.d.ts +43 -0
- package/dist/core/published.js +44 -0
- package/dist/core/replay.d.ts +8 -0
- package/dist/core/schema.d.ts +3 -1
- package/dist/core/schema.js +38 -0
- package/dist/core/snapshot-store.d.ts +4 -0
- package/dist/core/snapshot-store.js +7 -0
- package/dist/core/snapshots.js +3 -17
- package/dist/core/sqlite-store.js +39 -0
- package/dist/core/state.d.ts +14 -0
- package/dist/core/state.js +25 -2
- package/dist/core/store.d.ts +1 -0
- package/dist/debugger/app/assets/index-BevQYa-U.js +22 -0
- package/dist/debugger/app/assets/index-CgDzWJg7.css +2 -0
- package/dist/debugger/app/assets/rolldown-runtime-CbXtAM7H.js +1 -0
- package/dist/debugger/app/assets/routes-B17Om93i.js +47 -0
- package/dist/debugger/app/index.html +14 -0
- package/dist/debugger/components/composer.d.ts +20 -0
- package/dist/debugger/components/composer.js +26 -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 +12 -71
- 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 +50 -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 +25 -17
- package/dist/debugger/events/protocol-summarize.d.ts +1 -2
- package/dist/debugger/events/protocol-summarize.js +36 -37
- 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-counts.d.ts +2 -2
- package/dist/debugger/lib/event-counts.js +5 -9
- package/dist/debugger/lib/event-meta.d.ts +2 -3
- package/dist/debugger/lib/event-meta.js +6 -11
- 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 +5 -0
- package/dist/debugger/shell/run-controls.js +99 -0
- package/dist/debugger/shell/run-search.d.ts +6 -0
- package/dist/debugger/shell/run-search.js +100 -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/effects.d.ts +12 -0
- package/dist/evaluator/module.d.ts +24 -0
- package/dist/projectors/index-model.d.ts +13 -7
- package/dist/projectors/index-model.js +21 -26
- package/dist/projectors/memory.js +19 -11
- package/dist/projectors/postgres.js +20 -19
- package/dist/projectors/schema.js +20 -18
- package/dist/projectors/sqlite.js +32 -27
- package/dist/react/materialize.js +16 -11
- package/dist/react/react.d.ts +6 -2
- package/dist/react/react.js +5 -2
- package/dist/react/store.d.ts +1 -1
- package/dist/react/store.js +1 -1
- package/dist/react/tables.d.ts +3 -2
- package/dist/runtime/cancellation.js +14 -27
- package/dist/runtime/errors.d.ts +39 -0
- package/dist/runtime/errors.js +32 -0
- package/dist/runtime/helpers.d.ts +2 -0
- package/dist/runtime/helpers.js +23 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/looms.d.ts +13 -1
- package/dist/runtime/looms.js +5 -2
- package/dist/runtime/repository.js +16 -1
- package/dist/runtime/run-start.js +1 -3
- package/dist/runtime/runtime.d.ts +1 -1
- package/dist/runtime/runtime.js +60 -18
- package/dist/runtime/server/auth.d.ts +1 -0
- package/dist/runtime/server/auth.js +5 -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 +5 -1
- package/dist/runtime/server/fetch-handler.js +24 -13
- package/dist/runtime/server/http.d.ts +3 -0
- package/dist/runtime/server/http.js +21 -2
- package/dist/runtime/server/routes/definitions.d.ts +3 -0
- package/dist/runtime/server/routes/definitions.js +20 -0
- package/dist/runtime/server/routes/runs.js +43 -3
- package/dist/runtime/server.d.ts +3 -1
- package/dist/runtime/server.js +3 -1
- package/dist/runtime/types.d.ts +11 -1
- package/dist/runtime/wake-engine.js +5 -2
- package/dist/s2/snapshot-store.js +45 -7
- 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/effects.d.ts +24 -0
- package/dist/workflow/effects.js +1 -0
- package/dist/workflow/module.d.ts +48 -0
- package/package.json +20 -1
- 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
|
@@ -12,9 +12,9 @@ function applyOp(sql, op) {
|
|
|
12
12
|
switch (op.type) {
|
|
13
13
|
case 'upsertActor':
|
|
14
14
|
return sql `
|
|
15
|
-
INSERT INTO
|
|
16
|
-
VALUES (${op.actorId}, ${op.kind}, ${op.status}, ${op.definitionName}, ${op.parentActorId}, ${date})
|
|
17
|
-
ON CONFLICT (actor_id) DO UPDATE SET
|
|
15
|
+
INSERT INTO looms_run_actors (run_id, actor_id, kind, status, definition_name, parent_actor_id, updated_at)
|
|
16
|
+
VALUES (${op.runId}, ${op.actorId}, ${op.kind}, ${op.status}, ${op.definitionName}, ${op.parentActorId}, ${date})
|
|
17
|
+
ON CONFLICT (run_id, actor_id) DO UPDATE SET
|
|
18
18
|
kind = EXCLUDED.kind,
|
|
19
19
|
status = EXCLUDED.status,
|
|
20
20
|
definition_name = EXCLUDED.definition_name,
|
|
@@ -23,24 +23,24 @@ function applyOp(sql, op) {
|
|
|
23
23
|
`;
|
|
24
24
|
case 'setActorStatus':
|
|
25
25
|
return sql `
|
|
26
|
-
INSERT INTO
|
|
27
|
-
VALUES (${op.actorId}, ${op.status}, ${date})
|
|
28
|
-
ON CONFLICT (actor_id) DO UPDATE SET
|
|
26
|
+
INSERT INTO looms_run_actors (run_id, actor_id, status, updated_at)
|
|
27
|
+
VALUES (${op.runId}, ${op.actorId}, ${op.status}, ${date})
|
|
28
|
+
ON CONFLICT (run_id, actor_id) DO UPDATE SET
|
|
29
29
|
status = EXCLUDED.status,
|
|
30
30
|
updated_at = EXCLUDED.updated_at
|
|
31
31
|
`;
|
|
32
32
|
case 'upsertReview':
|
|
33
33
|
return sql `
|
|
34
|
-
INSERT INTO
|
|
35
|
-
VALUES (${op.
|
|
36
|
-
ON CONFLICT (review_id) DO UPDATE SET
|
|
34
|
+
INSERT INTO looms_run_reviews (run_id, review_id, status, title, updated_at)
|
|
35
|
+
VALUES (${op.runId}, ${op.reviewId}, ${op.status}, ${op.title}, ${date})
|
|
36
|
+
ON CONFLICT (run_id, review_id) DO UPDATE SET
|
|
37
37
|
status = EXCLUDED.status,
|
|
38
38
|
updated_at = EXCLUDED.updated_at
|
|
39
39
|
`;
|
|
40
40
|
case 'setReviewStatus':
|
|
41
41
|
return sql `
|
|
42
|
-
UPDATE
|
|
43
|
-
WHERE review_id = ${op.reviewId}
|
|
42
|
+
UPDATE looms_run_reviews SET status = ${op.status}, updated_at = ${date}
|
|
43
|
+
WHERE run_id = ${op.runId} AND review_id = ${op.reviewId}
|
|
44
44
|
`;
|
|
45
45
|
default: {
|
|
46
46
|
const exhaustiveCheck = op;
|
|
@@ -56,13 +56,14 @@ export function postgres(options) {
|
|
|
56
56
|
applyOps: (ops) => runProjectorPromise('postgres', () => sql.begin((tx) => Effect.runPromise(Effect.forEach(ops, (op) => Effect.promise(() => Promise.resolve(applyOp(tx, op))), {
|
|
57
57
|
discard: true,
|
|
58
58
|
})))).then(() => undefined),
|
|
59
|
-
getActor: (actorId) => runProjectorPromise('postgres', () => sql `
|
|
60
|
-
SELECT actor_id, kind, status, definition_name, parent_actor_id, updated_at
|
|
61
|
-
FROM
|
|
59
|
+
getActor: (runId, actorId) => runProjectorPromise('postgres', () => sql `
|
|
60
|
+
SELECT run_id, actor_id, kind, status, definition_name, parent_actor_id, updated_at
|
|
61
|
+
FROM looms_run_actors WHERE run_id = ${runId} AND actor_id = ${actorId}
|
|
62
62
|
`).then((rows) => {
|
|
63
63
|
const row = rows[0];
|
|
64
64
|
return row
|
|
65
65
|
? {
|
|
66
|
+
runId: row.run_id,
|
|
66
67
|
actorId: row.actor_id,
|
|
67
68
|
kind: row.kind,
|
|
68
69
|
status: row.status,
|
|
@@ -72,16 +73,16 @@ export function postgres(options) {
|
|
|
72
73
|
}
|
|
73
74
|
: null;
|
|
74
75
|
}),
|
|
75
|
-
listReviews: (
|
|
76
|
+
listReviews: (runId) => runProjectorPromise('postgres', () => runId
|
|
76
77
|
? sql `
|
|
77
|
-
SELECT
|
|
78
|
-
FROM
|
|
78
|
+
SELECT run_id, review_id, status, title, updated_at
|
|
79
|
+
FROM looms_run_reviews WHERE run_id = ${runId}
|
|
79
80
|
`
|
|
80
81
|
: sql `
|
|
81
|
-
SELECT
|
|
82
|
+
SELECT run_id, review_id, status, title, updated_at FROM looms_run_reviews
|
|
82
83
|
`).then((rows) => rows.map((row) => ({
|
|
84
|
+
runId: row.run_id,
|
|
83
85
|
reviewId: row.review_id,
|
|
84
|
-
actorId: row.actor_id,
|
|
85
86
|
status: row.status,
|
|
86
87
|
title: row.title,
|
|
87
88
|
updatedAt: row.updated_at.getTime(),
|
|
@@ -2,42 +2,44 @@
|
|
|
2
2
|
* SQL schema for the optional Looms secondary index.
|
|
3
3
|
*/
|
|
4
4
|
export const POSTGRES_SCHEMA_SQL = `
|
|
5
|
-
CREATE TABLE IF NOT EXISTS
|
|
6
|
-
|
|
5
|
+
CREATE TABLE IF NOT EXISTS looms_run_actors (
|
|
6
|
+
run_id TEXT NOT NULL,
|
|
7
|
+
actor_id TEXT NOT NULL,
|
|
7
8
|
kind TEXT,
|
|
8
9
|
status TEXT,
|
|
9
10
|
definition_name TEXT,
|
|
10
11
|
parent_actor_id TEXT,
|
|
11
|
-
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
12
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
13
|
+
PRIMARY KEY (run_id, actor_id)
|
|
12
14
|
);
|
|
13
15
|
|
|
14
|
-
CREATE TABLE IF NOT EXISTS
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
CREATE TABLE IF NOT EXISTS looms_run_reviews (
|
|
17
|
+
run_id TEXT NOT NULL,
|
|
18
|
+
review_id TEXT NOT NULL,
|
|
17
19
|
status TEXT NOT NULL,
|
|
18
20
|
title TEXT NOT NULL,
|
|
19
|
-
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
21
|
+
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
22
|
+
PRIMARY KEY (run_id, review_id)
|
|
20
23
|
);
|
|
21
|
-
|
|
22
|
-
CREATE INDEX IF NOT EXISTS looms_reviews_actor_id_idx ON looms_reviews (actor_id);
|
|
23
24
|
`.trim();
|
|
24
25
|
export const SQLITE_SCHEMA_SQL = `
|
|
25
|
-
CREATE TABLE IF NOT EXISTS
|
|
26
|
-
|
|
26
|
+
CREATE TABLE IF NOT EXISTS looms_run_actors (
|
|
27
|
+
run_id TEXT NOT NULL,
|
|
28
|
+
actor_id TEXT NOT NULL,
|
|
27
29
|
kind TEXT,
|
|
28
30
|
status TEXT,
|
|
29
31
|
definition_name TEXT,
|
|
30
32
|
parent_actor_id TEXT,
|
|
31
|
-
updated_at INTEGER NOT NULL
|
|
33
|
+
updated_at INTEGER NOT NULL,
|
|
34
|
+
PRIMARY KEY (run_id, actor_id)
|
|
32
35
|
);
|
|
33
36
|
|
|
34
|
-
CREATE TABLE IF NOT EXISTS
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
CREATE TABLE IF NOT EXISTS looms_run_reviews (
|
|
38
|
+
run_id TEXT NOT NULL,
|
|
39
|
+
review_id TEXT NOT NULL,
|
|
37
40
|
status TEXT NOT NULL,
|
|
38
41
|
title TEXT NOT NULL,
|
|
39
|
-
updated_at INTEGER NOT NULL
|
|
42
|
+
updated_at INTEGER NOT NULL,
|
|
43
|
+
PRIMARY KEY (run_id, review_id)
|
|
40
44
|
);
|
|
41
|
-
|
|
42
|
-
CREATE INDEX IF NOT EXISTS looms_reviews_actor_id_idx ON looms_reviews (actor_id);
|
|
43
45
|
`.trim();
|
|
@@ -9,35 +9,39 @@ function hasDb(options) {
|
|
|
9
9
|
function applyOp(db, op) {
|
|
10
10
|
switch (op.type) {
|
|
11
11
|
case 'upsertActor':
|
|
12
|
-
db.run(`INSERT INTO
|
|
13
|
-
VALUES (?, ?, ?, ?, ?, ?)
|
|
14
|
-
ON CONFLICT (actor_id) DO UPDATE SET
|
|
12
|
+
db.run(`INSERT INTO looms_run_actors (run_id, actor_id, kind, status, definition_name, parent_actor_id, updated_at)
|
|
13
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
14
|
+
ON CONFLICT (run_id, actor_id) DO UPDATE SET
|
|
15
15
|
kind = excluded.kind,
|
|
16
16
|
status = excluded.status,
|
|
17
17
|
definition_name = excluded.definition_name,
|
|
18
18
|
parent_actor_id = excluded.parent_actor_id,
|
|
19
|
-
updated_at = excluded.updated_at`, [
|
|
19
|
+
updated_at = excluded.updated_at`, [
|
|
20
|
+
op.runId,
|
|
21
|
+
op.actorId,
|
|
22
|
+
op.kind,
|
|
23
|
+
op.status,
|
|
24
|
+
op.definitionName,
|
|
25
|
+
op.parentActorId,
|
|
26
|
+
op.updatedAt,
|
|
27
|
+
]);
|
|
20
28
|
return;
|
|
21
29
|
case 'setActorStatus':
|
|
22
|
-
db.run(`INSERT INTO
|
|
23
|
-
VALUES (?, ?, ?)
|
|
24
|
-
ON CONFLICT (actor_id) DO UPDATE SET
|
|
30
|
+
db.run(`INSERT INTO looms_run_actors (run_id, actor_id, status, updated_at)
|
|
31
|
+
VALUES (?, ?, ?, ?)
|
|
32
|
+
ON CONFLICT (run_id, actor_id) DO UPDATE SET
|
|
25
33
|
status = excluded.status,
|
|
26
|
-
updated_at = excluded.updated_at`, [op.actorId, op.status, op.updatedAt]);
|
|
34
|
+
updated_at = excluded.updated_at`, [op.runId, op.actorId, op.status, op.updatedAt]);
|
|
27
35
|
return;
|
|
28
36
|
case 'upsertReview':
|
|
29
|
-
db.run(`INSERT INTO
|
|
37
|
+
db.run(`INSERT INTO looms_run_reviews (run_id, review_id, status, title, updated_at)
|
|
30
38
|
VALUES (?, ?, ?, ?, ?)
|
|
31
|
-
ON CONFLICT (review_id) DO UPDATE SET
|
|
39
|
+
ON CONFLICT (run_id, review_id) DO UPDATE SET
|
|
32
40
|
status = excluded.status,
|
|
33
|
-
updated_at = excluded.updated_at`, [op.
|
|
41
|
+
updated_at = excluded.updated_at`, [op.runId, op.reviewId, op.status, op.title, op.updatedAt]);
|
|
34
42
|
return;
|
|
35
43
|
case 'setReviewStatus':
|
|
36
|
-
db.run(`UPDATE
|
|
37
|
-
op.status,
|
|
38
|
-
op.updatedAt,
|
|
39
|
-
op.reviewId,
|
|
40
|
-
]);
|
|
44
|
+
db.run(`UPDATE looms_run_reviews SET status = ?, updated_at = ? WHERE run_id = ? AND review_id = ?`, [op.status, op.updatedAt, op.runId, op.reviewId]);
|
|
41
45
|
return;
|
|
42
46
|
default: {
|
|
43
47
|
const exhaustiveCheck = op;
|
|
@@ -60,13 +64,14 @@ export function sqlite(options = {}) {
|
|
|
60
64
|
});
|
|
61
65
|
apply(ops);
|
|
62
66
|
}),
|
|
63
|
-
getActor: (actorId) => runProjectorSync('sqlite', () => {
|
|
67
|
+
getActor: (runId, actorId) => runProjectorSync('sqlite', () => {
|
|
64
68
|
const row = db
|
|
65
|
-
.query(`SELECT actor_id, kind, status, definition_name, parent_actor_id, updated_at
|
|
66
|
-
FROM
|
|
67
|
-
.get(actorId);
|
|
69
|
+
.query(`SELECT run_id, actor_id, kind, status, definition_name, parent_actor_id, updated_at
|
|
70
|
+
FROM looms_run_actors WHERE run_id = ? AND actor_id = ?`)
|
|
71
|
+
.get(runId, actorId);
|
|
68
72
|
return row
|
|
69
73
|
? {
|
|
74
|
+
runId: row.run_id,
|
|
70
75
|
actorId: row.actor_id,
|
|
71
76
|
kind: row.kind,
|
|
72
77
|
status: row.status,
|
|
@@ -76,18 +81,18 @@ export function sqlite(options = {}) {
|
|
|
76
81
|
}
|
|
77
82
|
: null;
|
|
78
83
|
}),
|
|
79
|
-
listReviews: (
|
|
80
|
-
const rows =
|
|
84
|
+
listReviews: (runId) => runProjectorSync('sqlite', () => {
|
|
85
|
+
const rows = runId
|
|
81
86
|
? db
|
|
82
|
-
.query(`SELECT
|
|
83
|
-
FROM
|
|
84
|
-
.all(
|
|
87
|
+
.query(`SELECT run_id, review_id, status, title, updated_at
|
|
88
|
+
FROM looms_run_reviews WHERE run_id = ?`)
|
|
89
|
+
.all(runId)
|
|
85
90
|
: db
|
|
86
|
-
.query(`SELECT
|
|
91
|
+
.query(`SELECT run_id, review_id, status, title, updated_at FROM looms_run_reviews`)
|
|
87
92
|
.all();
|
|
88
93
|
return rows.map((row) => ({
|
|
94
|
+
runId: row.run_id,
|
|
89
95
|
reviewId: row.review_id,
|
|
90
|
-
actorId: row.actor_id,
|
|
91
96
|
status: row.status,
|
|
92
97
|
title: row.title,
|
|
93
98
|
updatedAt: row.updated_at,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isJsonObject, isJsonString } from '@swirls/looms/core';
|
|
1
|
+
import { completedRunStatus, isJsonObject, isJsonString, } from '@swirls/looms/core';
|
|
2
2
|
import { emptyTables } from './tables.js';
|
|
3
3
|
function payloadObject(event) {
|
|
4
4
|
return isJsonObject(event.payload) ? event.payload : {};
|
|
@@ -7,6 +7,16 @@ function readString(obj, key) {
|
|
|
7
7
|
const value = obj[key];
|
|
8
8
|
return isJsonString(value) ? value : undefined;
|
|
9
9
|
}
|
|
10
|
+
function setRunStatus(tables, runId, status) {
|
|
11
|
+
const existing = tables.runs.get(runId);
|
|
12
|
+
tables.runs.set(runId, {
|
|
13
|
+
runId,
|
|
14
|
+
status,
|
|
15
|
+
rootThreadId: existing?.rootThreadId ?? null,
|
|
16
|
+
kind: existing?.kind ?? null,
|
|
17
|
+
definitionName: existing?.definitionName ?? null,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
10
20
|
export function materializeEvents(events, from = emptyTables()) {
|
|
11
21
|
const tables = {
|
|
12
22
|
runs: from.runs,
|
|
@@ -28,17 +38,12 @@ export function materializeEvents(events, from = emptyTables()) {
|
|
|
28
38
|
tables.runs.set(event.runId, next);
|
|
29
39
|
break;
|
|
30
40
|
}
|
|
31
|
-
case 'runtime.run.completed':
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
rootThreadId: existing?.rootThreadId ?? null,
|
|
37
|
-
kind: existing?.kind ?? null,
|
|
38
|
-
definitionName: existing?.definitionName ?? null,
|
|
39
|
-
});
|
|
41
|
+
case 'runtime.run.completed':
|
|
42
|
+
setRunStatus(tables, event.runId, completedRunStatus(payload));
|
|
43
|
+
break;
|
|
44
|
+
case 'runtime.run.cancelled':
|
|
45
|
+
setRunStatus(tables, event.runId, 'cancelled');
|
|
40
46
|
break;
|
|
41
|
-
}
|
|
42
47
|
case 'runtime.thread.started': {
|
|
43
48
|
const threadId = readString(payload, 'threadId') ?? event.threadId;
|
|
44
49
|
const kind = readString(payload, 'kind');
|
package/dist/react/react.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
|
-
import { type ProjectionDefinition, type ThreadTree } from '@swirls/looms/core';
|
|
2
|
+
import { type ProjectionDefinition, type RunStatus, type ThreadTree } from '@swirls/looms/core';
|
|
3
3
|
import { createFold, foldEvents, type EventFoldDefinition } from './derived';
|
|
4
4
|
import type { AnyEventEnvelope, RegisteredEvent } from './register';
|
|
5
5
|
import { createLoomsStore, type CoalesceOption, type LoomsClientStore, type LoomsConnectionStatus } from './store';
|
|
@@ -30,7 +30,11 @@ export declare function useProjection<S, TEvent extends AnyEventEnvelope = Regis
|
|
|
30
30
|
/** Subscribe to arbitrary store derivations with an equality check. */
|
|
31
31
|
export declare function useRunSelector<Selected, TEvent extends AnyEventEnvelope = RegisteredEvent>(store: LoomsClientStore<TEvent>, selector: (store: LoomsClientStore<TEvent>) => Selected, isEqual?: (a: Selected, b: Selected) => boolean): Selected;
|
|
32
32
|
export interface RunSummary {
|
|
33
|
-
readonly status:
|
|
33
|
+
readonly status: RunStatus;
|
|
34
|
+
/** True once the run is completed, failed, or cancelled and accepts no new signals. */
|
|
35
|
+
readonly finished: boolean;
|
|
36
|
+
/** True when the run failed or was cancelled, so a fork can continue it from where it stopped. */
|
|
37
|
+
readonly resumable: boolean;
|
|
34
38
|
readonly kind: string | undefined;
|
|
35
39
|
readonly definitionName: string | undefined;
|
|
36
40
|
readonly rootThreadId: string | undefined;
|
package/dist/react/react.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Effect, Fiber } from 'effect';
|
|
2
2
|
import { createContext, createElement, useCallback, useContext, useEffect, useMemo, useRef, useSyncExternalStore, } from 'react';
|
|
3
|
-
import { threadTree, toThreadTree } from '@swirls/looms/core';
|
|
3
|
+
import { isTerminalStatus, threadTree, toThreadTree, } from '@swirls/looms/core';
|
|
4
4
|
import { createFold, foldEvents } from './derived.js';
|
|
5
5
|
import { createLoomsStore, } from './store.js';
|
|
6
6
|
const LoomsContext = createContext({ endpoint: '' });
|
|
@@ -125,8 +125,11 @@ function shallowEqualSummary(a, b) {
|
|
|
125
125
|
export function useRunSummary(store) {
|
|
126
126
|
const selector = useCallback((s) => {
|
|
127
127
|
const run = s.getState().runs.get(s.storeId);
|
|
128
|
+
const status = run?.status ?? 'running';
|
|
128
129
|
return {
|
|
129
|
-
status
|
|
130
|
+
status,
|
|
131
|
+
finished: isTerminalStatus(status),
|
|
132
|
+
resumable: status === 'failed' || status === 'cancelled',
|
|
130
133
|
kind: run?.kind ?? undefined,
|
|
131
134
|
definitionName: run?.definitionName ?? undefined,
|
|
132
135
|
rootThreadId: run?.rootThreadId ?? undefined,
|
package/dist/react/store.d.ts
CHANGED
|
@@ -45,7 +45,7 @@ export interface LoomsClientStore<TEvent extends AnyEventEnvelope = RegisteredEv
|
|
|
45
45
|
project<S>(definition: ProjectionDefinition<S>): S;
|
|
46
46
|
fold<S>(definition: EventFoldDefinition<S, TEvent>): S;
|
|
47
47
|
flush: () => void;
|
|
48
|
-
commit: (event: EventInput) => Promise<void>;
|
|
48
|
+
commit: (event: EventInput | readonly EventInput[]) => Promise<void>;
|
|
49
49
|
sync: () => Promise<void>;
|
|
50
50
|
dispose: () => void;
|
|
51
51
|
}
|
package/dist/react/store.js
CHANGED
|
@@ -302,7 +302,7 @@ export function createLoomsStore(options) {
|
|
|
302
302
|
try: (signal) => fetchFn(`${endpoint}/runs/${encodeURIComponent(options.storeId)}/events`, {
|
|
303
303
|
method: 'POST',
|
|
304
304
|
headers: { 'content-type': 'application/json' },
|
|
305
|
-
body: stringifyJson(event),
|
|
305
|
+
body: stringifyJson(Array.isArray(event) ? { events: event } : event),
|
|
306
306
|
signal,
|
|
307
307
|
}),
|
|
308
308
|
catch: (cause) => new LoomsStoreError('Run signal failed', cause),
|
package/dist/react/tables.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import type { RunStatus, ThreadStatus } from '@swirls/looms/core';
|
|
1
2
|
export interface RunRow {
|
|
2
3
|
runId: string;
|
|
3
|
-
status:
|
|
4
|
+
status: RunStatus;
|
|
4
5
|
rootThreadId: string | null;
|
|
5
6
|
kind: string | null;
|
|
6
7
|
definitionName: string | null;
|
|
@@ -11,7 +12,7 @@ export interface ThreadRow {
|
|
|
11
12
|
kind: string;
|
|
12
13
|
definitionName: string;
|
|
13
14
|
parentThreadId: string | null;
|
|
14
|
-
status:
|
|
15
|
+
status: ThreadStatus;
|
|
15
16
|
}
|
|
16
17
|
/** Materialized run/thread rows. Event log lives only in `store.events()` / EventIndex. */
|
|
17
18
|
export interface MaterializedTables {
|
|
@@ -1,29 +1,15 @@
|
|
|
1
1
|
import { Clock, Effect } from 'effect';
|
|
2
|
-
import { createEvent, EventStoreTag, foldRun, } from '@swirls/looms/core';
|
|
2
|
+
import { createEvent, descendantThreadIds, EventStoreTag, foldRun, } from '@swirls/looms/core';
|
|
3
3
|
import { RuntimeExecutionError } from './errors.js';
|
|
4
4
|
import { waitSatisfiedEvents, workerTask } from './helpers.js';
|
|
5
5
|
import { notifyObserver } from './observer.js';
|
|
6
6
|
import { isWorkerEffect } from './worker-effect-dispatch.js';
|
|
7
|
-
function descendantThreadIds(state, targetThreadId) {
|
|
8
|
-
return Object.values(state.threads)
|
|
9
|
-
.filter((record) => {
|
|
10
|
-
let parentThreadId = record.parentThreadId;
|
|
11
|
-
while (parentThreadId) {
|
|
12
|
-
if (parentThreadId === targetThreadId) {
|
|
13
|
-
return true;
|
|
14
|
-
}
|
|
15
|
-
parentThreadId = state.threads[parentThreadId]?.parentThreadId ?? null;
|
|
16
|
-
}
|
|
17
|
-
return false;
|
|
18
|
-
})
|
|
19
|
-
.map((record) => record.threadId);
|
|
20
|
-
}
|
|
21
7
|
/**
|
|
22
8
|
* Cancel a thread and its descendants. Worker attempts in flight are asked to stop and must
|
|
23
9
|
* acknowledge; attempts waiting to retry were never handed out and are cancelled outright.
|
|
24
10
|
*/
|
|
25
11
|
function planCancellation(input) {
|
|
26
|
-
const { runId, state, registry, now } = input;
|
|
12
|
+
const { runId, seq, state, registry, now } = input;
|
|
27
13
|
const targetThreadId = input.threadId ?? state.rootThreadId ?? '';
|
|
28
14
|
const idempotencyKey = `cancel:${targetThreadId}`;
|
|
29
15
|
if (state.processedIdempotencyKeys.includes(idempotencyKey)) {
|
|
@@ -65,18 +51,18 @@ function planCancellation(input) {
|
|
|
65
51
|
idempotencyKey,
|
|
66
52
|
}));
|
|
67
53
|
}
|
|
68
|
-
const threadEvents = [
|
|
69
|
-
...descendants.map((_, index) => descendants[descendants.length - 1 - index]),
|
|
70
|
-
targetThreadId,
|
|
71
|
-
]
|
|
54
|
+
const threadEvents = [...descendants.toReversed(), targetThreadId]
|
|
72
55
|
.filter((threadId) => threadId.length > 0)
|
|
73
|
-
.map((threadId) =>
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
56
|
+
.map((threadId) => {
|
|
57
|
+
const payload = { threadId, reason: 'cancelled' };
|
|
58
|
+
return createEvent(runId, {
|
|
59
|
+
type: 'runtime.thread.cancelled',
|
|
60
|
+
payload: threadId === targetThreadId ? { ...payload, resumeSeq: seq } : payload,
|
|
61
|
+
threadId,
|
|
62
|
+
origin: { type: 'external' },
|
|
63
|
+
idempotencyKey,
|
|
64
|
+
});
|
|
65
|
+
});
|
|
80
66
|
const batch = [...effectEvents, ...threadEvents];
|
|
81
67
|
const folded = foldRun(batch, registry, { runId, initial: state });
|
|
82
68
|
const satisfied = waitSatisfiedEvents(folded, batch).map((event) => createEvent(runId, event));
|
|
@@ -91,6 +77,7 @@ export function createCancellation(options) {
|
|
|
91
77
|
return yield* repository.commit(store, runId, (current) => {
|
|
92
78
|
const plan = planCancellation({
|
|
93
79
|
runId,
|
|
80
|
+
seq: current.seq,
|
|
94
81
|
state: current.state,
|
|
95
82
|
threadId,
|
|
96
83
|
registry,
|
package/dist/runtime/errors.d.ts
CHANGED
|
@@ -19,6 +19,45 @@ export declare class StartRunConflictError extends StartRunConflictError_base<{
|
|
|
19
19
|
}> {
|
|
20
20
|
constructor(runId: string, requested: RunStartIdentity, existing: DurableRunStartIdentity, mismatches: readonly (keyof RunStartIdentity)[]);
|
|
21
21
|
}
|
|
22
|
+
declare const RunTerminalError_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 & {
|
|
23
|
+
readonly _tag: "RunTerminalError";
|
|
24
|
+
} & Readonly<A>;
|
|
25
|
+
export declare class RunTerminalError extends RunTerminalError_base<{
|
|
26
|
+
readonly runId: string;
|
|
27
|
+
readonly status: string;
|
|
28
|
+
readonly message: string;
|
|
29
|
+
}> {
|
|
30
|
+
constructor(runId: string, status: string);
|
|
31
|
+
}
|
|
32
|
+
declare const RunNotFoundError_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 & {
|
|
33
|
+
readonly _tag: "RunNotFoundError";
|
|
34
|
+
} & Readonly<A>;
|
|
35
|
+
export declare class RunNotFoundError extends RunNotFoundError_base<{
|
|
36
|
+
readonly runId: string;
|
|
37
|
+
readonly message: string;
|
|
38
|
+
}> {
|
|
39
|
+
constructor(runId: string);
|
|
40
|
+
}
|
|
41
|
+
declare const RunNotFinishedError_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 & {
|
|
42
|
+
readonly _tag: "RunNotFinishedError";
|
|
43
|
+
} & Readonly<A>;
|
|
44
|
+
export declare class RunNotFinishedError extends RunNotFinishedError_base<{
|
|
45
|
+
readonly runId: string;
|
|
46
|
+
readonly status: string;
|
|
47
|
+
readonly message: string;
|
|
48
|
+
}> {
|
|
49
|
+
constructor(runId: string, status: string);
|
|
50
|
+
}
|
|
51
|
+
declare const ForkConflictError_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 & {
|
|
52
|
+
readonly _tag: "ForkConflictError";
|
|
53
|
+
} & Readonly<A>;
|
|
54
|
+
export declare class ForkConflictError extends ForkConflictError_base<{
|
|
55
|
+
readonly runId: string;
|
|
56
|
+
readonly sourceRunId: string;
|
|
57
|
+
readonly message: string;
|
|
58
|
+
}> {
|
|
59
|
+
constructor(runId: string, sourceRunId: string);
|
|
60
|
+
}
|
|
22
61
|
declare const DuplicateEffectDispatchError_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 & {
|
|
23
62
|
readonly _tag: "DuplicateEffectDispatchError";
|
|
24
63
|
} & Readonly<A>;
|
package/dist/runtime/errors.js
CHANGED
|
@@ -11,6 +11,38 @@ export class StartRunConflictError extends Data.TaggedError('StartRunConflictErr
|
|
|
11
11
|
this.name = 'StartRunConflictError';
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
+
export class RunTerminalError extends Data.TaggedError('RunTerminalError') {
|
|
15
|
+
constructor(runId, status) {
|
|
16
|
+
super({ runId, status, message: `Run "${runId}" is ${status} and accepts no new events` });
|
|
17
|
+
this.name = 'RunTerminalError';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class RunNotFoundError extends Data.TaggedError('RunNotFoundError') {
|
|
21
|
+
constructor(runId) {
|
|
22
|
+
super({ runId, message: `Run "${runId}" does not exist` });
|
|
23
|
+
this.name = 'RunNotFoundError';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export class RunNotFinishedError extends Data.TaggedError('RunNotFinishedError') {
|
|
27
|
+
constructor(runId, status) {
|
|
28
|
+
super({
|
|
29
|
+
runId,
|
|
30
|
+
status,
|
|
31
|
+
message: `Run "${runId}" is ${status}; only finished runs can be forked`,
|
|
32
|
+
});
|
|
33
|
+
this.name = 'RunNotFinishedError';
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export class ForkConflictError extends Data.TaggedError('ForkConflictError') {
|
|
37
|
+
constructor(runId, sourceRunId) {
|
|
38
|
+
super({
|
|
39
|
+
runId,
|
|
40
|
+
sourceRunId,
|
|
41
|
+
message: `Run "${runId}" already exists and is not a fork of "${sourceRunId}"`,
|
|
42
|
+
});
|
|
43
|
+
this.name = 'ForkConflictError';
|
|
44
|
+
}
|
|
45
|
+
}
|
|
14
46
|
export class DuplicateEffectDispatchError extends Data.TaggedError('DuplicateEffectDispatchError') {
|
|
15
47
|
constructor(runId, effectId, threadId) {
|
|
16
48
|
super({
|
|
@@ -43,6 +43,8 @@ export declare function threadStartedEvents(definitions: ReadonlyMap<string, Reg
|
|
|
43
43
|
parentThreadId: string | null;
|
|
44
44
|
}): Effect.Effect<ReadonlyArray<EventInput>, UnknownDefinitionError>;
|
|
45
45
|
export declare function synthesizedThreadFailed(before: RunState, after: RunState, written: readonly EventEnvelope[]): EventInput[];
|
|
46
|
+
/** Cancel whatever is still live below each thread `written` cancels, deepest first. */
|
|
47
|
+
export declare function cascadedCancellations(state: RunState, written: readonly EventEnvelope[]): EventInput[];
|
|
46
48
|
export declare function waitSatisfiedEvents(state: RunState, events: readonly EventEnvelope[]): EventInput[];
|
|
47
49
|
export declare function createEffectFailedEvent(runId: string, item: {
|
|
48
50
|
effectId: string;
|
package/dist/runtime/helpers.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Data, Effect, Layer, Predicate } from 'effect';
|
|
2
|
-
import { asJson, createEvent, definitionKey, makeMemorySnapshotStore, matchingWaits, snapshotStoreOf, validateEventInput, validateEventsEffect, validateInputEffect, withSnapshotStore, InvalidEventError, } from '@swirls/looms/core';
|
|
2
|
+
import { asJson, createEvent, definitionKey, descendantThreadIds, isTerminalStatus, makeMemorySnapshotStore, matchingWaits, snapshotStoreOf, validateEventInput, validateEventsEffect, validateInputEffect, withSnapshotStore, InvalidEventError, } from '@swirls/looms/core';
|
|
3
3
|
export function workerTask(runId, item, attempt) {
|
|
4
4
|
return {
|
|
5
5
|
runId,
|
|
@@ -180,6 +180,28 @@ export function synthesizedThreadFailed(before, after, written) {
|
|
|
180
180
|
}
|
|
181
181
|
return out;
|
|
182
182
|
}
|
|
183
|
+
/** Cancel whatever is still live below each thread `written` cancels, deepest first. */
|
|
184
|
+
export function cascadedCancellations(state, written) {
|
|
185
|
+
const cancelled = written.flatMap((event) => {
|
|
186
|
+
if (event.type !== 'runtime.thread.cancelled') {
|
|
187
|
+
return [];
|
|
188
|
+
}
|
|
189
|
+
const payload = Predicate.isObject(event.payload) ? event.payload : {};
|
|
190
|
+
const threadId = Predicate.isString(payload.threadId) ? payload.threadId : event.threadId;
|
|
191
|
+
return threadId ? [threadId] : [];
|
|
192
|
+
});
|
|
193
|
+
const live = new Set(cancelled
|
|
194
|
+
.flatMap((threadId) => descendantThreadIds(state, threadId))
|
|
195
|
+
.filter((threadId) => {
|
|
196
|
+
const record = state.threads[threadId];
|
|
197
|
+
return record !== undefined && !isTerminalStatus(record.status);
|
|
198
|
+
}));
|
|
199
|
+
return [...live].toReversed().map((threadId) => ({
|
|
200
|
+
type: 'runtime.thread.cancelled',
|
|
201
|
+
payload: { threadId, reason: 'cancelled' },
|
|
202
|
+
threadId,
|
|
203
|
+
}));
|
|
204
|
+
}
|
|
183
205
|
export function waitSatisfiedEvents(state, events) {
|
|
184
206
|
const produced = [];
|
|
185
207
|
const remaining = { ...state.waits };
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createRuntime, createTimeoutScheduler, DuplicateEffectDispatchError, MaxWakeIterationsError, RunOverloadedError, StartRunConflictError, type CreateRuntimeOptions, type EffectWorker, type EffectWorkerTask, type LoomsRuntime, type RunOperationalStatus, type RegisteredDefinition, type StartRunArgs, type WakeError, type WakeScheduler, type WorkerCallback, type WorkerCallbackInput, } from './runtime';
|
|
1
|
+
export { createRuntime, createTimeoutScheduler, DuplicateEffectDispatchError, ForkConflictError, MaxWakeIterationsError, RunNotFinishedError, RunNotFoundError, RunOverloadedError, RunTerminalError, StartRunConflictError, type CreateRuntimeOptions, type EffectWorker, type EffectWorkerTask, type LoomsRuntime, type RunOperationalStatus, type RegisteredDefinition, type StartRunArgs, type WakeError, type WakeScheduler, type WorkerCallback, type WorkerCallbackInput, } from './runtime';
|
|
2
2
|
export { createLooms, type Looms, type CreateLoomsOptions, type StartResult } from './looms';
|
|
3
3
|
export { serveHttp, createFetchHandler, isLoomsApiPath, type FetchHandlerOptions, authAllowed, authDenied, bearerAuth, defaultAuthorize, type AuthDecision, type AuthorizedAccess, type Authorize, type BearerTokens, type RouteAccess, type RouteInfo, type RunningServer, type LoomsFetchResult, } from './server';
|
|
4
4
|
export { createEventStreamResponse, type EventStreamOptions } from './sse';
|
package/dist/runtime/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createRuntime, createTimeoutScheduler, DuplicateEffectDispatchError, MaxWakeIterationsError, RunOverloadedError, StartRunConflictError, } from './runtime.js';
|
|
1
|
+
export { createRuntime, createTimeoutScheduler, DuplicateEffectDispatchError, ForkConflictError, MaxWakeIterationsError, RunNotFinishedError, RunNotFoundError, RunOverloadedError, RunTerminalError, StartRunConflictError, } from './runtime.js';
|
|
2
2
|
export { createLooms } from './looms.js';
|
|
3
3
|
export { serveHttp, createFetchHandler, isLoomsApiPath, authAllowed, authDenied, bearerAuth, defaultAuthorize, } from './server.js';
|
|
4
4
|
export { createEventStreamResponse } from './sse.js';
|
package/dist/runtime/looms.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AnyRuntimeModule, type DefinitionInput, type DefinitionRef, type EventEnvelope, type EventInput, type EventStore, type EventStoreTrimCoverage, type JsonValue, type SnapshotStore, type ProjectionDefinition, type ReplayStep, type RunState } from '@swirls/looms/core';
|
|
1
|
+
import { type AnyRuntimeModule, type DebuggerHost, type DefinitionInput, type DefinitionRef, type EventEnvelope, type EventInput, type EventStore, type EventStoreTrimCoverage, type JsonValue, type SnapshotStore, type ProjectionDefinition, type ReplayStep, type RunState } from '@swirls/looms/core';
|
|
2
2
|
import type { RuntimeObserver } from './observer';
|
|
3
3
|
import { type EffectWorker, type LoomsRuntime, type RunOperationalStatus, type WakeScheduler, type WorkerCallbackInput } from './runtime';
|
|
4
4
|
import { type Authorize, type RunningServer } from './server';
|
|
@@ -33,8 +33,16 @@ export interface CreateLoomsOptions {
|
|
|
33
33
|
/**
|
|
34
34
|
* Authorizes HTTP API requests. Without it, run reads and writes are open while worker callback
|
|
35
35
|
* and operations routes return 503; `bearerAuth({ worker, operations })` enables them.
|
|
36
|
+
*
|
|
37
|
+
* A mounted debugger is authorized as `{ access: 'read', name: 'debugger' }`. Bearer tokens on
|
|
38
|
+
* reads block browser navigation, so hosts that need auth should use a cookie or session policy.
|
|
36
39
|
*/
|
|
37
40
|
readonly authorize?: Authorize;
|
|
41
|
+
/**
|
|
42
|
+
* Serves a debugger UI under `debugger.basePath` (for example `/debugger`). The runtime does not
|
|
43
|
+
* bundle a UI; pass `debuggerUi()` from `@swirls/looms/debugger/server`.
|
|
44
|
+
*/
|
|
45
|
+
readonly debugger?: DebuggerHost;
|
|
38
46
|
}
|
|
39
47
|
export interface StartResult {
|
|
40
48
|
readonly runId: string;
|
|
@@ -81,6 +89,10 @@ export interface Looms {
|
|
|
81
89
|
project<S>(runId: string, definition: ProjectionDefinition<S>): Promise<S>;
|
|
82
90
|
replayTo(runId: string, seq: number): Promise<ReplayStep | null>;
|
|
83
91
|
cancel(runId: string, threadId?: string): Promise<RunState>;
|
|
92
|
+
/** Start a new run that continues where a finished run ended. */
|
|
93
|
+
fork(sourceRunId: string, options?: {
|
|
94
|
+
runId?: string;
|
|
95
|
+
}): Promise<StartResult>;
|
|
84
96
|
workerCallback(runId: string, input: WorkerCallbackInput): Promise<RunState>;
|
|
85
97
|
fetch(req: Request): Promise<Response | null>;
|
|
86
98
|
serve(options?: {
|