@sixb/core 0.1.0 → 0.1.2
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/README.md +54 -23
- package/dist/actions/commit-edits.d.ts +0 -2
- package/dist/actions/commit-edits.d.ts.map +1 -1
- package/dist/actions/execution.d.ts +21 -0
- package/dist/actions/execution.d.ts.map +1 -0
- package/dist/actions/index.d.ts +1 -1
- package/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/index.js +34 -23
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/registry.d.ts +16 -7
- package/dist/actions/registry.d.ts.map +1 -1
- package/dist/actions/request.d.ts +3 -2
- package/dist/actions/request.d.ts.map +1 -1
- package/dist/actions/run-dispatch.d.ts +21 -0
- package/dist/actions/run-dispatch.d.ts.map +1 -0
- package/dist/actions/types/context.d.ts +2 -2
- package/dist/actions/types/context.d.ts.map +1 -1
- package/dist/actions/validation.d.ts +1 -1
- package/dist/actions/validation.d.ts.map +1 -1
- package/dist/actions/worker.js +4 -4
- package/dist/actions/worker.js.map +1 -1
- package/dist/agents/adapters.d.ts +10 -0
- package/dist/agents/adapters.d.ts.map +1 -1
- package/dist/agents/authority.d.ts +31 -0
- package/dist/agents/authority.d.ts.map +1 -0
- package/dist/agents/builders.d.ts +8 -1
- package/dist/agents/builders.d.ts.map +1 -1
- package/dist/agents/context.js +2 -2
- package/dist/agents/dispatch.d.ts.map +1 -1
- package/dist/agents/errors.d.ts +16 -1
- package/dist/agents/errors.d.ts.map +1 -1
- package/dist/agents/execution.d.ts +45 -0
- package/dist/agents/execution.d.ts.map +1 -0
- package/dist/agents/index.d.ts +10 -10
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +81 -14
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/prompt.d.ts.map +1 -1
- package/dist/agents/request.d.ts +6 -2
- package/dist/agents/request.d.ts.map +1 -1
- package/dist/agents/streams.d.ts +29 -3
- package/dist/agents/streams.d.ts.map +1 -1
- package/dist/agents/streams.js +22 -3
- package/dist/agents/streams.js.map +1 -1
- package/dist/agents/tool-definition.d.ts +9 -0
- package/dist/agents/tool-definition.d.ts.map +1 -0
- package/dist/agents/types.d.ts +64 -0
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/agents/validation.d.ts +16 -3
- package/dist/agents/validation.d.ts.map +1 -1
- package/dist/auth/attribution.d.ts +17 -0
- package/dist/auth/attribution.d.ts.map +1 -0
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +9 -5
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/runtime.d.ts +4 -4
- package/dist/auth/runtime.d.ts.map +1 -1
- package/dist/authorization/decision.d.ts +24 -11
- package/dist/authorization/decision.d.ts.map +1 -1
- package/dist/authorization/grant-kinds.d.ts +2 -1
- package/dist/authorization/grant-kinds.d.ts.map +1 -1
- package/dist/authorization/index.d.ts +1 -1
- package/dist/authorization/index.d.ts.map +1 -1
- package/dist/authorization/index.js +8 -4
- package/dist/authorization/index.js.map +1 -1
- package/dist/blob-storage/browser.js +3 -2
- package/dist/blob-storage/browser.js.map +1 -1
- package/dist/blob-storage/execution.d.ts +16 -0
- package/dist/blob-storage/execution.d.ts.map +1 -0
- package/dist/blob-storage/index.js +4 -3
- package/dist/blob-storage/index.js.map +1 -1
- package/dist/blob-storage/validation.d.ts.map +1 -1
- package/dist/bootstrap/discovery.d.ts +90 -24
- package/dist/bootstrap/discovery.d.ts.map +1 -1
- package/dist/bootstrap/index.d.ts +2 -1
- package/dist/bootstrap/index.d.ts.map +1 -1
- package/dist/bootstrap/index.js +59 -59
- package/dist/bootstrap/index.js.map +1 -1
- package/dist/broker/in-memory.d.ts.map +1 -1
- package/dist/broker/index.js +2 -2
- package/dist/broker/types.d.ts +5 -0
- package/dist/broker/types.d.ts.map +1 -1
- package/dist/chunk-0172wgm9.js +333 -0
- package/dist/chunk-0172wgm9.js.map +11 -0
- package/dist/chunk-0k4avqr2.js +317 -0
- package/dist/chunk-0k4avqr2.js.map +11 -0
- package/dist/chunk-0mbx247x.js +2922 -0
- package/dist/chunk-0mbx247x.js.map +43 -0
- package/dist/chunk-34bqh420.js +1168 -0
- package/dist/chunk-34bqh420.js.map +23 -0
- package/dist/{chunk-mx84y05q.js → chunk-3j7573mj.js} +2 -2
- package/dist/{chunk-mx84y05q.js.map → chunk-3j7573mj.js.map} +2 -2
- package/dist/{chunk-45tw90k7.js → chunk-4gz41why.js} +1 -1
- package/dist/chunk-4x43bkbp.js +55 -0
- package/dist/chunk-4x43bkbp.js.map +11 -0
- package/dist/{chunk-xqbtf4wn.js → chunk-57r1cpxx.js} +3 -2
- package/dist/{chunk-xqbtf4wn.js.map → chunk-57r1cpxx.js.map} +3 -3
- package/dist/chunk-57zpb99z.js +194 -0
- package/dist/chunk-57zpb99z.js.map +10 -0
- package/dist/{chunk-dhmj53mx.js → chunk-5egfka8j.js} +13 -33
- package/dist/chunk-5egfka8j.js.map +15 -0
- package/dist/chunk-5gd7tpv6.js +28 -0
- package/dist/chunk-5gd7tpv6.js.map +11 -0
- package/dist/{chunk-867jxh7c.js → chunk-5sz8ta9r.js} +6 -295
- package/dist/chunk-5sz8ta9r.js.map +16 -0
- package/dist/chunk-62c7t4jc.js +27 -0
- package/dist/chunk-62c7t4jc.js.map +11 -0
- package/dist/{chunk-8r8cw2xw.js → chunk-63te770v.js} +40 -5
- package/dist/{chunk-8r8cw2xw.js.map → chunk-63te770v.js.map} +3 -3
- package/dist/chunk-663csy96.js +34 -0
- package/dist/chunk-663csy96.js.map +10 -0
- package/dist/{chunk-xz5g49bp.js → chunk-6gjqgd3d.js} +3 -1
- package/dist/chunk-6gjqgd3d.js.map +11 -0
- package/dist/chunk-7pc8b818.js +128 -0
- package/dist/chunk-7pc8b818.js.map +13 -0
- package/dist/{chunk-f2b5e2gf.js → chunk-85j5ybfj.js} +18 -3
- package/dist/{chunk-f2b5e2gf.js.map → chunk-85j5ybfj.js.map} +3 -3
- package/dist/{chunk-vj723r3p.js → chunk-8b55ygje.js} +1 -1
- package/dist/chunk-8m5ejdpn.js +33 -0
- package/dist/chunk-8m5ejdpn.js.map +10 -0
- package/dist/chunk-8ryen3p3.js +118 -0
- package/dist/chunk-8ryen3p3.js.map +10 -0
- package/dist/chunk-979ww6b3.js +298 -0
- package/dist/chunk-979ww6b3.js.map +12 -0
- package/dist/{chunk-ya6brh8a.js → chunk-9t8f5xfx.js} +10 -5
- package/dist/chunk-9t8f5xfx.js.map +11 -0
- package/dist/{chunk-r65yscvk.js → chunk-a31h57d5.js} +131 -13
- package/dist/chunk-a31h57d5.js.map +13 -0
- package/dist/chunk-bct7hmfc.js +402 -0
- package/dist/chunk-bct7hmfc.js.map +14 -0
- package/dist/chunk-bh6k3nc6.js +164 -0
- package/dist/chunk-bh6k3nc6.js.map +12 -0
- package/dist/{chunk-t72dvahb.js → chunk-bhxaq2nn.js} +61 -44
- package/dist/chunk-bhxaq2nn.js.map +12 -0
- package/dist/{chunk-jdwx7vzs.js → chunk-c6qd89g5.js} +240 -143
- package/dist/chunk-c6qd89g5.js.map +15 -0
- package/dist/{chunk-2s6sydsh.js → chunk-ckxfnx7f.js} +294 -4
- package/dist/chunk-ckxfnx7f.js.map +13 -0
- package/dist/chunk-cy0n5dms.js +27 -0
- package/dist/chunk-cy0n5dms.js.map +11 -0
- package/dist/chunk-dsrkgtnh.js +50 -0
- package/dist/chunk-dsrkgtnh.js.map +10 -0
- package/dist/{chunk-50kv63vj.js → chunk-dysw7nsm.js} +118 -26
- package/dist/chunk-dysw7nsm.js.map +14 -0
- package/dist/chunk-ezake7g1.js +32 -0
- package/dist/chunk-ezake7g1.js.map +11 -0
- package/dist/{chunk-yxss87qa.js → chunk-f2rt4vkh.js} +48 -29
- package/dist/chunk-f2rt4vkh.js.map +14 -0
- package/dist/{chunk-q4qzq0ea.js → chunk-fmx1sz2h.js} +117 -56
- package/dist/chunk-fmx1sz2h.js.map +15 -0
- package/dist/chunk-g9t3kdtx.js +90 -0
- package/dist/chunk-g9t3kdtx.js.map +10 -0
- package/dist/{chunk-c3zd880g.js → chunk-ghteq96b.js} +8 -8
- package/dist/{chunk-c3zd880g.js.map → chunk-ghteq96b.js.map} +4 -4
- package/dist/chunk-h9kxd41f.js +271 -0
- package/dist/chunk-h9kxd41f.js.map +11 -0
- package/dist/chunk-htq0qh7z.js +59 -0
- package/dist/chunk-htq0qh7z.js.map +11 -0
- package/dist/{chunk-dcgrzj1t.js → chunk-jaj13078.js} +121 -9
- package/dist/chunk-jaj13078.js.map +38 -0
- package/dist/{chunk-t358gywy.js → chunk-k9pts48t.js} +81 -58
- package/dist/chunk-k9pts48t.js.map +35 -0
- package/dist/chunk-n8herkry.js +3294 -0
- package/dist/chunk-n8herkry.js.map +35 -0
- package/dist/chunk-nf4r78r4.js +44 -0
- package/dist/chunk-nf4r78r4.js.map +10 -0
- package/dist/{chunk-2gpr6jsz.js → chunk-nnyp53zt.js} +14 -34
- package/dist/chunk-nnyp53zt.js.map +13 -0
- package/dist/chunk-nten49ta.js +404 -0
- package/dist/chunk-nten49ta.js.map +12 -0
- package/dist/chunk-qvybnnpe.js +137 -0
- package/dist/chunk-qvybnnpe.js.map +10 -0
- package/dist/{chunk-tsk2bxs3.js → chunk-rnshztfq.js} +13 -13
- package/dist/{chunk-tsk2bxs3.js.map → chunk-rnshztfq.js.map} +3 -3
- package/dist/chunk-sa4340y1.js +607 -0
- package/dist/chunk-sa4340y1.js.map +14 -0
- package/dist/{chunk-yvef9xwc.js → chunk-st4xgxey.js} +583 -251
- package/dist/chunk-st4xgxey.js.map +45 -0
- package/dist/{chunk-1vffvydj.js → chunk-t8t39h7v.js} +6 -6
- package/dist/chunk-t8t39h7v.js.map +10 -0
- package/dist/chunk-t9xghkva.js +28 -0
- package/dist/chunk-t9xghkva.js.map +10 -0
- package/dist/chunk-vp1vc6ee.js +35 -0
- package/dist/chunk-vp1vc6ee.js.map +11 -0
- package/dist/{chunk-p6r5g77m.js → chunk-vybf6pkp.js} +1 -1
- package/dist/{chunk-wj01s5hr.js → chunk-wtmzkcht.js} +4 -3
- package/dist/chunk-wtmzkcht.js.map +11 -0
- package/dist/{chunk-v5c085yp.js → chunk-xhy826cz.js} +3 -2
- package/dist/chunk-xhy826cz.js.map +10 -0
- package/dist/chunk-xkthy56g.js +33 -0
- package/dist/chunk-xkthy56g.js.map +11 -0
- package/dist/{chunk-aebzcsxr.js → chunk-ys1nse2v.js} +2178 -382
- package/dist/chunk-ys1nse2v.js.map +56 -0
- package/dist/{chunk-5yny9z0e.js → chunk-z3zp0bj1.js} +1 -1
- package/dist/chunk-zcnhxkvd.js +7 -0
- package/dist/chunk-zcnhxkvd.js.map +10 -0
- package/dist/chunk-zg9yryhz.js +252 -0
- package/dist/chunk-zg9yryhz.js.map +12 -0
- package/dist/chunk-zqqz8052.js +3 -0
- package/dist/{storage/projection-runs/lifecycle.js.map → chunk-zqqz8052.js.map} +1 -1
- package/dist/{chunk-4pycxcj3.js → chunk-zqysyfjt.js} +6 -9
- package/dist/{chunk-4pycxcj3.js.map → chunk-zqysyfjt.js.map} +3 -3
- package/dist/connectors/builders.d.ts +2 -1
- package/dist/connectors/builders.d.ts.map +1 -1
- package/dist/connectors/connections/authorizations.d.ts +64 -0
- package/dist/connectors/connections/authorizations.d.ts.map +1 -0
- package/dist/connectors/connections/capability.d.ts +7 -0
- package/dist/connectors/connections/capability.d.ts.map +1 -0
- package/dist/connectors/connections/command-context.d.ts +23 -0
- package/dist/connectors/connections/command-context.d.ts.map +1 -0
- package/dist/connectors/connections/contracts.d.ts +127 -0
- package/dist/connectors/connections/contracts.d.ts.map +1 -0
- package/dist/connectors/connections/credential-codec.d.ts +15 -0
- package/dist/connectors/connections/credential-codec.d.ts.map +1 -0
- package/dist/connectors/connections/credential-mutations.d.ts +63 -0
- package/dist/connectors/connections/credential-mutations.d.ts.map +1 -0
- package/dist/connectors/connections/execution.d.ts +20 -0
- package/dist/connectors/connections/execution.d.ts.map +1 -0
- package/dist/connectors/connections/internal.d.ts +5 -0
- package/dist/connectors/connections/internal.d.ts.map +1 -0
- package/dist/connectors/connections/internal.js +16 -0
- package/dist/connectors/connections/internal.js.map +9 -0
- package/dist/connectors/connections/provider-operation.d.ts +7 -0
- package/dist/connectors/connections/provider-operation.d.ts.map +1 -0
- package/dist/connectors/connections/request.d.ts +84 -0
- package/dist/connectors/connections/request.d.ts.map +1 -0
- package/dist/connectors/connections/runs.d.ts +51 -0
- package/dist/connectors/connections/runs.d.ts.map +1 -0
- package/dist/connectors/connections/service.d.ts +52 -0
- package/dist/connectors/connections/service.d.ts.map +1 -0
- package/dist/connectors/connections/storage-boundary.d.ts +3 -0
- package/dist/connectors/connections/storage-boundary.d.ts.map +1 -0
- package/dist/connectors/connections/tokens.d.ts +32 -0
- package/dist/connectors/connections/tokens.d.ts.map +1 -0
- package/dist/connectors/connections/validation.d.ts +27 -0
- package/dist/connectors/connections/validation.d.ts.map +1 -0
- package/dist/connectors/connections/views.d.ts +7 -0
- package/dist/connectors/connections/views.d.ts.map +1 -0
- package/dist/connectors/credentials.d.ts +25 -0
- package/dist/connectors/credentials.d.ts.map +1 -0
- package/dist/connectors/errors.d.ts +35 -3
- package/dist/connectors/errors.d.ts.map +1 -1
- package/dist/connectors/execution.d.ts +19 -0
- package/dist/connectors/execution.d.ts.map +1 -0
- package/dist/connectors/index.d.ts +5 -3
- package/dist/connectors/index.d.ts.map +1 -1
- package/dist/connectors/service.d.ts +23 -0
- package/dist/connectors/service.d.ts.map +1 -0
- package/dist/connectors/types.d.ts +94 -2
- package/dist/connectors/types.d.ts.map +1 -1
- package/dist/datasets/builders.d.ts +18 -5
- package/dist/datasets/builders.d.ts.map +1 -1
- package/dist/datasets/changes.d.ts +18 -0
- package/dist/datasets/changes.d.ts.map +1 -0
- package/dist/datasets/execution.d.ts +8 -0
- package/dist/datasets/execution.d.ts.map +1 -0
- package/dist/datasets/index.d.ts +3 -1
- package/dist/datasets/index.d.ts.map +1 -1
- package/dist/datasets/types.d.ts +2 -0
- package/dist/datasets/types.d.ts.map +1 -1
- package/dist/datasets/validation.d.ts.map +1 -1
- package/dist/error-reporting/capability.d.ts +4 -49
- package/dist/error-reporting/capability.d.ts.map +1 -1
- package/dist/error-reporting/internal.d.ts +2 -2
- package/dist/error-reporting/internal.d.ts.map +1 -1
- package/dist/error-reporting/internal.js +10 -4
- package/dist/error-reporting/internal.js.map +1 -1
- package/dist/error-reporting/reporter.d.ts +4 -1
- package/dist/error-reporting/reporter.d.ts.map +1 -1
- package/dist/error-reporting/reports.d.ts +64 -0
- package/dist/error-reporting/reports.d.ts.map +1 -0
- package/dist/error-reporting/types.d.ts +88 -34
- package/dist/error-reporting/types.d.ts.map +1 -1
- package/dist/errors/catalog.d.ts +141 -0
- package/dist/errors/catalog.d.ts.map +1 -0
- package/dist/errors/internal.d.ts +68 -0
- package/dist/errors/internal.d.ts.map +1 -0
- package/dist/errors/internal.js +29 -0
- package/dist/errors/internal.js.map +9 -0
- package/dist/errors/types.d.ts +20 -0
- package/dist/errors/types.d.ts.map +1 -0
- package/dist/events/definitions.d.ts +0 -1
- package/dist/events/definitions.d.ts.map +1 -1
- package/dist/events/execution.d.ts +13 -0
- package/dist/events/execution.d.ts.map +1 -0
- package/dist/events/index.d.ts +3 -2
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +10 -8
- package/dist/events/index.js.map +1 -1
- package/dist/events/outbox-dispatcher.d.ts +4 -2
- package/dist/events/outbox-dispatcher.d.ts.map +1 -1
- package/dist/events/{runtime.d.ts → service.d.ts} +13 -14
- package/dist/events/service.d.ts.map +1 -0
- package/dist/events/types/pipelines.d.ts +4 -1
- package/dist/events/types/pipelines.d.ts.map +1 -1
- package/dist/events/types/syncs.d.ts +3 -0
- package/dist/events/types/syncs.d.ts.map +1 -1
- package/dist/events/types/workflows.d.ts +4 -2
- package/dist/events/types/workflows.d.ts.map +1 -1
- package/dist/execution/agent.d.ts +42 -0
- package/dist/execution/agent.d.ts.map +1 -0
- package/dist/execution/agent.js +70 -0
- package/dist/execution/agent.js.map +9 -0
- package/dist/execution/authorization.d.ts +60 -0
- package/dist/execution/authorization.d.ts.map +1 -0
- package/dist/execution/dispatch.d.ts +8 -0
- package/dist/execution/dispatch.d.ts.map +1 -0
- package/dist/execution/durable.d.ts +37 -0
- package/dist/execution/durable.d.ts.map +1 -0
- package/dist/execution/index.d.ts +2 -0
- package/dist/execution/index.d.ts.map +1 -0
- package/dist/execution/primitive.d.ts +21 -0
- package/dist/execution/primitive.d.ts.map +1 -0
- package/dist/execution/primitive.js +88 -0
- package/dist/execution/primitive.js.map +10 -0
- package/dist/execution/request.d.ts +38 -0
- package/dist/execution/request.d.ts.map +1 -0
- package/dist/execution/request.js +97 -0
- package/dist/execution/request.js.map +10 -0
- package/dist/execution/scopes.d.ts +30 -0
- package/dist/execution/scopes.d.ts.map +1 -0
- package/dist/execution/types.d.ts +111 -0
- package/dist/execution/types.d.ts.map +1 -0
- package/dist/http/api-routes.d.ts.map +1 -1
- package/dist/http/index.js +1 -1
- package/dist/index.d.ts +35 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +142 -111
- package/dist/index.js.map +1 -1
- package/dist/json.d.ts +8 -2
- package/dist/json.d.ts.map +1 -1
- package/dist/lake-storage/definition-updates.d.ts.map +1 -1
- package/dist/lake-storage/in-memory.d.ts +15 -1
- package/dist/lake-storage/in-memory.d.ts.map +1 -1
- package/dist/lake-storage/index.d.ts +3 -1
- package/dist/lake-storage/index.d.ts.map +1 -1
- package/dist/lake-storage/index.js +15 -7
- package/dist/lake-storage/index.js.map +1 -1
- package/dist/lake-storage/merge-validation.d.ts +10 -0
- package/dist/lake-storage/merge-validation.d.ts.map +1 -0
- package/dist/lake-storage/merge.d.ts +32 -0
- package/dist/lake-storage/merge.d.ts.map +1 -0
- package/dist/lake-storage/types.d.ts +3 -1
- package/dist/lake-storage/types.d.ts.map +1 -1
- package/dist/logging/execution.d.ts +9 -0
- package/dist/logging/execution.d.ts.map +1 -0
- package/dist/logging/index.d.ts +1 -1
- package/dist/logging/index.d.ts.map +1 -1
- package/dist/logging/index.js +8 -8
- package/dist/logging/index.js.map +1 -1
- package/dist/logging/{runtime.d.ts → service.d.ts} +7 -7
- package/dist/logging/{runtime.d.ts.map → service.d.ts.map} +1 -1
- package/dist/logging/types.js +2 -2
- package/dist/materialization/events.d.ts +1 -0
- package/dist/materialization/events.d.ts.map +1 -1
- package/dist/materialization/index.d.ts +1 -1
- package/dist/materialization/index.d.ts.map +1 -1
- package/dist/materialization/index.js +2 -2
- package/dist/materialization/model.d.ts +26 -17
- package/dist/materialization/model.d.ts.map +1 -1
- package/dist/materializer/edits/commit.d.ts +2 -1
- package/dist/materializer/edits/commit.d.ts.map +1 -1
- package/dist/materializer/edits/load-state.d.ts +1 -1
- package/dist/materializer/edits/load-state.d.ts.map +1 -1
- package/dist/materializer/edits/operations.d.ts +1 -13
- package/dist/materializer/edits/operations.d.ts.map +1 -1
- package/dist/materializer/edits/plan.d.ts +2 -1
- package/dist/materializer/edits/plan.d.ts.map +1 -1
- package/dist/materializer/edits/working-state.d.ts +36 -8
- package/dist/materializer/edits/working-state.d.ts.map +1 -1
- package/dist/materializer/effective/build-events.d.ts +1 -0
- package/dist/materializer/effective/build-events.d.ts.map +1 -1
- package/dist/materializer/effective/diff.d.ts +7 -0
- package/dist/materializer/effective/diff.d.ts.map +1 -1
- package/dist/materializer/effective/load-state.d.ts +0 -2
- package/dist/materializer/effective/load-state.d.ts.map +1 -1
- package/dist/materializer/effective/resolve.d.ts +17 -2
- package/dist/materializer/effective/resolve.d.ts.map +1 -1
- package/dist/materializer/execution/commit-lifecycle.d.ts +2 -2
- package/dist/materializer/execution/commit-lifecycle.d.ts.map +1 -1
- package/dist/materializer/execution/plan-stream.d.ts.map +1 -1
- package/dist/materializer/execution/scope.d.ts +26 -0
- package/dist/materializer/execution/scope.d.ts.map +1 -0
- package/dist/materializer/execution/work-executor.d.ts.map +1 -1
- package/dist/materializer/execution/work-records.d.ts +6 -5
- package/dist/materializer/execution/work-records.d.ts.map +1 -1
- package/dist/materializer/index.d.ts +2 -2
- package/dist/materializer/index.d.ts.map +1 -1
- package/dist/materializer/index.js +30 -18
- package/dist/materializer/index.js.map +1 -1
- package/dist/materializer/materializer.d.ts +37 -5
- package/dist/materializer/materializer.d.ts.map +1 -1
- package/dist/materializer/projections/finish-run.d.ts +2 -1
- package/dist/materializer/projections/finish-run.d.ts.map +1 -1
- package/dist/materializer/projections/replace.d.ts +2 -1
- package/dist/materializer/projections/replace.d.ts.map +1 -1
- package/dist/materializer/projections/replacement-plan.d.ts +1 -0
- package/dist/materializer/projections/replacement-plan.d.ts.map +1 -1
- package/dist/materializer/shared/batching.d.ts.map +1 -1
- package/dist/materializer/shared/normalize.d.ts.map +1 -1
- package/dist/materializer/telemetry/append.d.ts +2 -1
- package/dist/materializer/telemetry/append.d.ts.map +1 -1
- package/dist/materializer/telemetry/plan.d.ts +7 -1
- package/dist/materializer/telemetry/plan.d.ts.map +1 -1
- package/dist/objects/action/request.d.ts +3 -3
- package/dist/objects/action/request.d.ts.map +1 -1
- package/dist/objects/context/index.d.ts +1 -1
- package/dist/objects/context/index.d.ts.map +1 -1
- package/dist/objects/context/types.d.ts +5 -0
- package/dist/objects/context/types.d.ts.map +1 -1
- package/dist/objects/execution.d.ts +100 -0
- package/dist/objects/execution.d.ts.map +1 -0
- package/dist/objects/index.js +37 -24
- package/dist/objects/index.js.map +1 -1
- package/dist/objects/materializer-adapter.d.ts +1 -1
- package/dist/objects/materializer-adapter.d.ts.map +1 -1
- package/dist/objects/query/executor.d.ts +3 -8
- package/dist/objects/query/executor.d.ts.map +1 -1
- package/dist/objects/query/index.d.ts +2 -2
- package/dist/objects/query/index.d.ts.map +1 -1
- package/dist/objects/query/index.js +9 -13
- package/dist/objects/query/index.js.map +1 -1
- package/dist/objects/query/planner.d.ts +0 -3
- package/dist/objects/query/planner.d.ts.map +1 -1
- package/dist/objects/sdk/object-handle.d.ts +2 -2
- package/dist/objects/sdk/object-handle.d.ts.map +1 -1
- package/dist/objects/sdk/object-set.d.ts +2 -0
- package/dist/objects/sdk/object-set.d.ts.map +1 -1
- package/dist/objects/sdk/runtime-query-executor.d.ts +2 -0
- package/dist/objects/sdk/runtime-query-executor.d.ts.map +1 -1
- package/dist/objects/sdk/telemetry-channel.d.ts.map +1 -1
- package/dist/objects/service/action-service.d.ts +3 -2
- package/dist/objects/service/action-service.d.ts.map +1 -1
- package/dist/objects/service/list-service.d.ts +1 -1
- package/dist/objects/telemetry/history.d.ts +2 -0
- package/dist/objects/telemetry/history.d.ts.map +1 -1
- package/dist/objects/telemetry/write-batch.d.ts.map +1 -1
- package/dist/ontology/index.d.ts +1 -1
- package/dist/ontology/index.d.ts.map +1 -1
- package/dist/ontology/index.js +5 -5
- package/dist/ontology/internal.js +7 -6
- package/dist/ontology/internal.js.map +3 -3
- package/dist/ontology/registry.d.ts +15 -2
- package/dist/ontology/registry.d.ts.map +1 -1
- package/dist/ontology/validation/normalize.d.ts.map +1 -1
- package/dist/pipelines/execution.d.ts +19 -0
- package/dist/pipelines/execution.d.ts.map +1 -0
- package/dist/pipelines/index.d.ts +1 -0
- package/dist/pipelines/index.d.ts.map +1 -1
- package/dist/pipelines/index.js +66 -0
- package/dist/pipelines/index.js.map +9 -0
- package/dist/pipelines/request.d.ts +6 -9
- package/dist/pipelines/request.d.ts.map +1 -1
- package/dist/pipelines/run-dispatch.d.ts +47 -0
- package/dist/pipelines/run-dispatch.d.ts.map +1 -0
- package/dist/projections/builders.d.ts +0 -2
- package/dist/projections/builders.d.ts.map +1 -1
- package/dist/projections/capability.d.ts +7 -0
- package/dist/projections/capability.d.ts.map +1 -0
- package/dist/projections/execution.d.ts +19 -0
- package/dist/projections/execution.d.ts.map +1 -0
- package/dist/projections/index.d.ts +3 -1
- package/dist/projections/index.d.ts.map +1 -1
- package/dist/projections/internal.d.ts +4 -10
- package/dist/projections/internal.d.ts.map +1 -1
- package/dist/projections/internal.js +42 -6
- package/dist/projections/internal.js.map +1 -1
- package/dist/projections/ownership.d.ts +2 -2
- package/dist/projections/ownership.d.ts.map +1 -1
- package/dist/projections/registry.d.ts +21 -11
- package/dist/projections/registry.d.ts.map +1 -1
- package/dist/projections/revision.d.ts +2 -2
- package/dist/projections/revision.d.ts.map +1 -1
- package/dist/projections/run-dispatch.d.ts +37 -0
- package/dist/projections/run-dispatch.d.ts.map +1 -0
- package/dist/projections/run-id.d.ts +3 -0
- package/dist/projections/run-id.d.ts.map +1 -0
- package/dist/projections/types.d.ts +3 -0
- package/dist/projections/types.d.ts.map +1 -1
- package/dist/projections/validation.d.ts +2 -2
- package/dist/projections/validation.d.ts.map +1 -1
- package/dist/queues/in-memory.d.ts +11 -10
- package/dist/queues/in-memory.d.ts.map +1 -1
- package/dist/queues/index.d.ts +1 -1
- package/dist/queues/index.d.ts.map +1 -1
- package/dist/queues/index.js +1 -1
- package/dist/queues/types.d.ts +52 -42
- package/dist/queues/types.d.ts.map +1 -1
- package/dist/rules/execution.d.ts +14 -0
- package/dist/rules/execution.d.ts.map +1 -0
- package/dist/rules/index.d.ts +1 -1
- package/dist/rules/index.d.ts.map +1 -1
- package/dist/rules/validation.d.ts +1 -2
- package/dist/rules/validation.d.ts.map +1 -1
- package/dist/runtime/ai-usage.d.ts +8 -0
- package/dist/runtime/ai-usage.d.ts.map +1 -0
- package/dist/runtime/create.d.ts +7 -5
- package/dist/runtime/create.d.ts.map +1 -1
- package/dist/runtime/definitions.d.ts +35 -0
- package/dist/runtime/definitions.d.ts.map +1 -0
- package/dist/runtime/host.d.ts +123 -0
- package/dist/runtime/host.d.ts.map +1 -0
- package/dist/runtime/index.d.ts +6 -5
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/internal.d.ts +4 -0
- package/dist/runtime/internal.d.ts.map +1 -1
- package/dist/runtime/internal.js +6 -2
- package/dist/runtime/internal.js.map +1 -1
- package/dist/runtime/ontology-mutations.d.ts +4 -2
- package/dist/runtime/ontology-mutations.d.ts.map +1 -1
- package/dist/runtime/resolve-definitions.d.ts +42 -0
- package/dist/runtime/resolve-definitions.d.ts.map +1 -0
- package/dist/runtime/sixb.d.ts +43 -219
- package/dist/runtime/sixb.d.ts.map +1 -1
- package/dist/runtime/types.d.ts +16 -216
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/scheduler/index.d.ts +1 -1
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +3 -6
- package/dist/scheduler/index.js.map +1 -1
- package/dist/scheduler/runtime.d.ts +7 -2
- package/dist/scheduler/runtime.d.ts.map +1 -1
- package/dist/schedules/execution.d.ts +6 -0
- package/dist/schedules/execution.d.ts.map +1 -0
- package/dist/schedules/index.js +9 -7
- package/dist/schedules/index.js.map +1 -1
- package/dist/schedules/types.d.ts +1 -3
- package/dist/schedules/types.d.ts.map +1 -1
- package/dist/security/every.d.ts +4 -1
- package/dist/security/every.d.ts.map +1 -1
- package/dist/security/grants.d.ts +4 -1
- package/dist/security/grants.d.ts.map +1 -1
- package/dist/security/index.d.ts +3 -1
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/registry.d.ts +42 -0
- package/dist/security/registry.d.ts.map +1 -0
- package/dist/security/types.d.ts +7 -12
- package/dist/security/types.d.ts.map +1 -1
- package/dist/security/validation.d.ts +2 -0
- package/dist/security/validation.d.ts.map +1 -1
- package/dist/storage/action-runs/failure.d.ts +7 -0
- package/dist/storage/action-runs/failure.d.ts.map +1 -0
- package/dist/storage/action-runs/failure.js +14 -0
- package/dist/storage/action-runs/failure.js.map +9 -0
- package/dist/storage/action-runs/idempotency.d.ts.map +1 -1
- package/dist/storage/action-runs/in-memory.d.ts +3 -1
- package/dist/storage/action-runs/in-memory.d.ts.map +1 -1
- package/dist/storage/action-runs/index.d.ts +2 -1
- package/dist/storage/action-runs/index.d.ts.map +1 -1
- package/dist/storage/action-runs/provider.d.ts +10 -0
- package/dist/storage/action-runs/provider.d.ts.map +1 -0
- package/dist/storage/action-runs/provider.js +13 -0
- package/dist/storage/action-runs/provider.js.map +9 -0
- package/dist/storage/action-runs/types.d.ts +37 -18
- package/dist/storage/action-runs/types.d.ts.map +1 -1
- package/dist/storage/agents/errors.d.ts +1 -1
- package/dist/storage/agents/errors.d.ts.map +1 -1
- package/dist/storage/agents/in-memory.d.ts +4 -1
- package/dist/storage/agents/in-memory.d.ts.map +1 -1
- package/dist/storage/agents/index.d.ts +2 -2
- package/dist/storage/agents/index.d.ts.map +1 -1
- package/dist/storage/agents/provider.d.ts +10 -0
- package/dist/storage/agents/provider.d.ts.map +1 -0
- package/dist/storage/agents/provider.js +17 -0
- package/dist/storage/agents/provider.js.map +9 -0
- package/dist/storage/agents/types.d.ts +13 -22
- package/dist/storage/agents/types.d.ts.map +1 -1
- package/dist/storage/ai-usage/errors.d.ts +8 -0
- package/dist/storage/ai-usage/errors.d.ts.map +1 -0
- package/dist/storage/ai-usage/in-memory.d.ts +28 -0
- package/dist/storage/ai-usage/in-memory.d.ts.map +1 -0
- package/dist/storage/ai-usage/index.d.ts +8 -0
- package/dist/storage/ai-usage/index.d.ts.map +1 -0
- package/dist/storage/ai-usage/record.d.ts +6 -0
- package/dist/storage/ai-usage/record.d.ts.map +1 -0
- package/dist/storage/ai-usage/types.d.ts +89 -0
- package/dist/storage/ai-usage/types.d.ts.map +1 -0
- package/dist/storage/ai-usage/usage.d.ts +11 -0
- package/dist/storage/ai-usage/usage.d.ts.map +1 -0
- package/dist/storage/auth/types.d.ts +1 -0
- package/dist/storage/auth/types.d.ts.map +1 -1
- package/dist/storage/connector-connections/errors.d.ts +12 -0
- package/dist/storage/connector-connections/errors.d.ts.map +1 -0
- package/dist/storage/connector-connections/in-memory.d.ts +81 -0
- package/dist/storage/connector-connections/in-memory.d.ts.map +1 -0
- package/dist/storage/connector-connections/index.d.ts +7 -0
- package/dist/storage/connector-connections/index.d.ts.map +1 -0
- package/dist/storage/connector-connections/provider/authorizations.d.ts +20 -0
- package/dist/storage/connector-connections/provider/authorizations.d.ts.map +1 -0
- package/dist/storage/connector-connections/provider/connections.d.ts +17 -0
- package/dist/storage/connector-connections/provider/connections.d.ts.map +1 -0
- package/dist/storage/connector-connections/provider/runs.d.ts +14 -0
- package/dist/storage/connector-connections/provider/runs.d.ts.map +1 -0
- package/dist/storage/connector-connections/provider/shared.d.ts +74 -0
- package/dist/storage/connector-connections/provider/shared.d.ts.map +1 -0
- package/dist/storage/connector-connections/provider.d.ts +49 -0
- package/dist/storage/connector-connections/provider.d.ts.map +1 -0
- package/dist/storage/connector-connections/provider.js +1025 -0
- package/dist/storage/connector-connections/provider.js.map +14 -0
- package/dist/storage/connector-connections/types.d.ts +402 -0
- package/dist/storage/connector-connections/types.d.ts.map +1 -0
- package/dist/storage/executions/errors.d.ts +8 -0
- package/dist/storage/executions/errors.d.ts.map +1 -0
- package/dist/storage/executions/in-memory.d.ts +21 -0
- package/dist/storage/executions/in-memory.d.ts.map +1 -0
- package/dist/storage/executions/index.d.ts +5 -0
- package/dist/storage/executions/index.d.ts.map +1 -0
- package/dist/storage/executions/provider.d.ts +29 -0
- package/dist/storage/executions/provider.d.ts.map +1 -0
- package/dist/storage/executions/provider.js +208 -0
- package/dist/storage/executions/provider.js.map +10 -0
- package/dist/storage/executions/run-link.d.ts +24 -0
- package/dist/storage/executions/run-link.d.ts.map +1 -0
- package/dist/storage/executions/types.d.ts +62 -0
- package/dist/storage/executions/types.d.ts.map +1 -0
- package/dist/storage/executions/validation.d.ts +13 -0
- package/dist/storage/executions/validation.d.ts.map +1 -0
- package/dist/storage/in-memory/index.d.ts +20 -5
- package/dist/storage/in-memory/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +28 -17
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +90 -27
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/ontology/commits.d.ts +1 -0
- package/dist/storage/ontology/commits.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/index.d.ts +1 -0
- package/dist/storage/ontology/in-memory/index.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/materializations-state.d.ts +3 -2
- package/dist/storage/ontology/in-memory/materializations-state.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/materializations-work.d.ts +2 -2
- package/dist/storage/ontology/in-memory/materializations-work.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/materializations.d.ts +3 -1
- package/dist/storage/ontology/in-memory/materializations.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/shared-state.d.ts +7 -2
- package/dist/storage/ontology/in-memory/shared-state.d.ts.map +1 -1
- package/dist/storage/ontology/index.d.ts +3 -2
- package/dist/storage/ontology/index.d.ts.map +1 -1
- package/dist/storage/ontology/materializations.d.ts +50 -5
- package/dist/storage/ontology/materializations.d.ts.map +1 -1
- package/dist/storage/ontology/outbox.d.ts +8 -2
- package/dist/storage/ontology/outbox.d.ts.map +1 -1
- package/dist/storage/ontology/provider-work.d.ts.map +1 -1
- package/dist/storage/ontology/provider.d.ts +5 -22
- package/dist/storage/ontology/provider.d.ts.map +1 -1
- package/dist/storage/ontology/provider.js +6 -7
- package/dist/storage/ontology/provider.js.map +1 -1
- package/dist/storage/operation-scope.d.ts.map +1 -1
- package/dist/storage/operation-scope.js +1 -1
- package/dist/storage/pipeline-runs/idempotency.d.ts +3 -0
- package/dist/storage/pipeline-runs/idempotency.d.ts.map +1 -0
- package/dist/storage/pipeline-runs/in-memory.d.ts +5 -1
- package/dist/storage/pipeline-runs/in-memory.d.ts.map +1 -1
- package/dist/storage/pipeline-runs/index.d.ts +3 -1
- package/dist/storage/pipeline-runs/index.d.ts.map +1 -1
- package/dist/storage/pipeline-runs/provider.d.ts +10 -0
- package/dist/storage/pipeline-runs/provider.d.ts.map +1 -0
- package/dist/storage/pipeline-runs/provider.js +11 -0
- package/dist/storage/pipeline-runs/provider.js.map +9 -0
- package/dist/storage/pipeline-runs/types.d.ts +30 -14
- package/dist/storage/pipeline-runs/types.d.ts.map +1 -1
- package/dist/storage/projection-runs/in-memory.d.ts +8 -3
- package/dist/storage/projection-runs/in-memory.d.ts.map +1 -1
- package/dist/storage/projection-runs/index.d.ts +2 -2
- package/dist/storage/projection-runs/index.d.ts.map +1 -1
- package/dist/storage/projection-runs/lifecycle.d.ts +14 -8
- package/dist/storage/projection-runs/lifecycle.d.ts.map +1 -1
- package/dist/storage/projection-runs/provider.d.ts +13 -0
- package/dist/storage/projection-runs/provider.d.ts.map +1 -0
- package/dist/storage/projection-runs/{lifecycle.js → provider.js} +15 -4
- package/dist/storage/projection-runs/provider.js.map +9 -0
- package/dist/storage/projection-runs/types.d.ts +28 -11
- package/dist/storage/projection-runs/types.d.ts.map +1 -1
- package/dist/storage/run-listing.d.ts +8 -9
- package/dist/storage/run-listing.d.ts.map +1 -1
- package/dist/storage/sync-runs/idempotency.d.ts +3 -0
- package/dist/storage/sync-runs/idempotency.d.ts.map +1 -0
- package/dist/storage/sync-runs/in-memory.d.ts +5 -1
- package/dist/storage/sync-runs/in-memory.d.ts.map +1 -1
- package/dist/storage/sync-runs/index.d.ts +3 -1
- package/dist/storage/sync-runs/index.d.ts.map +1 -1
- package/dist/storage/sync-runs/provider.d.ts +10 -0
- package/dist/storage/sync-runs/provider.d.ts.map +1 -0
- package/dist/storage/sync-runs/provider.js +11 -0
- package/dist/storage/sync-runs/provider.js.map +9 -0
- package/dist/storage/sync-runs/types.d.ts +35 -14
- package/dist/storage/sync-runs/types.d.ts.map +1 -1
- package/dist/storage/types.d.ts +20 -15
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/storage/webhook-runs/errors.d.ts +3 -0
- package/dist/storage/webhook-runs/errors.d.ts.map +1 -1
- package/dist/storage/webhook-runs/in-memory.d.ts +13 -1
- package/dist/storage/webhook-runs/in-memory.d.ts.map +1 -1
- package/dist/storage/webhook-runs/index.d.ts +3 -2
- package/dist/storage/webhook-runs/index.d.ts.map +1 -1
- package/dist/storage/webhook-runs/provider.d.ts +10 -0
- package/dist/storage/webhook-runs/provider.d.ts.map +1 -0
- package/dist/storage/webhook-runs/provider.js +11 -0
- package/dist/storage/webhook-runs/provider.js.map +9 -0
- package/dist/storage/webhook-runs/types.d.ts +37 -11
- package/dist/storage/webhook-runs/types.d.ts.map +1 -1
- package/dist/storage/workflow-runs/in-memory.d.ts +6 -2
- package/dist/storage/workflow-runs/in-memory.d.ts.map +1 -1
- package/dist/storage/workflow-runs/index.d.ts +2 -1
- package/dist/storage/workflow-runs/index.d.ts.map +1 -1
- package/dist/storage/workflow-runs/provider.d.ts +19 -0
- package/dist/storage/workflow-runs/provider.d.ts.map +1 -0
- package/dist/storage/workflow-runs/provider.js +19 -0
- package/dist/storage/workflow-runs/provider.js.map +9 -0
- package/dist/storage/workflow-runs/types.d.ts +30 -30
- package/dist/storage/workflow-runs/types.d.ts.map +1 -1
- package/dist/syncs/builders.d.ts +11 -3
- package/dist/syncs/builders.d.ts.map +1 -1
- package/dist/syncs/execution.d.ts +18 -0
- package/dist/syncs/execution.d.ts.map +1 -0
- package/dist/syncs/index.d.ts +3 -1
- package/dist/syncs/index.d.ts.map +1 -1
- package/dist/syncs/index.js +65 -0
- package/dist/syncs/index.js.map +9 -0
- package/dist/syncs/request.d.ts +6 -16
- package/dist/syncs/request.d.ts.map +1 -1
- package/dist/syncs/run-dispatch.d.ts +47 -0
- package/dist/syncs/run-dispatch.d.ts.map +1 -0
- package/dist/syncs/sources.d.ts +8 -0
- package/dist/syncs/sources.d.ts.map +1 -0
- package/dist/syncs/types.d.ts +34 -22
- package/dist/syncs/types.d.ts.map +1 -1
- package/dist/syncs/validation.d.ts +14 -0
- package/dist/syncs/validation.d.ts.map +1 -0
- package/dist/testing/action-execution.d.ts +12 -0
- package/dist/testing/action-execution.d.ts.map +1 -0
- package/dist/testing/agent-execution.d.ts +14 -0
- package/dist/testing/agent-execution.d.ts.map +1 -0
- package/dist/testing/agent-storage-contract.d.ts +10 -3
- package/dist/testing/agent-storage-contract.d.ts.map +1 -1
- package/dist/testing/ai-usage-storage-contract.d.ts +13 -0
- package/dist/testing/ai-usage-storage-contract.d.ts.map +1 -0
- package/dist/testing/auth-storage-contract.d.ts.map +1 -1
- package/dist/testing/broker-contract.d.ts.map +1 -1
- package/dist/testing/connector-connection-storage-contract.d.ts +16 -0
- package/dist/testing/connector-connection-storage-contract.d.ts.map +1 -0
- package/dist/testing/execution-storage-contract.d.ts +15 -0
- package/dist/testing/execution-storage-contract.d.ts.map +1 -0
- package/dist/testing/execution.d.ts +23 -0
- package/dist/testing/execution.d.ts.map +1 -0
- package/dist/testing/index.d.ts +13 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +4270 -1484
- package/dist/testing/index.js.map +27 -14
- package/dist/testing/lake-merge-storage-contract.d.ts +7 -0
- package/dist/testing/lake-merge-storage-contract.d.ts.map +1 -0
- package/dist/testing/lake-storage-contract.d.ts.map +1 -1
- package/dist/testing/materializer-fixture.d.ts +2 -2
- package/dist/testing/materializer-fixture.d.ts.map +1 -1
- package/dist/testing/materializer-storage-contract.d.ts.map +1 -1
- package/dist/testing/ontology-contract-fixture.d.ts +1 -0
- package/dist/testing/ontology-contract-fixture.d.ts.map +1 -1
- package/dist/testing/ontology-storage-contract.d.ts.map +1 -1
- package/dist/testing/pipeline-execution.d.ts +16 -0
- package/dist/testing/pipeline-execution.d.ts.map +1 -0
- package/dist/testing/projection-execution.d.ts +20 -0
- package/dist/testing/projection-execution.d.ts.map +1 -0
- package/dist/testing/projection-run-storage-contract.d.ts +9 -4
- package/dist/testing/projection-run-storage-contract.d.ts.map +1 -1
- package/dist/testing/queues-contract.d.ts.map +1 -1
- package/dist/testing/sync-execution.d.ts +16 -0
- package/dist/testing/sync-execution.d.ts.map +1 -0
- package/dist/testing/webhook-execution.d.ts +12 -0
- package/dist/testing/webhook-execution.d.ts.map +1 -0
- package/dist/testing/webhook-run-storage-contract.d.ts +11 -0
- package/dist/testing/webhook-run-storage-contract.d.ts.map +1 -0
- package/dist/testing/workflow-execution.d.ts +23 -0
- package/dist/testing/workflow-execution.d.ts.map +1 -0
- package/dist/webhooks/index.d.ts +2 -1
- package/dist/webhooks/index.d.ts.map +1 -1
- package/dist/webhooks/internal.d.ts +2 -0
- package/dist/webhooks/internal.d.ts.map +1 -0
- package/dist/webhooks/internal.js +150 -0
- package/dist/webhooks/internal.js.map +10 -0
- package/dist/webhooks/registry.d.ts +18 -4
- package/dist/webhooks/registry.d.ts.map +1 -1
- package/dist/webhooks/run-admission.d.ts +25 -0
- package/dist/webhooks/run-admission.d.ts.map +1 -0
- package/dist/webhooks/types.d.ts +8 -5
- package/dist/webhooks/types.d.ts.map +1 -1
- package/dist/workers/index.js +18 -19
- package/dist/workers/index.js.map +4 -4
- package/dist/workers/queue-delivery.d.ts +7 -7
- package/dist/workers/queue-delivery.d.ts.map +1 -1
- package/dist/workers/queue-worker.d.ts +30 -11
- package/dist/workers/queue-worker.d.ts.map +1 -1
- package/dist/workflows/execution.d.ts +49 -0
- package/dist/workflows/execution.d.ts.map +1 -0
- package/dist/workflows/failure.d.ts +28 -0
- package/dist/workflows/failure.d.ts.map +1 -0
- package/dist/workflows/index.d.ts +4 -2
- package/dist/workflows/index.d.ts.map +1 -1
- package/dist/workflows/index.js +63 -35
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/request.d.ts +2 -1
- package/dist/workflows/request.d.ts.map +1 -1
- package/dist/workflows/run-dispatch.d.ts +59 -0
- package/dist/workflows/run-dispatch.d.ts.map +1 -0
- package/dist/workflows/types.d.ts +38 -8
- package/dist/workflows/types.d.ts.map +1 -1
- package/package.json +107 -5
- package/src/actions/commit-edits.ts +0 -3
- package/src/actions/execution.ts +83 -0
- package/src/actions/index.ts +1 -1
- package/src/actions/registry.ts +22 -10
- package/src/actions/request.ts +55 -177
- package/src/actions/run-dispatch.ts +276 -0
- package/src/actions/types/context.ts +2 -4
- package/src/actions/validation.ts +2 -2
- package/src/agents/adapters.ts +8 -12
- package/src/agents/authority.ts +189 -0
- package/src/agents/builders.ts +53 -3
- package/src/agents/dispatch.ts +1 -6
- package/src/agents/errors.ts +24 -0
- package/src/agents/execution.ts +254 -0
- package/src/agents/index.ts +37 -5
- package/src/agents/prompt.ts +17 -5
- package/src/agents/request.ts +153 -13
- package/src/agents/streams.ts +150 -3
- package/src/agents/tool-definition.ts +93 -0
- package/src/agents/types.ts +99 -0
- package/src/agents/validation.ts +289 -5
- package/src/auth/attribution.ts +48 -0
- package/src/auth/index.ts +1 -0
- package/src/auth/runtime.ts +5 -5
- package/src/authorization/decision.ts +75 -14
- package/src/authorization/grant-kinds.ts +9 -0
- package/src/authorization/index.ts +2 -0
- package/src/blob-storage/execution.ts +78 -0
- package/src/blob-storage/validation.ts +2 -10
- package/src/bootstrap/discovery.ts +88 -268
- package/src/bootstrap/index.ts +2 -13
- package/src/broker/in-memory.ts +8 -1
- package/src/broker/types.ts +5 -0
- package/src/connectors/builders.ts +37 -2
- package/src/connectors/connections/authorizations.ts +646 -0
- package/src/connectors/connections/capability.ts +59 -0
- package/src/connectors/connections/command-context.ts +98 -0
- package/src/connectors/connections/contracts.ts +208 -0
- package/src/connectors/connections/credential-codec.ts +48 -0
- package/src/connectors/connections/credential-mutations.ts +574 -0
- package/src/connectors/connections/execution.ts +138 -0
- package/src/connectors/connections/internal.ts +17 -0
- package/src/connectors/connections/provider-operation.ts +41 -0
- package/src/connectors/connections/request.ts +447 -0
- package/src/connectors/connections/runs.ts +702 -0
- package/src/connectors/connections/service.ts +644 -0
- package/src/connectors/connections/storage-boundary.ts +13 -0
- package/src/connectors/connections/tokens.ts +292 -0
- package/src/connectors/connections/validation.ts +316 -0
- package/src/connectors/connections/views.ts +37 -0
- package/src/connectors/credentials.ts +149 -0
- package/src/connectors/errors.ts +111 -3
- package/src/connectors/execution.ts +157 -0
- package/src/connectors/index.ts +26 -2
- package/src/connectors/service.ts +142 -0
- package/src/connectors/types.ts +156 -7
- package/src/datasets/builders.ts +49 -5
- package/src/datasets/changes.ts +13 -0
- package/src/datasets/execution.ts +24 -0
- package/src/datasets/index.ts +3 -0
- package/src/datasets/types.ts +5 -0
- package/src/datasets/validation.ts +53 -11
- package/src/error-reporting/capability.ts +33 -106
- package/src/error-reporting/internal.ts +3 -1
- package/src/error-reporting/reporter.ts +19 -3
- package/src/error-reporting/reports.ts +172 -0
- package/src/error-reporting/types.ts +97 -43
- package/src/errors/catalog.ts +149 -0
- package/src/errors/internal.ts +322 -0
- package/src/errors/types.ts +21 -0
- package/src/events/definitions.ts +0 -4
- package/src/events/execution.ts +45 -0
- package/src/events/index.ts +15 -14
- package/src/events/outbox-dispatcher.ts +53 -18
- package/src/events/{runtime.ts → service.ts} +19 -23
- package/src/events/types/pipelines.ts +4 -1
- package/src/events/types/syncs.ts +3 -0
- package/src/events/types/workflows.ts +4 -2
- package/src/execution/agent.ts +130 -0
- package/src/execution/authorization.ts +409 -0
- package/src/execution/dispatch.ts +7 -0
- package/src/execution/durable.ts +193 -0
- package/src/execution/index.ts +12 -0
- package/src/execution/primitive.ts +50 -0
- package/src/execution/request.ts +109 -0
- package/src/execution/scopes.ts +198 -0
- package/src/execution/types.ts +113 -0
- package/src/http/api-routes.ts +42 -7
- package/src/index.ts +127 -10
- package/src/json.ts +11 -8
- package/src/lake-storage/definition-updates.ts +21 -0
- package/src/lake-storage/in-memory.ts +284 -2
- package/src/lake-storage/index.ts +14 -0
- package/src/lake-storage/merge-validation.ts +117 -0
- package/src/lake-storage/merge.ts +35 -0
- package/src/lake-storage/types.ts +3 -1
- package/src/logging/execution.ts +28 -0
- package/src/logging/index.ts +4 -4
- package/src/logging/{runtime.ts → service.ts} +7 -7
- package/src/materialization/events.ts +1 -0
- package/src/materialization/index.ts +2 -0
- package/src/materialization/model.ts +30 -18
- package/src/materializer/README.md +9 -13
- package/src/materializer/edits/commit.ts +85 -28
- package/src/materializer/edits/load-state.ts +79 -16
- package/src/materializer/edits/operations.ts +72 -36
- package/src/materializer/edits/plan.ts +95 -22
- package/src/materializer/edits/working-state.ts +86 -55
- package/src/materializer/effective/build-events.ts +2 -0
- package/src/materializer/effective/diff.ts +22 -0
- package/src/materializer/effective/load-state.ts +0 -31
- package/src/materializer/effective/resolve.ts +62 -0
- package/src/materializer/execution/commit-lifecycle.ts +9 -1
- package/src/materializer/execution/plan-stream.ts +33 -9
- package/src/materializer/execution/scope.ts +95 -0
- package/src/materializer/execution/work-executor.ts +6 -2
- package/src/materializer/execution/work-records.ts +39 -6
- package/src/materializer/index.ts +9 -1
- package/src/materializer/materializer.ts +67 -5
- package/src/materializer/projections/finish-run.ts +29 -11
- package/src/materializer/projections/replace.ts +55 -22
- package/src/materializer/projections/replacement-plan.ts +37 -7
- package/src/materializer/shared/batching.ts +4 -1
- package/src/materializer/shared/normalize.ts +0 -19
- package/src/materializer/telemetry/append.ts +57 -26
- package/src/materializer/telemetry/plan.ts +15 -6
- package/src/objects/action/request.ts +5 -5
- package/src/objects/context/index.ts +1 -0
- package/src/objects/context/types.ts +6 -0
- package/src/objects/execution.ts +346 -0
- package/src/objects/materializer-adapter.ts +1 -23
- package/src/objects/query/executor.ts +15 -29
- package/src/objects/query/index.ts +1 -2
- package/src/objects/query/planner.ts +0 -6
- package/src/objects/sdk/object-handle.ts +2 -2
- package/src/objects/sdk/object-set.ts +17 -7
- package/src/objects/sdk/runtime-query-executor.ts +9 -2
- package/src/objects/sdk/telemetry-channel.ts +5 -1
- package/src/objects/service/action-service.ts +5 -2
- package/src/objects/service/list-service.ts +1 -1
- package/src/objects/telemetry/history.ts +8 -3
- package/src/objects/telemetry/write-batch.ts +0 -2
- package/src/ontology/index.ts +6 -1
- package/src/ontology/json-schema.ts +2 -1
- package/src/ontology/registry.ts +16 -2
- package/src/ontology/validation/normalize.ts +9 -15
- package/src/pipelines/execution.ts +105 -0
- package/src/pipelines/index.ts +7 -0
- package/src/pipelines/request.ts +32 -26
- package/src/pipelines/run-dispatch.ts +308 -0
- package/src/projections/builders.ts +0 -9
- package/src/projections/capability.ts +37 -0
- package/src/projections/execution.ts +85 -0
- package/src/projections/index.ts +2 -1
- package/src/projections/internal.ts +17 -60
- package/src/projections/ownership.ts +2 -2
- package/src/projections/registry.ts +26 -11
- package/src/projections/revision.ts +7 -5
- package/src/projections/run-dispatch.ts +497 -0
- package/src/projections/run-id.ts +20 -0
- package/src/projections/types.ts +12 -0
- package/src/projections/validation.ts +3 -3
- package/src/queues/in-memory.ts +37 -11
- package/src/queues/index.ts +9 -2
- package/src/queues/types.ts +70 -45
- package/src/rules/execution.ts +49 -0
- package/src/rules/index.ts +0 -1
- package/src/rules/validation.ts +2 -6
- package/src/runtime/ai-usage.ts +17 -0
- package/src/runtime/create.ts +28 -68
- package/src/runtime/definitions.ts +44 -0
- package/src/runtime/host.ts +377 -0
- package/src/runtime/index.ts +5 -13
- package/src/runtime/internal.ts +12 -0
- package/src/runtime/ontology-mutations.ts +5 -3
- package/src/runtime/resolve-definitions.ts +238 -0
- package/src/runtime/sixb.ts +95 -807
- package/src/runtime/types.ts +17 -290
- package/src/scheduler/index.ts +1 -1
- package/src/scheduler/runtime.ts +37 -6
- package/src/schedules/execution.ts +14 -0
- package/src/schedules/types.ts +0 -8
- package/src/security/every.ts +4 -0
- package/src/security/grants.ts +13 -1
- package/src/security/index.ts +3 -1
- package/src/security/registry.ts +107 -0
- package/src/security/types.ts +8 -12
- package/src/security/validation.ts +7 -0
- package/src/storage/action-runs/failure.ts +64 -0
- package/src/storage/action-runs/idempotency.ts +3 -1
- package/src/storage/action-runs/in-memory.ts +39 -9
- package/src/storage/action-runs/index.ts +3 -0
- package/src/storage/action-runs/provider.ts +25 -0
- package/src/storage/action-runs/types.ts +61 -27
- package/src/storage/agents/errors.ts +1 -0
- package/src/storage/agents/in-memory.ts +49 -11
- package/src/storage/agents/index.ts +2 -1
- package/src/storage/agents/provider.ts +27 -0
- package/src/storage/agents/types.ts +19 -19
- package/src/storage/ai-usage/errors.ts +13 -0
- package/src/storage/ai-usage/in-memory.ts +162 -0
- package/src/storage/ai-usage/index.ts +21 -0
- package/src/storage/ai-usage/record.ts +74 -0
- package/src/storage/ai-usage/types.ts +102 -0
- package/src/storage/ai-usage/usage.ts +104 -0
- package/src/storage/auth/types.ts +1 -0
- package/src/storage/connector-connections/errors.ts +24 -0
- package/src/storage/connector-connections/in-memory.ts +1377 -0
- package/src/storage/connector-connections/index.ts +66 -0
- package/src/storage/connector-connections/provider/authorizations.ts +446 -0
- package/src/storage/connector-connections/provider/connections.ts +291 -0
- package/src/storage/connector-connections/provider/runs.ts +369 -0
- package/src/storage/connector-connections/provider/shared.ts +342 -0
- package/src/storage/connector-connections/provider.ts +219 -0
- package/src/storage/connector-connections/types.ts +546 -0
- package/src/storage/executions/errors.ts +21 -0
- package/src/storage/executions/in-memory.ts +75 -0
- package/src/storage/executions/index.ts +16 -0
- package/src/storage/executions/provider.ts +292 -0
- package/src/storage/executions/run-link.ts +70 -0
- package/src/storage/executions/types.ts +49 -0
- package/src/storage/executions/validation.ts +370 -0
- package/src/storage/in-memory/index.ts +50 -16
- package/src/storage/index.ts +155 -15
- package/src/storage/ontology/commits.ts +1 -0
- package/src/storage/ontology/in-memory/index.ts +2 -0
- package/src/storage/ontology/in-memory/materializations-finalization.ts +2 -1
- package/src/storage/ontology/in-memory/materializations-state.ts +10 -0
- package/src/storage/ontology/in-memory/materializations-work.ts +2 -1
- package/src/storage/ontology/in-memory/materializations.ts +131 -9
- package/src/storage/ontology/in-memory/outbox.ts +1 -1
- package/src/storage/ontology/in-memory/shared-state.ts +12 -1
- package/src/storage/ontology/index.ts +6 -0
- package/src/storage/ontology/materializations.ts +50 -4
- package/src/storage/ontology/outbox.ts +13 -2
- package/src/storage/ontology/provider-header-validation.ts +1 -0
- package/src/storage/ontology/provider-work.ts +33 -14
- package/src/storage/ontology/provider.ts +72 -52
- package/src/storage/operation-scope.ts +1 -0
- package/src/storage/pipeline-runs/idempotency.ts +14 -0
- package/src/storage/pipeline-runs/in-memory.ts +88 -8
- package/src/storage/pipeline-runs/index.ts +5 -1
- package/src/storage/pipeline-runs/provider.ts +25 -0
- package/src/storage/pipeline-runs/types.ts +37 -14
- package/src/storage/projection-runs/in-memory.ts +93 -24
- package/src/storage/projection-runs/index.ts +4 -0
- package/src/storage/projection-runs/lifecycle.ts +165 -36
- package/src/storage/projection-runs/provider.ts +34 -0
- package/src/storage/projection-runs/types.ts +34 -11
- package/src/storage/run-listing.ts +22 -13
- package/src/storage/sync-runs/idempotency.ts +18 -0
- package/src/storage/sync-runs/in-memory.ts +92 -9
- package/src/storage/sync-runs/index.ts +5 -1
- package/src/storage/sync-runs/provider.ts +25 -0
- package/src/storage/sync-runs/types.ts +44 -15
- package/src/storage/types.ts +45 -17
- package/src/storage/webhook-runs/errors.ts +14 -0
- package/src/storage/webhook-runs/in-memory.ts +84 -9
- package/src/storage/webhook-runs/index.ts +5 -1
- package/src/storage/webhook-runs/provider.ts +30 -0
- package/src/storage/webhook-runs/types.ts +52 -11
- package/src/storage/workflow-runs/in-memory.ts +91 -55
- package/src/storage/workflow-runs/index.ts +2 -0
- package/src/storage/workflow-runs/provider.ts +70 -0
- package/src/storage/workflow-runs/types.ts +38 -25
- package/src/syncs/builders.ts +33 -15
- package/src/syncs/execution.ts +78 -0
- package/src/syncs/index.ts +14 -0
- package/src/syncs/request.ts +32 -43
- package/src/syncs/run-dispatch.ts +312 -0
- package/src/syncs/sources.ts +20 -0
- package/src/syncs/types.ts +75 -25
- package/src/syncs/validation.ts +77 -0
- package/src/testing/action-execution.ts +61 -0
- package/src/testing/agent-execution.ts +81 -0
- package/src/testing/agent-storage-contract.ts +158 -63
- package/src/testing/ai-usage-storage-contract.ts +528 -0
- package/src/testing/auth-storage-contract.ts +17 -1
- package/src/testing/broker-contract.ts +16 -1
- package/src/testing/connector-connection-storage-contract.ts +1052 -0
- package/src/testing/execution-storage-contract.ts +435 -0
- package/src/testing/execution.ts +48 -0
- package/src/testing/index.ts +56 -0
- package/src/testing/lake-merge-storage-contract.ts +302 -0
- package/src/testing/lake-storage-contract.ts +23 -0
- package/src/testing/materializer-fixture.ts +11 -3
- package/src/testing/materializer-storage-contract.ts +213 -11
- package/src/testing/ontology-contract-fixture.ts +35 -2
- package/src/testing/ontology-storage-contract.ts +75 -14
- package/src/testing/pipeline-execution.ts +64 -0
- package/src/testing/projection-execution.ts +98 -0
- package/src/testing/projection-run-storage-contract.ts +215 -29
- package/src/testing/queues-contract.ts +40 -51
- package/src/testing/sync-execution.ts +61 -0
- package/src/testing/webhook-execution.ts +47 -0
- package/src/testing/webhook-run-storage-contract.ts +240 -0
- package/src/testing/workflow-execution.ts +77 -0
- package/src/webhooks/index.ts +2 -1
- package/src/webhooks/internal.ts +5 -0
- package/src/webhooks/registry.ts +60 -36
- package/src/webhooks/run-admission.ts +172 -0
- package/src/webhooks/types.ts +8 -5
- package/src/workers/queue-delivery.ts +25 -22
- package/src/workers/queue-worker.ts +62 -32
- package/src/workflows/execution.ts +292 -0
- package/src/workflows/failure.ts +63 -0
- package/src/workflows/index.ts +10 -1
- package/src/workflows/request.ts +39 -118
- package/src/workflows/run-dispatch.ts +359 -0
- package/src/workflows/snapshot.ts +1 -10
- package/src/workflows/types.ts +39 -8
- package/dist/actions/runtime.d.ts +0 -11
- package/dist/actions/runtime.d.ts.map +0 -1
- package/dist/agents/runtime.d.ts +0 -41
- package/dist/agents/runtime.d.ts.map +0 -1
- package/dist/chunk-0fygrz37.js +0 -354
- package/dist/chunk-0fygrz37.js.map +0 -17
- package/dist/chunk-0psb6kdw.js +0 -989
- package/dist/chunk-0psb6kdw.js.map +0 -15
- package/dist/chunk-1vffvydj.js.map +0 -10
- package/dist/chunk-2gpr6jsz.js.map +0 -13
- package/dist/chunk-2s6sydsh.js.map +0 -12
- package/dist/chunk-50kv63vj.js.map +0 -12
- package/dist/chunk-590dejbp.js +0 -49
- package/dist/chunk-590dejbp.js.map +0 -10
- package/dist/chunk-867jxh7c.js.map +0 -19
- package/dist/chunk-aebzcsxr.js.map +0 -48
- package/dist/chunk-btpe64e4.js +0 -554
- package/dist/chunk-btpe64e4.js.map +0 -13
- package/dist/chunk-dcgrzj1t.js.map +0 -36
- package/dist/chunk-dhmj53mx.js.map +0 -16
- package/dist/chunk-hsv43v58.js +0 -1390
- package/dist/chunk-hsv43v58.js.map +0 -21
- package/dist/chunk-jdwx7vzs.js.map +0 -14
- package/dist/chunk-k25jm1x5.js +0 -102
- package/dist/chunk-k25jm1x5.js.map +0 -10
- package/dist/chunk-k41ajtz7.js +0 -352
- package/dist/chunk-k41ajtz7.js.map +0 -13
- package/dist/chunk-k6j72mtt.js +0 -9
- package/dist/chunk-k6j72mtt.js.map +0 -10
- package/dist/chunk-nvamz5dv.js +0 -819
- package/dist/chunk-nvamz5dv.js.map +0 -21
- package/dist/chunk-pv1yad91.js +0 -1165
- package/dist/chunk-pv1yad91.js.map +0 -27
- package/dist/chunk-q4qzq0ea.js.map +0 -14
- package/dist/chunk-r65yscvk.js.map +0 -11
- package/dist/chunk-t358gywy.js.map +0 -34
- package/dist/chunk-t72dvahb.js.map +0 -12
- package/dist/chunk-v5c085yp.js.map +0 -10
- package/dist/chunk-wj01s5hr.js.map +0 -11
- package/dist/chunk-wxhdnwh4.js +0 -37
- package/dist/chunk-wxhdnwh4.js.map +0 -10
- package/dist/chunk-xz5g49bp.js.map +0 -11
- package/dist/chunk-ya6brh8a.js.map +0 -11
- package/dist/chunk-yvef9xwc.js.map +0 -44
- package/dist/chunk-yxss87qa.js.map +0 -14
- package/dist/connectors/runtime.d.ts +0 -13
- package/dist/connectors/runtime.d.ts.map +0 -1
- package/dist/events/runtime.d.ts.map +0 -1
- package/dist/objects/contexts.d.ts +0 -45
- package/dist/objects/contexts.d.ts.map +0 -1
- package/dist/objects/helpers.d.ts +0 -7
- package/dist/objects/helpers.d.ts.map +0 -1
- package/dist/runtime/scoped.d.ts +0 -158
- package/dist/runtime/scoped.d.ts.map +0 -1
- package/dist/security/runtime.d.ts +0 -16
- package/dist/security/runtime.d.ts.map +0 -1
- package/dist/storage/webhook-deliveries/in-memory.d.ts +0 -18
- package/dist/storage/webhook-deliveries/in-memory.d.ts.map +0 -1
- package/dist/storage/webhook-deliveries/index.d.ts +0 -3
- package/dist/storage/webhook-deliveries/index.d.ts.map +0 -1
- package/dist/storage/webhook-deliveries/types.d.ts +0 -43
- package/dist/storage/webhook-deliveries/types.d.ts.map +0 -1
- package/dist/workflows/runtime.d.ts +0 -33
- package/dist/workflows/runtime.d.ts.map +0 -1
- package/src/actions/runtime.ts +0 -31
- package/src/agents/runtime.ts +0 -124
- package/src/connectors/runtime.ts +0 -100
- package/src/objects/contexts.ts +0 -64
- package/src/objects/helpers.ts +0 -18
- package/src/runtime/scoped.ts +0 -436
- package/src/security/runtime.ts +0 -101
- package/src/storage/webhook-deliveries/in-memory.ts +0 -108
- package/src/storage/webhook-deliveries/index.ts +0 -9
- package/src/storage/webhook-deliveries/types.ts +0 -41
- package/src/workflows/runtime.ts +0 -68
- /package/dist/{chunk-45tw90k7.js.map → chunk-4gz41why.js.map} +0 -0
- /package/dist/{chunk-vj723r3p.js.map → chunk-8b55ygje.js.map} +0 -0
- /package/dist/{chunk-p6r5g77m.js.map → chunk-vybf6pkp.js.map} +0 -0
- /package/dist/{chunk-5yny9z0e.js.map → chunk-z3zp0bj1.js.map} +0 -0
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
compareCardinalityWork,
|
|
17
17
|
compareEventWork,
|
|
18
18
|
comparePlanWork,
|
|
19
|
+
createEventId,
|
|
19
20
|
finishScopeAccumulator,
|
|
20
21
|
invalidCorrelation,
|
|
21
22
|
isExactStagingManifest,
|
|
@@ -26,7 +27,7 @@ import {
|
|
|
26
27
|
startScopeAccumulator,
|
|
27
28
|
uniqueSorted,
|
|
28
29
|
workUniquenessKey
|
|
29
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-fmx1sz2h.js";
|
|
30
31
|
import {
|
|
31
32
|
createAgentOperationScope,
|
|
32
33
|
createAuthOperationScope,
|
|
@@ -34,20 +35,28 @@ import {
|
|
|
34
35
|
createOperationScopedFacade,
|
|
35
36
|
createStorageOperationScope,
|
|
36
37
|
createWorkflowRunOperationScope
|
|
37
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-57r1cpxx.js";
|
|
39
|
+
import {
|
|
40
|
+
PipelineRunError,
|
|
41
|
+
assertPipelineRunExecution
|
|
42
|
+
} from "./chunk-cy0n5dms.js";
|
|
38
43
|
import {
|
|
39
44
|
ProjectionRunError,
|
|
40
45
|
advanceProjectionTelemetry,
|
|
41
46
|
assertGenericProgressDoesNotAdvanceTelemetry,
|
|
42
47
|
assertProjectionMissingTarget,
|
|
43
|
-
|
|
48
|
+
assertProjectionRunAttempt,
|
|
49
|
+
assertProjectionRunDurableExecution,
|
|
44
50
|
assertProjectionRunIdentityMatches,
|
|
45
51
|
assertProjectionRunListWindow,
|
|
46
52
|
assertProjectionRunNonEmpty,
|
|
53
|
+
assertProjectionRunQueueInput,
|
|
47
54
|
assertProjectionRunRunning,
|
|
48
55
|
assertProjectionRunStartInput,
|
|
56
|
+
canRequeueProjectionRunAfterEnqueueFailure,
|
|
49
57
|
createProjectionRunClaim,
|
|
50
58
|
createProjectionRunRecord,
|
|
59
|
+
failProjectionRunEnqueue,
|
|
51
60
|
finishProjectionRunRecord,
|
|
52
61
|
immutableDatasetVersionConflict,
|
|
53
62
|
mergeProjectionRunProgress,
|
|
@@ -57,50 +66,83 @@ import {
|
|
|
57
66
|
publicProjectionRunRecord,
|
|
58
67
|
requireTelemetryProjectionRun,
|
|
59
68
|
staleProjectionRunExecution
|
|
60
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-dysw7nsm.js";
|
|
61
70
|
import {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
} from "./chunk-
|
|
71
|
+
SyncRunError,
|
|
72
|
+
assertSyncRunExecution
|
|
73
|
+
} from "./chunk-62c7t4jc.js";
|
|
74
|
+
import {
|
|
75
|
+
WebhookRunError,
|
|
76
|
+
assertWebhookRunExecution
|
|
77
|
+
} from "./chunk-ezake7g1.js";
|
|
78
|
+
import {
|
|
79
|
+
WorkflowRunError,
|
|
80
|
+
assertWorkflowAgentNodeRunExecution,
|
|
81
|
+
assertWorkflowRunExecution
|
|
82
|
+
} from "./chunk-4x43bkbp.js";
|
|
83
|
+
import {
|
|
84
|
+
parseActionRunFailure
|
|
85
|
+
} from "./chunk-htq0qh7z.js";
|
|
86
|
+
import {
|
|
87
|
+
ActionRunError,
|
|
88
|
+
assertActionRunExecution
|
|
89
|
+
} from "./chunk-xkthy56g.js";
|
|
65
90
|
import {
|
|
66
|
-
|
|
67
|
-
|
|
91
|
+
AgentStorageError,
|
|
92
|
+
assertAgentRunExecution
|
|
93
|
+
} from "./chunk-vp1vc6ee.js";
|
|
94
|
+
import {
|
|
95
|
+
CONNECTOR_CONNECTION_RUN_FAILURE_CODES,
|
|
96
|
+
ConnectorConnectionStorageError
|
|
97
|
+
} from "./chunk-5gd7tpv6.js";
|
|
98
|
+
import {
|
|
99
|
+
ExecutionStorageError,
|
|
100
|
+
cloneExecutionRecord,
|
|
101
|
+
normalizeExecutionRecord,
|
|
102
|
+
validateExecutionRecordReferences
|
|
103
|
+
} from "./chunk-h9kxd41f.js";
|
|
68
104
|
import {
|
|
69
105
|
assertPinnedDatasetWatermark
|
|
70
106
|
} from "./chunk-9dzba0f2.js";
|
|
71
107
|
import {
|
|
72
108
|
linkRefKey,
|
|
73
109
|
linkRefSortKey,
|
|
110
|
+
linkScopeKey,
|
|
74
111
|
linkScopeSortKey,
|
|
75
112
|
objectRefKey,
|
|
76
113
|
objectRefSortKey,
|
|
77
114
|
projectionEntityKey,
|
|
78
115
|
telemetryPointKey,
|
|
79
116
|
telemetryPointSortKey
|
|
80
|
-
} from "./chunk-
|
|
117
|
+
} from "./chunk-vybf6pkp.js";
|
|
81
118
|
import {
|
|
82
119
|
MaterializationConflictError,
|
|
83
120
|
MaterializationValidationError
|
|
84
121
|
} from "./chunk-ry24jbr1.js";
|
|
85
122
|
import {
|
|
86
|
-
|
|
87
|
-
|
|
123
|
+
compareQueryScalarValues,
|
|
124
|
+
queryScalarValuesEqual
|
|
125
|
+
} from "./chunk-6wetht33.js";
|
|
126
|
+
import {
|
|
127
|
+
AGENT_RUN_FAILURE_CODES
|
|
128
|
+
} from "./chunk-663csy96.js";
|
|
88
129
|
import {
|
|
89
130
|
InMemoryAuthStorage,
|
|
90
|
-
|
|
91
|
-
paginate
|
|
92
|
-
|
|
131
|
+
normalizeRequesterGroupIds,
|
|
132
|
+
paginate,
|
|
133
|
+
principalsEqual
|
|
134
|
+
} from "./chunk-jaj13078.js";
|
|
93
135
|
import {
|
|
136
|
+
createSixbError,
|
|
137
|
+
parseSixbFailure,
|
|
138
|
+
toSixbFailure
|
|
139
|
+
} from "./chunk-0172wgm9.js";
|
|
140
|
+
import {
|
|
141
|
+
assertJsonValue,
|
|
94
142
|
cloneJsonValue,
|
|
143
|
+
isPlainRecord,
|
|
95
144
|
stableJsonStringify
|
|
96
|
-
} from "./chunk-
|
|
97
|
-
// src/storage/action-runs/errors.ts
|
|
98
|
-
class ActionRunError extends MaterializationConflictError {
|
|
99
|
-
name = "ActionRunError";
|
|
100
|
-
constructor(message) {
|
|
101
|
-
super("run-correlation", message);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
145
|
+
} from "./chunk-t8t39h7v.js";
|
|
104
146
|
// src/storage/action-runs/idempotency.ts
|
|
105
147
|
function actionSubjectsEqual(left, right) {
|
|
106
148
|
if (left.kind !== right.kind)
|
|
@@ -121,10 +163,10 @@ function finishActionRunPhase(input, current) {
|
|
|
121
163
|
if (input.status === "succeeded") {
|
|
122
164
|
return input.phase ?? current ?? "validation";
|
|
123
165
|
}
|
|
124
|
-
return input.
|
|
166
|
+
return input.error.details.phase;
|
|
125
167
|
}
|
|
126
168
|
function canRequeueActionRunAfterEnqueueFailure(existing, input) {
|
|
127
|
-
return existing.status === "failed" && existing.phase === "enqueue" && existing.actionId === input.actionId && existing.idempotencyKey === input.idempotencyKey && actionSubjectsEqual(existing.subject, input.subject) && actionRunParamsEqual(existing.params, input.params);
|
|
169
|
+
return existing.status === "failed" && existing.phase === "enqueue" && existing.executionId === input.executionId && existing.error?.retryable === true && existing.actionId === input.actionId && existing.idempotencyKey === input.idempotencyKey && actionSubjectsEqual(existing.subject, input.subject) && actionRunParamsEqual(existing.params, input.params);
|
|
128
170
|
}
|
|
129
171
|
function isTerminalActionRun(record) {
|
|
130
172
|
return record.status === "succeeded" || record.status === "failed" || record.status === "cancelled";
|
|
@@ -152,8 +194,8 @@ function normalizeParams(params) {
|
|
|
152
194
|
function normalizeSubject(subject) {
|
|
153
195
|
return structuredClone(subject);
|
|
154
196
|
}
|
|
155
|
-
function normalizeError(error) {
|
|
156
|
-
return
|
|
197
|
+
function normalizeError(error, expectedPhase) {
|
|
198
|
+
return expectedPhase === undefined ? parseActionRunFailure(error) : parseActionRunFailure(error, expectedPhase);
|
|
157
199
|
}
|
|
158
200
|
function normalizeWriteback(input, completedAt) {
|
|
159
201
|
if (input.status === "succeeded") {
|
|
@@ -166,7 +208,7 @@ function normalizeWriteback(input, completedAt) {
|
|
|
166
208
|
return {
|
|
167
209
|
status: "failed",
|
|
168
210
|
completedAt,
|
|
169
|
-
error: normalizeError(input.error)
|
|
211
|
+
error: normalizeError(input.error, "writeback")
|
|
170
212
|
};
|
|
171
213
|
}
|
|
172
214
|
function normalizeEffects(input, completedAt) {
|
|
@@ -179,7 +221,7 @@ function normalizeEffects(input, completedAt) {
|
|
|
179
221
|
return {
|
|
180
222
|
status: "failed",
|
|
181
223
|
completedAt,
|
|
182
|
-
error: normalizeError(input.error)
|
|
224
|
+
error: normalizeError(input.error, "effects")
|
|
183
225
|
};
|
|
184
226
|
}
|
|
185
227
|
function compareRuns(a, b, order) {
|
|
@@ -196,9 +238,11 @@ function compareRuns(a, b, order) {
|
|
|
196
238
|
}
|
|
197
239
|
|
|
198
240
|
class InMemoryActionRunStorage {
|
|
241
|
+
executions;
|
|
199
242
|
rows = new Map;
|
|
200
243
|
runRootOperation;
|
|
201
|
-
constructor(input = {}) {
|
|
244
|
+
constructor(executions, input = {}) {
|
|
245
|
+
this.executions = executions;
|
|
202
246
|
this.runRootOperation = input.runRootOperation ?? runDirectly;
|
|
203
247
|
}
|
|
204
248
|
snapshot() {
|
|
@@ -214,15 +258,26 @@ class InMemoryActionRunStorage {
|
|
|
214
258
|
return this.runRootOperation(() => cloneActionRunRecord(this.requireMaterializationRun(input)));
|
|
215
259
|
}
|
|
216
260
|
async queue(input) {
|
|
217
|
-
return this.runRootOperation(() => {
|
|
261
|
+
return this.runRootOperation(async () => {
|
|
218
262
|
const key = actionRunKey(input.projectId, input.id);
|
|
219
263
|
const existing = this.rows.get(key);
|
|
220
264
|
if (existing && !canRequeueActionRunAfterEnqueueFailure(existing, input)) {
|
|
221
265
|
throw new ActionRunError(`[Sixb] Action run '${input.id}' already exists for project '${input.projectId}'.`);
|
|
222
266
|
}
|
|
267
|
+
if ([...this.rows.values()].some((run) => run.projectId === input.projectId && run.id !== input.id && run.executionId === input.executionId)) {
|
|
268
|
+
throw new ActionRunError(`[Sixb] Execution '${input.executionId}' already belongs to another Action run.`);
|
|
269
|
+
}
|
|
270
|
+
await assertActionRunExecution({
|
|
271
|
+
executions: this.executions,
|
|
272
|
+
projectId: input.projectId,
|
|
273
|
+
executionId: input.executionId,
|
|
274
|
+
runId: input.id,
|
|
275
|
+
actionId: input.actionId
|
|
276
|
+
});
|
|
223
277
|
const record = {
|
|
224
278
|
id: input.id,
|
|
225
279
|
projectId: input.projectId,
|
|
280
|
+
executionId: input.executionId,
|
|
226
281
|
actionId: input.actionId,
|
|
227
282
|
subject: normalizeSubject(input.subject),
|
|
228
283
|
status: "queued",
|
|
@@ -333,7 +388,7 @@ class InMemoryActionRunStorage {
|
|
|
333
388
|
if (isTerminalActionRun(existing)) {
|
|
334
389
|
throw new ActionRunError(`[Sixb] Action run '${input.id}' cannot finish from terminal status '${existing.status}'.`);
|
|
335
390
|
}
|
|
336
|
-
const phase = input.status === "succeeded" ? input.phase ?? existing.phase : input.
|
|
391
|
+
const phase = input.status === "succeeded" ? input.phase ?? existing.phase : input.error.details.phase;
|
|
337
392
|
const base = {
|
|
338
393
|
...existing,
|
|
339
394
|
status: input.status,
|
|
@@ -401,6 +456,1440 @@ class InMemoryActionRunStorage {
|
|
|
401
456
|
return existing;
|
|
402
457
|
}
|
|
403
458
|
}
|
|
459
|
+
// src/agents/message.ts
|
|
460
|
+
var AGENT_MESSAGE_CONTENT_VERSION = 1;
|
|
461
|
+
|
|
462
|
+
// src/storage/agents/in-memory.ts
|
|
463
|
+
function normalizeFailure(failure) {
|
|
464
|
+
return failure ? parseSixbFailure(failure, AGENT_RUN_FAILURE_CODES) : undefined;
|
|
465
|
+
}
|
|
466
|
+
function key(projectId, id) {
|
|
467
|
+
return `${projectId}:${id}`;
|
|
468
|
+
}
|
|
469
|
+
function clone(value) {
|
|
470
|
+
return structuredClone(value);
|
|
471
|
+
}
|
|
472
|
+
function compareByDate(left, right, leftId, rightId, order) {
|
|
473
|
+
const delta = (left?.getTime() ?? 0) - (right?.getTime() ?? 0);
|
|
474
|
+
if (delta !== 0) {
|
|
475
|
+
return order === "asc" ? delta : -delta;
|
|
476
|
+
}
|
|
477
|
+
if (leftId === rightId) {
|
|
478
|
+
return 0;
|
|
479
|
+
}
|
|
480
|
+
return order === "asc" ? leftId.localeCompare(rightId) : rightId.localeCompare(leftId);
|
|
481
|
+
}
|
|
482
|
+
function applyWindow(rows, offset = 0, limit) {
|
|
483
|
+
const total = rows.length;
|
|
484
|
+
const end = limit === undefined ? total : offset + limit;
|
|
485
|
+
const page = rows.slice(offset, end);
|
|
486
|
+
return { page, hasMore: offset + page.length < total, total };
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
class InMemoryAgentThreadStore {
|
|
490
|
+
state;
|
|
491
|
+
constructor(state) {
|
|
492
|
+
this.state = state;
|
|
493
|
+
}
|
|
494
|
+
async create(input) {
|
|
495
|
+
const threadKey = key(input.projectId, input.id);
|
|
496
|
+
if (this.state.threads.has(threadKey)) {
|
|
497
|
+
throw new AgentStorageError("duplicate_id", `[Sixb] Agent thread '${input.id}' already exists for project '${input.projectId}'.`);
|
|
498
|
+
}
|
|
499
|
+
const createdAt = new Date(input.createdAt ?? new Date);
|
|
500
|
+
const record = {
|
|
501
|
+
id: input.id,
|
|
502
|
+
projectId: input.projectId,
|
|
503
|
+
agentId: input.agentId,
|
|
504
|
+
ownerPrincipal: clone(input.ownerPrincipal),
|
|
505
|
+
...input.title === undefined ? {} : { title: input.title },
|
|
506
|
+
status: input.status ?? "active",
|
|
507
|
+
activeRunId: null,
|
|
508
|
+
messageCount: 0,
|
|
509
|
+
createdAt,
|
|
510
|
+
updatedAt: new Date(input.updatedAt ?? createdAt)
|
|
511
|
+
};
|
|
512
|
+
this.state.threads.set(threadKey, clone(record));
|
|
513
|
+
return clone(record);
|
|
514
|
+
}
|
|
515
|
+
async getById(params) {
|
|
516
|
+
const record = this.state.threads.get(key(params.projectId, params.id));
|
|
517
|
+
return record ? clone(record) : null;
|
|
518
|
+
}
|
|
519
|
+
async list(input) {
|
|
520
|
+
const order = input.order ?? "desc";
|
|
521
|
+
const statuses = input.statuses ? new Set(input.statuses) : null;
|
|
522
|
+
const agentIds = input.agentIds ? new Set(input.agentIds) : null;
|
|
523
|
+
const filtered = [...this.state.threads.values()].filter((thread) => thread.projectId === input.projectId).filter((thread) => input.agentId ? thread.agentId === input.agentId : true).filter((thread) => agentIds ? agentIds.has(thread.agentId) : true).filter((thread) => statuses ? statuses.has(thread.status) : true).filter((thread) => input.ownerPrincipal ? principalsEqual(thread.ownerPrincipal, input.ownerPrincipal) : true).sort((a, b) => compareByDate(a.lastMessageAt ?? a.createdAt, b.lastMessageAt ?? b.createdAt, a.id, b.id, order));
|
|
524
|
+
const { page, hasMore, total } = applyWindow(filtered, input.offset, input.limit);
|
|
525
|
+
return { threads: page.map(clone), hasMore, total };
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
class InMemoryAgentRunStore {
|
|
530
|
+
state;
|
|
531
|
+
executions;
|
|
532
|
+
constructor(state, executions) {
|
|
533
|
+
this.state = state;
|
|
534
|
+
this.executions = executions;
|
|
535
|
+
}
|
|
536
|
+
async create(input) {
|
|
537
|
+
await assertAgentRunExecution({
|
|
538
|
+
executions: this.executions,
|
|
539
|
+
projectId: input.projectId,
|
|
540
|
+
executionId: input.executionId,
|
|
541
|
+
runId: input.id,
|
|
542
|
+
agentId: input.agentId
|
|
543
|
+
});
|
|
544
|
+
const threadKey = key(input.projectId, input.threadId);
|
|
545
|
+
const thread = this.state.threads.get(threadKey);
|
|
546
|
+
if (!thread) {
|
|
547
|
+
throw new AgentStorageError("thread_not_found", `[Sixb] Agent thread '${input.threadId}' not found for project '${input.projectId}'.`);
|
|
548
|
+
}
|
|
549
|
+
if (thread.activeRunId !== null) {
|
|
550
|
+
throw new AgentStorageError("active_run_exists", `[Sixb] Agent thread '${input.threadId}' already has an active run '${thread.activeRunId}'.`);
|
|
551
|
+
}
|
|
552
|
+
const runKey = key(input.projectId, input.id);
|
|
553
|
+
if (this.state.runs.has(runKey)) {
|
|
554
|
+
throw new AgentStorageError("duplicate_id", `[Sixb] Agent run '${input.id}' already exists for project '${input.projectId}'.`);
|
|
555
|
+
}
|
|
556
|
+
if ([...this.state.runs.values()].some((run2) => run2.projectId === input.projectId && run2.executionId === input.executionId)) {
|
|
557
|
+
throw new AgentStorageError("duplicate_id", `[Sixb] Execution '${input.executionId}' already belongs to another Agent run.`);
|
|
558
|
+
}
|
|
559
|
+
const createdAt = new Date(input.createdAt ?? new Date);
|
|
560
|
+
const run = {
|
|
561
|
+
id: input.id,
|
|
562
|
+
projectId: input.projectId,
|
|
563
|
+
executionId: input.executionId,
|
|
564
|
+
threadId: input.threadId,
|
|
565
|
+
agentId: input.agentId,
|
|
566
|
+
triggerMessageId: input.triggerMessageId,
|
|
567
|
+
requesterGroupIds: normalizeRequesterGroupIds(input.requesterGroupIds),
|
|
568
|
+
status: "queued",
|
|
569
|
+
attempt: 0,
|
|
570
|
+
createdAt
|
|
571
|
+
};
|
|
572
|
+
this.state.runs.set(runKey, clone(run));
|
|
573
|
+
const updatedThread = {
|
|
574
|
+
...thread,
|
|
575
|
+
activeRunId: run.id,
|
|
576
|
+
updatedAt: createdAt
|
|
577
|
+
};
|
|
578
|
+
this.state.threads.set(threadKey, clone(updatedThread));
|
|
579
|
+
return clone(run);
|
|
580
|
+
}
|
|
581
|
+
async start(input) {
|
|
582
|
+
const run = this.requireStatus(input.projectId, input.id, "queued");
|
|
583
|
+
const startedAt = new Date(input.startedAt ?? new Date);
|
|
584
|
+
const next = {
|
|
585
|
+
...run,
|
|
586
|
+
status: "running",
|
|
587
|
+
...input.modelId === undefined ? {} : { modelId: input.modelId },
|
|
588
|
+
attempt: 1,
|
|
589
|
+
execution: clone(input.execution),
|
|
590
|
+
startedAt
|
|
591
|
+
};
|
|
592
|
+
this.state.runs.set(key(input.projectId, input.id), clone(next));
|
|
593
|
+
return clone(next);
|
|
594
|
+
}
|
|
595
|
+
async finishQueued(input) {
|
|
596
|
+
const run = this.requireStatus(input.projectId, input.id, "queued");
|
|
597
|
+
const completedAt = new Date(input.completedAt ?? new Date);
|
|
598
|
+
const next = {
|
|
599
|
+
...run,
|
|
600
|
+
status: input.status,
|
|
601
|
+
...input.error === undefined ? {} : { error: normalizeFailure(input.error) },
|
|
602
|
+
completedAt
|
|
603
|
+
};
|
|
604
|
+
this.state.runs.set(key(input.projectId, input.id), clone(next));
|
|
605
|
+
this.releaseThread(run, completedAt);
|
|
606
|
+
return clone(next);
|
|
607
|
+
}
|
|
608
|
+
async reclaim(input) {
|
|
609
|
+
const run = this.requireRunning(input.projectId, input.id);
|
|
610
|
+
const next = {
|
|
611
|
+
...run,
|
|
612
|
+
attempt: run.attempt + 1,
|
|
613
|
+
execution: clone(input.execution)
|
|
614
|
+
};
|
|
615
|
+
this.state.runs.set(key(input.projectId, input.id), clone(next));
|
|
616
|
+
return clone(next);
|
|
617
|
+
}
|
|
618
|
+
async confirmExecutionOwnership(input) {
|
|
619
|
+
const run = this.requireRunning(input.projectId, input.id);
|
|
620
|
+
if (!run.execution || run.execution.token !== input.executionToken) {
|
|
621
|
+
throw new AgentStorageError("execution_lost", `[Sixb] Execution token is no longer current on agent run '${input.id}'.`);
|
|
622
|
+
}
|
|
623
|
+
const next = {
|
|
624
|
+
...run,
|
|
625
|
+
execution: {
|
|
626
|
+
...run.execution,
|
|
627
|
+
queueLeaseExpiresAt: new Date(Math.max(run.execution.queueLeaseExpiresAt.getTime(), input.queueLeaseExpiresAt.getTime()))
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
this.state.runs.set(key(input.projectId, input.id), clone(next));
|
|
631
|
+
return clone(next);
|
|
632
|
+
}
|
|
633
|
+
async finish(input) {
|
|
634
|
+
const run = this.requireRunning(input.projectId, input.id);
|
|
635
|
+
if (!run.execution || run.execution.token !== input.executionToken) {
|
|
636
|
+
throw new AgentStorageError("execution_lost", `[Sixb] Execution token is no longer current on agent run '${input.id}'.`);
|
|
637
|
+
}
|
|
638
|
+
const completedAt = new Date(input.completedAt ?? new Date);
|
|
639
|
+
const next = {
|
|
640
|
+
...run,
|
|
641
|
+
status: input.status,
|
|
642
|
+
...input.modelId === undefined ? {} : { modelId: input.modelId },
|
|
643
|
+
...input.finishReason === undefined ? {} : { finishReason: input.finishReason },
|
|
644
|
+
...input.diagnostics === undefined ? {} : { diagnostics: clone(input.diagnostics) },
|
|
645
|
+
...input.status === "succeeded" || input.error === undefined ? {} : { error: normalizeFailure(input.error) },
|
|
646
|
+
execution: undefined,
|
|
647
|
+
completedAt
|
|
648
|
+
};
|
|
649
|
+
this.state.runs.set(key(input.projectId, input.id), clone(next));
|
|
650
|
+
this.releaseThread(run, completedAt);
|
|
651
|
+
return clone(next);
|
|
652
|
+
}
|
|
653
|
+
async getById(params) {
|
|
654
|
+
const record = this.state.runs.get(key(params.projectId, params.id));
|
|
655
|
+
return record ? clone(record) : null;
|
|
656
|
+
}
|
|
657
|
+
async getByIds(params) {
|
|
658
|
+
return [...new Set(params.ids)].map((id) => this.state.runs.get(key(params.projectId, id))).filter((record) => record !== undefined).map(clone);
|
|
659
|
+
}
|
|
660
|
+
async list(input) {
|
|
661
|
+
const order = input.order ?? "desc";
|
|
662
|
+
const statuses = input.statuses ? new Set(input.statuses) : null;
|
|
663
|
+
const filtered = [...this.state.runs.values()].filter((run) => run.projectId === input.projectId).filter((run) => input.threadId ? run.threadId === input.threadId : true).filter((run) => input.agentId ? run.agentId === input.agentId : true).filter((run) => statuses ? statuses.has(run.status) : true).filter((run) => input.startedAfter ? (run.startedAt ?? run.createdAt) >= input.startedAfter : true).filter((run) => input.startedBefore ? (run.startedAt ?? run.createdAt) <= input.startedBefore : true).sort((a, b) => compareByDate(a.startedAt ?? a.createdAt, b.startedAt ?? b.createdAt, a.id, b.id, order));
|
|
664
|
+
const { page, hasMore, total } = applyWindow(filtered, input.offset, input.limit);
|
|
665
|
+
return { runs: page.map(clone), hasMore, total };
|
|
666
|
+
}
|
|
667
|
+
requireRunning(projectId, id) {
|
|
668
|
+
return this.requireStatus(projectId, id, "running");
|
|
669
|
+
}
|
|
670
|
+
requireStatus(projectId, id, status) {
|
|
671
|
+
const run = this.state.runs.get(key(projectId, id));
|
|
672
|
+
if (!run) {
|
|
673
|
+
throw new AgentStorageError("run_not_found", `[Sixb] Agent run '${id}' not found for project '${projectId}'.`);
|
|
674
|
+
}
|
|
675
|
+
if (run.status !== status) {
|
|
676
|
+
throw new AgentStorageError("invalid_state", `[Sixb] Agent run '${id}' is not ${status} (status '${run.status}').`);
|
|
677
|
+
}
|
|
678
|
+
return run;
|
|
679
|
+
}
|
|
680
|
+
releaseThread(run, completedAt) {
|
|
681
|
+
const threadKey = key(run.projectId, run.threadId);
|
|
682
|
+
const thread = this.state.threads.get(threadKey);
|
|
683
|
+
if (thread && thread.activeRunId === run.id) {
|
|
684
|
+
this.state.threads.set(threadKey, clone({ ...thread, activeRunId: null, updatedAt: completedAt }));
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
class InMemoryAgentMessageStore {
|
|
690
|
+
state;
|
|
691
|
+
constructor(state) {
|
|
692
|
+
this.state = state;
|
|
693
|
+
}
|
|
694
|
+
async append(input) {
|
|
695
|
+
const threadKey = key(input.projectId, input.threadId);
|
|
696
|
+
const thread = this.state.threads.get(threadKey);
|
|
697
|
+
if (!thread) {
|
|
698
|
+
throw new AgentStorageError("thread_not_found", `[Sixb] Agent thread '${input.threadId}' not found for project '${input.projectId}'.`);
|
|
699
|
+
}
|
|
700
|
+
const messageKey = key(input.projectId, input.id);
|
|
701
|
+
if (this.state.messages.has(messageKey)) {
|
|
702
|
+
throw new AgentStorageError("duplicate_id", `[Sixb] Agent message '${input.id}' already exists for project '${input.projectId}'.`);
|
|
703
|
+
}
|
|
704
|
+
if (input.runId !== null && !this.state.runs.has(key(input.projectId, input.runId))) {
|
|
705
|
+
throw new AgentStorageError("run_not_found", `[Sixb] Agent run '${input.runId}' not found for project '${input.projectId}'.`);
|
|
706
|
+
}
|
|
707
|
+
const createdAt = new Date(input.createdAt ?? new Date);
|
|
708
|
+
const seq = this.nextSeq(input.projectId, input.threadId);
|
|
709
|
+
const message = {
|
|
710
|
+
id: input.id,
|
|
711
|
+
projectId: input.projectId,
|
|
712
|
+
threadId: input.threadId,
|
|
713
|
+
runId: input.runId,
|
|
714
|
+
role: input.role,
|
|
715
|
+
...input.authorPrincipal === undefined ? {} : { authorPrincipal: clone(input.authorPrincipal) },
|
|
716
|
+
seq,
|
|
717
|
+
parts: clone(input.parts),
|
|
718
|
+
...input.metadata === undefined ? {} : { metadata: clone(input.metadata) },
|
|
719
|
+
contentVersion: AGENT_MESSAGE_CONTENT_VERSION,
|
|
720
|
+
createdAt,
|
|
721
|
+
...input.completedAt === undefined ? {} : { completedAt: new Date(input.completedAt) }
|
|
722
|
+
};
|
|
723
|
+
this.state.messages.set(messageKey, clone(message));
|
|
724
|
+
this.state.threads.set(threadKey, clone({
|
|
725
|
+
...thread,
|
|
726
|
+
messageCount: thread.messageCount + 1,
|
|
727
|
+
lastMessageAt: createdAt,
|
|
728
|
+
updatedAt: createdAt
|
|
729
|
+
}));
|
|
730
|
+
return clone(message);
|
|
731
|
+
}
|
|
732
|
+
async getById(params) {
|
|
733
|
+
const record = this.state.messages.get(key(params.projectId, params.id));
|
|
734
|
+
return record ? clone(record) : null;
|
|
735
|
+
}
|
|
736
|
+
async list(input) {
|
|
737
|
+
const order = input.order ?? "asc";
|
|
738
|
+
const roles = input.roles ? new Set(input.roles) : null;
|
|
739
|
+
const filtered = [...this.state.messages.values()].filter((message) => message.projectId === input.projectId).filter((message) => message.threadId === input.threadId).filter((message) => roles ? roles.has(message.role) : true).sort((a, b) => order === "asc" ? a.seq - b.seq : b.seq - a.seq);
|
|
740
|
+
const { page, hasMore, total } = applyWindow(filtered, input.offset, input.limit);
|
|
741
|
+
return { messages: page.map(clone), hasMore, total };
|
|
742
|
+
}
|
|
743
|
+
nextSeq(projectId, threadId) {
|
|
744
|
+
let max = 0;
|
|
745
|
+
for (const message of this.state.messages.values()) {
|
|
746
|
+
if (message.projectId === projectId && message.threadId === threadId && message.seq > max) {
|
|
747
|
+
max = message.seq;
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
return max + 1;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
class InMemoryAgentStorage {
|
|
755
|
+
state = {
|
|
756
|
+
threads: new Map,
|
|
757
|
+
runs: new Map,
|
|
758
|
+
messages: new Map
|
|
759
|
+
};
|
|
760
|
+
threads;
|
|
761
|
+
runs;
|
|
762
|
+
messages;
|
|
763
|
+
constructor(executions) {
|
|
764
|
+
this.threads = new InMemoryAgentThreadStore(this.state);
|
|
765
|
+
this.runs = new InMemoryAgentRunStore(this.state, executions);
|
|
766
|
+
this.messages = new InMemoryAgentMessageStore(this.state);
|
|
767
|
+
}
|
|
768
|
+
snapshot() {
|
|
769
|
+
return {
|
|
770
|
+
threads: structuredClone(this.state.threads),
|
|
771
|
+
runs: structuredClone(this.state.runs),
|
|
772
|
+
messages: structuredClone(this.state.messages)
|
|
773
|
+
};
|
|
774
|
+
}
|
|
775
|
+
restore(snapshot) {
|
|
776
|
+
replace(this.state.threads, snapshot.threads);
|
|
777
|
+
replace(this.state.runs, snapshot.runs);
|
|
778
|
+
replace(this.state.messages, snapshot.messages);
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
function replace(target, source) {
|
|
782
|
+
target.clear();
|
|
783
|
+
for (const [k, value] of structuredClone(source)) {
|
|
784
|
+
target.set(k, value);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
// src/storage/ai-usage/errors.ts
|
|
788
|
+
class AiUsageStorageError extends Error {
|
|
789
|
+
code;
|
|
790
|
+
name = "AiUsageStorageError";
|
|
791
|
+
constructor(code, message) {
|
|
792
|
+
super(message);
|
|
793
|
+
this.code = code;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
// src/storage/ai-usage/usage.ts
|
|
797
|
+
var USAGE_FIELDS = [
|
|
798
|
+
"inputTokens",
|
|
799
|
+
"outputTokens",
|
|
800
|
+
"uncachedInputTokens",
|
|
801
|
+
"cacheReadInputTokens",
|
|
802
|
+
"cacheWriteInputTokens",
|
|
803
|
+
"textOutputTokens",
|
|
804
|
+
"reasoningOutputTokens"
|
|
805
|
+
];
|
|
806
|
+
function normalizeAiModelCallUsage(input) {
|
|
807
|
+
for (const field of USAGE_FIELDS) {
|
|
808
|
+
assertUsageCount(input[field], field);
|
|
809
|
+
}
|
|
810
|
+
const totalTokens = input.inputTokens === undefined || input.outputTokens === undefined ? undefined : addUsageCounts(input.inputTokens, input.outputTokens, "totalTokens");
|
|
811
|
+
const reportingStatus = input.inputTokens !== undefined && input.outputTokens !== undefined ? "complete" : USAGE_FIELDS.some((field) => input[field] !== undefined) ? "partial" : "unavailable";
|
|
812
|
+
return {
|
|
813
|
+
...input.inputTokens === undefined ? {} : { inputTokens: input.inputTokens },
|
|
814
|
+
...input.outputTokens === undefined ? {} : { outputTokens: input.outputTokens },
|
|
815
|
+
...totalTokens === undefined ? {} : { totalTokens },
|
|
816
|
+
...input.uncachedInputTokens === undefined ? {} : { uncachedInputTokens: input.uncachedInputTokens },
|
|
817
|
+
...input.cacheReadInputTokens === undefined ? {} : { cacheReadInputTokens: input.cacheReadInputTokens },
|
|
818
|
+
...input.cacheWriteInputTokens === undefined ? {} : { cacheWriteInputTokens: input.cacheWriteInputTokens },
|
|
819
|
+
...input.textOutputTokens === undefined ? {} : { textOutputTokens: input.textOutputTokens },
|
|
820
|
+
...input.reasoningOutputTokens === undefined ? {} : { reasoningOutputTokens: input.reasoningOutputTokens },
|
|
821
|
+
reportingStatus
|
|
822
|
+
};
|
|
823
|
+
}
|
|
824
|
+
function aggregateAiModelCallUsage(usages) {
|
|
825
|
+
const normalized = Array.from(usages, normalizeAiModelCallUsage);
|
|
826
|
+
const fields = Object.fromEntries(USAGE_FIELDS.map((field) => [field, sumUsageField(normalized, field)]));
|
|
827
|
+
const aggregate = normalizeAiModelCallUsage(fields);
|
|
828
|
+
if (aggregate.reportingStatus === "unavailable" && normalized.some((usage) => usage.reportingStatus !== "unavailable")) {
|
|
829
|
+
return { ...aggregate, reportingStatus: "partial" };
|
|
830
|
+
}
|
|
831
|
+
return aggregate;
|
|
832
|
+
}
|
|
833
|
+
function sumUsageField(usages, field) {
|
|
834
|
+
if (usages.length === 0)
|
|
835
|
+
return;
|
|
836
|
+
let total = 0;
|
|
837
|
+
for (const usage of usages) {
|
|
838
|
+
const value = usage[field];
|
|
839
|
+
if (value === undefined)
|
|
840
|
+
return;
|
|
841
|
+
total = addUsageCounts(total, value, `aggregate ${field}`);
|
|
842
|
+
}
|
|
843
|
+
return total;
|
|
844
|
+
}
|
|
845
|
+
function assertUsageCount(value, field) {
|
|
846
|
+
if (value !== undefined && (!Number.isSafeInteger(value) || value < 0)) {
|
|
847
|
+
throw new TypeError(`[Sixb] AI model-call usage ${field} must be a non-negative safe integer.`);
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
function addUsageCounts(left, right, field) {
|
|
851
|
+
const result = left + right;
|
|
852
|
+
if (!Number.isSafeInteger(result)) {
|
|
853
|
+
throw new TypeError(`[Sixb] AI model-call usage ${field} exceeds the safe integer range.`);
|
|
854
|
+
}
|
|
855
|
+
return result;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
// src/storage/ai-usage/record.ts
|
|
859
|
+
function normalizeAiModelCallRecord(input) {
|
|
860
|
+
assertNonBlank2(input.id, "id");
|
|
861
|
+
assertNonBlank2(input.projectId, "projectId");
|
|
862
|
+
assertAiUsageExecutionId(input.executionId);
|
|
863
|
+
assertPositiveSafeInteger(input.attempt, "attempt");
|
|
864
|
+
assertNonBlank2(input.callId, "callId");
|
|
865
|
+
assertNonBlank2(input.providerId, "providerId");
|
|
866
|
+
assertNonBlank2(input.requestedModelId, "requestedModelId");
|
|
867
|
+
if (input.responseModelId !== undefined) {
|
|
868
|
+
assertNonBlank2(input.responseModelId, "responseModelId");
|
|
869
|
+
}
|
|
870
|
+
assertNonBlank2(input.responseId, "responseId");
|
|
871
|
+
const occurredAt = cloneValidDate(input.occurredAt, "occurredAt");
|
|
872
|
+
const recordedAt = cloneValidDate(input.recordedAt ?? new Date, "recordedAt");
|
|
873
|
+
const requesterGroupIds = normalizeRequesterGroupIds(input.requesterGroupIds);
|
|
874
|
+
const rawUsage = cloneRawUsage(input.rawUsage);
|
|
875
|
+
return {
|
|
876
|
+
id: input.id,
|
|
877
|
+
projectId: input.projectId,
|
|
878
|
+
executionId: input.executionId,
|
|
879
|
+
attempt: input.attempt,
|
|
880
|
+
callId: input.callId,
|
|
881
|
+
requesterGroupIds,
|
|
882
|
+
providerId: input.providerId,
|
|
883
|
+
requestedModelId: input.requestedModelId,
|
|
884
|
+
...input.responseModelId === undefined ? {} : { responseModelId: input.responseModelId },
|
|
885
|
+
responseId: input.responseId,
|
|
886
|
+
usage: normalizeAiModelCallUsage(input.usage),
|
|
887
|
+
...rawUsage === undefined ? {} : { rawUsage },
|
|
888
|
+
occurredAt,
|
|
889
|
+
recordedAt
|
|
890
|
+
};
|
|
891
|
+
}
|
|
892
|
+
function assertAiUsageExecutionId(executionId) {
|
|
893
|
+
assertNonBlank2(executionId, "executionId");
|
|
894
|
+
}
|
|
895
|
+
function cloneRawUsage(rawUsage) {
|
|
896
|
+
if (rawUsage === undefined)
|
|
897
|
+
return;
|
|
898
|
+
if (!isPlainRecord(rawUsage)) {
|
|
899
|
+
throw new TypeError("[Sixb] AI usage rawUsage must be a JSON object.");
|
|
900
|
+
}
|
|
901
|
+
assertJsonValue(rawUsage, "AI usage rawUsage");
|
|
902
|
+
return structuredClone(rawUsage);
|
|
903
|
+
}
|
|
904
|
+
function assertNonBlank2(value, field) {
|
|
905
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
906
|
+
throw new TypeError(`[Sixb] AI usage ${field} must be nonblank.`);
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
function assertPositiveSafeInteger(value, field) {
|
|
910
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
911
|
+
throw new TypeError(`[Sixb] AI usage ${field} must be a positive safe integer.`);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
function cloneValidDate(value, field) {
|
|
915
|
+
if (!(value instanceof Date) || !Number.isFinite(value.getTime())) {
|
|
916
|
+
throw new TypeError(`[Sixb] AI usage ${field} must be a valid Date.`);
|
|
917
|
+
}
|
|
918
|
+
return new Date(value);
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
// src/storage/ai-usage/in-memory.ts
|
|
922
|
+
class InMemoryAiUsageStorage {
|
|
923
|
+
executions;
|
|
924
|
+
records = new Map;
|
|
925
|
+
recordKeysByIdempotencyKey = new Map;
|
|
926
|
+
groupRows = new Map;
|
|
927
|
+
constructor(executions) {
|
|
928
|
+
this.executions = executions;
|
|
929
|
+
}
|
|
930
|
+
async recordModelCall(input) {
|
|
931
|
+
const record = normalizeAiModelCallRecord(input);
|
|
932
|
+
await this.assertExecutionExists(record.projectId, record.executionId);
|
|
933
|
+
const idempotencyKey = modelCallIdempotencyKey(record);
|
|
934
|
+
const existingRecordKey = this.recordKeysByIdempotencyKey.get(idempotencyKey);
|
|
935
|
+
if (existingRecordKey !== undefined) {
|
|
936
|
+
const existing = this.records.get(existingRecordKey);
|
|
937
|
+
if (!existing) {
|
|
938
|
+
throw new Error("[Sixb] In-memory AI usage idempotency index is inconsistent.");
|
|
939
|
+
}
|
|
940
|
+
return { record: structuredClone(existing), created: false };
|
|
941
|
+
}
|
|
942
|
+
const recordKey = modelCallRecordKey(record.projectId, record.id);
|
|
943
|
+
if (this.records.has(recordKey)) {
|
|
944
|
+
throw new AiUsageStorageError("duplicate_id", `[Sixb] AI usage record '${record.id}' already exists for project '${record.projectId}'.`);
|
|
945
|
+
}
|
|
946
|
+
this.records.set(recordKey, structuredClone(record));
|
|
947
|
+
this.recordKeysByIdempotencyKey.set(idempotencyKey, recordKey);
|
|
948
|
+
for (const groupId of record.requesterGroupIds) {
|
|
949
|
+
const row = {
|
|
950
|
+
projectId: record.projectId,
|
|
951
|
+
usageRecordId: record.id,
|
|
952
|
+
groupId,
|
|
953
|
+
occurredAt: record.occurredAt
|
|
954
|
+
};
|
|
955
|
+
this.groupRows.set(groupRowKey(row), row);
|
|
956
|
+
}
|
|
957
|
+
return { record: structuredClone(record), created: true };
|
|
958
|
+
}
|
|
959
|
+
async summarizeExecution(input) {
|
|
960
|
+
const [summary] = await this.summarizeExecutions({
|
|
961
|
+
projectId: input.projectId,
|
|
962
|
+
executionIds: [input.executionId]
|
|
963
|
+
});
|
|
964
|
+
return summary;
|
|
965
|
+
}
|
|
966
|
+
async summarizeExecutions(input) {
|
|
967
|
+
if (typeof input.projectId !== "string" || input.projectId.trim().length === 0) {
|
|
968
|
+
throw new TypeError("[Sixb] AI usage projectId must be nonblank.");
|
|
969
|
+
}
|
|
970
|
+
const usageByExecutionId = new Map;
|
|
971
|
+
for (const executionId of input.executionIds) {
|
|
972
|
+
assertAiUsageExecutionId(executionId);
|
|
973
|
+
usageByExecutionId.set(executionId, []);
|
|
974
|
+
}
|
|
975
|
+
if (usageByExecutionId.size === 0)
|
|
976
|
+
return [];
|
|
977
|
+
for (const record of this.records.values()) {
|
|
978
|
+
if (record.projectId !== input.projectId)
|
|
979
|
+
continue;
|
|
980
|
+
usageByExecutionId.get(record.executionId)?.push(record.usage);
|
|
981
|
+
}
|
|
982
|
+
return input.executionIds.map((executionId) => {
|
|
983
|
+
const usages = usageByExecutionId.get(executionId) ?? [];
|
|
984
|
+
return {
|
|
985
|
+
modelCallCount: usages.length,
|
|
986
|
+
usage: aggregateAiModelCallUsage(usages)
|
|
987
|
+
};
|
|
988
|
+
});
|
|
989
|
+
}
|
|
990
|
+
snapshot() {
|
|
991
|
+
return structuredClone({
|
|
992
|
+
records: this.records,
|
|
993
|
+
recordKeysByIdempotencyKey: this.recordKeysByIdempotencyKey,
|
|
994
|
+
groupRows: this.groupRows
|
|
995
|
+
});
|
|
996
|
+
}
|
|
997
|
+
restore(snapshot) {
|
|
998
|
+
replaceMap(this.records, snapshot.records);
|
|
999
|
+
replaceMap(this.recordKeysByIdempotencyKey, snapshot.recordKeysByIdempotencyKey);
|
|
1000
|
+
replaceMap(this.groupRows, snapshot.groupRows);
|
|
1001
|
+
}
|
|
1002
|
+
async assertExecutionExists(projectId, executionId) {
|
|
1003
|
+
const execution = await this.executions.getById({ projectId, id: executionId });
|
|
1004
|
+
if (execution)
|
|
1005
|
+
return;
|
|
1006
|
+
throw new AiUsageStorageError("missing_execution", `[Sixb] AI usage execution '${executionId}' does not exist in project '${projectId}'.`);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
function modelCallRecordKey(projectId, id) {
|
|
1010
|
+
return JSON.stringify([projectId, id]);
|
|
1011
|
+
}
|
|
1012
|
+
function modelCallIdempotencyKey(record) {
|
|
1013
|
+
return JSON.stringify([
|
|
1014
|
+
record.projectId,
|
|
1015
|
+
record.executionId,
|
|
1016
|
+
record.attempt,
|
|
1017
|
+
record.callId,
|
|
1018
|
+
record.responseId
|
|
1019
|
+
]);
|
|
1020
|
+
}
|
|
1021
|
+
function groupRowKey(row) {
|
|
1022
|
+
return JSON.stringify([row.projectId, row.usageRecordId, row.groupId]);
|
|
1023
|
+
}
|
|
1024
|
+
function replaceMap(target, source) {
|
|
1025
|
+
target.clear();
|
|
1026
|
+
for (const [key2, value] of structuredClone(source)) {
|
|
1027
|
+
target.set(key2, value);
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
// src/storage/connector-connections/in-memory.ts
|
|
1031
|
+
import { timingSafeEqual } from "crypto";
|
|
1032
|
+
function connectionRunBase(record, updatedAt) {
|
|
1033
|
+
return {
|
|
1034
|
+
id: record.id,
|
|
1035
|
+
projectId: record.projectId,
|
|
1036
|
+
connectorId: record.connectorId,
|
|
1037
|
+
kind: record.kind,
|
|
1038
|
+
owner: structuredClone(record.owner),
|
|
1039
|
+
slot: record.slot,
|
|
1040
|
+
initiatedByExecutionId: record.initiatedByExecutionId,
|
|
1041
|
+
createdAt: new Date(record.createdAt),
|
|
1042
|
+
updatedAt: new Date(updatedAt)
|
|
1043
|
+
};
|
|
1044
|
+
}
|
|
1045
|
+
function expireConnectionRun(record, now) {
|
|
1046
|
+
return {
|
|
1047
|
+
...connectionRunBase(record, now),
|
|
1048
|
+
status: "expired",
|
|
1049
|
+
...record.waitingFor === "account_selection" ? { authorizationId: record.authorizationId } : {},
|
|
1050
|
+
finishedAt: new Date(now)
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
1053
|
+
function failExpiredProcessingRun(record, now) {
|
|
1054
|
+
return {
|
|
1055
|
+
...connectionRunBase(record, now),
|
|
1056
|
+
status: "failed",
|
|
1057
|
+
...record.authorizationId === undefined ? {} : { authorizationId: record.authorizationId },
|
|
1058
|
+
error: toSixbFailure(createSixbError("internal.unexpected", "[Sixb] Connector callback processing did not complete before its deadline."), { allowedCodes: CONNECTOR_CONNECTION_RUN_FAILURE_CODES, at: now }),
|
|
1059
|
+
finishedAt: new Date(now)
|
|
1060
|
+
};
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
class InMemoryConnectorConnectionStorage {
|
|
1064
|
+
options;
|
|
1065
|
+
durability = "ephemeral";
|
|
1066
|
+
attempts = new Map;
|
|
1067
|
+
connectionRuns = new Map;
|
|
1068
|
+
authorizations = new Map;
|
|
1069
|
+
connections = new Map;
|
|
1070
|
+
constructor(options = {}) {
|
|
1071
|
+
this.options = options;
|
|
1072
|
+
}
|
|
1073
|
+
async createAuthorizationAttempt(input) {
|
|
1074
|
+
assertPositiveDuration(input.ttlMs, "authorization attempt TTL");
|
|
1075
|
+
if (this.attempts.has(input.id)) {
|
|
1076
|
+
throw new ConnectorConnectionStorageError("attempt_conflict", "[Sixb] Connector authorization attempt already exists.");
|
|
1077
|
+
}
|
|
1078
|
+
if (input.connectionRunId !== undefined) {
|
|
1079
|
+
const run = this.connectionRuns.get(input.connectionRunId);
|
|
1080
|
+
const existingAttempt = this.findAuthorizationAttemptByConnectionRunId(input.connectionRunId);
|
|
1081
|
+
if (!run || existingAttempt || run.projectId !== input.projectId || run.connectorId !== input.connectorId || run.status !== "waiting" || run.waitingFor !== "provider_authorization" || run.slot !== input.slot || run.initiatedByExecutionId !== input.initiatedByExecutionId) {
|
|
1082
|
+
throw new ConnectorConnectionStorageError("attempt_conflict", "[Sixb] Connector authorization attempt does not match its connection run.");
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
const now = this.now();
|
|
1086
|
+
const record = {
|
|
1087
|
+
id: input.id,
|
|
1088
|
+
projectId: input.projectId,
|
|
1089
|
+
connectorId: input.connectorId,
|
|
1090
|
+
owner: structuredClone(input.owner),
|
|
1091
|
+
slot: input.slot,
|
|
1092
|
+
initiatedByExecutionId: input.initiatedByExecutionId,
|
|
1093
|
+
stateHash: input.stateHash,
|
|
1094
|
+
codeVerifier: structuredClone(input.codeVerifier),
|
|
1095
|
+
redirectUri: input.redirectUri,
|
|
1096
|
+
...input.connectionRunId === undefined ? {} : { connectionRunId: input.connectionRunId },
|
|
1097
|
+
...input.returnTo === undefined ? {} : { returnTo: input.returnTo },
|
|
1098
|
+
...input.callbackBindingHash === undefined ? {} : { callbackBindingHash: input.callbackBindingHash },
|
|
1099
|
+
...input.reauthorizationId === undefined ? {} : { reauthorizationId: input.reauthorizationId },
|
|
1100
|
+
...input.reauthorizationRevision === undefined ? {} : { reauthorizationRevision: input.reauthorizationRevision },
|
|
1101
|
+
...input.reauthorizationConnectionIds === undefined ? {} : { reauthorizationConnectionIds: [...input.reauthorizationConnectionIds] },
|
|
1102
|
+
createdAt: now,
|
|
1103
|
+
expiresAt: new Date(now.getTime() + input.ttlMs)
|
|
1104
|
+
};
|
|
1105
|
+
this.attempts.set(record.id, record);
|
|
1106
|
+
return structuredClone(record);
|
|
1107
|
+
}
|
|
1108
|
+
async consumeAuthorizationAttempt(input) {
|
|
1109
|
+
const record = this.attempts.get(input.id);
|
|
1110
|
+
if (record && record.expiresAt.getTime() <= this.now().getTime()) {
|
|
1111
|
+
this.attempts.delete(record.id);
|
|
1112
|
+
throw invalidAttempt();
|
|
1113
|
+
}
|
|
1114
|
+
if (!record || record.projectId !== input.projectId || record.connectorId !== input.connectorId || record.redirectUri !== input.redirectUri || !safeEqual(record.stateHash, input.stateHash)) {
|
|
1115
|
+
throw invalidAttempt();
|
|
1116
|
+
}
|
|
1117
|
+
this.attempts.delete(input.id);
|
|
1118
|
+
return structuredClone(record);
|
|
1119
|
+
}
|
|
1120
|
+
async createConnectionRun(input) {
|
|
1121
|
+
assertPositiveDuration(input.ttlMs, "connection run TTL");
|
|
1122
|
+
if (this.connectionRuns.has(input.id)) {
|
|
1123
|
+
throw new ConnectorConnectionStorageError("run_conflict", "[Sixb] Connector connection run already exists.");
|
|
1124
|
+
}
|
|
1125
|
+
const now = this.now();
|
|
1126
|
+
const record = {
|
|
1127
|
+
id: input.id,
|
|
1128
|
+
projectId: input.projectId,
|
|
1129
|
+
connectorId: input.connectorId,
|
|
1130
|
+
kind: input.kind,
|
|
1131
|
+
owner: structuredClone(input.owner),
|
|
1132
|
+
slot: input.slot,
|
|
1133
|
+
initiatedByExecutionId: input.initiatedByExecutionId,
|
|
1134
|
+
status: "waiting",
|
|
1135
|
+
waitingFor: "provider_authorization",
|
|
1136
|
+
createdAt: now,
|
|
1137
|
+
updatedAt: now,
|
|
1138
|
+
expiresAt: new Date(now.getTime() + input.ttlMs)
|
|
1139
|
+
};
|
|
1140
|
+
this.connectionRuns.set(record.id, record);
|
|
1141
|
+
return structuredClone(record);
|
|
1142
|
+
}
|
|
1143
|
+
async createConnectionSelectionRun(input) {
|
|
1144
|
+
assertPositiveDuration(input.ttlMs, "connection run TTL");
|
|
1145
|
+
if (this.connectionRuns.has(input.id)) {
|
|
1146
|
+
throw new ConnectorConnectionStorageError("run_conflict", "[Sixb] Connector connection run already exists.");
|
|
1147
|
+
}
|
|
1148
|
+
const authorization = this.authorizations.get(input.authorizationId);
|
|
1149
|
+
if (!sameAuthorizationScope(authorization, input) || authorization.status !== "active" || authorization.credentialMutation) {
|
|
1150
|
+
throw authorizationConflict();
|
|
1151
|
+
}
|
|
1152
|
+
const now = this.now();
|
|
1153
|
+
const record = {
|
|
1154
|
+
id: input.id,
|
|
1155
|
+
projectId: input.projectId,
|
|
1156
|
+
connectorId: input.connectorId,
|
|
1157
|
+
kind: "connect",
|
|
1158
|
+
owner: structuredClone(input.owner),
|
|
1159
|
+
slot: input.slot,
|
|
1160
|
+
initiatedByExecutionId: input.initiatedByExecutionId,
|
|
1161
|
+
status: "waiting",
|
|
1162
|
+
waitingFor: "account_selection",
|
|
1163
|
+
authorizationId: input.authorizationId,
|
|
1164
|
+
createdAt: now,
|
|
1165
|
+
updatedAt: now,
|
|
1166
|
+
expiresAt: new Date(now.getTime() + input.ttlMs)
|
|
1167
|
+
};
|
|
1168
|
+
this.connectionRuns.set(record.id, record);
|
|
1169
|
+
return structuredClone(record);
|
|
1170
|
+
}
|
|
1171
|
+
async claimConnectionRunCallback(input) {
|
|
1172
|
+
assertPositiveDuration(input.processingTtlMs, "connection run processing TTL");
|
|
1173
|
+
const attempt = this.attempts.get(input.attemptId);
|
|
1174
|
+
if (!attempt || attempt.projectId !== input.projectId || attempt.connectionRunId === undefined || attempt.returnTo === undefined || attempt.callbackBindingHash === undefined || attempt.redirectUri !== input.redirectUri || !safeEqual(attempt.stateHash, input.stateHash) || !safeEqual(attempt.callbackBindingHash, input.callbackBindingHash)) {
|
|
1175
|
+
return null;
|
|
1176
|
+
}
|
|
1177
|
+
const run = this.connectionRuns.get(attempt.connectionRunId);
|
|
1178
|
+
if (!run || run.projectId !== input.projectId || run.connectorId !== attempt.connectorId || run.status !== "waiting" || run.waitingFor !== "provider_authorization" || run.slot !== attempt.slot || run.initiatedByExecutionId !== attempt.initiatedByExecutionId) {
|
|
1179
|
+
return null;
|
|
1180
|
+
}
|
|
1181
|
+
const now = this.now();
|
|
1182
|
+
this.attempts.delete(attempt.id);
|
|
1183
|
+
if (attempt.expiresAt.getTime() <= now.getTime() || run.expiresAt.getTime() <= now.getTime()) {
|
|
1184
|
+
const expired = expireConnectionRun(run, now);
|
|
1185
|
+
this.connectionRuns.set(run.id, expired);
|
|
1186
|
+
return { type: "expired", run: structuredClone(expired), returnTo: attempt.returnTo };
|
|
1187
|
+
}
|
|
1188
|
+
const processing = {
|
|
1189
|
+
...connectionRunBase(run, now),
|
|
1190
|
+
status: "running",
|
|
1191
|
+
processingId: input.processingId,
|
|
1192
|
+
callbackStartedAt: now,
|
|
1193
|
+
expiresAt: new Date(now.getTime() + input.processingTtlMs),
|
|
1194
|
+
...attempt.reauthorizationId === undefined ? {} : { authorizationId: attempt.reauthorizationId }
|
|
1195
|
+
};
|
|
1196
|
+
this.connectionRuns.set(run.id, processing);
|
|
1197
|
+
return {
|
|
1198
|
+
type: "claimed",
|
|
1199
|
+
run: structuredClone(processing),
|
|
1200
|
+
attempt: structuredClone(attempt),
|
|
1201
|
+
returnTo: attempt.returnTo
|
|
1202
|
+
};
|
|
1203
|
+
}
|
|
1204
|
+
async attachConnectionRunAuthorization(input) {
|
|
1205
|
+
const run = this.currentConnectionRun(input.runId);
|
|
1206
|
+
const authorization = this.authorizations.get(input.authorizationId);
|
|
1207
|
+
if (!sameConnectionRunScope(run, input) || run.status !== "running" || run.processingId !== input.processingId || run.authorizationId !== undefined && run.authorizationId !== input.authorizationId || !sameAuthorizationScope(authorization, input) || authorization.status !== "pending_selection") {
|
|
1208
|
+
return null;
|
|
1209
|
+
}
|
|
1210
|
+
const updated = {
|
|
1211
|
+
...run,
|
|
1212
|
+
authorizationId: input.authorizationId,
|
|
1213
|
+
updatedAt: this.now()
|
|
1214
|
+
};
|
|
1215
|
+
this.connectionRuns.set(run.id, updated);
|
|
1216
|
+
return structuredClone(updated);
|
|
1217
|
+
}
|
|
1218
|
+
async waitForConnectionRunSelection(input) {
|
|
1219
|
+
const run = this.currentConnectionRun(input.runId);
|
|
1220
|
+
if (!sameConnectionRunScope(run, input) || run.status !== "running" || run.kind !== "connect" || run.processingId !== input.processingId || run.authorizationId !== input.authorizationId) {
|
|
1221
|
+
return null;
|
|
1222
|
+
}
|
|
1223
|
+
const now = this.now();
|
|
1224
|
+
const waiting = {
|
|
1225
|
+
...connectionRunBase(run, now),
|
|
1226
|
+
status: "waiting",
|
|
1227
|
+
waitingFor: "account_selection",
|
|
1228
|
+
authorizationId: input.authorizationId,
|
|
1229
|
+
expiresAt: new Date(input.expiresAt)
|
|
1230
|
+
};
|
|
1231
|
+
this.connectionRuns.set(run.id, waiting);
|
|
1232
|
+
return structuredClone(waiting);
|
|
1233
|
+
}
|
|
1234
|
+
async finishConnectionRun(input) {
|
|
1235
|
+
const run = this.currentConnectionRun(input.runId);
|
|
1236
|
+
if (!sameConnectionRunScope(run, input) || run.status !== "running")
|
|
1237
|
+
return null;
|
|
1238
|
+
if (input.processingId !== run.processingId)
|
|
1239
|
+
return null;
|
|
1240
|
+
const now = this.now();
|
|
1241
|
+
const authorizationId = input.status === "succeeded" ? input.authorizationId : input.status === "failed" ? input.authorizationId ?? run.authorizationId : run.authorizationId;
|
|
1242
|
+
if (input.status !== "succeeded" && run.kind === "connect" && authorizationId) {
|
|
1243
|
+
this.markPendingAuthorizationForCleanup(run.connectorId, authorizationId, now);
|
|
1244
|
+
}
|
|
1245
|
+
const base = connectionRunBase(run, now);
|
|
1246
|
+
const finished = input.status === "succeeded" ? {
|
|
1247
|
+
...base,
|
|
1248
|
+
status: "succeeded",
|
|
1249
|
+
authorizationId: input.authorizationId,
|
|
1250
|
+
...input.cleanupAuthorizationId === undefined ? {} : { cleanupAuthorizationId: input.cleanupAuthorizationId },
|
|
1251
|
+
connections: structuredClone(input.connections),
|
|
1252
|
+
finishedAt: now
|
|
1253
|
+
} : input.status === "failed" ? {
|
|
1254
|
+
...base,
|
|
1255
|
+
status: "failed",
|
|
1256
|
+
...authorizationId === undefined ? {} : { authorizationId },
|
|
1257
|
+
error: parseSixbFailure(input.error, CONNECTOR_CONNECTION_RUN_FAILURE_CODES),
|
|
1258
|
+
finishedAt: now
|
|
1259
|
+
} : {
|
|
1260
|
+
...base,
|
|
1261
|
+
status: "cancelled",
|
|
1262
|
+
...authorizationId === undefined ? {} : { authorizationId },
|
|
1263
|
+
finishedAt: now
|
|
1264
|
+
};
|
|
1265
|
+
this.connectionRuns.set(run.id, finished);
|
|
1266
|
+
return structuredClone(finished);
|
|
1267
|
+
}
|
|
1268
|
+
async getConnectionRun(input) {
|
|
1269
|
+
const run = this.currentConnectionRun(input.runId);
|
|
1270
|
+
return sameConnectionRunScope(run, input) ? structuredClone(run) : null;
|
|
1271
|
+
}
|
|
1272
|
+
async createAuthorization(input) {
|
|
1273
|
+
assertPositiveDuration(input.selectionTtlMs, "account selection TTL");
|
|
1274
|
+
if (this.authorizations.has(input.id)) {
|
|
1275
|
+
throw new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] Connector authorization already exists.");
|
|
1276
|
+
}
|
|
1277
|
+
const now = this.now();
|
|
1278
|
+
const record = {
|
|
1279
|
+
id: input.id,
|
|
1280
|
+
projectId: input.projectId,
|
|
1281
|
+
connectorId: input.connectorId,
|
|
1282
|
+
authorizedBy: structuredClone(input.authorizedBy),
|
|
1283
|
+
credentials: structuredClone(input.credentials),
|
|
1284
|
+
...input.credentialExpiresAt === undefined ? {} : { credentialExpiresAt: new Date(input.credentialExpiresAt) },
|
|
1285
|
+
scopes: [...input.scopes],
|
|
1286
|
+
accounts: structuredClone(input.accounts),
|
|
1287
|
+
status: "pending_selection",
|
|
1288
|
+
selectionExpiresAt: new Date(now.getTime() + input.selectionTtlMs),
|
|
1289
|
+
revision: 0,
|
|
1290
|
+
createdAt: now,
|
|
1291
|
+
updatedAt: now
|
|
1292
|
+
};
|
|
1293
|
+
this.authorizations.set(record.id, record);
|
|
1294
|
+
return structuredClone(record);
|
|
1295
|
+
}
|
|
1296
|
+
async initializeAuthorizationAccounts(input) {
|
|
1297
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1298
|
+
if (!sameAuthorizationScope(record, input) || record.revision !== input.expectedRevision || record.status !== "pending_selection" || record.credentialMutation) {
|
|
1299
|
+
return null;
|
|
1300
|
+
}
|
|
1301
|
+
const updated = {
|
|
1302
|
+
...record,
|
|
1303
|
+
accounts: structuredClone(input.accounts),
|
|
1304
|
+
revision: record.revision + 1,
|
|
1305
|
+
updatedAt: this.now()
|
|
1306
|
+
};
|
|
1307
|
+
this.authorizations.set(record.id, updated);
|
|
1308
|
+
return structuredClone(updated);
|
|
1309
|
+
}
|
|
1310
|
+
async getAuthorization(input) {
|
|
1311
|
+
const authorization = this.authorizations.get(input.authorizationId);
|
|
1312
|
+
return sameAuthorizationScope(authorization, input) ? structuredClone(authorization) : null;
|
|
1313
|
+
}
|
|
1314
|
+
async getAuthorizationByConnectionId(input) {
|
|
1315
|
+
const connection = this.connections.get(input.connectionId);
|
|
1316
|
+
if (!sameConnectionScope(connection, input))
|
|
1317
|
+
return null;
|
|
1318
|
+
const authorization = this.authorizations.get(connection.authorizationId);
|
|
1319
|
+
return sameAuthorizationScope(authorization, input) ? structuredClone(authorization) : null;
|
|
1320
|
+
}
|
|
1321
|
+
async claimCredentialMutation(input) {
|
|
1322
|
+
assertPositiveDuration(input.leaseDurationMs, "credential mutation lease duration");
|
|
1323
|
+
assertPositiveDuration(input.operationTimeoutMs, "credential mutation timeout");
|
|
1324
|
+
const now = this.now();
|
|
1325
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1326
|
+
if (!sameAuthorizationScope(record, input) || record.revision !== input.expectedRevision || !canClaimMutation(record.status, input.mutation.kind)) {
|
|
1327
|
+
return null;
|
|
1328
|
+
}
|
|
1329
|
+
if (record.credentialMutation) {
|
|
1330
|
+
const canReplacePrepared = record.credentialMutation.phase === "prepared" && record.credentialMutation.expiresAt.getTime() <= now.getTime();
|
|
1331
|
+
if (!canReplacePrepared)
|
|
1332
|
+
return null;
|
|
1333
|
+
}
|
|
1334
|
+
const attached = this.connectedConnectionsForAuthorization(record.id);
|
|
1335
|
+
if (input.mutation.kind === "reauthorization" && !sameIds(attached.map((connection) => connection.id), input.expectedConnectionIds ?? [])) {
|
|
1336
|
+
return null;
|
|
1337
|
+
}
|
|
1338
|
+
const deadlineAt = new Date(now.getTime() + input.operationTimeoutMs);
|
|
1339
|
+
const mutation = {
|
|
1340
|
+
...structuredClone(input.mutation),
|
|
1341
|
+
phase: "prepared",
|
|
1342
|
+
expiresAt: leaseExpiry(now, input.leaseDurationMs, deadlineAt),
|
|
1343
|
+
deadlineAt,
|
|
1344
|
+
...input.mutation.kind === "reauthorization" ? { expectedConnectionIds: [...input.expectedConnectionIds ?? []] } : {}
|
|
1345
|
+
};
|
|
1346
|
+
const startsRevocation = input.mutation.kind === "revocation" && record.status !== "revocation_pending";
|
|
1347
|
+
const updated = {
|
|
1348
|
+
...record,
|
|
1349
|
+
status: input.mutation.kind === "revocation" ? "revocation_pending" : record.status,
|
|
1350
|
+
selectionExpiresAt: input.mutation.kind === "revocation" ? undefined : record.selectionExpiresAt,
|
|
1351
|
+
revision: startsRevocation ? record.revision + 1 : record.revision,
|
|
1352
|
+
credentialMutation: mutation,
|
|
1353
|
+
updatedAt: now
|
|
1354
|
+
};
|
|
1355
|
+
this.authorizations.set(record.id, updated);
|
|
1356
|
+
const disconnected = [];
|
|
1357
|
+
if (input.mutation.kind === "revocation") {
|
|
1358
|
+
for (const connection of attached) {
|
|
1359
|
+
const updatedConnection = disconnectConnectionRecord(connection, now);
|
|
1360
|
+
this.connections.set(connection.id, updatedConnection);
|
|
1361
|
+
disconnected.push(structuredClone(updatedConnection));
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1364
|
+
return { authorization: structuredClone(updated), disconnected };
|
|
1365
|
+
}
|
|
1366
|
+
async markCredentialMutationExecuting(input) {
|
|
1367
|
+
const now = this.now();
|
|
1368
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1369
|
+
if (!matchesMutation(record, input, input.holderId) || record.credentialMutation.phase !== "prepared" || mutationExpired(record, now)) {
|
|
1370
|
+
return null;
|
|
1371
|
+
}
|
|
1372
|
+
const updated = {
|
|
1373
|
+
...record,
|
|
1374
|
+
credentialMutation: { ...record.credentialMutation, phase: "executing" },
|
|
1375
|
+
updatedAt: now
|
|
1376
|
+
};
|
|
1377
|
+
this.authorizations.set(record.id, updated);
|
|
1378
|
+
return structuredClone(updated);
|
|
1379
|
+
}
|
|
1380
|
+
async renewCredentialMutation(input) {
|
|
1381
|
+
assertPositiveDuration(input.leaseDurationMs, "credential mutation lease duration");
|
|
1382
|
+
const now = this.now();
|
|
1383
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1384
|
+
if (!matchesMutation(record, input, input.holderId) || record.credentialMutation.phase === "result_staged" || mutationExpired(record, now)) {
|
|
1385
|
+
return null;
|
|
1386
|
+
}
|
|
1387
|
+
const updated = {
|
|
1388
|
+
...record,
|
|
1389
|
+
credentialMutation: {
|
|
1390
|
+
...record.credentialMutation,
|
|
1391
|
+
expiresAt: leaseExpiry(now, input.leaseDurationMs, record.credentialMutation.deadlineAt)
|
|
1392
|
+
}
|
|
1393
|
+
};
|
|
1394
|
+
this.authorizations.set(record.id, updated);
|
|
1395
|
+
return structuredClone(updated);
|
|
1396
|
+
}
|
|
1397
|
+
async stageCredentialMutationCredentials(input) {
|
|
1398
|
+
const now = this.now();
|
|
1399
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1400
|
+
if (!matchesMutation(record, input, input.holderId) || record.credentialMutation.phase !== "executing" || mutationExpired(record, now) || record.credentialMutation.kind === "revocation") {
|
|
1401
|
+
return null;
|
|
1402
|
+
}
|
|
1403
|
+
const updated = {
|
|
1404
|
+
...record,
|
|
1405
|
+
credentialMutation: {
|
|
1406
|
+
...record.credentialMutation,
|
|
1407
|
+
phase: "result_staged",
|
|
1408
|
+
stagedCredentials: {
|
|
1409
|
+
credentials: structuredClone(input.credentials),
|
|
1410
|
+
...input.credentialExpiresAt === undefined ? {} : { credentialExpiresAt: new Date(input.credentialExpiresAt) },
|
|
1411
|
+
scopes: [...input.scopes]
|
|
1412
|
+
}
|
|
1413
|
+
},
|
|
1414
|
+
updatedAt: now
|
|
1415
|
+
};
|
|
1416
|
+
this.authorizations.set(record.id, updated);
|
|
1417
|
+
return structuredClone(updated);
|
|
1418
|
+
}
|
|
1419
|
+
async stageCredentialMutationRevocation(input) {
|
|
1420
|
+
const now = this.now();
|
|
1421
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1422
|
+
if (!matchesMutation(record, input, input.holderId) || record.credentialMutation.phase !== "executing" || record.credentialMutation.kind !== "revocation" || mutationExpired(record, now)) {
|
|
1423
|
+
return null;
|
|
1424
|
+
}
|
|
1425
|
+
const updated = {
|
|
1426
|
+
...record,
|
|
1427
|
+
credentialMutation: { ...record.credentialMutation, phase: "result_staged" },
|
|
1428
|
+
updatedAt: now
|
|
1429
|
+
};
|
|
1430
|
+
this.authorizations.set(record.id, updated);
|
|
1431
|
+
return structuredClone(updated);
|
|
1432
|
+
}
|
|
1433
|
+
async releaseCredentialMutation(input) {
|
|
1434
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1435
|
+
if (!matchesMutation(record, input, input.holderId) || record.credentialMutation.phase === "result_staged") {
|
|
1436
|
+
return false;
|
|
1437
|
+
}
|
|
1438
|
+
this.authorizations.set(record.id, {
|
|
1439
|
+
...record,
|
|
1440
|
+
credentialMutation: undefined,
|
|
1441
|
+
updatedAt: this.now()
|
|
1442
|
+
});
|
|
1443
|
+
return true;
|
|
1444
|
+
}
|
|
1445
|
+
async recoverExpiredCredentialMutation(input) {
|
|
1446
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1447
|
+
if (!sameAuthorizationScope(record, input) || !record.credentialMutation)
|
|
1448
|
+
return null;
|
|
1449
|
+
if (record.credentialMutation.phase === "result_staged")
|
|
1450
|
+
return structuredClone(record);
|
|
1451
|
+
const now = this.now();
|
|
1452
|
+
if (!mutationExpired(record, now))
|
|
1453
|
+
return null;
|
|
1454
|
+
const ambiguous = record.credentialMutation.phase === "executing";
|
|
1455
|
+
const failClosed = ambiguous && record.credentialMutation.kind !== "revocation";
|
|
1456
|
+
const updated = {
|
|
1457
|
+
...record,
|
|
1458
|
+
status: failClosed ? "needs_reauthorization" : record.status,
|
|
1459
|
+
selectionExpiresAt: failClosed ? undefined : record.selectionExpiresAt,
|
|
1460
|
+
revision: failClosed ? record.revision + 1 : record.revision,
|
|
1461
|
+
credentialMutation: undefined,
|
|
1462
|
+
updatedAt: now
|
|
1463
|
+
};
|
|
1464
|
+
this.authorizations.set(record.id, updated);
|
|
1465
|
+
return structuredClone(updated);
|
|
1466
|
+
}
|
|
1467
|
+
async markNeedsReauthorization(input) {
|
|
1468
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1469
|
+
if (!matchesMutation(record, input))
|
|
1470
|
+
return null;
|
|
1471
|
+
const staged = record.credentialMutation.stagedCredentials;
|
|
1472
|
+
const updated = {
|
|
1473
|
+
...record,
|
|
1474
|
+
...staged ? {
|
|
1475
|
+
credentials: structuredClone(staged.credentials),
|
|
1476
|
+
credentialExpiresAt: staged.credentialExpiresAt === undefined ? undefined : new Date(staged.credentialExpiresAt),
|
|
1477
|
+
scopes: [...staged.scopes]
|
|
1478
|
+
} : {},
|
|
1479
|
+
status: "needs_reauthorization",
|
|
1480
|
+
selectionExpiresAt: undefined,
|
|
1481
|
+
revision: record.revision + 1,
|
|
1482
|
+
credentialMutation: undefined,
|
|
1483
|
+
updatedAt: this.now()
|
|
1484
|
+
};
|
|
1485
|
+
this.authorizations.set(record.id, updated);
|
|
1486
|
+
return structuredClone(updated);
|
|
1487
|
+
}
|
|
1488
|
+
async finalizeRefresh(input) {
|
|
1489
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1490
|
+
const staged = stagedCredentials(record, input, "refresh");
|
|
1491
|
+
if (!record || !staged)
|
|
1492
|
+
return null;
|
|
1493
|
+
const updated = applyStagedCredentials(record, staged, this.now(), {
|
|
1494
|
+
status: "active",
|
|
1495
|
+
accounts: record.accounts
|
|
1496
|
+
});
|
|
1497
|
+
this.authorizations.set(record.id, updated);
|
|
1498
|
+
return structuredClone(updated);
|
|
1499
|
+
}
|
|
1500
|
+
async finalizeReauthorization(input) {
|
|
1501
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1502
|
+
const staged = stagedCredentials(record, input, "reauthorization");
|
|
1503
|
+
if (!record || !staged || !record.credentialMutation)
|
|
1504
|
+
return null;
|
|
1505
|
+
const attached = this.connectedConnectionsForAuthorization(record.id);
|
|
1506
|
+
if (!sameIds(attached.map((connection) => connection.id), record.credentialMutation.expectedConnectionIds ?? [])) {
|
|
1507
|
+
throw new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] Connections attached to the connector authorization changed during reauthorization.");
|
|
1508
|
+
}
|
|
1509
|
+
const accountsById = new Map(input.accounts.map((account) => [account.id, account]));
|
|
1510
|
+
if (attached.some((connection) => !accountsById.has(connection.account.id))) {
|
|
1511
|
+
throw new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] Reauthorized connector grant no longer exposes every attached account.");
|
|
1512
|
+
}
|
|
1513
|
+
const now = this.now();
|
|
1514
|
+
const updated = applyStagedCredentials(record, staged, now, {
|
|
1515
|
+
status: "active",
|
|
1516
|
+
accounts: input.accounts
|
|
1517
|
+
});
|
|
1518
|
+
this.authorizations.set(record.id, updated);
|
|
1519
|
+
for (const connection of attached) {
|
|
1520
|
+
this.connections.set(connection.id, {
|
|
1521
|
+
...connection,
|
|
1522
|
+
account: structuredClone(accountsById.get(connection.account.id)),
|
|
1523
|
+
updatedAt: now
|
|
1524
|
+
});
|
|
1525
|
+
}
|
|
1526
|
+
return structuredClone(updated);
|
|
1527
|
+
}
|
|
1528
|
+
async finalizeRevocation(input) {
|
|
1529
|
+
const record = this.authorizations.get(input.authorizationId);
|
|
1530
|
+
if (!matchesMutation(record, input) || record.credentialMutation.kind !== "revocation" || record.credentialMutation.phase !== "result_staged") {
|
|
1531
|
+
return null;
|
|
1532
|
+
}
|
|
1533
|
+
const updated = {
|
|
1534
|
+
...record,
|
|
1535
|
+
status: "revoked",
|
|
1536
|
+
credentials: undefined,
|
|
1537
|
+
credentialExpiresAt: undefined,
|
|
1538
|
+
scopes: [],
|
|
1539
|
+
accounts: [],
|
|
1540
|
+
selectionExpiresAt: undefined,
|
|
1541
|
+
revision: record.revision + 1,
|
|
1542
|
+
credentialMutation: undefined,
|
|
1543
|
+
updatedAt: this.now()
|
|
1544
|
+
};
|
|
1545
|
+
this.authorizations.set(record.id, updated);
|
|
1546
|
+
return structuredClone(updated);
|
|
1547
|
+
}
|
|
1548
|
+
async putConnection(input) {
|
|
1549
|
+
return this.putConnectionNow(input, this.now());
|
|
1550
|
+
}
|
|
1551
|
+
async putConnectionFromRun(input) {
|
|
1552
|
+
const run = this.currentConnectionRun(input.runId);
|
|
1553
|
+
if (!sameConnectionRunScope(run, input) || run.status !== "waiting" || run.waitingFor !== "account_selection") {
|
|
1554
|
+
throw invalidRun();
|
|
1555
|
+
}
|
|
1556
|
+
const now = this.now();
|
|
1557
|
+
const result = this.putConnectionNow({
|
|
1558
|
+
id: input.id,
|
|
1559
|
+
projectId: input.projectId,
|
|
1560
|
+
connectorId: input.connectorId,
|
|
1561
|
+
owner: run.owner,
|
|
1562
|
+
slot: run.slot,
|
|
1563
|
+
authorizationId: run.authorizationId,
|
|
1564
|
+
account: input.account,
|
|
1565
|
+
replace: input.replace
|
|
1566
|
+
}, now);
|
|
1567
|
+
const succeeded = {
|
|
1568
|
+
...connectionRunBase(run, now),
|
|
1569
|
+
status: "succeeded",
|
|
1570
|
+
authorizationId: run.authorizationId,
|
|
1571
|
+
...result.revocationPendingAuthorizationId === undefined ? {} : { cleanupAuthorizationId: result.revocationPendingAuthorizationId },
|
|
1572
|
+
connections: [structuredClone(result.connection)],
|
|
1573
|
+
finishedAt: now
|
|
1574
|
+
};
|
|
1575
|
+
this.connectionRuns.set(run.id, succeeded);
|
|
1576
|
+
return { ...result, run: structuredClone(succeeded) };
|
|
1577
|
+
}
|
|
1578
|
+
putConnectionNow(input, now) {
|
|
1579
|
+
let authorization = this.authorizations.get(input.authorizationId);
|
|
1580
|
+
if (!sameAuthorizationScope(authorization, input) || !isSelectable(authorization.status) || authorization.credentialMutation?.kind === "reauthorization") {
|
|
1581
|
+
throw authorizationConflict();
|
|
1582
|
+
}
|
|
1583
|
+
if (authorization.status === "pending_selection" && authorization.selectionExpiresAt.getTime() <= now.getTime()) {
|
|
1584
|
+
authorization = {
|
|
1585
|
+
...authorization,
|
|
1586
|
+
status: "revocation_pending",
|
|
1587
|
+
selectionExpiresAt: undefined,
|
|
1588
|
+
revision: authorization.revision + 1,
|
|
1589
|
+
updatedAt: now
|
|
1590
|
+
};
|
|
1591
|
+
this.authorizations.set(authorization.id, authorization);
|
|
1592
|
+
throw authorizationConflict();
|
|
1593
|
+
}
|
|
1594
|
+
const account = authorization.accounts.find((candidate) => candidate.id === input.account.id);
|
|
1595
|
+
if (!account) {
|
|
1596
|
+
throw new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] Connector connection account is not exposed by its authorization.");
|
|
1597
|
+
}
|
|
1598
|
+
const existing = this.findConnectionRecord(input);
|
|
1599
|
+
const sameAccount = existing?.account.id === account.id;
|
|
1600
|
+
if (existing && !sameAccount && !input.replace) {
|
|
1601
|
+
throw new ConnectorConnectionStorageError("connection_conflict", `[Sixb] Connector slot '${input.slot}' is already connected to another account; explicit replacement is required.`);
|
|
1602
|
+
}
|
|
1603
|
+
if (!existing && this.connections.has(input.id)) {
|
|
1604
|
+
throw new ConnectorConnectionStorageError("connection_conflict", "[Sixb] Connector connection id already exists.");
|
|
1605
|
+
}
|
|
1606
|
+
let revocationPendingAuthorizationId;
|
|
1607
|
+
if (existing?.status === "connected" && existing.authorizationId !== authorization.id) {
|
|
1608
|
+
const previous = this.authorizations.get(existing.authorizationId);
|
|
1609
|
+
if (!previous) {
|
|
1610
|
+
throw new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] Existing connector connection references an unavailable authorization.");
|
|
1611
|
+
}
|
|
1612
|
+
const remaining = this.connectedConnectionsForAuthorization(previous.id).filter((connection2) => connection2.id !== existing.id);
|
|
1613
|
+
this.assertConnectionCanMove(existing, previous, remaining.length === 0);
|
|
1614
|
+
if (remaining.length === 0) {
|
|
1615
|
+
const pending = markAuthorizationRevocationPending(previous, now);
|
|
1616
|
+
this.authorizations.set(previous.id, pending);
|
|
1617
|
+
revocationPendingAuthorizationId = previous.id;
|
|
1618
|
+
}
|
|
1619
|
+
} else if (existing?.status === "connected") {
|
|
1620
|
+
const previous = this.authorizations.get(existing.authorizationId);
|
|
1621
|
+
if (previous)
|
|
1622
|
+
this.assertConnectionCanMove(existing, previous, false);
|
|
1623
|
+
}
|
|
1624
|
+
const updatedAuthorization = authorization.status === "pending_selection" ? {
|
|
1625
|
+
...authorization,
|
|
1626
|
+
status: "active",
|
|
1627
|
+
selectionExpiresAt: undefined,
|
|
1628
|
+
revision: authorization.revision + 1,
|
|
1629
|
+
updatedAt: now
|
|
1630
|
+
} : authorization;
|
|
1631
|
+
const connection = existing ? {
|
|
1632
|
+
...existing,
|
|
1633
|
+
authorizationId: input.authorizationId,
|
|
1634
|
+
account: structuredClone(account),
|
|
1635
|
+
status: "connected",
|
|
1636
|
+
disconnectedAt: undefined,
|
|
1637
|
+
updatedAt: now
|
|
1638
|
+
} : {
|
|
1639
|
+
id: input.id,
|
|
1640
|
+
projectId: input.projectId,
|
|
1641
|
+
connectorId: input.connectorId,
|
|
1642
|
+
owner: structuredClone(input.owner),
|
|
1643
|
+
slot: input.slot,
|
|
1644
|
+
authorizationId: input.authorizationId,
|
|
1645
|
+
account: structuredClone(account),
|
|
1646
|
+
status: "connected",
|
|
1647
|
+
createdAt: now,
|
|
1648
|
+
updatedAt: now
|
|
1649
|
+
};
|
|
1650
|
+
if (updatedAuthorization !== authorization) {
|
|
1651
|
+
this.authorizations.set(updatedAuthorization.id, updatedAuthorization);
|
|
1652
|
+
}
|
|
1653
|
+
this.connections.set(connection.id, connection);
|
|
1654
|
+
return {
|
|
1655
|
+
connection: structuredClone(connection),
|
|
1656
|
+
authorization: structuredClone(updatedAuthorization),
|
|
1657
|
+
...revocationPendingAuthorizationId === undefined ? {} : { revocationPendingAuthorizationId },
|
|
1658
|
+
created: existing === undefined,
|
|
1659
|
+
replaced: existing !== undefined && !sameAccount
|
|
1660
|
+
};
|
|
1661
|
+
}
|
|
1662
|
+
async getConnection(input) {
|
|
1663
|
+
const connection = this.findConnectionRecord(input);
|
|
1664
|
+
return connection?.status === "connected" ? structuredClone(connection) : null;
|
|
1665
|
+
}
|
|
1666
|
+
async getConnectionById(input) {
|
|
1667
|
+
const connection = this.connections.get(input.connectionId);
|
|
1668
|
+
return sameConnectionScope(connection, input) ? structuredClone(connection) : null;
|
|
1669
|
+
}
|
|
1670
|
+
async listConnections(input) {
|
|
1671
|
+
return [...this.connections.values()].filter((connection) => sameConnectionScope(connection, input)).map((connection) => structuredClone(connection));
|
|
1672
|
+
}
|
|
1673
|
+
async listConnectionsByAuthorization(input) {
|
|
1674
|
+
const authorization = this.authorizations.get(input.authorizationId);
|
|
1675
|
+
if (!sameAuthorizationScope(authorization, input))
|
|
1676
|
+
return [];
|
|
1677
|
+
return this.connectedConnectionsForAuthorization(input.authorizationId).filter((connection) => sameConnectionScope(connection, input)).map((connection) => structuredClone(connection));
|
|
1678
|
+
}
|
|
1679
|
+
async disconnectConnection(input) {
|
|
1680
|
+
const connection = this.connections.get(input.connectionId);
|
|
1681
|
+
if (!connection || connection.projectId !== input.projectId || connection.connectorId !== input.connectorId) {
|
|
1682
|
+
return null;
|
|
1683
|
+
}
|
|
1684
|
+
const authorization = this.authorizations.get(connection.authorizationId);
|
|
1685
|
+
if (!sameAuthorizationScope(authorization, input)) {
|
|
1686
|
+
throw new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] Connector connection references an unavailable authorization.");
|
|
1687
|
+
}
|
|
1688
|
+
if (connection.status === "disconnected") {
|
|
1689
|
+
return {
|
|
1690
|
+
connection: structuredClone(connection),
|
|
1691
|
+
authorization: structuredClone(authorization),
|
|
1692
|
+
...authorization.status === "revocation_pending" ? { revocationPendingAuthorizationId: authorization.id } : {}
|
|
1693
|
+
};
|
|
1694
|
+
}
|
|
1695
|
+
const now = this.now();
|
|
1696
|
+
const remaining = this.connectedConnectionsForAuthorization(authorization.id).filter((candidate) => candidate.id !== connection.id);
|
|
1697
|
+
this.assertConnectionCanMove(connection, authorization, remaining.length === 0);
|
|
1698
|
+
const disconnected = disconnectConnectionRecord(connection, now);
|
|
1699
|
+
this.connections.set(connection.id, disconnected);
|
|
1700
|
+
const updatedAuthorization = remaining.length === 0 ? markAuthorizationRevocationPending(authorization, now) : authorization;
|
|
1701
|
+
if (updatedAuthorization !== authorization) {
|
|
1702
|
+
this.authorizations.set(authorization.id, updatedAuthorization);
|
|
1703
|
+
}
|
|
1704
|
+
return {
|
|
1705
|
+
connection: structuredClone(disconnected),
|
|
1706
|
+
authorization: structuredClone(updatedAuthorization),
|
|
1707
|
+
...updatedAuthorization.status === "revocation_pending" && remaining.length === 0 ? { revocationPendingAuthorizationId: updatedAuthorization.id } : {}
|
|
1708
|
+
};
|
|
1709
|
+
}
|
|
1710
|
+
snapshot() {
|
|
1711
|
+
return {
|
|
1712
|
+
attempts: structuredClone(this.attempts),
|
|
1713
|
+
connectionRuns: structuredClone(this.connectionRuns),
|
|
1714
|
+
authorizations: structuredClone(this.authorizations),
|
|
1715
|
+
connections: structuredClone(this.connections)
|
|
1716
|
+
};
|
|
1717
|
+
}
|
|
1718
|
+
restore(snapshot) {
|
|
1719
|
+
replaceMap2(this.attempts, snapshot.attempts);
|
|
1720
|
+
replaceMap2(this.connectionRuns, snapshot.connectionRuns);
|
|
1721
|
+
replaceMap2(this.authorizations, snapshot.authorizations);
|
|
1722
|
+
replaceMap2(this.connections, snapshot.connections);
|
|
1723
|
+
}
|
|
1724
|
+
now() {
|
|
1725
|
+
return new Date(this.options.now?.() ?? new Date);
|
|
1726
|
+
}
|
|
1727
|
+
currentConnectionRun(runId) {
|
|
1728
|
+
const run = this.connectionRuns.get(runId);
|
|
1729
|
+
if (!run || run.status !== "waiting" && run.status !== "running")
|
|
1730
|
+
return run;
|
|
1731
|
+
const now = this.now();
|
|
1732
|
+
if (run.expiresAt.getTime() > now.getTime())
|
|
1733
|
+
return run;
|
|
1734
|
+
if (run.status === "waiting" && run.waitingFor === "provider_authorization") {
|
|
1735
|
+
const attempt = this.findAuthorizationAttemptByConnectionRunId(run.id);
|
|
1736
|
+
if (attempt)
|
|
1737
|
+
this.attempts.delete(attempt.id);
|
|
1738
|
+
}
|
|
1739
|
+
if (run.status === "waiting") {
|
|
1740
|
+
if (run.kind === "connect" && run.waitingFor === "account_selection") {
|
|
1741
|
+
this.markPendingAuthorizationForCleanup(run.connectorId, run.authorizationId, now);
|
|
1742
|
+
}
|
|
1743
|
+
const expired = expireConnectionRun(run, now);
|
|
1744
|
+
this.connectionRuns.set(run.id, expired);
|
|
1745
|
+
return expired;
|
|
1746
|
+
}
|
|
1747
|
+
if (run.kind === "connect" && run.authorizationId) {
|
|
1748
|
+
this.markPendingAuthorizationForCleanup(run.connectorId, run.authorizationId, now);
|
|
1749
|
+
}
|
|
1750
|
+
const failed = failExpiredProcessingRun(run, now);
|
|
1751
|
+
this.connectionRuns.set(run.id, failed);
|
|
1752
|
+
return failed;
|
|
1753
|
+
}
|
|
1754
|
+
findConnectionRecord(input) {
|
|
1755
|
+
for (const connection of this.connections.values()) {
|
|
1756
|
+
if (connection.projectId === input.projectId && connection.connectorId === input.connectorId && connection.owner.type === input.owner.type && connection.slot === input.slot) {
|
|
1757
|
+
return connection;
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
return;
|
|
1761
|
+
}
|
|
1762
|
+
findAuthorizationAttemptByConnectionRunId(connectionRunId) {
|
|
1763
|
+
for (const attempt of this.attempts.values()) {
|
|
1764
|
+
if (attempt.connectionRunId === connectionRunId)
|
|
1765
|
+
return attempt;
|
|
1766
|
+
}
|
|
1767
|
+
return;
|
|
1768
|
+
}
|
|
1769
|
+
connectionRecordsForAuthorization(authorizationId) {
|
|
1770
|
+
return [...this.connections.values()].filter((connection) => connection.authorizationId === authorizationId);
|
|
1771
|
+
}
|
|
1772
|
+
connectedConnectionsForAuthorization(authorizationId) {
|
|
1773
|
+
return this.connectionRecordsForAuthorization(authorizationId).filter((connection) => connection.status === "connected");
|
|
1774
|
+
}
|
|
1775
|
+
assertConnectionCanMove(_connection, authorization, removingLastConnection = true) {
|
|
1776
|
+
const mutation = authorization.credentialMutation;
|
|
1777
|
+
if (mutation?.kind === "reauthorization") {
|
|
1778
|
+
throw new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] Connections cannot change while their connector authorization is being reauthorized.");
|
|
1779
|
+
}
|
|
1780
|
+
if (removingLastConnection && mutation) {
|
|
1781
|
+
throw new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] The last connector connection cannot be removed while credentials are being mutated.");
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
markPendingAuthorizationForCleanup(connectorId, authorizationId, now) {
|
|
1785
|
+
const authorization = this.authorizations.get(authorizationId);
|
|
1786
|
+
if (!authorization || authorization.connectorId !== connectorId || authorization.status !== "pending_selection") {
|
|
1787
|
+
return;
|
|
1788
|
+
}
|
|
1789
|
+
this.authorizations.set(authorization.id, markAuthorizationRevocationPending(authorization, now));
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
function disconnectConnectionRecord(connection, now) {
|
|
1793
|
+
return {
|
|
1794
|
+
...connection,
|
|
1795
|
+
status: "disconnected",
|
|
1796
|
+
disconnectedAt: new Date(now),
|
|
1797
|
+
updatedAt: new Date(now)
|
|
1798
|
+
};
|
|
1799
|
+
}
|
|
1800
|
+
function markAuthorizationRevocationPending(authorization, now) {
|
|
1801
|
+
if (authorization.status === "revocation_pending" || authorization.status === "revoked") {
|
|
1802
|
+
return authorization;
|
|
1803
|
+
}
|
|
1804
|
+
if (authorization.credentialMutation) {
|
|
1805
|
+
throw new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] Connector authorization cannot begin revocation while credentials are being mutated.");
|
|
1806
|
+
}
|
|
1807
|
+
return {
|
|
1808
|
+
...authorization,
|
|
1809
|
+
status: "revocation_pending",
|
|
1810
|
+
selectionExpiresAt: undefined,
|
|
1811
|
+
revision: authorization.revision + 1,
|
|
1812
|
+
updatedAt: new Date(now)
|
|
1813
|
+
};
|
|
1814
|
+
}
|
|
1815
|
+
function safeEqual(left, right) {
|
|
1816
|
+
const leftBytes = Buffer.from(left);
|
|
1817
|
+
const rightBytes = Buffer.from(right);
|
|
1818
|
+
return leftBytes.length === rightBytes.length && timingSafeEqual(leftBytes, rightBytes);
|
|
1819
|
+
}
|
|
1820
|
+
function invalidRun() {
|
|
1821
|
+
return new ConnectorConnectionStorageError("run_invalid", "[Sixb] Connector connection run is invalid, expired, or already used.");
|
|
1822
|
+
}
|
|
1823
|
+
function replaceMap2(target, source) {
|
|
1824
|
+
target.clear();
|
|
1825
|
+
for (const [key2, value] of structuredClone(source))
|
|
1826
|
+
target.set(key2, value);
|
|
1827
|
+
}
|
|
1828
|
+
function sameIds(left, right) {
|
|
1829
|
+
const leftSorted = [...left].sort();
|
|
1830
|
+
const rightSorted = [...right].sort();
|
|
1831
|
+
return leftSorted.length === rightSorted.length && leftSorted.every((value, index) => value === rightSorted[index]);
|
|
1832
|
+
}
|
|
1833
|
+
function invalidAttempt() {
|
|
1834
|
+
return new ConnectorConnectionStorageError("attempt_invalid", "[Sixb] Connector authorization attempt is invalid, expired, or already used.");
|
|
1835
|
+
}
|
|
1836
|
+
function authorizationConflict() {
|
|
1837
|
+
return new ConnectorConnectionStorageError("authorization_conflict", "[Sixb] Connector connection requires a selectable authorization from the same project and connector.");
|
|
1838
|
+
}
|
|
1839
|
+
function assertPositiveDuration(value, name) {
|
|
1840
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
1841
|
+
throw new ConnectorConnectionStorageError("invalid_input", `[Sixb] Connector ${name} must be positive.`);
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
function sameAuthorizationScope(record, input) {
|
|
1845
|
+
return record !== undefined && record.projectId === input.projectId && record.connectorId === input.connectorId;
|
|
1846
|
+
}
|
|
1847
|
+
function sameConnectionScope(record, input) {
|
|
1848
|
+
return record !== undefined && record.projectId === input.projectId && record.connectorId === input.connectorId;
|
|
1849
|
+
}
|
|
1850
|
+
function sameConnectionRunScope(record, input) {
|
|
1851
|
+
return record !== undefined && record.projectId === input.projectId && record.connectorId === input.connectorId;
|
|
1852
|
+
}
|
|
1853
|
+
function canClaimMutation(status, kind) {
|
|
1854
|
+
if (kind === "refresh")
|
|
1855
|
+
return status === "active";
|
|
1856
|
+
if (kind === "reauthorization") {
|
|
1857
|
+
return status === "active" || status === "needs_reauthorization";
|
|
1858
|
+
}
|
|
1859
|
+
return status !== "revoked";
|
|
1860
|
+
}
|
|
1861
|
+
function isSelectable(status) {
|
|
1862
|
+
return status === "pending_selection" || status === "active";
|
|
1863
|
+
}
|
|
1864
|
+
function leaseExpiry(now, durationMs, deadlineAt) {
|
|
1865
|
+
return new Date(Math.min(now.getTime() + durationMs, deadlineAt.getTime()));
|
|
1866
|
+
}
|
|
1867
|
+
function mutationExpired(record, now) {
|
|
1868
|
+
return record.credentialMutation.expiresAt.getTime() <= now.getTime() || record.credentialMutation.deadlineAt.getTime() <= now.getTime();
|
|
1869
|
+
}
|
|
1870
|
+
function matchesMutation(record, input, holderId) {
|
|
1871
|
+
return sameAuthorizationScope(record, input) && record.revision === input.expectedRevision && record.credentialMutation?.id === input.mutationId && (holderId === undefined || record.credentialMutation.holderId === holderId);
|
|
1872
|
+
}
|
|
1873
|
+
function stagedCredentials(record, input, kind) {
|
|
1874
|
+
if (!matchesMutation(record, input) || record.credentialMutation.kind !== kind || record.credentialMutation.phase !== "result_staged") {
|
|
1875
|
+
return null;
|
|
1876
|
+
}
|
|
1877
|
+
return record.credentialMutation.stagedCredentials ?? null;
|
|
1878
|
+
}
|
|
1879
|
+
function applyStagedCredentials(record, staged, now, input) {
|
|
1880
|
+
return {
|
|
1881
|
+
...record,
|
|
1882
|
+
credentials: structuredClone(staged.credentials),
|
|
1883
|
+
credentialExpiresAt: staged.credentialExpiresAt === undefined ? undefined : new Date(staged.credentialExpiresAt),
|
|
1884
|
+
scopes: [...staged.scopes],
|
|
1885
|
+
accounts: structuredClone(input.accounts),
|
|
1886
|
+
status: input.status,
|
|
1887
|
+
selectionExpiresAt: undefined,
|
|
1888
|
+
revision: record.revision + 1,
|
|
1889
|
+
credentialMutation: undefined,
|
|
1890
|
+
updatedAt: now
|
|
1891
|
+
};
|
|
1892
|
+
}
|
|
404
1893
|
// src/storage/errors.ts
|
|
405
1894
|
class ObjectNotFoundError extends Error {
|
|
406
1895
|
objectTypeId;
|
|
@@ -589,6 +2078,55 @@ class InMemoryFileUploadSessions {
|
|
|
589
2078
|
// src/storage/in-memory/index.ts
|
|
590
2079
|
import { AsyncLocalStorage } from "async_hooks";
|
|
591
2080
|
|
|
2081
|
+
// src/storage/executions/in-memory.ts
|
|
2082
|
+
var runDirectly2 = async (run) => run();
|
|
2083
|
+
function executionKey(projectId, id) {
|
|
2084
|
+
return JSON.stringify([projectId, id]);
|
|
2085
|
+
}
|
|
2086
|
+
|
|
2087
|
+
class InMemoryExecutionStorage {
|
|
2088
|
+
auth;
|
|
2089
|
+
rows = new Map;
|
|
2090
|
+
runRootOperation;
|
|
2091
|
+
constructor(auth, input = {}) {
|
|
2092
|
+
this.auth = auth;
|
|
2093
|
+
this.runRootOperation = input.runRootOperation ?? runDirectly2;
|
|
2094
|
+
}
|
|
2095
|
+
snapshot() {
|
|
2096
|
+
return structuredClone(this.rows);
|
|
2097
|
+
}
|
|
2098
|
+
restore(snapshot) {
|
|
2099
|
+
this.rows.clear();
|
|
2100
|
+
for (const [key2, record] of structuredClone(snapshot)) {
|
|
2101
|
+
this.rows.set(key2, record);
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
async create(input) {
|
|
2105
|
+
return this.runRootOperation(async () => {
|
|
2106
|
+
const record = normalizeExecutionRecord(input);
|
|
2107
|
+
const key2 = executionKey(record.projectId, record.id);
|
|
2108
|
+
if (this.rows.has(key2)) {
|
|
2109
|
+
throw new ExecutionStorageError("duplicate_execution", `[Sixb] Execution '${record.id}' already exists in project '${record.projectId}'.`);
|
|
2110
|
+
}
|
|
2111
|
+
await validateExecutionRecordReferences(record, {
|
|
2112
|
+
auth: this.auth,
|
|
2113
|
+
getExecution: async ({ projectId, id }) => {
|
|
2114
|
+
const existing = this.rows.get(executionKey(projectId, id));
|
|
2115
|
+
return existing ? cloneExecutionRecord(existing) : null;
|
|
2116
|
+
}
|
|
2117
|
+
});
|
|
2118
|
+
this.rows.set(key2, cloneExecutionRecord(record));
|
|
2119
|
+
return cloneExecutionRecord(record);
|
|
2120
|
+
});
|
|
2121
|
+
}
|
|
2122
|
+
async getById(params) {
|
|
2123
|
+
return this.runRootOperation(() => {
|
|
2124
|
+
const record = this.rows.get(executionKey(params.projectId, params.id));
|
|
2125
|
+
return record ? cloneExecutionRecord(record) : null;
|
|
2126
|
+
});
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
|
|
592
2130
|
// src/storage/objects/in-memory.ts
|
|
593
2131
|
var IN_MEMORY_OBJECT_QUERY_CAPABILITIES = {
|
|
594
2132
|
queryObjects: true,
|
|
@@ -715,12 +2253,12 @@ class InMemoryObjectStorage {
|
|
|
715
2253
|
}
|
|
716
2254
|
restore(snapshot) {
|
|
717
2255
|
this.rows.clear();
|
|
718
|
-
for (const [
|
|
719
|
-
this.rows.set(
|
|
2256
|
+
for (const [key2, bucket] of cloneObjectBuckets(snapshot.rows)) {
|
|
2257
|
+
this.rows.set(key2, bucket);
|
|
720
2258
|
}
|
|
721
2259
|
this.links.clear();
|
|
722
|
-
for (const [
|
|
723
|
-
this.links.set(
|
|
2260
|
+
for (const [key2, bucket] of cloneLinkBuckets(snapshot.links)) {
|
|
2261
|
+
this.links.set(key2, bucket);
|
|
724
2262
|
}
|
|
725
2263
|
}
|
|
726
2264
|
getExactObjectRow(projectId, objectTypeId, primaryId) {
|
|
@@ -907,8 +2445,8 @@ class InMemoryObjectStorage {
|
|
|
907
2445
|
if (op === "intersect") {
|
|
908
2446
|
const otherKeySets = evaluations.slice(1).map((evaluation) => new Set(evaluation.entries.map((entry) => rowIdentityKey(entry.row))));
|
|
909
2447
|
const entries = first.entries.filter((entry) => {
|
|
910
|
-
const
|
|
911
|
-
return otherKeySets.every((keys) => keys.has(
|
|
2448
|
+
const key2 = rowIdentityKey(entry.row);
|
|
2449
|
+
return otherKeySets.every((keys) => keys.has(key2));
|
|
912
2450
|
});
|
|
913
2451
|
return completeEvaluation(entries);
|
|
914
2452
|
}
|
|
@@ -1055,8 +2593,8 @@ class InMemoryObjectStorage {
|
|
|
1055
2593
|
}
|
|
1056
2594
|
}
|
|
1057
2595
|
} else {
|
|
1058
|
-
for (const [
|
|
1059
|
-
if (
|
|
2596
|
+
for (const [key2, bucket] of this.rows) {
|
|
2597
|
+
if (key2.startsWith(`${params.projectId}:`)) {
|
|
1060
2598
|
allRows.push(...bucket.values());
|
|
1061
2599
|
}
|
|
1062
2600
|
}
|
|
@@ -1113,18 +2651,18 @@ function assertReconciliationPageLimit(limit) {
|
|
|
1113
2651
|
}
|
|
1114
2652
|
}
|
|
1115
2653
|
function cloneObjectBuckets(rows) {
|
|
1116
|
-
const
|
|
1117
|
-
for (const [
|
|
1118
|
-
|
|
2654
|
+
const clone2 = new Map;
|
|
2655
|
+
for (const [key2, bucket] of rows) {
|
|
2656
|
+
clone2.set(key2, new Map([...bucket.entries()].map(([primaryId, row]) => [primaryId, structuredClone(row)])));
|
|
1119
2657
|
}
|
|
1120
|
-
return
|
|
2658
|
+
return clone2;
|
|
1121
2659
|
}
|
|
1122
2660
|
function cloneLinkBuckets(links) {
|
|
1123
|
-
const
|
|
1124
|
-
for (const [
|
|
1125
|
-
|
|
2661
|
+
const clone2 = new Map;
|
|
2662
|
+
for (const [key2, bucket] of links) {
|
|
2663
|
+
clone2.set(key2, new Map([...bucket.entries()].map(([linkId, row]) => [linkId, structuredClone(row)])));
|
|
1126
2664
|
}
|
|
1127
|
-
return
|
|
2665
|
+
return clone2;
|
|
1128
2666
|
}
|
|
1129
2667
|
function completeEvaluation(entries) {
|
|
1130
2668
|
return {
|
|
@@ -1302,12 +2840,12 @@ function buildFacetBuckets(rows, facet) {
|
|
|
1302
2840
|
const value = row.properties[facet.propertyId];
|
|
1303
2841
|
if (value === undefined)
|
|
1304
2842
|
continue;
|
|
1305
|
-
const
|
|
1306
|
-
const existing = buckets.get(
|
|
2843
|
+
const key2 = facetValueKey(value);
|
|
2844
|
+
const existing = buckets.get(key2);
|
|
1307
2845
|
if (existing) {
|
|
1308
2846
|
existing.count += 1;
|
|
1309
2847
|
} else {
|
|
1310
|
-
buckets.set(
|
|
2848
|
+
buckets.set(key2, { value, count: 1 });
|
|
1311
2849
|
}
|
|
1312
2850
|
}
|
|
1313
2851
|
return [...buckets.values()].sort((left, right) => right.count - left.count || facetValueSortKey(left.value).localeCompare(facetValueSortKey(right.value))).slice(0, facet.limit);
|
|
@@ -1325,14 +2863,14 @@ function rowIdentityKeyParts(objectTypeId, primaryId) {
|
|
|
1325
2863
|
return `${objectTypeId}:${primaryId}`;
|
|
1326
2864
|
}
|
|
1327
2865
|
function upsertEntry(entriesByKey, entry) {
|
|
1328
|
-
const
|
|
1329
|
-
const existing = entriesByKey.get(
|
|
2866
|
+
const key2 = rowIdentityKey(entry.row);
|
|
2867
|
+
const existing = entriesByKey.get(key2);
|
|
1330
2868
|
if (!existing) {
|
|
1331
|
-
entriesByKey.set(
|
|
2869
|
+
entriesByKey.set(key2, entry);
|
|
1332
2870
|
return;
|
|
1333
2871
|
}
|
|
1334
2872
|
if (entry.score > existing.score) {
|
|
1335
|
-
entriesByKey.set(
|
|
2873
|
+
entriesByKey.set(key2, {
|
|
1336
2874
|
...existing,
|
|
1337
2875
|
score: entry.score
|
|
1338
2876
|
});
|
|
@@ -1366,6 +2904,7 @@ function createInMemoryOntologyState() {
|
|
|
1366
2904
|
sourceMaterializations: new Map,
|
|
1367
2905
|
objectOverrides: new Map,
|
|
1368
2906
|
linkOverrides: new Map,
|
|
2907
|
+
linkSlotOverrides: new Map,
|
|
1369
2908
|
outbox: new Map
|
|
1370
2909
|
};
|
|
1371
2910
|
}
|
|
@@ -1387,8 +2926,8 @@ function sourceMaterializationRecord(materialization) {
|
|
|
1387
2926
|
function commitKey(projectId, commitId) {
|
|
1388
2927
|
return JSON.stringify([projectId, commitId]);
|
|
1389
2928
|
}
|
|
1390
|
-
function idempotencyKey(projectId,
|
|
1391
|
-
return JSON.stringify([projectId,
|
|
2929
|
+
function idempotencyKey(projectId, key2) {
|
|
2930
|
+
return JSON.stringify([projectId, key2]);
|
|
1392
2931
|
}
|
|
1393
2932
|
function ontologyCommitOriginSelector(origin) {
|
|
1394
2933
|
if (origin.kind === "action")
|
|
@@ -1422,9 +2961,9 @@ function cloneOntologyState(state) {
|
|
|
1422
2961
|
return structuredClone(state);
|
|
1423
2962
|
}
|
|
1424
2963
|
function restoreOntologyState(target, snapshot) {
|
|
1425
|
-
for (const
|
|
1426
|
-
const targetMap = target[
|
|
1427
|
-
const sourceMap = structuredClone(snapshot[
|
|
2964
|
+
for (const key2 of Object.keys(target)) {
|
|
2965
|
+
const targetMap = target[key2];
|
|
2966
|
+
const sourceMap = structuredClone(snapshot[key2]);
|
|
1428
2967
|
targetMap.clear();
|
|
1429
2968
|
for (const [entryKey, value] of sourceMap)
|
|
1430
2969
|
targetMap.set(entryKey, value);
|
|
@@ -1555,8 +3094,8 @@ class InMemoryTimeseriesStorage {
|
|
|
1555
3094
|
}
|
|
1556
3095
|
restore(snapshot) {
|
|
1557
3096
|
this.pointsByKey.clear();
|
|
1558
|
-
for (const [
|
|
1559
|
-
this.pointsByKey.set(
|
|
3097
|
+
for (const [key2, points] of structuredClone(snapshot.pointsByKey)) {
|
|
3098
|
+
this.pointsByKey.set(key2, points);
|
|
1560
3099
|
}
|
|
1561
3100
|
}
|
|
1562
3101
|
getExactPoint(projectId, series, at) {
|
|
@@ -1580,8 +3119,8 @@ class InMemoryTimeseriesStorage {
|
|
|
1580
3119
|
return latest;
|
|
1581
3120
|
}
|
|
1582
3121
|
applyExactPoint(projectId, point) {
|
|
1583
|
-
const
|
|
1584
|
-
const series = this.pointsByKey.get(
|
|
3122
|
+
const key2 = pointKey(projectId, point.series.object.objectTypeId, point.series.object.primaryId, point.series.propertyId);
|
|
3123
|
+
const series = this.pointsByKey.get(key2) ?? new Map;
|
|
1585
3124
|
series.set(new Date(point.at).getTime(), {
|
|
1586
3125
|
projectId,
|
|
1587
3126
|
objectTypeId: point.series.object.objectTypeId,
|
|
@@ -1592,12 +3131,12 @@ class InMemoryTimeseriesStorage {
|
|
|
1592
3131
|
at: new Date(point.at),
|
|
1593
3132
|
lastCommitId: point.lastCommitId
|
|
1594
3133
|
});
|
|
1595
|
-
this.pointsByKey.set(
|
|
3134
|
+
this.pointsByKey.set(key2, series);
|
|
1596
3135
|
}
|
|
1597
3136
|
async getHistory(params) {
|
|
1598
|
-
const
|
|
3137
|
+
const key2 = pointKey(params.projectId, params.objectTypeId, params.objectId, params.propertyId);
|
|
1599
3138
|
const { from, to } = params;
|
|
1600
|
-
let points = [...this.pointsByKey.get(
|
|
3139
|
+
let points = [...this.pointsByKey.get(key2)?.values() ?? []];
|
|
1601
3140
|
if (from || to) {
|
|
1602
3141
|
points = points.filter((point) => (!from || point.at >= from) && (!to || point.at <= to));
|
|
1603
3142
|
}
|
|
@@ -1671,6 +3210,12 @@ function publicLinkOverride(value) {
|
|
|
1671
3210
|
const { projectId: _, ...stored } = value;
|
|
1672
3211
|
return stored;
|
|
1673
3212
|
}
|
|
3213
|
+
function publicLinkSlotOverride(value) {
|
|
3214
|
+
if (!value)
|
|
3215
|
+
return null;
|
|
3216
|
+
const { projectId: _, ...stored } = value;
|
|
3217
|
+
return stored;
|
|
3218
|
+
}
|
|
1674
3219
|
function uniqueBy(values, keyOf) {
|
|
1675
3220
|
return [...new Map(values.map((value) => [keyOf(value), structuredClone(value)])).values()];
|
|
1676
3221
|
}
|
|
@@ -1751,15 +3296,15 @@ function storedSourceLink(sourceId, materializationId, row) {
|
|
|
1751
3296
|
return storedSource(sourceId, materializationId, row);
|
|
1752
3297
|
}
|
|
1753
3298
|
function addReplacementLink(replacement, ref, diffRequired) {
|
|
1754
|
-
const
|
|
1755
|
-
const existing = replacement.links.get(
|
|
3299
|
+
const key2 = linkRefKey(ref);
|
|
3300
|
+
const existing = replacement.links.get(key2);
|
|
1756
3301
|
if (existing) {
|
|
1757
3302
|
existing.diffRequired ||= diffRequired;
|
|
1758
3303
|
if (diffRequired)
|
|
1759
3304
|
replacement.affectedScopes.add(linkScopeSortKey(ref.source, ref.linkId));
|
|
1760
3305
|
return;
|
|
1761
3306
|
}
|
|
1762
|
-
replacement.links.set(
|
|
3307
|
+
replacement.links.set(key2, {
|
|
1763
3308
|
ref: structuredClone(ref),
|
|
1764
3309
|
sortKey: linkRefSortKey(ref),
|
|
1765
3310
|
diffRequired
|
|
@@ -1921,9 +3466,9 @@ function remainingClassifiedCount(classified, created, updated, deleted) {
|
|
|
1921
3466
|
return classified - created - updated - deleted;
|
|
1922
3467
|
}
|
|
1923
3468
|
function effectiveChangeCountsMatch(actual, expected) {
|
|
1924
|
-
return effectiveChangeCountKeys.every((
|
|
1925
|
-
const count = actual[
|
|
1926
|
-
return Number.isSafeInteger(count) && count >= 0 && count === expected[
|
|
3469
|
+
return effectiveChangeCountKeys.every((key2) => {
|
|
3470
|
+
const count = actual[key2];
|
|
3471
|
+
return Number.isSafeInteger(count) && count >= 0 && count === expected[key2];
|
|
1927
3472
|
});
|
|
1928
3473
|
}
|
|
1929
3474
|
function telemetryCountsCorrelate(session, pointCount, actual) {
|
|
@@ -1946,7 +3491,7 @@ function telemetryCountsCorrelate(session, pointCount, actual) {
|
|
|
1946
3491
|
pointsUnchanged: pointCount - pointsCreated - pointsUpdated,
|
|
1947
3492
|
latestObjectsChanged
|
|
1948
3493
|
};
|
|
1949
|
-
return expected.pointsUnchanged >= 0 && Object.keys(expected).every((
|
|
3494
|
+
return expected.pointsUnchanged >= 0 && Object.keys(expected).every((key2) => Number.isSafeInteger(actual[key2]) && actual[key2] >= 0 && actual[key2] === expected[key2]);
|
|
1950
3495
|
}
|
|
1951
3496
|
function assertSourceActivationCorrelation(activation, session, state) {
|
|
1952
3497
|
const { header } = session;
|
|
@@ -2017,10 +3562,11 @@ function assertFinalizedWork(session, state, objects) {
|
|
|
2017
3562
|
}
|
|
2018
3563
|
}
|
|
2019
3564
|
function assertFinalCardinality(records, projectId, objects) {
|
|
3565
|
+
const effectiveOccupants = records.filter((record) => record.view === "effective");
|
|
2020
3566
|
const scopes = new Map;
|
|
2021
3567
|
let currentScope = null;
|
|
2022
3568
|
let occupiedCount = 0;
|
|
2023
|
-
for (const record of
|
|
3569
|
+
for (const record of effectiveOccupants) {
|
|
2024
3570
|
if (record.scopeSortKey !== currentScope) {
|
|
2025
3571
|
currentScope = record.scopeSortKey;
|
|
2026
3572
|
occupiedCount = 0;
|
|
@@ -2062,7 +3608,7 @@ function assertReplacementFullyStreamed(session, activation) {
|
|
|
2062
3608
|
invalidCorrelation("Link projection replacement state was not fully streamed.");
|
|
2063
3609
|
}
|
|
2064
3610
|
const expectedObjectKeys = activation.projectionKind === "object" ? [...replacement.objects.keys()].sort() : [];
|
|
2065
|
-
const expectedLinkKeys = [...replacement.links.entries()].filter(([, value]) => value.diffRequired).map(([
|
|
3611
|
+
const expectedLinkKeys = [...replacement.links.entries()].filter(([, value]) => value.diffRequired).map(([key2]) => key2).sort();
|
|
2066
3612
|
if (stableJsonStringify(classificationKeys(session, "object")) !== stableJsonStringify(expectedObjectKeys) || stableJsonStringify(classificationKeys(session, "link")) !== stableJsonStringify(expectedLinkKeys) || classificationKeys(session, "point").length > 0) {
|
|
2067
3613
|
invalidCorrelation("Projection replacement classification coverage does not match its streamed state.");
|
|
2068
3614
|
}
|
|
@@ -2082,15 +3628,17 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2082
3628
|
timeseries;
|
|
2083
3629
|
getTransactionToken;
|
|
2084
3630
|
getMaterializationLifecycle;
|
|
3631
|
+
executionExists;
|
|
2085
3632
|
hooks;
|
|
2086
3633
|
sessions = new WeakMap;
|
|
2087
3634
|
liveSessions = new Set;
|
|
2088
|
-
constructor(state, objects, timeseries, getTransactionToken, getMaterializationLifecycle, hooks = {}) {
|
|
3635
|
+
constructor(state, objects, timeseries, getTransactionToken, getMaterializationLifecycle, executionExists, hooks = {}) {
|
|
2089
3636
|
this.state = state;
|
|
2090
3637
|
this.objects = objects;
|
|
2091
3638
|
this.timeseries = timeseries;
|
|
2092
3639
|
this.getTransactionToken = getTransactionToken;
|
|
2093
3640
|
this.getMaterializationLifecycle = getMaterializationLifecycle;
|
|
3641
|
+
this.executionExists = executionExists;
|
|
2094
3642
|
this.hooks = hooks;
|
|
2095
3643
|
}
|
|
2096
3644
|
async begin(input) {
|
|
@@ -2100,6 +3648,9 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2100
3648
|
throw new MaterializationValidationError("Materialization sessions require an active storage transaction.");
|
|
2101
3649
|
}
|
|
2102
3650
|
assertMaterializationHeader(input);
|
|
3651
|
+
if (!await this.executionExists(input.commit.projectId, input.commit.executionId)) {
|
|
3652
|
+
throw new MaterializationValidationError(`Ontology commit execution '${input.commit.executionId}' does not exist in project '${input.commit.projectId}'.`);
|
|
3653
|
+
}
|
|
2103
3654
|
this.assertCommitAbsent(input);
|
|
2104
3655
|
for (const expected of input.expected.sources)
|
|
2105
3656
|
this.assertSource(expected, input.commit.projectId);
|
|
@@ -2109,9 +3660,9 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2109
3660
|
await this.assertLink(expected, input.commit.projectId);
|
|
2110
3661
|
const expectedScopeStates = new Map;
|
|
2111
3662
|
for (const expected of input.expected.linkScopes) {
|
|
2112
|
-
const
|
|
2113
|
-
const current = expectedScopeStates.get(
|
|
2114
|
-
expectedScopeStates.set(
|
|
3663
|
+
const key2 = linkScopeSortKey(expected.source, expected.linkId);
|
|
3664
|
+
const current = expectedScopeStates.get(key2) ?? this.computeLinkScopeState(input.commit.projectId, expected.source, expected.linkId);
|
|
3665
|
+
expectedScopeStates.set(key2, current);
|
|
2115
3666
|
if (current.fingerprint !== expected.fingerprint) {
|
|
2116
3667
|
throw new MaterializationConflictError("effective-state", `Expected link scope changed for ${expected.source.objectTypeId}:${expected.source.primaryId}.${expected.linkId}.`);
|
|
2117
3668
|
}
|
|
@@ -2249,11 +3800,11 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2249
3800
|
const selected = replacement.orderedObjects.slice(offset, offset + input.pageRows);
|
|
2250
3801
|
const objects = [];
|
|
2251
3802
|
for (const entry of selected) {
|
|
2252
|
-
const
|
|
3803
|
+
const key2 = projectionEntityKey({ kind: "object", ref: entry.ref });
|
|
2253
3804
|
const base = await this.objectState(session, entry.ref);
|
|
2254
3805
|
objects.push({
|
|
2255
3806
|
ref: base.ref,
|
|
2256
|
-
candidateSource: storedSourceObject(input.source.projectionId, replacement.candidate.materializationId, replacement.candidate.rowsByEntity.get(
|
|
3807
|
+
candidateSource: storedSourceObject(input.source.projectionId, replacement.candidate.materializationId, replacement.candidate.rowsByEntity.get(key2)),
|
|
2257
3808
|
override: base.override,
|
|
2258
3809
|
effective: base.effective,
|
|
2259
3810
|
latestTelemetry: base.latestTelemetry
|
|
@@ -2281,13 +3832,14 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2281
3832
|
const selected = replacement.orderedLinks.slice(offset, offset + input.pageRows);
|
|
2282
3833
|
const links = [];
|
|
2283
3834
|
for (const entry of selected) {
|
|
2284
|
-
const
|
|
3835
|
+
const key2 = projectionEntityKey({ kind: "link", ref: entry.ref });
|
|
2285
3836
|
const base = await this.linkState(session, entry.ref);
|
|
2286
|
-
const ownedByReplacement = replacement.previous?.rowsByEntity.has(
|
|
3837
|
+
const ownedByReplacement = replacement.previous?.rowsByEntity.has(key2) || replacement.candidate.rowsByEntity.has(key2);
|
|
2287
3838
|
links.push({
|
|
2288
3839
|
ref: base.ref,
|
|
2289
|
-
candidateSource: ownedByReplacement ? storedSourceLink(input.source.projectionId, replacement.candidate.materializationId, replacement.candidate.rowsByEntity.get(
|
|
3840
|
+
candidateSource: ownedByReplacement ? storedSourceLink(input.source.projectionId, replacement.candidate.materializationId, replacement.candidate.rowsByEntity.get(key2)) : base.source,
|
|
2290
3841
|
override: base.override,
|
|
3842
|
+
slotOverride: base.slotOverride,
|
|
2291
3843
|
effective: base.effective,
|
|
2292
3844
|
diffRequired: entry.diffRequired
|
|
2293
3845
|
});
|
|
@@ -2389,11 +3941,11 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2389
3941
|
this.hooks.beforeWrite?.(boundary, session.writeOrdinal++);
|
|
2390
3942
|
apply();
|
|
2391
3943
|
};
|
|
2392
|
-
for (const item of input.chunk.overrides.
|
|
3944
|
+
for (const item of input.chunk.overrides.objects.upserts)
|
|
2393
3945
|
write("override.object.upsert", () => {
|
|
2394
|
-
const
|
|
2395
|
-
assertLastCommit(this.state.objectOverrides.get(
|
|
2396
|
-
this.state.objectOverrides.set(
|
|
3946
|
+
const key2 = projectEntityKey(projectId, objectRefKey(item.ref));
|
|
3947
|
+
assertLastCommit(this.state.objectOverrides.get(key2), item.expectedLastCommitId, "object override");
|
|
3948
|
+
this.state.objectOverrides.set(key2, structuredClone({
|
|
2397
3949
|
projectId,
|
|
2398
3950
|
ref: item.ref,
|
|
2399
3951
|
value: item.value,
|
|
@@ -2401,17 +3953,17 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2401
3953
|
updatedAt: item.updatedAt
|
|
2402
3954
|
}));
|
|
2403
3955
|
});
|
|
2404
|
-
for (const item of input.chunk.overrides.
|
|
3956
|
+
for (const item of input.chunk.overrides.objects.deletes)
|
|
2405
3957
|
write("override.object.delete", () => {
|
|
2406
|
-
const
|
|
2407
|
-
assertLastCommit(this.state.objectOverrides.get(
|
|
2408
|
-
this.state.objectOverrides.delete(
|
|
3958
|
+
const key2 = projectEntityKey(projectId, objectRefKey(item.ref));
|
|
3959
|
+
assertLastCommit(this.state.objectOverrides.get(key2), item.expectedLastCommitId, "object override");
|
|
3960
|
+
this.state.objectOverrides.delete(key2);
|
|
2409
3961
|
});
|
|
2410
|
-
for (const item of input.chunk.overrides.
|
|
3962
|
+
for (const item of input.chunk.overrides.links.edges.upserts)
|
|
2411
3963
|
write("override.link.upsert", () => {
|
|
2412
|
-
const
|
|
2413
|
-
assertLastCommit(this.state.linkOverrides.get(
|
|
2414
|
-
this.state.linkOverrides.set(
|
|
3964
|
+
const key2 = projectEntityKey(projectId, linkRefKey(item.ref));
|
|
3965
|
+
assertLastCommit(this.state.linkOverrides.get(key2), item.expectedLastCommitId, "link edge override");
|
|
3966
|
+
this.state.linkOverrides.set(key2, structuredClone({
|
|
2415
3967
|
projectId,
|
|
2416
3968
|
ref: item.ref,
|
|
2417
3969
|
value: item.value,
|
|
@@ -2419,11 +3971,29 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2419
3971
|
updatedAt: item.updatedAt
|
|
2420
3972
|
}));
|
|
2421
3973
|
});
|
|
2422
|
-
for (const item of input.chunk.overrides.
|
|
3974
|
+
for (const item of input.chunk.overrides.links.edges.deletes)
|
|
2423
3975
|
write("override.link.delete", () => {
|
|
2424
|
-
const
|
|
2425
|
-
assertLastCommit(this.state.linkOverrides.get(
|
|
2426
|
-
this.state.linkOverrides.delete(
|
|
3976
|
+
const key2 = projectEntityKey(projectId, linkRefKey(item.ref));
|
|
3977
|
+
assertLastCommit(this.state.linkOverrides.get(key2), item.expectedLastCommitId, "link edge override");
|
|
3978
|
+
this.state.linkOverrides.delete(key2);
|
|
3979
|
+
});
|
|
3980
|
+
for (const item of input.chunk.overrides.links.slots.upserts)
|
|
3981
|
+
write("override.link-slot.upsert", () => {
|
|
3982
|
+
const key2 = projectEntityKey(projectId, linkScopeKey(item.ref.source, item.ref.linkId));
|
|
3983
|
+
assertLastCommit(this.state.linkSlotOverrides.get(key2), item.expectedLastCommitId, "link slot override");
|
|
3984
|
+
this.state.linkSlotOverrides.set(key2, structuredClone({
|
|
3985
|
+
projectId,
|
|
3986
|
+
ref: item.ref,
|
|
3987
|
+
value: item.value,
|
|
3988
|
+
lastCommitId: item.lastCommitId,
|
|
3989
|
+
updatedAt: item.updatedAt
|
|
3990
|
+
}));
|
|
3991
|
+
});
|
|
3992
|
+
for (const item of input.chunk.overrides.links.slots.deletes)
|
|
3993
|
+
write("override.link-slot.delete", () => {
|
|
3994
|
+
const key2 = projectEntityKey(projectId, linkScopeKey(item.ref.source, item.ref.linkId));
|
|
3995
|
+
assertLastCommit(this.state.linkSlotOverrides.get(key2), item.expectedLastCommitId, "link slot override");
|
|
3996
|
+
this.state.linkSlotOverrides.delete(key2);
|
|
2427
3997
|
});
|
|
2428
3998
|
for (const item of input.chunk.effective.linkDeletes)
|
|
2429
3999
|
write("effective.link.delete", () => {
|
|
@@ -2466,20 +4036,20 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2466
4036
|
assertTimestamp2(item.availableAt, "Outbox availableAt");
|
|
2467
4037
|
assertTimestamp2(item.createdAt, "Outbox createdAt");
|
|
2468
4038
|
assertTimestamp2(envelope.occurredAt, "Outbox event occurredAt");
|
|
2469
|
-
const
|
|
2470
|
-
if (this.state.outbox.has(
|
|
4039
|
+
const key2 = outboxKey(projectId, envelope.id);
|
|
4040
|
+
if (this.state.outbox.has(key2)) {
|
|
2471
4041
|
throw new MaterializationConflictError("effective-state", `Duplicate outbox event '${envelope.id}'.`);
|
|
2472
4042
|
}
|
|
2473
4043
|
if (session.outboxEnvelopes.has(envelope.commitOrdinal))
|
|
2474
4044
|
throw new MaterializationConflictError("effective-state", "Duplicate outbox commit ordinal.");
|
|
2475
|
-
this.state.outbox.set(
|
|
4045
|
+
this.state.outbox.set(key2, {
|
|
2476
4046
|
envelope: structuredClone(envelope),
|
|
2477
4047
|
availableAt: item.availableAt,
|
|
2478
4048
|
attempts: 0,
|
|
2479
4049
|
leaseId: null,
|
|
2480
4050
|
leaseExpiresAt: null,
|
|
2481
4051
|
publishedAt: null,
|
|
2482
|
-
|
|
4052
|
+
lastFailure: null,
|
|
2483
4053
|
createdAt: item.createdAt
|
|
2484
4054
|
});
|
|
2485
4055
|
session.outboxEnvelopes.set(envelope.commitOrdinal, structuredClone(envelope));
|
|
@@ -2610,6 +4180,17 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2610
4180
|
if (touchesIncident(override.ref))
|
|
2611
4181
|
addReplacementLink(replacement, override.ref, true);
|
|
2612
4182
|
}
|
|
4183
|
+
for (const override of this.state.linkSlotOverrides.values()) {
|
|
4184
|
+
if (override.projectId !== projectId)
|
|
4185
|
+
continue;
|
|
4186
|
+
const ref = {
|
|
4187
|
+
source: override.ref.source,
|
|
4188
|
+
linkId: override.ref.linkId,
|
|
4189
|
+
target: override.value.target
|
|
4190
|
+
};
|
|
4191
|
+
if (touchesIncident(ref))
|
|
4192
|
+
addReplacementLink(replacement, ref, true);
|
|
4193
|
+
}
|
|
2613
4194
|
for (const active of this.state.sourceMaterializations.values()) {
|
|
2614
4195
|
if (active.projectId !== projectId || active.status !== "active")
|
|
2615
4196
|
continue;
|
|
@@ -2625,6 +4206,15 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2625
4206
|
addReplacementLink(replacement, ref, false);
|
|
2626
4207
|
}
|
|
2627
4208
|
});
|
|
4209
|
+
for (const override of this.state.linkSlotOverrides.values()) {
|
|
4210
|
+
if (override.projectId === projectId && replacement.affectedScopes.has(linkScopeSortKey(override.ref.source, override.ref.linkId))) {
|
|
4211
|
+
addReplacementLink(replacement, {
|
|
4212
|
+
source: override.ref.source,
|
|
4213
|
+
linkId: override.ref.linkId,
|
|
4214
|
+
target: override.value.target
|
|
4215
|
+
}, false);
|
|
4216
|
+
}
|
|
4217
|
+
}
|
|
2628
4218
|
replacement.linksExpanded = true;
|
|
2629
4219
|
replacement.orderedLinks = null;
|
|
2630
4220
|
}
|
|
@@ -2714,24 +4304,25 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2714
4304
|
ref: structuredClone(ref),
|
|
2715
4305
|
source: this.findActiveLinkSource(projectId, ref),
|
|
2716
4306
|
override: structuredClone(publicLinkOverride(this.state.linkOverrides.get(projectEntityKey(projectId, linkRefKey(ref))))),
|
|
4307
|
+
slotOverride: structuredClone(publicLinkSlotOverride(this.state.linkSlotOverrides.get(projectEntityKey(projectId, linkScopeKey(ref.source, ref.linkId))))),
|
|
2717
4308
|
effective: row ? linkSnapshot(row) : null
|
|
2718
4309
|
};
|
|
2719
4310
|
}
|
|
2720
4311
|
linkScopeState(session, source, linkId) {
|
|
2721
4312
|
session.linkScopeStates ??= new Map;
|
|
2722
|
-
const
|
|
2723
|
-
const existing = session.linkScopeStates.get(
|
|
4313
|
+
const key2 = linkScopeSortKey(source, linkId);
|
|
4314
|
+
const existing = session.linkScopeStates.get(key2);
|
|
2724
4315
|
if (existing)
|
|
2725
4316
|
return structuredClone(existing);
|
|
2726
4317
|
const computed = this.computeLinkScopeState(session.header.commit.projectId, source, linkId);
|
|
2727
|
-
session.linkScopeStates.set(
|
|
4318
|
+
session.linkScopeStates.set(key2, computed);
|
|
2728
4319
|
return structuredClone(computed);
|
|
2729
4320
|
}
|
|
2730
4321
|
computeLinkScopeState(projectId, source, linkId) {
|
|
2731
4322
|
const rows = [];
|
|
2732
4323
|
getInMemoryObjectMaterializerAdapter(this.objects).visitExactScopeLinks(projectId, source.objectTypeId, source.primaryId, linkId, (row) => rows.push(row));
|
|
2733
4324
|
rows.sort((left, right) => linkRefSortKey(linkRef(left)).localeCompare(linkRefSortKey(linkRef(right))));
|
|
2734
|
-
const accumulator = startScopeAccumulator(source, linkId
|
|
4325
|
+
const accumulator = startScopeAccumulator(source, linkId);
|
|
2735
4326
|
for (let offset = 0;offset < rows.length; offset += 1000) {
|
|
2736
4327
|
const page = rows.slice(offset, offset + 1000);
|
|
2737
4328
|
this.hooks.observeBuffer?.("state.link-scope.page", page.length);
|
|
@@ -2739,7 +4330,30 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2739
4330
|
appendScopeSnapshot(accumulator, linkSnapshot(row));
|
|
2740
4331
|
}
|
|
2741
4332
|
}
|
|
2742
|
-
|
|
4333
|
+
const effective = rows.length === 1 ? linkSnapshot(rows[0]) : null;
|
|
4334
|
+
return {
|
|
4335
|
+
...finishScopeAccumulator(accumulator),
|
|
4336
|
+
sourceAssertion: this.findActiveLinkScopeSource(projectId, source, linkId),
|
|
4337
|
+
override: structuredClone(publicLinkSlotOverride(this.state.linkSlotOverrides.get(projectEntityKey(projectId, linkScopeKey(source, linkId))))),
|
|
4338
|
+
effective
|
|
4339
|
+
};
|
|
4340
|
+
}
|
|
4341
|
+
findActiveLinkScopeSource(projectId, source, linkId) {
|
|
4342
|
+
let found = null;
|
|
4343
|
+
for (const active of this.state.sourceMaterializations.values()) {
|
|
4344
|
+
if (active.projectId !== projectId || active.status !== "active")
|
|
4345
|
+
continue;
|
|
4346
|
+
for (const row of active.rowsByEntity.values()) {
|
|
4347
|
+
if (row.assertion.kind !== "link" || objectRefKey(row.assertion.ref.source) !== objectRefKey(source) || row.assertion.ref.linkId !== linkId) {
|
|
4348
|
+
continue;
|
|
4349
|
+
}
|
|
4350
|
+
if (found) {
|
|
4351
|
+
throw new MaterializationConflictError("source-materialization", `Multiple active source links assert cardinality-one scope '${source.objectTypeId}.${linkId}'.`);
|
|
4352
|
+
}
|
|
4353
|
+
found = storedSource(active.source.projectionId, active.materializationId, row);
|
|
4354
|
+
}
|
|
4355
|
+
}
|
|
4356
|
+
return structuredClone(found);
|
|
2743
4357
|
}
|
|
2744
4358
|
findActiveObjectSource(projectId, ref) {
|
|
2745
4359
|
const found = this.findActiveSource(projectId, projectionEntityKey({ kind: "object", ref }));
|
|
@@ -2780,10 +4394,10 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2780
4394
|
const consider = (ref) => {
|
|
2781
4395
|
const sortKey = linkRefSortKey(ref);
|
|
2782
4396
|
for (const endpoint of [ref.source, ref.target]) {
|
|
2783
|
-
const
|
|
2784
|
-
const links = mutable.get(
|
|
4397
|
+
const key2 = objectRefKey(endpoint);
|
|
4398
|
+
const links = mutable.get(key2) ?? new Map;
|
|
2785
4399
|
links.set(sortKey, structuredClone(ref));
|
|
2786
|
-
mutable.set(
|
|
4400
|
+
mutable.set(key2, links);
|
|
2787
4401
|
}
|
|
2788
4402
|
};
|
|
2789
4403
|
getInMemoryObjectMaterializerAdapter(this.objects).visitExactLinks(projectId, (row) => consider(linkRef(row)));
|
|
@@ -2791,6 +4405,15 @@ class InMemoryOntologyMaterializationStorage {
|
|
|
2791
4405
|
if (override.projectId === projectId)
|
|
2792
4406
|
consider(override.ref);
|
|
2793
4407
|
}
|
|
4408
|
+
for (const override of this.state.linkSlotOverrides.values()) {
|
|
4409
|
+
if (override.projectId !== projectId)
|
|
4410
|
+
continue;
|
|
4411
|
+
consider({
|
|
4412
|
+
source: override.ref.source,
|
|
4413
|
+
linkId: override.ref.linkId,
|
|
4414
|
+
target: override.value.target
|
|
4415
|
+
});
|
|
4416
|
+
}
|
|
2794
4417
|
for (const active of this.state.sourceMaterializations.values()) {
|
|
2795
4418
|
if (active.projectId !== projectId || active.status !== "active")
|
|
2796
4419
|
continue;
|
|
@@ -2857,8 +4480,8 @@ class InMemoryOntologyOutboxStorage {
|
|
|
2857
4480
|
assertNonblank(input.leaseId, "Ontology outbox lease id");
|
|
2858
4481
|
assertTimestamp2(input.publishedAt, "Ontology outbox publishedAt");
|
|
2859
4482
|
const rows = this.validateLeaseBatch(input.projectId, input.ids, input.leaseId);
|
|
2860
|
-
for (const [
|
|
2861
|
-
this.state.outbox.set(
|
|
4483
|
+
for (const [key2, row] of rows) {
|
|
4484
|
+
this.state.outbox.set(key2, {
|
|
2862
4485
|
...row,
|
|
2863
4486
|
publishedAt: input.publishedAt,
|
|
2864
4487
|
leaseId: null,
|
|
@@ -2874,11 +4497,11 @@ class InMemoryOntologyOutboxStorage {
|
|
|
2874
4497
|
assertNonblank(input.leaseId, "Ontology outbox lease id");
|
|
2875
4498
|
assertTimestamp2(input.availableAt, "Ontology outbox availableAt");
|
|
2876
4499
|
const rows = this.validateLeaseBatch(input.projectId, input.ids, input.leaseId);
|
|
2877
|
-
for (const [
|
|
2878
|
-
this.state.outbox.set(
|
|
4500
|
+
for (const [key2, row] of rows) {
|
|
4501
|
+
this.state.outbox.set(key2, {
|
|
2879
4502
|
...row,
|
|
2880
4503
|
availableAt: input.availableAt,
|
|
2881
|
-
|
|
4504
|
+
lastFailure: input.failure === undefined ? row.lastFailure : structuredClone(input.failure),
|
|
2882
4505
|
leaseId: null,
|
|
2883
4506
|
leaseExpiresAt: null
|
|
2884
4507
|
});
|
|
@@ -2920,12 +4543,12 @@ class InMemoryOntologyOutboxStorage {
|
|
|
2920
4543
|
}
|
|
2921
4544
|
insertBounded(rows, entry, input.limit, ([, left], [, right]) => comparePublishedRows(left, right));
|
|
2922
4545
|
}
|
|
2923
|
-
for (const [
|
|
2924
|
-
this.state.outbox.delete(
|
|
4546
|
+
for (const [key2] of rows)
|
|
4547
|
+
this.state.outbox.delete(key2);
|
|
2925
4548
|
return rows.length;
|
|
2926
4549
|
}
|
|
2927
|
-
requireLease(
|
|
2928
|
-
const row = this.state.outbox.get(
|
|
4550
|
+
requireLease(key2, leaseId) {
|
|
4551
|
+
const row = this.state.outbox.get(key2);
|
|
2929
4552
|
if (!row || row.leaseId !== leaseId || row.leaseExpiresAt === null) {
|
|
2930
4553
|
throw new MaterializationConflictError("outbox-lease", "Ontology outbox lease does not match.");
|
|
2931
4554
|
}
|
|
@@ -2939,8 +4562,8 @@ class InMemoryOntologyOutboxStorage {
|
|
|
2939
4562
|
throw new MaterializationValidationError(`Ontology outbox lease batch repeats event '${id}'.`);
|
|
2940
4563
|
}
|
|
2941
4564
|
seen.add(id);
|
|
2942
|
-
const
|
|
2943
|
-
return [
|
|
4565
|
+
const key2 = outboxKey(projectId, id);
|
|
4566
|
+
return [key2, this.requireLease(key2, leaseId)];
|
|
2944
4567
|
});
|
|
2945
4568
|
}
|
|
2946
4569
|
}
|
|
@@ -2975,8 +4598,8 @@ class InMemoryOntologySourceStorage {
|
|
|
2975
4598
|
return this.runRootOperation(async () => {
|
|
2976
4599
|
assertSourceBeginInput(input);
|
|
2977
4600
|
await this.assertCurrentExecution(input);
|
|
2978
|
-
const
|
|
2979
|
-
const existing = this.state.sourceMaterializations.get(
|
|
4601
|
+
const key2 = sourceMaterializationKey(input.projectId, input.source.projectionId, input.materializationId);
|
|
4602
|
+
const existing = this.state.sourceMaterializations.get(key2);
|
|
2980
4603
|
if (existing) {
|
|
2981
4604
|
if (isExactStagingManifest(sourceMaterializationRecord(existing), input)) {
|
|
2982
4605
|
return sourceMaterializationRecord(existing);
|
|
@@ -3012,7 +4635,7 @@ class InMemoryOntologySourceStorage {
|
|
|
3012
4635
|
rootOrdinals: new Map,
|
|
3013
4636
|
ordinalRoots: new Map
|
|
3014
4637
|
};
|
|
3015
|
-
this.state.sourceMaterializations.set(
|
|
4638
|
+
this.state.sourceMaterializations.set(key2, materialization);
|
|
3016
4639
|
return sourceMaterializationRecord(materialization);
|
|
3017
4640
|
});
|
|
3018
4641
|
}
|
|
@@ -3097,10 +4720,10 @@ class InMemoryOntologySourceStorage {
|
|
|
3097
4720
|
let remaining = input.limit;
|
|
3098
4721
|
let rowsDeleted = 0;
|
|
3099
4722
|
let materializationsDeleted = 0;
|
|
3100
|
-
for (const [
|
|
4723
|
+
for (const [key2, candidate] of candidates) {
|
|
3101
4724
|
if (remaining === 0)
|
|
3102
4725
|
break;
|
|
3103
|
-
const current = this.state.sourceMaterializations.get(
|
|
4726
|
+
const current = this.state.sourceMaterializations.get(key2);
|
|
3104
4727
|
if (current !== candidate)
|
|
3105
4728
|
continue;
|
|
3106
4729
|
current.rootOrdinals.clear();
|
|
@@ -3113,7 +4736,7 @@ class InMemoryOntologySourceStorage {
|
|
|
3113
4736
|
remaining -= 1;
|
|
3114
4737
|
}
|
|
3115
4738
|
if (current.rowsByEntity.size === 0 && remaining > 0) {
|
|
3116
|
-
this.state.sourceMaterializations.delete(
|
|
4739
|
+
this.state.sourceMaterializations.delete(key2);
|
|
3117
4740
|
materializationsDeleted += 1;
|
|
3118
4741
|
remaining -= 1;
|
|
3119
4742
|
}
|
|
@@ -3320,7 +4943,7 @@ class InMemoryOntologyStorage {
|
|
|
3320
4943
|
this.commits = new InMemoryOntologyCommitStorage(this.state, options.runRootOperation);
|
|
3321
4944
|
this.sources = new InMemoryOntologySourceStorage(this.state, options.runRootOperation, options.assertSourceMaterializationExecution);
|
|
3322
4945
|
this.outbox = new InMemoryOntologyOutboxStorage(this.state, options.runRootOperation);
|
|
3323
|
-
this.materializations = new InMemoryOntologyMaterializationStorage(this.state, objects, timeseries, options.getTransactionToken, options.getMaterializationLifecycle, {
|
|
4946
|
+
this.materializations = new InMemoryOntologyMaterializationStorage(this.state, objects, timeseries, options.getTransactionToken, options.getMaterializationLifecycle, options.executionExists, {
|
|
3324
4947
|
beforeRead: (boundary) => this.testHooks.beforeRead?.(boundary),
|
|
3325
4948
|
beforeWrite: (boundary, ordinal) => this.testHooks.beforeWrite?.(boundary, ordinal),
|
|
3326
4949
|
observeBuffer: (boundary, rows) => this.testHooks.observeBuffer?.(boundary, rows),
|
|
@@ -3344,10 +4967,9 @@ class InMemoryOntologyStorage {
|
|
|
3344
4967
|
this.materializations.deactivateTransaction(transactionToken);
|
|
3345
4968
|
}
|
|
3346
4969
|
}
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
name = "PipelineRunError";
|
|
4970
|
+
// src/storage/pipeline-runs/idempotency.ts
|
|
4971
|
+
function canRequeuePipelineRunAfterEnqueueFailure(existing, input) {
|
|
4972
|
+
return existing.status === "failed" && existing.error?.code === "queue.enqueue_failed" && existing.error.retryable && existing.executionId === input.executionId && existing.pipelineId === input.pipelineId;
|
|
3351
4973
|
}
|
|
3352
4974
|
// src/storage/run-listing.ts
|
|
3353
4975
|
function storageKey(projectId, id) {
|
|
@@ -3366,16 +4988,17 @@ function matchesRunListDateFilters(record, filters) {
|
|
|
3366
4988
|
if (filters.statuses && !filters.statuses.has(record.status)) {
|
|
3367
4989
|
return false;
|
|
3368
4990
|
}
|
|
3369
|
-
|
|
4991
|
+
const startedAt = effectiveStartedAt(record);
|
|
4992
|
+
if (filters.startedAfter && startedAt < filters.startedAfter) {
|
|
3370
4993
|
return false;
|
|
3371
4994
|
}
|
|
3372
|
-
if (filters.startedBefore &&
|
|
4995
|
+
if (filters.startedBefore && startedAt > filters.startedBefore) {
|
|
3373
4996
|
return false;
|
|
3374
4997
|
}
|
|
3375
4998
|
return true;
|
|
3376
4999
|
}
|
|
3377
5000
|
function compareStartedAt(left, right, order) {
|
|
3378
|
-
const delta = left.
|
|
5001
|
+
const delta = effectiveStartedAt(left).getTime() - effectiveStartedAt(right).getTime();
|
|
3379
5002
|
if (delta !== 0) {
|
|
3380
5003
|
return order === "asc" ? delta : -delta;
|
|
3381
5004
|
}
|
|
@@ -3406,10 +5029,25 @@ function latestStartedAtByOwnerId(records, ownerIds, ownerIdFor) {
|
|
|
3406
5029
|
return record ? [record] : [];
|
|
3407
5030
|
});
|
|
3408
5031
|
}
|
|
5032
|
+
function effectiveStartedAt(record) {
|
|
5033
|
+
const value = record.startedAt ?? record.queuedAt;
|
|
5034
|
+
if (!value) {
|
|
5035
|
+
throw new Error(`[Sixb] Run '${record.id}' has neither startedAt nor queuedAt.`);
|
|
5036
|
+
}
|
|
5037
|
+
return value;
|
|
5038
|
+
}
|
|
5039
|
+
|
|
5040
|
+
// src/storage/pipeline-runs/types.ts
|
|
5041
|
+
var PIPELINE_RUN_FAILURE_CODES = [
|
|
5042
|
+
"internal.unexpected",
|
|
5043
|
+
"runtime.cancelled",
|
|
5044
|
+
"queue.enqueue_failed",
|
|
5045
|
+
"pipeline.step_failed"
|
|
5046
|
+
];
|
|
3409
5047
|
|
|
3410
5048
|
// src/storage/pipeline-runs/in-memory.ts
|
|
3411
5049
|
function normalizeError2(error) {
|
|
3412
|
-
return error ?
|
|
5050
|
+
return error ? parseSixbFailure(error, PIPELINE_RUN_FAILURE_CODES) : undefined;
|
|
3413
5051
|
}
|
|
3414
5052
|
function assertNonNegativeInteger(value, fieldName) {
|
|
3415
5053
|
if (value !== undefined && (!Number.isInteger(value) || value < 0)) {
|
|
@@ -3418,8 +5056,12 @@ function assertNonNegativeInteger(value, fieldName) {
|
|
|
3418
5056
|
}
|
|
3419
5057
|
|
|
3420
5058
|
class InMemoryPipelineRunStorage {
|
|
5059
|
+
executions;
|
|
3421
5060
|
runs = new Map;
|
|
3422
5061
|
steps = new Map;
|
|
5062
|
+
constructor(executions) {
|
|
5063
|
+
this.executions = executions;
|
|
5064
|
+
}
|
|
3423
5065
|
snapshot() {
|
|
3424
5066
|
return {
|
|
3425
5067
|
runs: structuredClone(this.runs),
|
|
@@ -3428,31 +5070,79 @@ class InMemoryPipelineRunStorage {
|
|
|
3428
5070
|
}
|
|
3429
5071
|
restore(snapshot) {
|
|
3430
5072
|
this.runs.clear();
|
|
3431
|
-
for (const [
|
|
3432
|
-
this.runs.set(
|
|
5073
|
+
for (const [key2, record] of structuredClone(snapshot.runs)) {
|
|
5074
|
+
this.runs.set(key2, record);
|
|
3433
5075
|
}
|
|
3434
5076
|
this.steps.clear();
|
|
3435
|
-
for (const [
|
|
3436
|
-
this.steps.set(
|
|
5077
|
+
for (const [key2, record] of structuredClone(snapshot.steps)) {
|
|
5078
|
+
this.steps.set(key2, record);
|
|
3437
5079
|
}
|
|
3438
5080
|
}
|
|
3439
|
-
async
|
|
3440
|
-
const
|
|
3441
|
-
|
|
5081
|
+
async queue(input) {
|
|
5082
|
+
const key2 = storageKey(input.projectId, input.id);
|
|
5083
|
+
const existing = this.runs.get(key2);
|
|
5084
|
+
if (existing && !canRequeuePipelineRunAfterEnqueueFailure(existing, input)) {
|
|
3442
5085
|
throw new PipelineRunError(`[Sixb] Pipeline run '${input.id}' already exists for project '${input.projectId}'.`);
|
|
3443
5086
|
}
|
|
5087
|
+
if ([...this.runs.values()].some((run) => run.projectId === input.projectId && run.id !== input.id && run.executionId === input.executionId)) {
|
|
5088
|
+
throw new PipelineRunError(`[Sixb] Execution '${input.executionId}' already belongs to another Pipeline run.`);
|
|
5089
|
+
}
|
|
5090
|
+
await assertPipelineRunExecution({
|
|
5091
|
+
executions: this.executions,
|
|
5092
|
+
projectId: input.projectId,
|
|
5093
|
+
executionId: input.executionId,
|
|
5094
|
+
runId: input.id,
|
|
5095
|
+
pipelineId: input.pipelineId
|
|
5096
|
+
});
|
|
5097
|
+
const queuedAt = new Date(input.queuedAt ?? new Date);
|
|
5098
|
+
if (existing) {
|
|
5099
|
+
const next = {
|
|
5100
|
+
...existing,
|
|
5101
|
+
status: "queued",
|
|
5102
|
+
queuedAt,
|
|
5103
|
+
startedAt: undefined,
|
|
5104
|
+
finishedAt: undefined,
|
|
5105
|
+
output: undefined,
|
|
5106
|
+
error: undefined
|
|
5107
|
+
};
|
|
5108
|
+
this.runs.set(key2, cloneRecord(next));
|
|
5109
|
+
return cloneRecord(next);
|
|
5110
|
+
}
|
|
3444
5111
|
const record = {
|
|
3445
5112
|
id: input.id,
|
|
3446
5113
|
projectId: input.projectId,
|
|
5114
|
+
executionId: input.executionId,
|
|
3447
5115
|
pipelineId: input.pipelineId,
|
|
3448
|
-
status: "
|
|
3449
|
-
|
|
5116
|
+
status: "queued",
|
|
5117
|
+
queuedAt
|
|
3450
5118
|
};
|
|
3451
|
-
this.runs.set(
|
|
5119
|
+
this.runs.set(key2, cloneRecord(record));
|
|
3452
5120
|
return cloneRecord(record);
|
|
3453
5121
|
}
|
|
5122
|
+
async start(input) {
|
|
5123
|
+
const key2 = storageKey(input.projectId, input.id);
|
|
5124
|
+
const existing = this.runs.get(key2);
|
|
5125
|
+
if (!existing) {
|
|
5126
|
+
throw new PipelineRunError(`[Sixb] Pipeline run '${input.id}' not found for project '${input.projectId}'.`);
|
|
5127
|
+
}
|
|
5128
|
+
if (existing.status !== "queued") {
|
|
5129
|
+
throw new PipelineRunError(`[Sixb] Pipeline run '${input.id}' cannot start from status '${existing.status}'.`);
|
|
5130
|
+
}
|
|
5131
|
+
const next = {
|
|
5132
|
+
...existing,
|
|
5133
|
+
status: "running",
|
|
5134
|
+
startedAt: new Date(input.startedAt ?? new Date),
|
|
5135
|
+
error: undefined
|
|
5136
|
+
};
|
|
5137
|
+
this.runs.set(key2, cloneRecord(next));
|
|
5138
|
+
return cloneRecord(next);
|
|
5139
|
+
}
|
|
3454
5140
|
async finish(input) {
|
|
3455
|
-
const existing = this.
|
|
5141
|
+
const existing = this.requireExistingPipelineRun(input.projectId, input.id);
|
|
5142
|
+
const enqueueFailure = input.status === "failed" && input.error.code === "queue.enqueue_failed";
|
|
5143
|
+
if (enqueueFailure && existing.status !== "queued" || !enqueueFailure && existing.status !== "running") {
|
|
5144
|
+
throw new PipelineRunError(`[Sixb] Pipeline run '${input.id}' cannot finish from status '${existing.status}'.`);
|
|
5145
|
+
}
|
|
3456
5146
|
const base = {
|
|
3457
5147
|
...existing,
|
|
3458
5148
|
status: input.status,
|
|
@@ -3475,8 +5165,8 @@ class InMemoryPipelineRunStorage {
|
|
|
3475
5165
|
if (pipelineRun.pipelineId !== input.pipelineId) {
|
|
3476
5166
|
throw new PipelineRunError(`[Sixb] Pipeline step run '${input.id}' pipeline '${input.pipelineId}' does not match pipeline run '${input.pipelineRunId}' pipeline '${pipelineRun.pipelineId}'.`);
|
|
3477
5167
|
}
|
|
3478
|
-
const
|
|
3479
|
-
if (this.steps.has(
|
|
5168
|
+
const key2 = storageKey(input.projectId, input.id);
|
|
5169
|
+
if (this.steps.has(key2)) {
|
|
3480
5170
|
throw new PipelineRunError(`[Sixb] Pipeline step run '${input.id}' already exists for project '${input.projectId}'.`);
|
|
3481
5171
|
}
|
|
3482
5172
|
const record = {
|
|
@@ -3491,7 +5181,7 @@ class InMemoryPipelineRunStorage {
|
|
|
3491
5181
|
startedAt: new Date(input.startedAt ?? new Date),
|
|
3492
5182
|
inputs: cloneRecord(input.inputs)
|
|
3493
5183
|
};
|
|
3494
|
-
this.steps.set(
|
|
5184
|
+
this.steps.set(key2, cloneRecord(record));
|
|
3495
5185
|
return cloneRecord(record);
|
|
3496
5186
|
}
|
|
3497
5187
|
async finishStep(input) {
|
|
@@ -3600,17 +5290,12 @@ class InMemoryPipelineRunStorage {
|
|
|
3600
5290
|
}
|
|
3601
5291
|
// src/storage/projection-runs/in-memory.ts
|
|
3602
5292
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
3603
|
-
var
|
|
5293
|
+
var runDirectly3 = async (run) => run();
|
|
3604
5294
|
function projectionRunKey(projectId, id) {
|
|
3605
5295
|
return JSON.stringify([projectId, id]);
|
|
3606
5296
|
}
|
|
3607
5297
|
function compareRuns2(a, b, order) {
|
|
3608
|
-
|
|
3609
|
-
if (delta !== 0)
|
|
3610
|
-
return order === "asc" ? delta : -delta;
|
|
3611
|
-
if (a.id === b.id)
|
|
3612
|
-
return 0;
|
|
3613
|
-
return order === "asc" ? a.id.localeCompare(b.id) : b.id.localeCompare(a.id);
|
|
5298
|
+
return compareStartedAt(a, b, order);
|
|
3614
5299
|
}
|
|
3615
5300
|
|
|
3616
5301
|
class InMemoryProjectionRunStorage {
|
|
@@ -3618,10 +5303,12 @@ class InMemoryProjectionRunStorage {
|
|
|
3618
5303
|
executionTokensByRun = new Map;
|
|
3619
5304
|
runRootOperation;
|
|
3620
5305
|
createExecutionToken;
|
|
3621
|
-
constructor(input
|
|
3622
|
-
this.
|
|
5306
|
+
constructor(input) {
|
|
5307
|
+
this.executions = input.executions;
|
|
5308
|
+
this.runRootOperation = input.runRootOperation ?? runDirectly3;
|
|
3623
5309
|
this.createExecutionToken = input.executionToken ?? randomUUID2;
|
|
3624
5310
|
}
|
|
5311
|
+
executions;
|
|
3625
5312
|
snapshot() {
|
|
3626
5313
|
return structuredClone({
|
|
3627
5314
|
rows: this.rows,
|
|
@@ -3631,25 +5318,71 @@ class InMemoryProjectionRunStorage {
|
|
|
3631
5318
|
restore(snapshot) {
|
|
3632
5319
|
this.rows.clear();
|
|
3633
5320
|
this.executionTokensByRun.clear();
|
|
3634
|
-
for (const [
|
|
3635
|
-
this.rows.set(
|
|
3636
|
-
for (const [
|
|
3637
|
-
this.executionTokensByRun.set(
|
|
5321
|
+
for (const [key2, record] of structuredClone(snapshot.rows))
|
|
5322
|
+
this.rows.set(key2, record);
|
|
5323
|
+
for (const [key2, tokens] of structuredClone(snapshot.executionTokensByRun)) {
|
|
5324
|
+
this.executionTokensByRun.set(key2, tokens);
|
|
3638
5325
|
}
|
|
3639
5326
|
}
|
|
5327
|
+
async queue(input) {
|
|
5328
|
+
return this.runRootOperation(async () => {
|
|
5329
|
+
assertProjectionRunQueueInput(input);
|
|
5330
|
+
this.assertDatasetVersionIsImmutable(input);
|
|
5331
|
+
const key2 = projectionRunKey(input.projectId, input.id);
|
|
5332
|
+
const existing = this.rows.get(key2);
|
|
5333
|
+
if (existing && !canRequeueProjectionRunAfterEnqueueFailure(existing, input)) {
|
|
5334
|
+
throw new ProjectionRunError(`[Sixb] Projection run '${input.id}' already exists for project '${input.projectId}'.`);
|
|
5335
|
+
}
|
|
5336
|
+
if ([...this.rows.values()].some((run) => run.projectId === input.projectId && run.id !== input.id && run.executionId === input.executionId)) {
|
|
5337
|
+
throw new ProjectionRunError(`[Sixb] Execution '${input.executionId}' already belongs to another Projection run.`);
|
|
5338
|
+
}
|
|
5339
|
+
await assertProjectionRunDurableExecution({
|
|
5340
|
+
executions: this.executions,
|
|
5341
|
+
projectId: input.projectId,
|
|
5342
|
+
executionId: input.executionId,
|
|
5343
|
+
runId: input.id,
|
|
5344
|
+
projectionId: input.identity.projectionId,
|
|
5345
|
+
datasetId: input.identity.datasetVersion.datasetId,
|
|
5346
|
+
datasetVersionId: input.identity.datasetVersion.versionId
|
|
5347
|
+
});
|
|
5348
|
+
const record = createProjectionRunRecord(input);
|
|
5349
|
+
this.rows.set(key2, structuredClone(record));
|
|
5350
|
+
return publicProjectionRunRecord(record);
|
|
5351
|
+
});
|
|
5352
|
+
}
|
|
3640
5353
|
async startOrReclaim(input) {
|
|
3641
5354
|
return this.runRootOperation(() => {
|
|
3642
5355
|
assertProjectionRunStartInput(input);
|
|
3643
|
-
|
|
3644
|
-
const
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
const
|
|
3648
|
-
const
|
|
3649
|
-
|
|
5356
|
+
const key2 = projectionRunKey(input.projectId, input.id);
|
|
5357
|
+
const existing = this.rows.get(key2);
|
|
5358
|
+
if (!existing)
|
|
5359
|
+
throw projectionRunNotFound(input.projectId, input.id);
|
|
5360
|
+
const attempt = planProjectionRunReclaim(existing, input).attempt;
|
|
5361
|
+
const executionToken = this.issueExecutionToken(key2, input.id, existing.executionToken);
|
|
5362
|
+
const record = {
|
|
5363
|
+
...existing,
|
|
5364
|
+
status: "running",
|
|
5365
|
+
attempt,
|
|
5366
|
+
executionToken,
|
|
5367
|
+
startedAt: existing.startedAt ?? new Date(input.startedAt ?? new Date),
|
|
5368
|
+
finishedAt: undefined,
|
|
5369
|
+
error: undefined
|
|
5370
|
+
};
|
|
5371
|
+
this.rows.set(key2, structuredClone(record));
|
|
3650
5372
|
return createProjectionRunClaim(record);
|
|
3651
5373
|
});
|
|
3652
5374
|
}
|
|
5375
|
+
async failEnqueue(input) {
|
|
5376
|
+
return this.runRootOperation(() => {
|
|
5377
|
+
const key2 = projectionRunKey(input.projectId, input.id);
|
|
5378
|
+
const existing = this.rows.get(key2);
|
|
5379
|
+
if (!existing)
|
|
5380
|
+
throw projectionRunNotFound(input.projectId, input.id);
|
|
5381
|
+
const next = failProjectionRunEnqueue(existing, input);
|
|
5382
|
+
this.rows.set(key2, structuredClone(next));
|
|
5383
|
+
return publicProjectionRunRecord(next);
|
|
5384
|
+
});
|
|
5385
|
+
}
|
|
3653
5386
|
async lockForMaterialization(input) {
|
|
3654
5387
|
return this.runRootOperation(() => publicProjectionRunRecord(this.requireExecution(input)));
|
|
3655
5388
|
}
|
|
@@ -3733,7 +5466,11 @@ class InMemoryProjectionRunStorage {
|
|
|
3733
5466
|
const limit = input.limit ?? this.rows.size;
|
|
3734
5467
|
const statuses = input.statuses ? new Set(input.statuses) : null;
|
|
3735
5468
|
const objectTypeIds = input.objectTypeIds ? new Set(input.objectTypeIds) : null;
|
|
3736
|
-
const filtered = [...this.rows.values()].filter((record) => record.projectId === input.projectId).filter((record) => input.projectionId ? record.identity.projectionId === input.projectionId : true).filter((record) => input.projectionKind ? record.identity.projectionKind === input.projectionKind : true).filter((record) => input.datasetId ? record.identity.datasetVersion.datasetId === input.datasetId : true).filter((record) => input.datasetVersionId ? record.identity.datasetVersion.versionId === input.datasetVersionId : true).filter((record) => objectTypeIds ? projectionRunObjectTypesVisible(record, (id) => objectTypeIds.has(id)) : true).filter((record) => statuses ? statuses.has(record.status) : true).filter((record) =>
|
|
5469
|
+
const filtered = [...this.rows.values()].filter((record) => record.projectId === input.projectId).filter((record) => input.projectionId ? record.identity.projectionId === input.projectionId : true).filter((record) => input.projectionKind ? record.identity.projectionKind === input.projectionKind : true).filter((record) => input.datasetId ? record.identity.datasetVersion.datasetId === input.datasetId : true).filter((record) => input.datasetVersionId ? record.identity.datasetVersion.versionId === input.datasetVersionId : true).filter((record) => objectTypeIds ? projectionRunObjectTypesVisible(record, (id) => objectTypeIds.has(id)) : true).filter((record) => statuses ? statuses.has(record.status) : true).filter((record) => matchesRunListDateFilters(record, {
|
|
5470
|
+
statuses,
|
|
5471
|
+
startedAfter: input.startedAfter,
|
|
5472
|
+
startedBefore: input.startedBefore
|
|
5473
|
+
})).sort((left, right) => compareRuns2(left, right, order));
|
|
3737
5474
|
const total = filtered.length;
|
|
3738
5475
|
const runs = filtered.slice(offset, offset + limit).map(publicProjectionRunRecord);
|
|
3739
5476
|
return { runs, hasMore: offset + runs.length < total, total };
|
|
@@ -3752,22 +5489,22 @@ class InMemoryProjectionRunStorage {
|
|
|
3752
5489
|
}
|
|
3753
5490
|
}
|
|
3754
5491
|
}
|
|
3755
|
-
issueExecutionToken(
|
|
5492
|
+
issueExecutionToken(key2, runId, currentToken) {
|
|
3756
5493
|
const executionToken = this.createExecutionToken();
|
|
3757
5494
|
assertProjectionRunNonEmpty(executionToken, "executionToken");
|
|
3758
|
-
const usedTokens = this.executionTokensByRun.get(
|
|
5495
|
+
const usedTokens = this.executionTokensByRun.get(key2) ?? new Set;
|
|
3759
5496
|
if (currentToken)
|
|
3760
5497
|
usedTokens.add(currentToken);
|
|
3761
5498
|
if (usedTokens.has(executionToken)) {
|
|
3762
5499
|
throw new ProjectionRunError(`[Sixb] Projection run '${runId}' execution token was already used.`);
|
|
3763
5500
|
}
|
|
3764
5501
|
usedTokens.add(executionToken);
|
|
3765
|
-
this.executionTokensByRun.set(
|
|
5502
|
+
this.executionTokensByRun.set(key2, usedTokens);
|
|
3766
5503
|
return executionToken;
|
|
3767
5504
|
}
|
|
3768
5505
|
requireExecution(input) {
|
|
3769
5506
|
const record = this.requireRunning(input.projectId, input.id);
|
|
3770
|
-
|
|
5507
|
+
assertProjectionRunAttempt(record, input);
|
|
3771
5508
|
return record;
|
|
3772
5509
|
}
|
|
3773
5510
|
requireTelemetryExecution(input) {
|
|
@@ -3827,8 +5564,8 @@ class InMemoryRulesStorage {
|
|
|
3827
5564
|
}
|
|
3828
5565
|
restore(snapshot) {
|
|
3829
5566
|
this.active.clear();
|
|
3830
|
-
for (const [
|
|
3831
|
-
this.active.set(
|
|
5567
|
+
for (const [key2, record] of structuredClone(snapshot)) {
|
|
5568
|
+
this.active.set(key2, record);
|
|
3832
5569
|
}
|
|
3833
5570
|
}
|
|
3834
5571
|
async getActive(params) {
|
|
@@ -3899,10 +5636,18 @@ class InMemoryRulesStorage {
|
|
|
3899
5636
|
}
|
|
3900
5637
|
}
|
|
3901
5638
|
}
|
|
3902
|
-
// src/storage/sync-runs/
|
|
3903
|
-
|
|
3904
|
-
|
|
5639
|
+
// src/storage/sync-runs/idempotency.ts
|
|
5640
|
+
function canRequeueSyncRunAfterEnqueueFailure(existing, input) {
|
|
5641
|
+
return existing.status === "failed" && existing.error?.code === "queue.enqueue_failed" && existing.error.retryable && existing.executionId === input.executionId && existing.syncId === input.syncId && existing.datasetId === input.datasetId && existing.mode === input.mode && existing.expectedLatestVersionId === input.expectedLatestVersionId && existing.commitMessage === input.commitMessage;
|
|
3905
5642
|
}
|
|
5643
|
+
// src/storage/sync-runs/types.ts
|
|
5644
|
+
var SYNC_RUN_FAILURE_CODES = [
|
|
5645
|
+
"internal.unexpected",
|
|
5646
|
+
"runtime.cancelled",
|
|
5647
|
+
"queue.enqueue_failed",
|
|
5648
|
+
"sync.execution_failed"
|
|
5649
|
+
];
|
|
5650
|
+
|
|
3906
5651
|
// src/storage/sync-runs/in-memory.ts
|
|
3907
5652
|
function syncRunKey(projectId, id) {
|
|
3908
5653
|
return `${projectId}:${id}`;
|
|
@@ -3914,51 +5659,105 @@ function normalizeCheckpoint(checkpoint) {
|
|
|
3914
5659
|
return checkpoint !== undefined ? cloneJsonValue(checkpoint) : undefined;
|
|
3915
5660
|
}
|
|
3916
5661
|
function normalizeError3(error) {
|
|
3917
|
-
return error ?
|
|
5662
|
+
return error ? parseSixbFailure(error, SYNC_RUN_FAILURE_CODES) : undefined;
|
|
3918
5663
|
}
|
|
3919
5664
|
|
|
3920
5665
|
class InMemorySyncRunStorage {
|
|
5666
|
+
executions;
|
|
3921
5667
|
rows = new Map;
|
|
5668
|
+
constructor(executions) {
|
|
5669
|
+
this.executions = executions;
|
|
5670
|
+
}
|
|
3922
5671
|
snapshot() {
|
|
3923
5672
|
return structuredClone(this.rows);
|
|
3924
5673
|
}
|
|
3925
5674
|
restore(snapshot) {
|
|
3926
5675
|
this.rows.clear();
|
|
3927
|
-
for (const [
|
|
3928
|
-
this.rows.set(
|
|
5676
|
+
for (const [key2, record] of structuredClone(snapshot)) {
|
|
5677
|
+
this.rows.set(key2, record);
|
|
3929
5678
|
}
|
|
3930
5679
|
}
|
|
3931
|
-
async
|
|
3932
|
-
const
|
|
3933
|
-
|
|
5680
|
+
async queue(input) {
|
|
5681
|
+
const key2 = syncRunKey(input.projectId, input.id);
|
|
5682
|
+
const existing = this.rows.get(key2);
|
|
5683
|
+
if (existing && !canRequeueSyncRunAfterEnqueueFailure(existing, input)) {
|
|
3934
5684
|
throw new SyncRunError(`[Sixb] Sync run '${input.id}' already exists for project '${input.projectId}'.`);
|
|
3935
5685
|
}
|
|
5686
|
+
if ([...this.rows.values()].some((run) => run.projectId === input.projectId && run.id !== input.id && run.executionId === input.executionId)) {
|
|
5687
|
+
throw new SyncRunError(`[Sixb] Execution '${input.executionId}' already belongs to another Sync run.`);
|
|
5688
|
+
}
|
|
5689
|
+
await assertSyncRunExecution({
|
|
5690
|
+
executions: this.executions,
|
|
5691
|
+
projectId: input.projectId,
|
|
5692
|
+
executionId: input.executionId,
|
|
5693
|
+
runId: input.id,
|
|
5694
|
+
syncId: input.syncId
|
|
5695
|
+
});
|
|
5696
|
+
const queuedAt = new Date(input.queuedAt ?? new Date);
|
|
5697
|
+
if (existing) {
|
|
5698
|
+
const next = {
|
|
5699
|
+
...existing,
|
|
5700
|
+
status: "queued",
|
|
5701
|
+
queuedAt,
|
|
5702
|
+
startedAt: undefined,
|
|
5703
|
+
finishedAt: undefined,
|
|
5704
|
+
rowsRead: undefined,
|
|
5705
|
+
output: undefined,
|
|
5706
|
+
error: undefined,
|
|
5707
|
+
checkpoint: undefined
|
|
5708
|
+
};
|
|
5709
|
+
this.rows.set(key2, structuredClone(next));
|
|
5710
|
+
return cloneSyncRunRecord(next);
|
|
5711
|
+
}
|
|
3936
5712
|
const record = {
|
|
3937
5713
|
id: input.id,
|
|
3938
5714
|
projectId: input.projectId,
|
|
5715
|
+
executionId: input.executionId,
|
|
3939
5716
|
syncId: input.syncId,
|
|
3940
5717
|
datasetId: input.datasetId,
|
|
3941
5718
|
mode: input.mode,
|
|
3942
|
-
status: "
|
|
3943
|
-
|
|
5719
|
+
status: "queued",
|
|
5720
|
+
queuedAt,
|
|
3944
5721
|
expectedLatestVersionId: input.expectedLatestVersionId,
|
|
3945
5722
|
commitMessage: input.commitMessage
|
|
3946
5723
|
};
|
|
3947
|
-
this.rows.set(
|
|
5724
|
+
this.rows.set(key2, structuredClone(record));
|
|
3948
5725
|
return cloneSyncRunRecord(record);
|
|
3949
5726
|
}
|
|
5727
|
+
async start(input) {
|
|
5728
|
+
const key2 = syncRunKey(input.projectId, input.id);
|
|
5729
|
+
const existing = this.rows.get(key2);
|
|
5730
|
+
if (!existing) {
|
|
5731
|
+
throw new SyncRunError(`[Sixb] Sync run '${input.id}' not found for project '${input.projectId}'.`);
|
|
5732
|
+
}
|
|
5733
|
+
if (existing.status !== "queued") {
|
|
5734
|
+
throw new SyncRunError(`[Sixb] Sync run '${input.id}' cannot start from status '${existing.status}'.`);
|
|
5735
|
+
}
|
|
5736
|
+
const next = {
|
|
5737
|
+
...existing,
|
|
5738
|
+
status: "running",
|
|
5739
|
+
startedAt: new Date(input.startedAt ?? new Date),
|
|
5740
|
+
error: undefined
|
|
5741
|
+
};
|
|
5742
|
+
this.rows.set(key2, structuredClone(next));
|
|
5743
|
+
return cloneSyncRunRecord(next);
|
|
5744
|
+
}
|
|
3950
5745
|
async finish(input) {
|
|
3951
|
-
const
|
|
3952
|
-
const existing = this.rows.get(
|
|
5746
|
+
const key2 = syncRunKey(input.projectId, input.id);
|
|
5747
|
+
const existing = this.rows.get(key2);
|
|
3953
5748
|
if (!existing) {
|
|
3954
5749
|
throw new SyncRunError(`[Sixb] Sync run '${input.id}' not found for project '${input.projectId}'.`);
|
|
3955
5750
|
}
|
|
5751
|
+
const enqueueFailure = input.status === "failed" && input.error.code === "queue.enqueue_failed";
|
|
5752
|
+
if (enqueueFailure && existing.status !== "queued" || !enqueueFailure && existing.status !== "running") {
|
|
5753
|
+
throw new SyncRunError(`[Sixb] Sync run '${input.id}' cannot finish from status '${existing.status}'.`);
|
|
5754
|
+
}
|
|
3956
5755
|
if (input.status === "succeeded") {
|
|
3957
5756
|
if (input.output && input.output.datasetId !== existing.datasetId) {
|
|
3958
5757
|
throw new SyncRunError(`[Sixb] Sync run '${input.id}' output dataset '${input.output.datasetId}' does not match '${existing.datasetId}'.`);
|
|
3959
5758
|
}
|
|
3960
|
-
if (!input.output &&
|
|
3961
|
-
throw new SyncRunError(`[Sixb] Sync run '${input.id}' may omit its output only for an
|
|
5759
|
+
if (!input.output && input.rowsRead !== 0 && existing.mode !== "merge") {
|
|
5760
|
+
throw new SyncRunError(`[Sixb] Sync run '${input.id}' may omit its output with rows read only for an initial merge no-op.`);
|
|
3962
5761
|
}
|
|
3963
5762
|
}
|
|
3964
5763
|
const base = {
|
|
@@ -3979,7 +5778,7 @@ class InMemorySyncRunStorage {
|
|
|
3979
5778
|
error: normalizeError3(input.error),
|
|
3980
5779
|
checkpoint: undefined
|
|
3981
5780
|
};
|
|
3982
|
-
this.rows.set(
|
|
5781
|
+
this.rows.set(key2, structuredClone(next));
|
|
3983
5782
|
return cloneSyncRunRecord(next);
|
|
3984
5783
|
}
|
|
3985
5784
|
async getById(params) {
|
|
@@ -4054,133 +5853,85 @@ function throwNestedStorageTransaction() {
|
|
|
4054
5853
|
code: "nested_transaction"
|
|
4055
5854
|
});
|
|
4056
5855
|
}
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
5856
|
+
// src/storage/webhook-runs/types.ts
|
|
5857
|
+
var WEBHOOK_RUN_FAILURE_CODES = [
|
|
5858
|
+
"internal.unexpected",
|
|
5859
|
+
"webhook.delivery_failed",
|
|
5860
|
+
"webhook.delivery_rejected"
|
|
5861
|
+
];
|
|
5862
|
+
function canRetryWebhookRun(run) {
|
|
5863
|
+
return run.status === "failed" && run.error?.retryable === true;
|
|
4061
5864
|
}
|
|
4062
5865
|
|
|
4063
|
-
class InMemoryWebhookDeliveryStorage {
|
|
4064
|
-
deliveries = new Map;
|
|
4065
|
-
snapshot() {
|
|
4066
|
-
return structuredClone(this.deliveries);
|
|
4067
|
-
}
|
|
4068
|
-
restore(snapshot) {
|
|
4069
|
-
this.deliveries.clear();
|
|
4070
|
-
for (const [key, record] of structuredClone(snapshot)) {
|
|
4071
|
-
this.deliveries.set(key, record);
|
|
4072
|
-
}
|
|
4073
|
-
}
|
|
4074
|
-
async claim(input) {
|
|
4075
|
-
const key = serializeKey(input);
|
|
4076
|
-
const existing = this.deliveries.get(key);
|
|
4077
|
-
if (existing?.status === "completed") {
|
|
4078
|
-
return {
|
|
4079
|
-
...cloneDeliveryRecord(existing),
|
|
4080
|
-
claimResult: "duplicate"
|
|
4081
|
-
};
|
|
4082
|
-
}
|
|
4083
|
-
if (existing?.status === "in_progress") {
|
|
4084
|
-
return {
|
|
4085
|
-
...cloneDeliveryRecord(existing),
|
|
4086
|
-
claimResult: "in_progress"
|
|
4087
|
-
};
|
|
4088
|
-
}
|
|
4089
|
-
const next = {
|
|
4090
|
-
projectId: input.projectId,
|
|
4091
|
-
connectorId: input.connectorId,
|
|
4092
|
-
webhookId: input.webhookId,
|
|
4093
|
-
idempotencyKey: input.idempotencyKey,
|
|
4094
|
-
status: "in_progress",
|
|
4095
|
-
receivedAt: input.receivedAt
|
|
4096
|
-
};
|
|
4097
|
-
this.deliveries.set(key, structuredClone(next));
|
|
4098
|
-
return {
|
|
4099
|
-
...cloneDeliveryRecord(next),
|
|
4100
|
-
claimResult: "claimed"
|
|
4101
|
-
};
|
|
4102
|
-
}
|
|
4103
|
-
async complete(input) {
|
|
4104
|
-
const key = serializeKey(input);
|
|
4105
|
-
const next = {
|
|
4106
|
-
projectId: input.projectId,
|
|
4107
|
-
connectorId: input.connectorId,
|
|
4108
|
-
webhookId: input.webhookId,
|
|
4109
|
-
idempotencyKey: input.idempotencyKey,
|
|
4110
|
-
...this.deliveries.get(key),
|
|
4111
|
-
status: "completed",
|
|
4112
|
-
completedAt: input.completedAt,
|
|
4113
|
-
failedAt: undefined,
|
|
4114
|
-
error: undefined
|
|
4115
|
-
};
|
|
4116
|
-
this.deliveries.set(key, structuredClone(next));
|
|
4117
|
-
return cloneDeliveryRecord(next);
|
|
4118
|
-
}
|
|
4119
|
-
async fail(input) {
|
|
4120
|
-
const key = serializeKey(input);
|
|
4121
|
-
const next = {
|
|
4122
|
-
projectId: input.projectId,
|
|
4123
|
-
connectorId: input.connectorId,
|
|
4124
|
-
webhookId: input.webhookId,
|
|
4125
|
-
idempotencyKey: input.idempotencyKey,
|
|
4126
|
-
...this.deliveries.get(key),
|
|
4127
|
-
status: "failed",
|
|
4128
|
-
failedAt: input.failedAt,
|
|
4129
|
-
error: input.error,
|
|
4130
|
-
completedAt: undefined
|
|
4131
|
-
};
|
|
4132
|
-
this.deliveries.set(key, structuredClone(next));
|
|
4133
|
-
return cloneDeliveryRecord(next);
|
|
4134
|
-
}
|
|
4135
|
-
}
|
|
4136
|
-
function serializeKey(key) {
|
|
4137
|
-
return JSON.stringify([key.projectId, key.connectorId, key.webhookId, key.idempotencyKey]);
|
|
4138
|
-
}
|
|
4139
|
-
// src/storage/webhook-runs/errors.ts
|
|
4140
|
-
class WebhookRunError extends Error {
|
|
4141
|
-
name = "WebhookRunError";
|
|
4142
|
-
}
|
|
4143
5866
|
// src/storage/webhook-runs/in-memory.ts
|
|
4144
5867
|
class InMemoryWebhookRunStorage {
|
|
5868
|
+
executions;
|
|
4145
5869
|
runs = new Map;
|
|
5870
|
+
constructor(executions) {
|
|
5871
|
+
this.executions = executions;
|
|
5872
|
+
}
|
|
4146
5873
|
snapshot() {
|
|
4147
5874
|
return structuredClone(this.runs);
|
|
4148
5875
|
}
|
|
4149
5876
|
restore(snapshot) {
|
|
4150
5877
|
this.runs.clear();
|
|
4151
|
-
for (const [
|
|
4152
|
-
this.runs.set(
|
|
5878
|
+
for (const [key2, record] of structuredClone(snapshot)) {
|
|
5879
|
+
this.runs.set(key2, record);
|
|
4153
5880
|
}
|
|
4154
5881
|
}
|
|
4155
5882
|
async start(input) {
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
5883
|
+
await assertWebhookRunExecution({
|
|
5884
|
+
executions: this.executions,
|
|
5885
|
+
projectId: input.projectId,
|
|
5886
|
+
executionId: input.executionId,
|
|
5887
|
+
runId: input.id,
|
|
5888
|
+
route: input.route
|
|
5889
|
+
});
|
|
5890
|
+
const key2 = storageKey(input.projectId, input.id);
|
|
5891
|
+
if (this.runs.has(key2) || this.findByDelivery(input)) {
|
|
5892
|
+
throw new WebhookRunError(`[Sixb] Webhook run '${input.id}' or delivery key already exists for project '${input.projectId}'.`, "duplicate_run");
|
|
4159
5893
|
}
|
|
4160
5894
|
const record = {
|
|
4161
5895
|
id: input.id,
|
|
4162
5896
|
projectId: input.projectId,
|
|
5897
|
+
executionId: input.executionId,
|
|
4163
5898
|
connectorId: input.connectorId,
|
|
4164
5899
|
webhookId: input.webhookId,
|
|
4165
5900
|
status: "running",
|
|
4166
5901
|
method: input.method,
|
|
4167
5902
|
route: input.route,
|
|
4168
|
-
startedAt: new Date(input.startedAt ?? new Date)
|
|
5903
|
+
startedAt: new Date(input.startedAt ?? new Date),
|
|
5904
|
+
requestBodyBytes: input.requestBodyBytes,
|
|
5905
|
+
requestBodySha256: input.requestBodySha256,
|
|
5906
|
+
idempotencyKey: input.idempotencyKey
|
|
4169
5907
|
};
|
|
4170
|
-
this.runs.set(
|
|
5908
|
+
this.runs.set(key2, cloneRecord(record));
|
|
4171
5909
|
return cloneRecord(record);
|
|
4172
5910
|
}
|
|
5911
|
+
async restart(input) {
|
|
5912
|
+
const existing = this.requireWebhookRun(input.projectId, input.id);
|
|
5913
|
+
if (!canRetryWebhookRun(existing)) {
|
|
5914
|
+
throw new WebhookRunError(`[Sixb] Webhook run '${input.id}' cannot restart from status '${existing.status}'.`, "invalid_transition");
|
|
5915
|
+
}
|
|
5916
|
+
const next = {
|
|
5917
|
+
...existing,
|
|
5918
|
+
status: "running",
|
|
5919
|
+
startedAt: new Date(input.startedAt ?? new Date),
|
|
5920
|
+
finishedAt: undefined,
|
|
5921
|
+
responseStatus: undefined,
|
|
5922
|
+
error: undefined
|
|
5923
|
+
};
|
|
5924
|
+
this.runs.set(storageKey(input.projectId, input.id), cloneRecord(next));
|
|
5925
|
+
return cloneRecord(next);
|
|
5926
|
+
}
|
|
4173
5927
|
async finish(input) {
|
|
4174
5928
|
const existing = this.requireRunningWebhookRun(input.projectId, input.id);
|
|
4175
5929
|
const next = {
|
|
4176
5930
|
...existing,
|
|
4177
5931
|
status: input.status,
|
|
4178
5932
|
finishedAt: new Date(input.finishedAt ?? new Date),
|
|
4179
|
-
requestBodyBytes: input.requestBodyBytes,
|
|
4180
5933
|
responseStatus: input.responseStatus,
|
|
4181
|
-
|
|
4182
|
-
deliveryClaimResult: input.deliveryClaimResult,
|
|
4183
|
-
error: input.status === "succeeded" ? undefined : input.error
|
|
5934
|
+
error: input.status === "failed" ? parseSixbFailure(input.error, WEBHOOK_RUN_FAILURE_CODES) : undefined
|
|
4184
5935
|
};
|
|
4185
5936
|
this.runs.set(storageKey(input.projectId, input.id), cloneRecord(next));
|
|
4186
5937
|
return cloneRecord(next);
|
|
@@ -4189,6 +5940,10 @@ class InMemoryWebhookRunStorage {
|
|
|
4189
5940
|
const record = this.runs.get(storageKey(params.projectId, params.id));
|
|
4190
5941
|
return record ? cloneRecord(record) : null;
|
|
4191
5942
|
}
|
|
5943
|
+
async getByDelivery(input) {
|
|
5944
|
+
const record = this.findByDelivery(input);
|
|
5945
|
+
return record ? cloneRecord(record) : null;
|
|
5946
|
+
}
|
|
4192
5947
|
async list(input) {
|
|
4193
5948
|
if (hasEmptyStatuses(input)) {
|
|
4194
5949
|
return {
|
|
@@ -4211,16 +5966,25 @@ class InMemoryWebhookRunStorage {
|
|
|
4211
5966
|
total
|
|
4212
5967
|
};
|
|
4213
5968
|
}
|
|
4214
|
-
|
|
5969
|
+
requireWebhookRun(projectId, id) {
|
|
4215
5970
|
const record = this.runs.get(storageKey(projectId, id));
|
|
4216
5971
|
if (!record) {
|
|
4217
|
-
throw new WebhookRunError(`[Sixb] Webhook run '${id}' not found for project '${projectId}'
|
|
5972
|
+
throw new WebhookRunError(`[Sixb] Webhook run '${id}' not found for project '${projectId}'.`, "not_found");
|
|
4218
5973
|
}
|
|
5974
|
+
return record;
|
|
5975
|
+
}
|
|
5976
|
+
requireRunningWebhookRun(projectId, id) {
|
|
5977
|
+
const record = this.requireWebhookRun(projectId, id);
|
|
4219
5978
|
if (record.status !== "running") {
|
|
4220
|
-
throw new WebhookRunError(`[Sixb] Webhook run '${id}' for project '${projectId}' is already terminal
|
|
5979
|
+
throw new WebhookRunError(`[Sixb] Webhook run '${id}' for project '${projectId}' is already terminal.`, "invalid_transition");
|
|
4221
5980
|
}
|
|
4222
5981
|
return record;
|
|
4223
5982
|
}
|
|
5983
|
+
findByDelivery(input) {
|
|
5984
|
+
if (input.idempotencyKey === undefined)
|
|
5985
|
+
return;
|
|
5986
|
+
return [...this.runs.values()].find((run) => run.projectId === input.projectId && run.connectorId === input.connectorId && run.webhookId === input.webhookId && run.idempotencyKey === input.idempotencyKey);
|
|
5987
|
+
}
|
|
4224
5988
|
}
|
|
4225
5989
|
// src/storage/workflow-interventions/errors.ts
|
|
4226
5990
|
class WorkflowInterventionError extends Error {
|
|
@@ -4240,14 +6004,14 @@ class InMemoryWorkflowInterventionStorage {
|
|
|
4240
6004
|
}
|
|
4241
6005
|
restore(snapshot) {
|
|
4242
6006
|
this.interventions.clear();
|
|
4243
|
-
for (const [
|
|
4244
|
-
this.interventions.set(
|
|
6007
|
+
for (const [key2, record] of structuredClone(snapshot)) {
|
|
6008
|
+
this.interventions.set(key2, record);
|
|
4245
6009
|
}
|
|
4246
6010
|
}
|
|
4247
6011
|
async create(input) {
|
|
4248
6012
|
assertNonNegativeInteger2(input.nodeIndex, "nodeIndex");
|
|
4249
|
-
const
|
|
4250
|
-
if (this.interventions.has(
|
|
6013
|
+
const key2 = storageKey(input.projectId, input.id);
|
|
6014
|
+
if (this.interventions.has(key2)) {
|
|
4251
6015
|
throw new WorkflowInterventionError(`[Sixb] Workflow intervention '${input.id}' already exists for project '${input.projectId}'.`);
|
|
4252
6016
|
}
|
|
4253
6017
|
const record = {
|
|
@@ -4266,7 +6030,7 @@ class InMemoryWorkflowInterventionStorage {
|
|
|
4266
6030
|
requestedAt: new Date(input.requestedAt ?? new Date),
|
|
4267
6031
|
expiresAt: input.expiresAt ? new Date(input.expiresAt) : undefined
|
|
4268
6032
|
};
|
|
4269
|
-
this.interventions.set(
|
|
6033
|
+
this.interventions.set(key2, cloneRecord(record));
|
|
4270
6034
|
return cloneRecord(record);
|
|
4271
6035
|
}
|
|
4272
6036
|
async submit(input) {
|
|
@@ -4346,11 +6110,20 @@ function compareRequestedAt(left, right, order) {
|
|
|
4346
6110
|
}
|
|
4347
6111
|
return order === "asc" ? left.id.localeCompare(right.id) : right.id.localeCompare(left.id);
|
|
4348
6112
|
}
|
|
4349
|
-
// src/storage/workflow-runs/
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
6113
|
+
// src/storage/workflow-runs/types.ts
|
|
6114
|
+
var WORKFLOW_RUN_FAILURE_CODES = [
|
|
6115
|
+
"internal.unexpected",
|
|
6116
|
+
"runtime.cancelled",
|
|
6117
|
+
"workflow.node_failed"
|
|
6118
|
+
];
|
|
6119
|
+
|
|
4353
6120
|
// src/storage/workflow-runs/in-memory.ts
|
|
6121
|
+
function normalizeFailure2(failure) {
|
|
6122
|
+
return failure ? parseSixbFailure(failure, WORKFLOW_RUN_FAILURE_CODES) : undefined;
|
|
6123
|
+
}
|
|
6124
|
+
function normalizeAgentFailure(failure) {
|
|
6125
|
+
return failure ? parseSixbFailure(failure, AGENT_RUN_FAILURE_CODES) : undefined;
|
|
6126
|
+
}
|
|
4354
6127
|
function assertNonNegativeInteger3(value, fieldName) {
|
|
4355
6128
|
if (!Number.isInteger(value) || value < 0) {
|
|
4356
6129
|
throw new WorkflowRunError(`[Sixb] Workflow run ${fieldName} must be a non-negative integer.`);
|
|
@@ -4358,18 +6131,21 @@ function assertNonNegativeInteger3(value, fieldName) {
|
|
|
4358
6131
|
}
|
|
4359
6132
|
|
|
4360
6133
|
class InMemoryWorkflowRunStorage {
|
|
6134
|
+
executions;
|
|
4361
6135
|
nodes;
|
|
4362
6136
|
agentNodes;
|
|
4363
6137
|
runs = new Map;
|
|
4364
|
-
constructor() {
|
|
6138
|
+
constructor(executions) {
|
|
6139
|
+
this.executions = executions;
|
|
4365
6140
|
this.nodes = new InMemoryWorkflowNodeRunStorage({
|
|
4366
6141
|
requireRunningWorkflowRun: (projectId, id) => this.requireRunningWorkflowRun(projectId, id),
|
|
4367
6142
|
requireActiveWorkflowRun: (projectId, id) => this.requireActiveWorkflowRun(projectId, id),
|
|
4368
6143
|
assertExecutionOwnership: (projectId, id, token) => this.assertExecutionOwnership(projectId, id, token)
|
|
4369
6144
|
});
|
|
4370
6145
|
this.agentNodes = new InMemoryWorkflowAgentNodeRunStorage({
|
|
4371
|
-
requireAgentNodeRun: (projectId, id) => this.nodes.requireAgentNodeRun(projectId, id)
|
|
4372
|
-
|
|
6146
|
+
requireAgentNodeRun: (projectId, id) => this.nodes.requireAgentNodeRun(projectId, id),
|
|
6147
|
+
requireWorkflowRun: (projectId, id) => this.requireExistingWorkflowRun(projectId, id)
|
|
6148
|
+
}, this.executions);
|
|
4373
6149
|
}
|
|
4374
6150
|
snapshot() {
|
|
4375
6151
|
return {
|
|
@@ -4380,71 +6156,60 @@ class InMemoryWorkflowRunStorage {
|
|
|
4380
6156
|
}
|
|
4381
6157
|
restore(snapshot) {
|
|
4382
6158
|
this.runs.clear();
|
|
4383
|
-
for (const [
|
|
4384
|
-
this.runs.set(
|
|
6159
|
+
for (const [key2, record] of structuredClone(snapshot.runs)) {
|
|
6160
|
+
this.runs.set(key2, record);
|
|
4385
6161
|
}
|
|
4386
6162
|
this.nodes.restore(snapshot.nodes);
|
|
4387
6163
|
this.agentNodes.restore(snapshot.agentNodes);
|
|
4388
6164
|
}
|
|
4389
6165
|
async queue(input) {
|
|
4390
|
-
const
|
|
4391
|
-
if (this.runs.has(
|
|
6166
|
+
const key2 = storageKey(input.projectId, input.id);
|
|
6167
|
+
if (this.runs.has(key2)) {
|
|
4392
6168
|
throw new WorkflowRunError(`[Sixb] Workflow run '${input.id}' already exists for project '${input.projectId}'.`);
|
|
4393
6169
|
}
|
|
6170
|
+
if ([...this.runs.values()].some((run) => run.projectId === input.projectId && run.executionId === input.executionId)) {
|
|
6171
|
+
throw new WorkflowRunError(`[Sixb] Execution '${input.executionId}' already belongs to another workflow run.`);
|
|
6172
|
+
}
|
|
6173
|
+
await assertWorkflowRunExecution({
|
|
6174
|
+
executions: this.executions,
|
|
6175
|
+
projectId: input.projectId,
|
|
6176
|
+
executionId: input.executionId,
|
|
6177
|
+
runId: input.id,
|
|
6178
|
+
workflowId: input.workflowId
|
|
6179
|
+
});
|
|
4394
6180
|
const queuedAt = new Date(input.queuedAt ?? new Date);
|
|
4395
6181
|
const record = {
|
|
4396
6182
|
id: input.id,
|
|
4397
6183
|
projectId: input.projectId,
|
|
6184
|
+
executionId: input.executionId,
|
|
4398
6185
|
workflowId: input.workflowId,
|
|
4399
6186
|
status: "queued",
|
|
4400
6187
|
input: cloneRecord(input.input),
|
|
4401
6188
|
queuedAt,
|
|
4402
6189
|
startedAt: queuedAt,
|
|
4403
6190
|
attempt: 0,
|
|
4404
|
-
|
|
4405
|
-
...input.source ? { source: cloneRecord(input.source) } : {}
|
|
6191
|
+
requesterGroupIds: normalizeRequesterGroupIds(input.requesterGroupIds)
|
|
4406
6192
|
};
|
|
4407
|
-
this.runs.set(
|
|
6193
|
+
this.runs.set(key2, cloneRecord(record));
|
|
4408
6194
|
return cloneRecord(record);
|
|
4409
6195
|
}
|
|
4410
6196
|
async start(input) {
|
|
4411
|
-
const
|
|
4412
|
-
const existing = this.runs.get(
|
|
4413
|
-
if (existing) {
|
|
4414
|
-
|
|
4415
|
-
throw new WorkflowRunError(`[Sixb] Workflow run '${input.id}' already exists for project '${input.projectId}'.`);
|
|
4416
|
-
}
|
|
4417
|
-
if (existing.workflowId !== input.workflowId) {
|
|
4418
|
-
throw new WorkflowRunError(`[Sixb] Workflow run '${input.id}' workflow '${input.workflowId}' does not match existing workflow '${existing.workflowId}'.`);
|
|
4419
|
-
}
|
|
4420
|
-
const next = {
|
|
4421
|
-
...existing,
|
|
4422
|
-
status: "running",
|
|
4423
|
-
input: cloneRecord(input.input),
|
|
4424
|
-
startedAt: new Date(input.startedAt ?? new Date),
|
|
4425
|
-
finishedAt: undefined,
|
|
4426
|
-
error: undefined,
|
|
4427
|
-
source: existing.source ?? (input.source === undefined ? undefined : cloneRecord(input.source)),
|
|
4428
|
-
attempt: existing.attempt + 1,
|
|
4429
|
-
execution: input.execution ? cloneRecord(input.execution) : undefined
|
|
4430
|
-
};
|
|
4431
|
-
this.runs.set(key, cloneRecord(next));
|
|
4432
|
-
return cloneRecord(next);
|
|
6197
|
+
const key2 = storageKey(input.projectId, input.id);
|
|
6198
|
+
const existing = this.runs.get(key2);
|
|
6199
|
+
if (!existing || existing.status !== "queued") {
|
|
6200
|
+
throw new WorkflowRunError(existing ? `[Sixb] Workflow run '${input.id}' cannot start from status '${existing.status}'.` : `[Sixb] Workflow run '${input.id}' not found for project '${input.projectId}'.`);
|
|
4433
6201
|
}
|
|
4434
|
-
const
|
|
4435
|
-
|
|
4436
|
-
projectId: input.projectId,
|
|
4437
|
-
workflowId: input.workflowId,
|
|
6202
|
+
const next = {
|
|
6203
|
+
...existing,
|
|
4438
6204
|
status: "running",
|
|
4439
|
-
input: cloneRecord(input.input),
|
|
4440
6205
|
startedAt: new Date(input.startedAt ?? new Date),
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
6206
|
+
finishedAt: undefined,
|
|
6207
|
+
error: undefined,
|
|
6208
|
+
attempt: existing.attempt + 1,
|
|
6209
|
+
execution: input.execution ? cloneRecord(input.execution) : undefined
|
|
4445
6210
|
};
|
|
4446
|
-
this.runs.set(
|
|
4447
|
-
return cloneRecord(
|
|
6211
|
+
this.runs.set(key2, cloneRecord(next));
|
|
6212
|
+
return cloneRecord(next);
|
|
4448
6213
|
}
|
|
4449
6214
|
async finish(input) {
|
|
4450
6215
|
const existing = this.requireFinishableWorkflowRun(input);
|
|
@@ -4457,10 +6222,12 @@ class InMemoryWorkflowRunStorage {
|
|
|
4457
6222
|
};
|
|
4458
6223
|
const next = input.status === "succeeded" ? {
|
|
4459
6224
|
...base,
|
|
6225
|
+
output: cloneRecord(input.output),
|
|
4460
6226
|
error: undefined
|
|
4461
6227
|
} : {
|
|
4462
6228
|
...base,
|
|
4463
|
-
|
|
6229
|
+
output: undefined,
|
|
6230
|
+
error: normalizeFailure2(input.error)
|
|
4464
6231
|
};
|
|
4465
6232
|
this.runs.set(storageKey(input.projectId, input.id), cloneRecord(next));
|
|
4466
6233
|
return cloneRecord(next);
|
|
@@ -4609,8 +6376,8 @@ class InMemoryWorkflowNodeRunStorage {
|
|
|
4609
6376
|
}
|
|
4610
6377
|
restore(snapshot) {
|
|
4611
6378
|
this.nodes.clear();
|
|
4612
|
-
for (const [
|
|
4613
|
-
this.nodes.set(
|
|
6379
|
+
for (const [key2, record] of structuredClone(snapshot)) {
|
|
6380
|
+
this.nodes.set(key2, record);
|
|
4614
6381
|
}
|
|
4615
6382
|
}
|
|
4616
6383
|
async start(input) {
|
|
@@ -4620,8 +6387,8 @@ class InMemoryWorkflowNodeRunStorage {
|
|
|
4620
6387
|
if (workflowRun.workflowId !== input.workflowId) {
|
|
4621
6388
|
throw new WorkflowRunError(`[Sixb] Workflow node run '${input.id}' workflow '${input.workflowId}' does not match workflow run '${input.workflowRunId}' workflow '${workflowRun.workflowId}'.`);
|
|
4622
6389
|
}
|
|
4623
|
-
const
|
|
4624
|
-
if (this.nodes.has(
|
|
6390
|
+
const key2 = storageKey(input.projectId, input.id);
|
|
6391
|
+
if (this.nodes.has(key2)) {
|
|
4625
6392
|
throw new WorkflowRunError(`[Sixb] Workflow node run '${input.id}' already exists for project '${input.projectId}'.`);
|
|
4626
6393
|
}
|
|
4627
6394
|
const record = {
|
|
@@ -4637,7 +6404,7 @@ class InMemoryWorkflowNodeRunStorage {
|
|
|
4637
6404
|
input: cloneRecord(input.input),
|
|
4638
6405
|
startedAt: new Date(input.startedAt ?? new Date)
|
|
4639
6406
|
};
|
|
4640
|
-
this.nodes.set(
|
|
6407
|
+
this.nodes.set(key2, cloneRecord(record));
|
|
4641
6408
|
return cloneRecord(record);
|
|
4642
6409
|
}
|
|
4643
6410
|
async finish(input) {
|
|
@@ -4655,7 +6422,7 @@ class InMemoryWorkflowNodeRunStorage {
|
|
|
4655
6422
|
} : {
|
|
4656
6423
|
...base,
|
|
4657
6424
|
output: undefined,
|
|
4658
|
-
error: input.error
|
|
6425
|
+
error: normalizeFailure2(input.error)
|
|
4659
6426
|
};
|
|
4660
6427
|
this.nodes.set(storageKey(input.projectId, input.id), cloneRecord(next));
|
|
4661
6428
|
return cloneRecord(next);
|
|
@@ -4734,37 +6501,52 @@ class InMemoryWorkflowNodeRunStorage {
|
|
|
4734
6501
|
|
|
4735
6502
|
class InMemoryWorkflowAgentNodeRunStorage {
|
|
4736
6503
|
nodes;
|
|
6504
|
+
executions;
|
|
4737
6505
|
runs = new Map;
|
|
4738
|
-
constructor(nodes) {
|
|
6506
|
+
constructor(nodes, executions) {
|
|
4739
6507
|
this.nodes = nodes;
|
|
6508
|
+
this.executions = executions;
|
|
4740
6509
|
}
|
|
4741
6510
|
snapshot() {
|
|
4742
6511
|
return structuredClone(this.runs);
|
|
4743
6512
|
}
|
|
4744
6513
|
restore(snapshot) {
|
|
4745
6514
|
this.runs.clear();
|
|
4746
|
-
for (const [
|
|
4747
|
-
this.runs.set(
|
|
6515
|
+
for (const [key2, record] of structuredClone(snapshot))
|
|
6516
|
+
this.runs.set(key2, record);
|
|
4748
6517
|
}
|
|
4749
6518
|
async create(input) {
|
|
4750
6519
|
const node = this.nodes.requireAgentNodeRun(input.projectId, input.nodeRunId);
|
|
6520
|
+
const workflowRun = this.nodes.requireWorkflowRun(input.projectId, node.workflowRunId);
|
|
6521
|
+
await assertWorkflowAgentNodeRunExecution({
|
|
6522
|
+
executions: this.executions,
|
|
6523
|
+
projectId: input.projectId,
|
|
6524
|
+
executionId: input.executionId,
|
|
6525
|
+
nodeRunId: input.nodeRunId,
|
|
6526
|
+
agentId: input.agentId,
|
|
6527
|
+
workflowExecutionId: workflowRun.executionId
|
|
6528
|
+
});
|
|
4751
6529
|
if (node.status !== "running") {
|
|
4752
6530
|
throw new WorkflowRunError(`[Sixb] Agent workflow node run '${input.nodeRunId}' must be running when queued.`);
|
|
4753
6531
|
}
|
|
4754
|
-
const
|
|
4755
|
-
if (this.runs.has(
|
|
6532
|
+
const key2 = storageKey(input.projectId, input.nodeRunId);
|
|
6533
|
+
if (this.runs.has(key2)) {
|
|
4756
6534
|
throw new WorkflowRunError(`[Sixb] Agent execution already exists for workflow node run '${input.nodeRunId}'.`);
|
|
4757
6535
|
}
|
|
6536
|
+
if ([...this.runs.values()].some((run) => run.projectId === input.projectId && run.executionId === input.executionId)) {
|
|
6537
|
+
throw new WorkflowRunError(`[Sixb] Execution '${input.executionId}' already belongs to another Workflow Agent-node run.`);
|
|
6538
|
+
}
|
|
4758
6539
|
const record = {
|
|
4759
6540
|
projectId: input.projectId,
|
|
4760
6541
|
nodeRunId: input.nodeRunId,
|
|
6542
|
+
executionId: input.executionId,
|
|
4761
6543
|
agentId: input.agentId,
|
|
4762
6544
|
status: "queued",
|
|
4763
6545
|
prompt: input.prompt,
|
|
4764
6546
|
attempt: 0,
|
|
4765
6547
|
createdAt: new Date(input.createdAt ?? new Date)
|
|
4766
6548
|
};
|
|
4767
|
-
this.runs.set(
|
|
6549
|
+
this.runs.set(key2, cloneRecord(record));
|
|
4768
6550
|
return cloneRecord(record);
|
|
4769
6551
|
}
|
|
4770
6552
|
async start(input) {
|
|
@@ -4772,7 +6554,6 @@ class InMemoryWorkflowAgentNodeRunStorage {
|
|
|
4772
6554
|
const next = {
|
|
4773
6555
|
...run,
|
|
4774
6556
|
status: "running",
|
|
4775
|
-
...input.executionPrincipal ? { executionPrincipal: cloneRecord(input.executionPrincipal) } : {},
|
|
4776
6557
|
...input.modelId ? { modelId: input.modelId } : {},
|
|
4777
6558
|
attempt: 1,
|
|
4778
6559
|
execution: cloneRecord(input.execution),
|
|
@@ -4801,10 +6582,9 @@ class InMemoryWorkflowAgentNodeRunStorage {
|
|
|
4801
6582
|
status: input.status,
|
|
4802
6583
|
...input.modelId === undefined ? {} : { modelId: input.modelId },
|
|
4803
6584
|
...input.finishReason === undefined ? {} : { finishReason: input.finishReason },
|
|
4804
|
-
...input.usage === undefined ? {} : { usage: cloneRecord(input.usage) },
|
|
4805
6585
|
...input.trace === undefined ? {} : { trace: cloneRecord(input.trace) },
|
|
4806
6586
|
...input.diagnostics === undefined ? {} : { diagnostics: cloneRecord(input.diagnostics) },
|
|
4807
|
-
...input.status === "succeeded" || input.error === undefined ? {} : { error: input.error },
|
|
6587
|
+
...input.status === "succeeded" || input.error === undefined ? {} : { error: normalizeAgentFailure(input.error) },
|
|
4808
6588
|
execution: undefined,
|
|
4809
6589
|
completedAt: new Date(input.completedAt ?? new Date)
|
|
4810
6590
|
});
|
|
@@ -4818,7 +6598,7 @@ class InMemoryWorkflowAgentNodeRunStorage {
|
|
|
4818
6598
|
...run,
|
|
4819
6599
|
status: "cancelled",
|
|
4820
6600
|
execution: undefined,
|
|
4821
|
-
error: input.error,
|
|
6601
|
+
error: normalizeAgentFailure(input.error),
|
|
4822
6602
|
completedAt: new Date(input.completedAt ?? new Date)
|
|
4823
6603
|
});
|
|
4824
6604
|
}
|
|
@@ -4876,50 +6656,60 @@ class InMemoryStorage {
|
|
|
4876
6656
|
timeseriesStorage = new InMemoryTimeseriesStorage;
|
|
4877
6657
|
ontologyStorage;
|
|
4878
6658
|
authStorage = new InMemoryAuthStorage;
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
6659
|
+
executionStorage = new InMemoryExecutionStorage(this.authStorage);
|
|
6660
|
+
agentStorage = new InMemoryAgentStorage(this.executionStorage);
|
|
6661
|
+
aiUsageStorage = new InMemoryAiUsageStorage(this.executionStorage);
|
|
6662
|
+
actionRunStorage = new InMemoryActionRunStorage(this.executionStorage);
|
|
6663
|
+
syncRunStorage = new InMemorySyncRunStorage(this.executionStorage);
|
|
6664
|
+
pipelineRunStorage = new InMemoryPipelineRunStorage(this.executionStorage);
|
|
6665
|
+
projectionRunStorage = new InMemoryProjectionRunStorage({
|
|
6666
|
+
executions: this.executionStorage
|
|
6667
|
+
});
|
|
6668
|
+
workflowRunStorage = new InMemoryWorkflowRunStorage(this.executionStorage);
|
|
4885
6669
|
workflowInterventionStorage = new InMemoryWorkflowInterventionStorage;
|
|
4886
|
-
|
|
4887
|
-
webhookRunStorage = new InMemoryWebhookRunStorage;
|
|
6670
|
+
webhookRunStorage = new InMemoryWebhookRunStorage(this.executionStorage);
|
|
4888
6671
|
rulesStorage = new InMemoryRulesStorage;
|
|
4889
6672
|
fileUploadSessionStorage = new InMemoryFileUploadSessions;
|
|
6673
|
+
connectorConnectionStorage;
|
|
4890
6674
|
auth;
|
|
6675
|
+
executions;
|
|
4891
6676
|
agents;
|
|
6677
|
+
aiUsage;
|
|
4892
6678
|
actionRuns;
|
|
4893
6679
|
syncRuns;
|
|
4894
6680
|
pipelineRuns;
|
|
4895
6681
|
projectionRuns;
|
|
4896
6682
|
workflowRuns;
|
|
4897
6683
|
workflowInterventions;
|
|
4898
|
-
webhookDeliveries;
|
|
4899
6684
|
webhookRuns;
|
|
4900
6685
|
rules;
|
|
4901
6686
|
fileUploadSessions;
|
|
4902
|
-
|
|
6687
|
+
connectorConnections;
|
|
6688
|
+
constructor(options = {}) {
|
|
6689
|
+
this.connectorConnectionStorage = new InMemoryConnectorConnectionStorage(options.connectorConnections);
|
|
4903
6690
|
const scope = createStorageOperationScope((run) => this.withStorageOperation(run), () => this.assertRootOperationAvailable());
|
|
4904
6691
|
this.objects = createOperationScopedFacade(this.objectStorage, scope);
|
|
4905
6692
|
this.timeseries = createOperationScopedFacade(this.timeseriesStorage, scope);
|
|
4906
6693
|
this.auth = createAuthOperationScope(this.authStorage, scope);
|
|
6694
|
+
this.executions = createOperationScopedFacade(this.executionStorage, scope);
|
|
4907
6695
|
this.agents = createAgentOperationScope(this.agentStorage, scope);
|
|
6696
|
+
this.aiUsage = createOperationScopedFacade(this.aiUsageStorage, scope);
|
|
4908
6697
|
this.actionRuns = createOperationScopedFacade(this.actionRunStorage, scope);
|
|
4909
6698
|
this.syncRuns = createOperationScopedFacade(this.syncRunStorage, scope);
|
|
4910
6699
|
this.pipelineRuns = createOperationScopedFacade(this.pipelineRunStorage, scope);
|
|
4911
6700
|
this.projectionRuns = createOperationScopedFacade(this.projectionRunStorage, scope);
|
|
4912
6701
|
this.workflowRuns = createWorkflowRunOperationScope(this.workflowRunStorage, scope);
|
|
4913
6702
|
this.workflowInterventions = createOperationScopedFacade(this.workflowInterventionStorage, scope);
|
|
4914
|
-
this.webhookDeliveries = createOperationScopedFacade(this.webhookDeliveryStorage, scope);
|
|
4915
6703
|
this.webhookRuns = createOperationScopedFacade(this.webhookRunStorage, scope);
|
|
4916
6704
|
this.rules = createOperationScopedFacade(this.rulesStorage, scope);
|
|
4917
6705
|
this.fileUploadSessions = createOperationScopedFacade(this.fileUploadSessionStorage, scope);
|
|
6706
|
+
this.connectorConnections = createOperationScopedFacade(this.connectorConnectionStorage, scope);
|
|
4918
6707
|
this.ontologyStorage = new InMemoryOntologyStorage(this.objectStorage, this.timeseriesStorage, {
|
|
4919
6708
|
runRootOperation: async (run) => run(),
|
|
4920
6709
|
getTransactionToken: () => this.getActiveTransactionToken(),
|
|
4921
6710
|
getMaterializationLifecycle: () => this.getActiveMaterializationLifecycle(),
|
|
4922
|
-
assertSourceMaterializationExecution: (input) => this.projectionRunStorage.assertSourceMaterializationExecutionUnlocked(input)
|
|
6711
|
+
assertSourceMaterializationExecution: (input) => this.projectionRunStorage.assertSourceMaterializationExecutionUnlocked(input),
|
|
6712
|
+
executionExists: async (projectId, executionId) => await this.executionStorage.getById({ projectId, id: executionId }) !== null
|
|
4923
6713
|
});
|
|
4924
6714
|
this.ontology = createOntologyOperationScope(this.ontologyStorage, scope);
|
|
4925
6715
|
this.ontologyStorage.registerTestingAlias(this.ontology);
|
|
@@ -5002,17 +6792,19 @@ class InMemoryStorage {
|
|
|
5002
6792
|
timeseries: this.timeseriesStorage,
|
|
5003
6793
|
ontology: this.ontologyStorage,
|
|
5004
6794
|
auth: this.authStorage,
|
|
6795
|
+
executions: this.executionStorage,
|
|
5005
6796
|
agents: this.agentStorage,
|
|
6797
|
+
aiUsage: this.aiUsageStorage,
|
|
5006
6798
|
actionRuns: this.actionRunStorage,
|
|
5007
6799
|
syncRuns: this.syncRunStorage,
|
|
5008
6800
|
pipelineRuns: this.pipelineRunStorage,
|
|
5009
6801
|
projectionRuns: this.projectionRunStorage,
|
|
5010
6802
|
workflowRuns: this.workflowRunStorage,
|
|
5011
6803
|
workflowInterventions: this.workflowInterventionStorage,
|
|
5012
|
-
webhookDeliveries: this.webhookDeliveryStorage,
|
|
5013
6804
|
webhookRuns: this.webhookRunStorage,
|
|
5014
6805
|
rules: this.rulesStorage,
|
|
5015
6806
|
fileUploadSessions: this.fileUploadSessionStorage,
|
|
6807
|
+
connectorConnections: this.connectorConnectionStorage,
|
|
5016
6808
|
ping: async () => {
|
|
5017
6809
|
return;
|
|
5018
6810
|
},
|
|
@@ -5027,17 +6819,19 @@ class InMemoryStorage {
|
|
|
5027
6819
|
timeseries: this.timeseriesStorage.snapshot(),
|
|
5028
6820
|
ontology: this.ontologyStorage.snapshot(),
|
|
5029
6821
|
auth: this.authStorage.snapshot(),
|
|
6822
|
+
executions: this.executionStorage.snapshot(),
|
|
5030
6823
|
agents: this.agentStorage.snapshot(),
|
|
6824
|
+
aiUsage: this.aiUsageStorage.snapshot(),
|
|
5031
6825
|
actionRuns: this.actionRunStorage.snapshot(),
|
|
5032
6826
|
syncRuns: this.syncRunStorage.snapshot(),
|
|
5033
6827
|
pipelineRuns: this.pipelineRunStorage.snapshot(),
|
|
5034
6828
|
projectionRuns: this.projectionRunStorage.snapshot(),
|
|
5035
6829
|
workflowRuns: this.workflowRunStorage.snapshot(),
|
|
5036
6830
|
workflowInterventions: this.workflowInterventionStorage.snapshot(),
|
|
5037
|
-
webhookDeliveries: this.webhookDeliveryStorage.snapshot(),
|
|
5038
6831
|
webhookRuns: this.webhookRunStorage.snapshot(),
|
|
5039
6832
|
rules: this.rulesStorage.snapshot(),
|
|
5040
|
-
fileUploadSessions: this.fileUploadSessionStorage.snapshot()
|
|
6833
|
+
fileUploadSessions: this.fileUploadSessionStorage.snapshot(),
|
|
6834
|
+
connectorConnections: this.connectorConnectionStorage.snapshot()
|
|
5041
6835
|
};
|
|
5042
6836
|
}
|
|
5043
6837
|
restore(snapshot) {
|
|
@@ -5045,17 +6839,19 @@ class InMemoryStorage {
|
|
|
5045
6839
|
this.timeseriesStorage.restore(snapshot.timeseries);
|
|
5046
6840
|
this.ontologyStorage.restore(snapshot.ontology);
|
|
5047
6841
|
this.authStorage.restore(snapshot.auth);
|
|
6842
|
+
this.executionStorage.restore(snapshot.executions);
|
|
5048
6843
|
this.agentStorage.restore(snapshot.agents);
|
|
6844
|
+
this.aiUsageStorage.restore(snapshot.aiUsage);
|
|
5049
6845
|
this.actionRunStorage.restore(snapshot.actionRuns);
|
|
5050
6846
|
this.syncRunStorage.restore(snapshot.syncRuns);
|
|
5051
6847
|
this.pipelineRunStorage.restore(snapshot.pipelineRuns);
|
|
5052
6848
|
this.projectionRunStorage.restore(snapshot.projectionRuns);
|
|
5053
6849
|
this.workflowRunStorage.restore(snapshot.workflowRuns);
|
|
5054
6850
|
this.workflowInterventionStorage.restore(snapshot.workflowInterventions);
|
|
5055
|
-
this.webhookDeliveryStorage.restore(snapshot.webhookDeliveries);
|
|
5056
6851
|
this.webhookRunStorage.restore(snapshot.webhookRuns);
|
|
5057
6852
|
this.rulesStorage.restore(snapshot.rules);
|
|
5058
6853
|
this.fileUploadSessionStorage.restore(snapshot.fileUploadSessions);
|
|
6854
|
+
this.connectorConnectionStorage.restore(snapshot.connectorConnections);
|
|
5059
6855
|
}
|
|
5060
6856
|
}
|
|
5061
6857
|
// src/storage/migrations/migrate-storage.ts
|
|
@@ -5267,6 +7063,6 @@ function assertAppliedPrefix(migrations, rows) {
|
|
|
5267
7063
|
}
|
|
5268
7064
|
return [...rows].sort((a, b) => a.version - b.version);
|
|
5269
7065
|
}
|
|
5270
|
-
export {
|
|
7066
|
+
export { actionSubjectsEqual, actionRunParamsEqual, actionRunPhaseRecordsEqual, finishActionRunPhase, canRequeueActionRunAfterEnqueueFailure, isTerminalActionRun, InMemoryActionRunStorage, AGENT_MESSAGE_CONTENT_VERSION, InMemoryAgentStorage, AiUsageStorageError, normalizeAiModelCallUsage, aggregateAiModelCallUsage, normalizeAiModelCallRecord, assertAiUsageExecutionId, InMemoryAiUsageStorage, InMemoryConnectorConnectionStorage, ObjectNotFoundError, ObjectStorageError, StorageTransactionError, isStorageSerializationFailure, FileUploadSessionError, DEFAULT_FILE_UPLOAD_SESSION_TTL_MS, DEFAULT_FILE_UPLOAD_TERMINAL_SESSION_TTL_MS, createUploadExpiresAt, createFileUploadId, InMemoryFileUploadSessions, canRequeuePipelineRunAfterEnqueueFailure, PIPELINE_RUN_FAILURE_CODES, InMemoryPipelineRunStorage, InMemoryProjectionRunStorage, InMemoryRulesStorage, canRequeueSyncRunAfterEnqueueFailure, SYNC_RUN_FAILURE_CODES, InMemorySyncRunStorage, createTransactionStorageProxy, assertTransactionActive, throwNestedStorageTransaction, WEBHOOK_RUN_FAILURE_CODES, canRetryWebhookRun, InMemoryWebhookRunStorage, WorkflowInterventionError, InMemoryWorkflowInterventionStorage, WORKFLOW_RUN_FAILURE_CODES, InMemoryWorkflowRunStorage, InMemoryWorkflowNodeRunStorage, InMemoryWorkflowAgentNodeRunStorage, InMemoryStorage, isMigrationCapableStorage, migrateStorage, checkStorageSchema, step, defineMigrations, runMigrationSet, describeMigrationHistory };
|
|
5271
7067
|
|
|
5272
|
-
//# debugId=
|
|
7068
|
+
//# debugId=0974A6B3A889270064756E2164756E21
|