@sixb/core 0.1.9 → 0.1.11
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/dist/actions/index.js +9 -9
- package/dist/agents/index.js +17 -16
- package/dist/agents/index.js.map +1 -1
- package/dist/blob-storage/types.d.ts +4 -1
- package/dist/blob-storage/types.d.ts.map +1 -1
- package/dist/bootstrap/index.js +21 -20
- package/dist/bootstrap/index.js.map +1 -1
- package/dist/broker/in-memory.d.ts +8 -2
- package/dist/broker/in-memory.d.ts.map +1 -1
- package/dist/broker/index.d.ts +4 -2
- package/dist/broker/index.d.ts.map +1 -1
- package/dist/broker/index.js +7 -3
- package/dist/broker/index.js.map +1 -1
- package/dist/broker/retention.d.ts +4 -0
- package/dist/broker/retention.d.ts.map +1 -0
- package/dist/broker/subscriber.d.ts +10 -0
- package/dist/broker/subscriber.d.ts.map +1 -0
- package/dist/broker/types.d.ts +14 -1
- package/dist/broker/types.d.ts.map +1 -1
- package/dist/{chunk-ypbtykv6.js → chunk-01kj2pbh.js} +1 -1
- package/dist/{chunk-k3cqkkn2.js → chunk-1824gssz.js} +30 -65
- package/dist/chunk-1824gssz.js.map +12 -0
- package/dist/{chunk-xyr8kppc.js → chunk-1yefycb1.js} +1 -1
- package/dist/chunk-2c4j899j.js.map +1 -1
- package/dist/{chunk-ppytyr6w.js → chunk-358caqf5.js} +4 -4
- package/dist/chunk-358caqf5.js.map +12 -0
- package/dist/{chunk-m3z3x9v0.js → chunk-3ckk0xfj.js} +2 -2
- package/dist/{chunk-kxwa347f.js → chunk-3qms4nax.js} +2 -2
- package/dist/{chunk-kxwa347f.js.map → chunk-3qms4nax.js.map} +3 -3
- package/dist/{chunk-52hbv0ak.js → chunk-4zhmdsx6.js} +141 -55
- package/dist/chunk-4zhmdsx6.js.map +36 -0
- package/dist/{chunk-zcnq6105.js → chunk-85cd7e8c.js} +2 -1
- package/dist/chunk-85cd7e8c.js.map +10 -0
- package/dist/{chunk-3f7veca0.js → chunk-9x8dybsb.js} +3 -3
- package/dist/chunk-9x8dybsb.js.map +10 -0
- package/dist/{chunk-0w35wavj.js → chunk-a0e6x5hd.js} +1 -1
- package/dist/{chunk-r29fxdhn.js → chunk-aa6z4a19.js} +160 -44
- package/dist/chunk-aa6z4a19.js.map +12 -0
- package/dist/{chunk-emyyk7dx.js → chunk-cfvakeax.js} +22 -145
- package/dist/chunk-cfvakeax.js.map +12 -0
- package/dist/chunk-d62kjtbg.js.map +1 -1
- package/dist/{chunk-h1gfhhbh.js → chunk-d63nnr5b.js} +2 -2
- package/dist/{chunk-r4tfx1sf.js → chunk-fh8kgex1.js} +5 -5
- package/dist/{chunk-an5tt9y0.js → chunk-ftv470j8.js} +42 -4
- package/dist/{chunk-an5tt9y0.js.map → chunk-ftv470j8.js.map} +7 -7
- package/dist/{chunk-jjy0fhrn.js → chunk-g91qxjj0.js} +20 -3
- package/dist/chunk-g91qxjj0.js.map +12 -0
- package/dist/{chunk-hpr1r6av.js → chunk-gq8vhakp.js} +51 -40
- package/dist/{chunk-hpr1r6av.js.map → chunk-gq8vhakp.js.map} +6 -6
- package/dist/{chunk-x57ycxq0.js → chunk-gqh45d2n.js} +42 -3
- package/dist/{chunk-x57ycxq0.js.map → chunk-gqh45d2n.js.map} +3 -3
- package/dist/{chunk-mjbk2djy.js → chunk-gqm76kse.js} +231 -125
- package/dist/{chunk-mjbk2djy.js.map → chunk-gqm76kse.js.map} +9 -8
- package/dist/{chunk-e0d1rzef.js → chunk-jsy70480.js} +16 -3
- package/dist/chunk-jsy70480.js.map +15 -0
- package/dist/{chunk-0rdrecsb.js → chunk-kfee1h52.js} +116 -32
- package/dist/chunk-kfee1h52.js.map +13 -0
- package/dist/{chunk-3frsnm7x.js → chunk-qma80ych.js} +4 -6
- package/dist/chunk-qma80ych.js.map +11 -0
- package/dist/{chunk-vf691g1r.js → chunk-sepyxgpc.js} +3 -3
- package/dist/chunk-v2vcg0w6.js +151 -0
- package/dist/chunk-v2vcg0w6.js.map +11 -0
- package/dist/{chunk-3tgwrcyh.js → chunk-wf88w4kp.js} +17 -23
- package/dist/chunk-wf88w4kp.js.map +14 -0
- package/dist/{chunk-xfbydgzy.js → chunk-x9m9x2eq.js} +7 -8
- package/dist/{chunk-xfbydgzy.js.map → chunk-x9m9x2eq.js.map} +3 -3
- package/dist/{chunk-qhcpj9wc.js → chunk-z0271qkp.js} +98 -2
- package/dist/chunk-z0271qkp.js.map +15 -0
- package/dist/{chunk-1enhpacz.js → chunk-z0s4axeh.js} +6 -6
- package/dist/connectors/connections/authorizations.d.ts.map +1 -1
- package/dist/connectors/connections/command-context.d.ts +2 -0
- package/dist/connectors/connections/command-context.d.ts.map +1 -1
- package/dist/connectors/connections/contracts.d.ts +4 -1
- package/dist/connectors/connections/contracts.d.ts.map +1 -1
- package/dist/connectors/connections/execution.d.ts +1 -0
- package/dist/connectors/connections/execution.d.ts.map +1 -1
- package/dist/connectors/connections/internal.js +1 -1
- package/dist/connectors/connections/request.d.ts +3 -1
- package/dist/connectors/connections/request.d.ts.map +1 -1
- package/dist/connectors/connections/runs.d.ts +1 -0
- package/dist/connectors/connections/runs.d.ts.map +1 -1
- package/dist/connectors/connections/service.d.ts +2 -0
- package/dist/connectors/connections/service.d.ts.map +1 -1
- package/dist/connectors/connections/tokens.d.ts.map +1 -1
- package/dist/connectors/connections/validation.d.ts +5 -1
- package/dist/connectors/connections/validation.d.ts.map +1 -1
- package/dist/connectors/types.d.ts +19 -4
- package/dist/connectors/types.d.ts.map +1 -1
- package/dist/events/execution.d.ts +1 -1
- package/dist/events/execution.d.ts.map +1 -1
- package/dist/events/index.js +1 -1
- package/dist/events/outbox-dispatcher.d.ts +2 -2
- package/dist/events/outbox-dispatcher.d.ts.map +1 -1
- package/dist/events/service.d.ts +2 -2
- package/dist/events/service.d.ts.map +1 -1
- package/dist/execution/agent.js +17 -16
- package/dist/execution/agent.js.map +1 -1
- package/dist/execution/primitive.js +17 -16
- package/dist/execution/primitive.js.map +2 -2
- package/dist/execution/request.js +17 -16
- package/dist/execution/request.js.map +2 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +31 -29
- package/dist/index.js.map +1 -1
- package/dist/lake-storage/changes.d.ts +5 -0
- package/dist/lake-storage/changes.d.ts.map +1 -0
- package/dist/lake-storage/in-memory.d.ts +2 -1
- package/dist/lake-storage/in-memory.d.ts.map +1 -1
- package/dist/lake-storage/index.d.ts +2 -1
- package/dist/lake-storage/index.d.ts.map +1 -1
- package/dist/lake-storage/index.js +4 -2
- package/dist/lake-storage/index.js.map +1 -1
- package/dist/lake-storage/types.d.ts +38 -0
- package/dist/lake-storage/types.d.ts.map +1 -1
- package/dist/logging/internal.js +1 -1
- package/dist/maintenance/ontology-maintenance.d.ts.map +1 -1
- package/dist/maintenance/types.d.ts +1 -1
- package/dist/maintenance/types.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/model.d.ts +12 -1
- package/dist/materialization/model.d.ts.map +1 -1
- package/dist/materializer/index.d.ts +1 -1
- package/dist/materializer/index.d.ts.map +1 -1
- package/dist/materializer/index.js +6 -6
- package/dist/materializer/materializer.d.ts +5 -1
- package/dist/materializer/materializer.d.ts.map +1 -1
- package/dist/materializer/projections/entry-validator.d.ts +2 -1
- package/dist/materializer/projections/entry-validator.d.ts.map +1 -1
- package/dist/materializer/projections/replace.d.ts.map +1 -1
- package/dist/materializer/projections/source-materialization.d.ts +4 -3
- package/dist/materializer/projections/source-materialization.d.ts.map +1 -1
- package/dist/materializer/shared/normalize.d.ts +2 -1
- package/dist/materializer/shared/normalize.d.ts.map +1 -1
- package/dist/models/definitions.d.ts +7 -0
- package/dist/models/definitions.d.ts.map +1 -1
- package/dist/models/execution/index.js +6 -6
- package/dist/models/index.js +1 -1
- package/dist/objects/index.js +10 -10
- package/dist/objects/query/index.js +6 -6
- package/dist/pipelines/index.js +7 -7
- package/dist/pipelines/run-dispatch.d.ts.map +1 -1
- package/dist/projections/internal.js +7 -9
- package/dist/projections/internal.js.map +1 -1
- package/dist/projections/run-dispatch.d.ts.map +1 -1
- package/dist/queues/in-memory.d.ts +7 -3
- package/dist/queues/in-memory.d.ts.map +1 -1
- package/dist/queues/index.js +1 -1
- package/dist/queues/indexed-heap.d.ts +15 -0
- package/dist/queues/indexed-heap.d.ts.map +1 -0
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/internal.js +1 -1
- package/dist/runtime/ontology-mutations.d.ts +3 -1
- package/dist/runtime/ontology-mutations.d.ts.map +1 -1
- package/dist/shares/internal.js +5 -5
- package/dist/storage/agents/provider.js +1 -1
- package/dist/storage/connector-connections/in-memory.d.ts +1 -0
- package/dist/storage/connector-connections/in-memory.d.ts.map +1 -1
- package/dist/storage/connector-connections/provider/connections.d.ts.map +1 -1
- package/dist/storage/connector-connections/provider/runs.d.ts +1 -0
- package/dist/storage/connector-connections/provider/runs.d.ts.map +1 -1
- package/dist/storage/connector-connections/provider/shared.d.ts +1 -0
- package/dist/storage/connector-connections/provider/shared.d.ts.map +1 -1
- package/dist/storage/connector-connections/provider.d.ts +1 -0
- package/dist/storage/connector-connections/provider.d.ts.map +1 -1
- package/dist/storage/connector-connections/provider.js +11 -17
- package/dist/storage/connector-connections/provider.js.map +6 -6
- package/dist/storage/connector-connections/types.d.ts +6 -3
- package/dist/storage/connector-connections/types.d.ts.map +1 -1
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +5 -5
- package/dist/storage/internal.js +1 -1
- package/dist/storage/ontology/in-memory/materializations-state.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/materializations.d.ts +1 -1
- package/dist/storage/ontology/in-memory/materializations.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/shared-state.d.ts +15 -2
- package/dist/storage/ontology/in-memory/shared-state.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/source-roots.d.ts +6 -0
- package/dist/storage/ontology/in-memory/source-roots.d.ts.map +1 -0
- package/dist/storage/ontology/in-memory/sources.d.ts.map +1 -1
- package/dist/storage/ontology/index.d.ts +1 -1
- package/dist/storage/ontology/index.d.ts.map +1 -1
- package/dist/storage/ontology/outbox.d.ts +1 -0
- package/dist/storage/ontology/outbox.d.ts.map +1 -1
- package/dist/storage/ontology/provider.d.ts +16 -0
- package/dist/storage/ontology/provider.d.ts.map +1 -1
- package/dist/storage/ontology/provider.js +4 -2
- package/dist/storage/ontology/provider.js.map +1 -1
- package/dist/storage/ontology/sources.d.ts +13 -4
- package/dist/storage/ontology/sources.d.ts.map +1 -1
- package/dist/storage/projection-runs/lifecycle.d.ts.map +1 -1
- package/dist/storage/projection-runs/provider.js +2 -2
- package/dist/storage/projection-runs/types.d.ts +2 -0
- package/dist/storage/projection-runs/types.d.ts.map +1 -1
- package/dist/syncs/index.js +9 -8
- package/dist/syncs/index.js.map +1 -1
- package/dist/syncs/run-dispatch.d.ts.map +1 -1
- package/dist/testing/broker-contract.d.ts.map +1 -1
- package/dist/testing/connector-connection-storage-contract.d.ts.map +1 -1
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +1499 -963
- package/dist/testing/index.js.map +10 -9
- package/dist/testing/lake-changes-contract.d.ts +6 -0
- package/dist/testing/lake-changes-contract.d.ts.map +1 -0
- package/dist/testing/lake-storage-contract.d.ts.map +1 -1
- package/dist/testing/materializer-storage-contract.d.ts.map +1 -1
- package/dist/testing/ontology-storage-contract.d.ts.map +1 -1
- package/dist/testing/projection-run-storage-contract.d.ts.map +1 -1
- package/dist/webhooks/connections.d.ts +6 -0
- package/dist/webhooks/connections.d.ts.map +1 -0
- package/dist/webhooks/index.d.ts +1 -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 -1
- package/dist/webhooks/internal.js +55 -10
- package/dist/webhooks/internal.js.map +4 -3
- package/dist/webhooks/registry.d.ts +1 -1
- package/dist/webhooks/registry.d.ts.map +1 -1
- package/dist/webhooks/types.d.ts +15 -4
- package/dist/webhooks/types.d.ts.map +1 -1
- package/dist/workflows/index.js +18 -17
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/run-dispatch.d.ts +3 -1
- package/dist/workflows/run-dispatch.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/agents/model-loop.ts +7 -0
- package/src/blob-storage/types.ts +4 -1
- package/src/broker/in-memory.ts +104 -39
- package/src/broker/index.ts +4 -1
- package/src/broker/retention.ts +28 -0
- package/src/broker/subscriber.ts +21 -0
- package/src/broker/types.ts +15 -1
- package/src/connectors/builders.ts +0 -6
- package/src/connectors/connections/authorizations.ts +11 -5
- package/src/connectors/connections/command-context.ts +21 -4
- package/src/connectors/connections/contracts.ts +7 -1
- package/src/connectors/connections/execution.ts +3 -0
- package/src/connectors/connections/request.ts +56 -22
- package/src/connectors/connections/runs.ts +39 -1
- package/src/connectors/connections/service.ts +6 -0
- package/src/connectors/connections/tokens.ts +4 -0
- package/src/connectors/connections/validation.ts +91 -5
- package/src/connectors/types.ts +19 -4
- package/src/events/execution.ts +2 -2
- package/src/events/outbox-dispatcher.ts +20 -26
- package/src/events/service.ts +3 -3
- package/src/index.ts +10 -2
- package/src/lake-storage/changes.ts +43 -0
- package/src/lake-storage/in-memory.ts +75 -0
- package/src/lake-storage/index.ts +4 -0
- package/src/lake-storage/types.ts +42 -0
- package/src/logging/service.ts +1 -1
- package/src/maintenance/ontology-maintenance.ts +6 -2
- package/src/maintenance/types.ts +1 -1
- package/src/materialization/index.ts +2 -0
- package/src/materialization/model.ts +14 -1
- package/src/materializer/README.md +1 -1
- package/src/materializer/index.ts +2 -0
- package/src/materializer/materializer.ts +10 -0
- package/src/materializer/projections/entry-validator.ts +19 -1
- package/src/materializer/projections/replace.ts +36 -1
- package/src/materializer/projections/source-materialization.ts +26 -6
- package/src/materializer/shared/normalize.ts +1 -1
- package/src/models/definitions.ts +19 -0
- package/src/models/pricing.ts +6 -2
- package/src/pipelines/run-dispatch.ts +21 -1
- package/src/projections/run-dispatch.ts +30 -68
- package/src/queues/in-memory.ts +105 -62
- package/src/queues/indexed-heap.ts +74 -0
- package/src/runtime/host.ts +0 -14
- package/src/runtime/ontology-mutations.ts +4 -0
- package/src/storage/connector-connections/in-memory.ts +19 -19
- package/src/storage/connector-connections/provider/connections.ts +1 -15
- package/src/storage/connector-connections/provider/runs.ts +9 -1
- package/src/storage/connector-connections/provider/shared.ts +2 -3
- package/src/storage/connector-connections/provider.ts +6 -0
- package/src/storage/connector-connections/types.ts +8 -3
- package/src/storage/index.ts +1 -0
- package/src/storage/ontology/in-memory/materializations-state.ts +5 -18
- package/src/storage/ontology/in-memory/materializations.ts +73 -92
- package/src/storage/ontology/in-memory/shared-state.ts +36 -4
- package/src/storage/ontology/in-memory/source-roots.ts +123 -0
- package/src/storage/ontology/in-memory/sources.ts +78 -23
- package/src/storage/ontology/index.ts +1 -0
- package/src/storage/ontology/outbox.ts +1 -0
- package/src/storage/ontology/provider.ts +70 -0
- package/src/storage/ontology/sources.ts +14 -3
- package/src/storage/projection-runs/lifecycle.ts +5 -2
- package/src/storage/projection-runs/types.ts +4 -3
- package/src/syncs/run-dispatch.ts +19 -1
- package/src/testing/broker-contract.ts +95 -0
- package/src/testing/connector-connection-storage-contract.ts +29 -12
- package/src/testing/index.ts +1 -0
- package/src/testing/lake-changes-contract.ts +240 -0
- package/src/testing/lake-storage-contract.ts +29 -0
- package/src/testing/materializer-storage-contract.ts +172 -1
- package/src/testing/ontology-storage-contract.ts +15 -3
- package/src/testing/projection-run-storage-contract.ts +34 -0
- package/src/webhooks/connections.ts +56 -0
- package/src/webhooks/index.ts +2 -0
- package/src/webhooks/internal.ts +2 -0
- package/src/webhooks/registry.ts +3 -4
- package/src/webhooks/types.ts +17 -4
- package/src/workflows/run-dispatch.ts +42 -29
- package/dist/chunk-0rdrecsb.js.map +0 -11
- package/dist/chunk-3f7veca0.js.map +0 -10
- package/dist/chunk-3frsnm7x.js.map +0 -11
- package/dist/chunk-3tgwrcyh.js.map +0 -14
- package/dist/chunk-52hbv0ak.js.map +0 -36
- package/dist/chunk-e0d1rzef.js.map +0 -15
- package/dist/chunk-emyyk7dx.js.map +0 -14
- package/dist/chunk-jjy0fhrn.js.map +0 -12
- package/dist/chunk-k3cqkkn2.js.map +0 -12
- package/dist/chunk-ppytyr6w.js.map +0 -12
- package/dist/chunk-qhcpj9wc.js.map +0 -14
- package/dist/chunk-r29fxdhn.js.map +0 -11
- package/dist/chunk-zcnq6105.js.map +0 -10
- /package/dist/{chunk-ypbtykv6.js.map → chunk-01kj2pbh.js.map} +0 -0
- /package/dist/{chunk-xyr8kppc.js.map → chunk-1yefycb1.js.map} +0 -0
- /package/dist/{chunk-m3z3x9v0.js.map → chunk-3ckk0xfj.js.map} +0 -0
- /package/dist/{chunk-0w35wavj.js.map → chunk-a0e6x5hd.js.map} +0 -0
- /package/dist/{chunk-h1gfhhbh.js.map → chunk-d63nnr5b.js.map} +0 -0
- /package/dist/{chunk-r4tfx1sf.js.map → chunk-fh8kgex1.js.map} +0 -0
- /package/dist/{chunk-vf691g1r.js.map → chunk-sepyxgpc.js.map} +0 -0
- /package/dist/{chunk-1enhpacz.js.map → chunk-z0s4axeh.js.map} +0 -0
package/src/webhooks/types.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ConnectorConnectionMetadata, ConnectorDefinition } from "../connectors/types"
|
|
2
2
|
import type { Logger } from "../logging"
|
|
3
3
|
import type { OntologySource, Sixb } from "../runtime"
|
|
4
4
|
|
|
@@ -49,7 +49,7 @@ export interface WebhookMetadata {
|
|
|
49
49
|
|
|
50
50
|
/** Pre-admission input. It intentionally has no execution SDK or run-scoped logger. */
|
|
51
51
|
export interface WebhookVerifyContext {
|
|
52
|
-
readonly connector:
|
|
52
|
+
readonly connector: ConnectorDefinition
|
|
53
53
|
readonly webhook: WebhookMetadata
|
|
54
54
|
readonly request: Request
|
|
55
55
|
readonly rawBody: Uint8Array
|
|
@@ -60,7 +60,9 @@ export interface WebhookHandlerContext<TBody, TClient> extends WebhookVerifyCont
|
|
|
60
60
|
readonly sixb: Sixb<readonly OntologySource[]>
|
|
61
61
|
readonly logger: Logger
|
|
62
62
|
readonly body: TBody
|
|
63
|
-
/**
|
|
63
|
+
/** Resolve selected managed connections for an external account in this connector. */
|
|
64
|
+
readonly connections: WebhookConnections<TClient>
|
|
65
|
+
/** Resolve a static connector's client. For OAuth, use connections.forAccount(). */
|
|
64
66
|
client(): Promise<TClient>
|
|
65
67
|
}
|
|
66
68
|
|
|
@@ -93,9 +95,20 @@ export type WebhookHandlerResult = WebhookResponse | void
|
|
|
93
95
|
export interface RegisteredWebhook<
|
|
94
96
|
TBody = unknown,
|
|
95
97
|
TClient = unknown,
|
|
96
|
-
TConnector extends
|
|
98
|
+
TConnector extends ConnectorDefinition = ConnectorDefinition,
|
|
97
99
|
> {
|
|
98
100
|
readonly connector: TConnector
|
|
99
101
|
readonly webhook: WebhookDefinition<TBody, TClient>
|
|
100
102
|
readonly route: string
|
|
101
103
|
}
|
|
104
|
+
|
|
105
|
+
export interface WebhookConnection<TClient = unknown> {
|
|
106
|
+
readonly connection: ConnectorConnectionMetadata
|
|
107
|
+
/** First call rechecks the connection and creates its client; later calls reuse that client. */
|
|
108
|
+
client(): Promise<TClient>
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface WebhookConnections<TClient = unknown> {
|
|
112
|
+
/** Returns all matching selected connections; an unknown account returns an empty array. */
|
|
113
|
+
forAccount(accountId: string): Promise<readonly WebhookConnection<TClient>[]>
|
|
114
|
+
}
|
|
@@ -57,6 +57,8 @@ interface DispatchWorkflowRunInput {
|
|
|
57
57
|
readonly source?: WorkflowRunSource
|
|
58
58
|
readonly metadata?: Readonly<Record<string, string>>
|
|
59
59
|
readonly queueJobId?: string
|
|
60
|
+
/** Automatic callers own publication retries; validate provenance before any replay effect. */
|
|
61
|
+
readonly validateExistingRun?: (run: WorkflowRunRecord) => Promise<void>
|
|
60
62
|
readonly createExecution: (executionId: string, runId: string) => Promise<CreateExecutionInput>
|
|
61
63
|
}
|
|
62
64
|
|
|
@@ -88,7 +90,7 @@ export class WorkflowRunDispatcher implements WorkflowRunDispatchPort {
|
|
|
88
90
|
throw new WorkflowValidationError(`[Sixb] Unknown workflow '${input.workflowId}'`)
|
|
89
91
|
}
|
|
90
92
|
|
|
91
|
-
|
|
93
|
+
return dispatchWorkflowRun({
|
|
92
94
|
errorReporterHost: this.dependencies,
|
|
93
95
|
projectId: this.dependencies.id,
|
|
94
96
|
workflow,
|
|
@@ -106,6 +108,7 @@ export class WorkflowRunDispatcher implements WorkflowRunDispatchPort {
|
|
|
106
108
|
},
|
|
107
109
|
metadata: input.metadata,
|
|
108
110
|
queueJobId: input.runId,
|
|
111
|
+
validateExistingRun: (run) => assertAutomaticExecutionIdentity(this.dependencies, input, run),
|
|
109
112
|
createExecution: async (executionId, runId) =>
|
|
110
113
|
createPrimitiveExecutionRecord({
|
|
111
114
|
id: executionId,
|
|
@@ -118,10 +121,6 @@ export class WorkflowRunDispatcher implements WorkflowRunDispatchPort {
|
|
|
118
121
|
},
|
|
119
122
|
}),
|
|
120
123
|
})
|
|
121
|
-
if (!result.created) {
|
|
122
|
-
await assertAutomaticExecutionIdentity(this.dependencies, input, result.runId)
|
|
123
|
-
}
|
|
124
|
-
return result
|
|
125
124
|
}
|
|
126
125
|
}
|
|
127
126
|
|
|
@@ -131,7 +130,15 @@ export async function dispatchWorkflowRun(
|
|
|
131
130
|
): Promise<WorkflowRunRequestResult> {
|
|
132
131
|
const request = prepareWorkflowRun(input)
|
|
133
132
|
const persisted = await persistWorkflowRun(input, request)
|
|
134
|
-
if (!persisted.created)
|
|
133
|
+
if (!persisted.created) {
|
|
134
|
+
await input.validateExistingRun?.(persisted.run)
|
|
135
|
+
if (input.validateExistingRun && persisted.run.status === "queued") {
|
|
136
|
+
// A queued run is also the recoverable intent when publication never completed.
|
|
137
|
+
// Reuse the provider job identity, including after a successful but unacknowledged enqueue.
|
|
138
|
+
await enqueueWorkflowRun(input, persisted.run)
|
|
139
|
+
}
|
|
140
|
+
return existingWorkflowRunResult(persisted.run)
|
|
141
|
+
}
|
|
135
142
|
return publishWorkflowRun(input, persisted)
|
|
136
143
|
}
|
|
137
144
|
|
|
@@ -213,20 +220,11 @@ async function publishWorkflowRun(
|
|
|
213
220
|
): Promise<WorkflowRunRequestResult> {
|
|
214
221
|
let job: Awaited<ReturnType<Queues["workflows"]["enqueue"]>>[number] | undefined
|
|
215
222
|
try {
|
|
216
|
-
|
|
217
|
-
projectId: input.projectId,
|
|
218
|
-
jobs: [
|
|
219
|
-
{
|
|
220
|
-
...(input.queueJobId === undefined ? {} : { id: input.queueJobId }),
|
|
221
|
-
type: "workflow.run.requested",
|
|
222
|
-
payload: { runId: persisted.run.id },
|
|
223
|
-
...(input.metadata === undefined ? {} : { metadata: input.metadata }),
|
|
224
|
-
},
|
|
225
|
-
],
|
|
226
|
-
})
|
|
227
|
-
job = jobs[0]
|
|
223
|
+
job = await enqueueWorkflowRun(input, persisted.run)
|
|
228
224
|
} catch (error) {
|
|
229
|
-
|
|
225
|
+
// Automatic dispatch retries the same run. Do not turn an uncertain enqueue into
|
|
226
|
+
// a terminal business failure: the queue may have accepted it before losing the reply.
|
|
227
|
+
if (!input.validateExistingRun) await failWorkflowRunPublication(input, persisted.run, error)
|
|
230
228
|
throw error
|
|
231
229
|
}
|
|
232
230
|
|
|
@@ -258,6 +256,27 @@ async function publishWorkflowRun(
|
|
|
258
256
|
}
|
|
259
257
|
}
|
|
260
258
|
|
|
259
|
+
async function enqueueWorkflowRun(
|
|
260
|
+
input: DispatchWorkflowRunInput,
|
|
261
|
+
run: WorkflowRunRecord
|
|
262
|
+
): Promise<Awaited<ReturnType<Queues["workflows"]["enqueue"]>>[number]> {
|
|
263
|
+
const [job] = await input.queue.enqueue({
|
|
264
|
+
projectId: input.projectId,
|
|
265
|
+
jobs: [
|
|
266
|
+
{
|
|
267
|
+
...(input.queueJobId === undefined ? {} : { id: input.queueJobId }),
|
|
268
|
+
type: "workflow.run.requested",
|
|
269
|
+
payload: { runId: run.id },
|
|
270
|
+
...(input.metadata === undefined ? {} : { metadata: input.metadata }),
|
|
271
|
+
},
|
|
272
|
+
],
|
|
273
|
+
})
|
|
274
|
+
if (!job || (input.queueJobId !== undefined && job.id !== input.queueJobId)) {
|
|
275
|
+
throw new WorkflowRunError(`[Sixb] Queue did not acknowledge workflow run '${run.id}'.`)
|
|
276
|
+
}
|
|
277
|
+
return job
|
|
278
|
+
}
|
|
279
|
+
|
|
261
280
|
async function failWorkflowRunPublication(
|
|
262
281
|
input: DispatchWorkflowRunInput,
|
|
263
282
|
run: WorkflowRunRecord,
|
|
@@ -326,18 +345,12 @@ function assertAutomaticDispatchInput(input: AutomaticWorkflowRunDispatchInput):
|
|
|
326
345
|
async function assertAutomaticExecutionIdentity(
|
|
327
346
|
dependencies: WorkflowRunDispatcherDependencies,
|
|
328
347
|
input: AutomaticWorkflowRunDispatchInput,
|
|
329
|
-
|
|
348
|
+
run: WorkflowRunRecord
|
|
330
349
|
): Promise<void> {
|
|
331
|
-
const
|
|
350
|
+
const execution = await dependencies.storage.executions.getById({
|
|
332
351
|
projectId: dependencies.id,
|
|
333
|
-
id:
|
|
352
|
+
id: run.executionId,
|
|
334
353
|
})
|
|
335
|
-
const execution = run
|
|
336
|
-
? await dependencies.storage.executions.getById({
|
|
337
|
-
projectId: dependencies.id,
|
|
338
|
-
id: run.executionId,
|
|
339
|
-
})
|
|
340
|
-
: null
|
|
341
354
|
if (
|
|
342
355
|
!execution ||
|
|
343
356
|
execution.source.type !== input.source.type ||
|
|
@@ -346,7 +359,7 @@ async function assertAutomaticExecutionIdentity(
|
|
|
346
359
|
execution.requestedBy !== undefined
|
|
347
360
|
) {
|
|
348
361
|
throw new WorkflowValidationError(
|
|
349
|
-
`[Sixb] Workflow run '${
|
|
362
|
+
`[Sixb] Workflow run '${run.id}' already exists with different automatic provenance.`
|
|
350
363
|
)
|
|
351
364
|
}
|
|
352
365
|
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/broker/errors.ts", "../src/broker/in-memory.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"export class BrokerError extends Error {\n readonly name: string = \"BrokerError\"\n\n constructor(message: string, options?: ErrorOptions) {\n super(`[Broker] ${message}`, options)\n }\n}\n\n/**\n * Raised when retention has removed the cursor a consumer wants to resume\n * from. Transports use this provider-independent type to request a reset.\n */\nexport class BrokerCursorExpiredError extends BrokerError {\n override readonly name = \"BrokerCursorExpiredError\"\n}\n",
|
|
6
|
-
"import { getInvalidJsonValueReason, type JsonValue } from \"../json\"\nimport { BrokerCursorExpiredError, BrokerError } from \"./errors\"\nimport type {\n Broker,\n BrokerPage,\n BrokerRecord,\n BrokerRecordInput,\n BrokerStreamDefinition,\n} from \"./types\"\n\n// Payloads are validated by assertBrokerPayload above the call site, so we can\n// skip the redundant validity walk that cloneJsonValue performs.\nfunction cloneValidatedPayload(value: JsonValue): JsonValue {\n return JSON.parse(JSON.stringify(value)) as JsonValue\n}\n\n// Records stored internally carry a numeric publishedAtMs alongside the public\n// ISO publishedAt string so retention sweeps can avoid Date.parse on every\n// record on every append/read.\ninterface StoredRecord extends BrokerRecord {\n readonly publishedAtMs: number\n readonly byteSize: number\n}\n\ninterface StoredStream {\n definition: BrokerStreamDefinition\n nextSequence: bigint\n records: StoredRecord[]\n retainedBytes: number\n}\n\ninterface Subscription {\n readonly projectId: string\n readonly streamId: string\n readonly names?: readonly string[]\n readonly keys?: readonly string[]\n readonly handler: (records: readonly BrokerRecord[]) => void\n}\n\nexport class InMemoryBroker implements Broker {\n readonly scope = \"process\" as const\n private readonly streams = new Map<string, StoredStream>()\n private readonly subscriptions = new Set<Subscription>()\n\n async ensureStream(params: { projectId: string; stream: BrokerStreamDefinition }): Promise<void> {\n assertProjectId(params.projectId)\n assertStream(params.stream)\n this.getOrCreateStream(params.projectId, params.stream)\n }\n\n async append(params: {\n projectId: string\n streamId: string\n records: readonly BrokerRecordInput[]\n }): Promise<readonly BrokerRecord[]> {\n assertProjectId(params.projectId)\n assertStreamId(params.streamId)\n\n if (params.records.length === 0) {\n return []\n }\n\n for (const record of params.records) {\n assertBrokerPayload(record.payload)\n }\n\n const storedStream = this.getEnsuredStream(params.projectId, params.streamId)\n const stored: StoredRecord[] = []\n\n for (const record of params.records) {\n const cursor = storedStream.nextSequence.toString()\n storedStream.nextSequence += 1n\n const publishedAtMs = Date.now()\n const storedRecord = {\n streamId: params.streamId,\n cursor,\n name: record.name,\n key: record.key,\n payload: cloneValidatedPayload(record.payload as JsonValue),\n publishedAt: new Date(publishedAtMs).toISOString(),\n publishedAtMs,\n }\n stored.push({\n ...storedRecord,\n byteSize: utf8Bytes(JSON.stringify(storedRecord)),\n })\n }\n\n storedStream.records.push(...stored)\n storedStream.retainedBytes += stored.reduce((total, record) => total + record.byteSize, 0)\n this.applyRetention(storedStream)\n const records = stored.map(toBrokerRecord)\n this.notify(params.projectId, params.streamId, stored)\n return records\n }\n\n async read(params: {\n projectId: string\n streamId: string\n afterCursor?: string\n limit?: number\n names?: readonly string[]\n keys?: readonly string[]\n }): Promise<BrokerPage> {\n assertProjectId(params.projectId)\n assertStreamId(params.streamId)\n assertCursor(params.afterCursor)\n\n if (params.limit !== undefined && params.limit <= 0) {\n return { records: [], cursor: params.afterCursor, hasMore: false }\n }\n\n const storedStream = this.streams.get(streamKey(params.projectId, params.streamId))\n if (!storedStream) {\n return { records: [], cursor: params.afterCursor, hasMore: false }\n }\n\n this.applyRetention(storedStream)\n this.assertCursorInRetainedRange(storedStream, params.afterCursor)\n return this.readForward(storedStream.records, {\n afterCursor: params.afterCursor,\n limit: params.limit,\n names: params.names,\n keys: params.keys,\n })\n }\n\n async tail(params: {\n projectId: string\n streamId: string\n beforeCursor?: string\n limit?: number\n names?: readonly string[]\n keys?: readonly string[]\n }): Promise<BrokerPage> {\n assertProjectId(params.projectId)\n assertStreamId(params.streamId)\n assertCursor(params.beforeCursor)\n\n if (params.limit !== undefined && params.limit <= 0) {\n return { records: [], cursor: params.beforeCursor, hasMore: false }\n }\n\n const storedStream = this.streams.get(streamKey(params.projectId, params.streamId))\n if (!storedStream) {\n return { records: [], cursor: params.beforeCursor, hasMore: false }\n }\n\n this.applyRetention(storedStream)\n this.assertTailCursorInRetainedRange(storedStream, params.beforeCursor)\n return this.readBackward(storedStream.records, params)\n }\n\n async latestCursor(params: { projectId: string; streamId: string }): Promise<string | undefined> {\n assertProjectId(params.projectId)\n assertStreamId(params.streamId)\n\n const storedStream = this.streams.get(streamKey(params.projectId, params.streamId))\n if (!storedStream) {\n return undefined\n }\n\n this.applyRetention(storedStream)\n return storedStream.records.at(-1)?.cursor\n }\n\n async subscribe(\n params: {\n projectId: string\n streamId: string\n from?: \"latest\" | \"earliest\"\n afterCursor?: string\n names?: readonly string[]\n keys?: readonly string[]\n },\n handler: (records: readonly BrokerRecord[]) => void\n ): Promise<() => void> {\n assertProjectId(params.projectId)\n assertStreamId(params.streamId)\n assertCursor(params.afterCursor)\n const storedStream = this.getEnsuredStream(params.projectId, params.streamId)\n\n // Retention may have trimmed past the caller's cursor. Reject that here rather than let\n // `readForward` skip silently to the oldest retained record: a resuming subscriber would be\n // fast-forwarded over the gap and would believe it had seen everything. `read` and `tail`\n // already reject it, and so does the Redis provider, so this keeps the three consistent.\n // Checked before the subscription is registered so a throw cannot leave one behind.\n this.applyRetention(storedStream)\n this.assertCursorInRetainedRange(storedStream, params.afterCursor)\n\n const subscription: Subscription = {\n projectId: params.projectId,\n streamId: params.streamId,\n names: params.names,\n keys: params.keys,\n handler,\n }\n this.subscriptions.add(subscription)\n\n const startMode = params.afterCursor !== undefined ? undefined : (params.from ?? \"latest\")\n if (params.afterCursor !== undefined || startMode === \"earliest\") {\n const initial = this.readForward(storedStream.records, {\n afterCursor: params.afterCursor,\n names: params.names,\n keys: params.keys,\n }).records\n this.deliver(subscription, initial)\n }\n\n return () => {\n this.subscriptions.delete(subscription)\n }\n }\n\n private getOrCreateStream(projectId: string, stream: BrokerStreamDefinition): StoredStream {\n const key = streamKey(projectId, stream.id)\n let storedStream = this.streams.get(key)\n if (!storedStream) {\n storedStream = {\n definition: stream,\n nextSequence: 1n,\n records: [],\n retainedBytes: 0,\n }\n this.streams.set(key, storedStream)\n }\n this.applyRetention(storedStream)\n return storedStream\n }\n\n private getEnsuredStream(projectId: string, streamId: string): StoredStream {\n const storedStream = this.streams.get(streamKey(projectId, streamId))\n if (!storedStream) {\n throw new BrokerError(\n `stream '${streamId}' has not been ensured for project '${projectId}'. Call ensureStream() before append or subscribe.`\n )\n }\n return storedStream\n }\n\n private applyRetention(storedStream: StoredStream): void {\n const { retention } = storedStream.definition\n if (!retention) {\n return\n }\n\n let removeCount = 0\n const records = storedStream.records\n\n if (retention.maxAgeMs !== undefined) {\n if (retention.maxAgeMs <= 0) {\n removeCount = records.length\n } else {\n const oldestAllowed = Date.now() - retention.maxAgeMs\n // Records are appended in chronological order, so we only need to find\n // the first record that is still in range and slice off the prefix —\n // avoids walking the entire retained set on every sweep.\n let firstInRange = 0\n while (\n firstInRange < records.length &&\n records[firstInRange].publishedAtMs < oldestAllowed\n ) {\n firstInRange += 1\n }\n removeCount = Math.max(removeCount, firstInRange)\n }\n }\n\n if (retention.maxRecords !== undefined) {\n if (retention.maxRecords <= 0) {\n removeCount = records.length\n } else if (records.length - removeCount > retention.maxRecords) {\n removeCount = records.length - retention.maxRecords\n }\n }\n\n if (retention.maxBytes !== undefined) {\n if (retention.maxBytes <= 0) {\n removeCount = records.length\n } else {\n let bytes = storedStream.retainedBytes\n for (let index = 0; index < removeCount; index += 1) {\n bytes -= records[index]!.byteSize\n }\n while (removeCount < records.length && bytes > retention.maxBytes) {\n bytes -= records[removeCount]!.byteSize\n removeCount += 1\n }\n }\n }\n\n if (removeCount > 0) {\n for (let index = 0; index < removeCount; index += 1) {\n storedStream.retainedBytes -= records[index]!.byteSize\n }\n storedStream.records = records.slice(removeCount)\n }\n }\n\n private assertCursorInRetainedRange(\n storedStream: StoredStream,\n afterCursor: string | undefined\n ): void {\n if (afterCursor === undefined) {\n return\n }\n\n const requestedNextSequence = BigInt(afterCursor) + 1n\n const firstRecord = storedStream.records[0]\n const firstAvailableSequence =\n firstRecord === undefined ? storedStream.nextSequence : BigInt(firstRecord.cursor)\n\n if (requestedNextSequence < firstAvailableSequence) {\n throw new BrokerCursorExpiredError(\n `afterCursor '${afterCursor}' is outside the retained range for stream '${storedStream.definition.id}'. ` +\n `The next requested cursor sequence is '${requestedNextSequence}', but the earliest ` +\n `available cursor sequence is '${firstAvailableSequence}'.`\n )\n }\n }\n\n private assertTailCursorInRetainedRange(\n storedStream: StoredStream,\n beforeCursor: string | undefined\n ): void {\n if (beforeCursor === undefined || storedStream.records.length === 0) {\n return\n }\n const firstAvailableSequence = BigInt(storedStream.records[0]!.cursor)\n if (BigInt(beforeCursor) < firstAvailableSequence) {\n throw new BrokerCursorExpiredError(\n `beforeCursor '${beforeCursor}' is outside the retained range for stream '${storedStream.definition.id}'. ` +\n `The earliest available cursor sequence is '${firstAvailableSequence}'.`\n )\n }\n }\n\n private notify(projectId: string, streamId: string, records: readonly StoredRecord[]): void {\n for (const subscription of this.subscriptions) {\n if (subscription.projectId !== projectId || subscription.streamId !== streamId) {\n continue\n }\n this.deliver(\n subscription,\n this.readForward(records, {\n names: subscription.names,\n keys: subscription.keys,\n }).records\n )\n }\n }\n\n private deliver(subscription: Subscription, records: readonly BrokerRecord[]): void {\n if (records.length === 0) {\n return\n }\n\n try {\n subscription.handler(records)\n } catch {\n // Broker subscriptions are live fan-out; handler failures should not break publishers.\n }\n }\n\n private readForward(\n records: readonly StoredRecord[],\n filters: {\n afterCursor?: string\n limit?: number\n names?: readonly string[]\n keys?: readonly string[]\n }\n ): BrokerPage {\n const names = filters.names && filters.names.length > 0 ? new Set(filters.names) : undefined\n const keys = filters.keys && filters.keys.length > 0 ? new Set(filters.keys) : undefined\n const afterCursor = filters.afterCursor ? BigInt(filters.afterCursor) : undefined\n const result: BrokerRecord[] = []\n let cursor = filters.afterCursor\n let stoppedAt = records.length\n\n for (let index = 0; index < records.length; index += 1) {\n const record = records[index]!\n if (afterCursor !== undefined && BigInt(record.cursor) <= afterCursor) {\n continue\n }\n cursor = record.cursor\n if (!matchesFilters(record, names, keys)) {\n continue\n }\n result.push(toBrokerRecord(record))\n if (filters.limit !== undefined && result.length >= filters.limit) {\n stoppedAt = index + 1\n break\n }\n }\n\n return {\n records: result,\n cursor,\n hasMore: records.slice(stoppedAt).some((record) => matchesFilters(record, names, keys)),\n }\n }\n\n private readBackward(\n records: readonly StoredRecord[],\n filters: {\n beforeCursor?: string\n limit?: number\n names?: readonly string[]\n keys?: readonly string[]\n }\n ): BrokerPage {\n const names = filters.names && filters.names.length > 0 ? new Set(filters.names) : undefined\n const keys = filters.keys && filters.keys.length > 0 ? new Set(filters.keys) : undefined\n const beforeCursor = filters.beforeCursor ? BigInt(filters.beforeCursor) : undefined\n const reversed: BrokerRecord[] = []\n let cursor = filters.beforeCursor\n let stoppedAt = -1\n\n for (let index = records.length - 1; index >= 0; index -= 1) {\n const record = records[index]!\n if (beforeCursor !== undefined && BigInt(record.cursor) >= beforeCursor) {\n continue\n }\n cursor = record.cursor\n if (!matchesFilters(record, names, keys)) {\n continue\n }\n reversed.push(toBrokerRecord(record))\n if (filters.limit !== undefined && reversed.length >= filters.limit) {\n stoppedAt = index - 1\n break\n }\n }\n\n return {\n records: reversed.reverse(),\n cursor,\n hasMore:\n stoppedAt >= 0 &&\n records.slice(0, stoppedAt + 1).some((record) => matchesFilters(record, names, keys)),\n }\n }\n}\n\nfunction matchesFilters(\n record: BrokerRecord,\n names: ReadonlySet<string> | undefined,\n keys: ReadonlySet<string> | undefined\n): boolean {\n return (\n (!names || (!!record.name && names.has(record.name))) &&\n (!keys || (!!record.key && keys.has(record.key)))\n )\n}\n\nfunction streamKey(projectId: string, streamId: string): string {\n return `${projectId}\\0${streamId}`\n}\n\nfunction toBrokerRecord(record: StoredRecord): BrokerRecord {\n return {\n streamId: record.streamId,\n cursor: record.cursor,\n name: record.name,\n key: record.key,\n payload: record.payload,\n publishedAt: record.publishedAt,\n }\n}\n\nfunction utf8Bytes(value: string): number {\n return new TextEncoder().encode(value).byteLength\n}\n\nfunction assertProjectId(projectId: string): void {\n if (projectId.trim().length === 0) {\n throw new BrokerError(\"projectId must be a non-empty string\")\n }\n}\n\nfunction assertStream(stream: BrokerStreamDefinition): void {\n if (stream.id.trim().length === 0) {\n throw new BrokerError(\"stream.id must be a non-empty string\")\n }\n}\n\nfunction assertStreamId(streamId: string): void {\n if (streamId.trim().length === 0) {\n throw new BrokerError(\"streamId must be a non-empty string\")\n }\n}\n\nfunction assertBrokerPayload(payload: unknown): void {\n const reason = getInvalidJsonValueReason(payload, \"record.payload\")\n if (reason) {\n throw new BrokerError(`record.payload must be a JSON value; ${reason}`)\n }\n}\n\nfunction assertCursor(cursor: string | undefined): void {\n if (cursor === undefined) {\n return\n }\n\n try {\n if (BigInt(cursor) < 0n) {\n throw new BrokerError(\"cursor must be non-negative\")\n }\n } catch (error) {\n if (error instanceof BrokerError) {\n throw error\n }\n throw new BrokerError(\"cursor must be a numeric in-memory broker cursor\", {\n cause: error,\n })\n }\n}\n"
|
|
7
|
-
],
|
|
8
|
-
"mappings": "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",
|
|
9
|
-
"debugId": "356153004EE6A88A64756E2164756E21",
|
|
10
|
-
"names": []
|
|
11
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/connectors/types.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"import type { WebhookDefinition } from \"../webhooks/types\"\n\n/**\n * Runtime context passed to connector adapters when Sixb establishes a connection.\n *\n * Connectors can use this to scope logs, build cache keys, or attach cancellation\n * to long-running startup work.\n */\nexport interface ConnectorContext {\n readonly projectId: string\n readonly connectorId: string\n readonly signal: AbortSignal\n}\n\n/**\n * Minimal contract for a Sixb connector adapter.\n *\n * Adapters are responsible for creating and optionally tearing down a client for an\n * external system. They should return the client shape that feels natural for that system.\n */\nexport interface ConnectorAdapter<TType extends string = string, TClient = unknown> {\n readonly type: TType\n readonly authentication?: never\n readonly webhooks?: readonly WebhookDefinition<unknown, TClient>[]\n connect(context: ConnectorContext): Promise<TClient> | TClient\n disconnect?(client: TClient): Promise<void> | void\n}\n\n/** One OAuth token set normalized by an OAuth connector adapter. */\nexport interface ConnectorOAuthCredentials {\n readonly accessToken: string\n readonly refreshToken?: string\n readonly tokenType?: string\n readonly scopes?: readonly string[]\n readonly expiresAt?: Date\n}\n\n/** Public, non-secret account information returned for framework-owned selection UI. */\nexport interface ConnectorAccountCandidate {\n readonly id: string\n readonly label: string\n readonly description?: string\n readonly avatarUrl?: string\n}\n\n/** V1 intentionally supports project-owned connector connections only. */\nexport interface ProjectConnectorConnectionOwner {\n readonly type: \"project\"\n}\n\nexport type ConnectorConnectionOwner = ProjectConnectorConnectionOwner\n\n/** Stable application-defined lookup key for one connector connection. */\nexport interface ConnectorConnectionSelector {\n readonly owner: ConnectorConnectionOwner\n readonly slot: string\n}\n\n/** Stable, non-secret metadata shared by connector connection consumers. */\nexport interface ConnectorConnectionMetadata extends ConnectorConnectionSelector {\n readonly id: string\n readonly connectorId: string\n readonly account: ConnectorAccountCandidate\n}\n\n/** Credential protection required when an OAuth connector uses durable connection storage. */\nexport interface ConnectorConnectionOptions {\n /** Canonical base64url encoding of exactly 32 random bytes, shared by storage replicas. */\n readonly encryptionKey: string\n}\n\nexport interface OAuthConnectorAuthorizationContext extends ConnectorContext {\n readonly redirectUri: string\n}\n\nexport interface OAuthConnectorAuthorizationUrlInput {\n readonly state: string\n readonly codeChallenge: string\n readonly codeChallengeMethod: \"S256\"\n}\n\nexport interface OAuthConnectorCodeExchangeInput {\n readonly code: string\n readonly codeVerifier: string\n}\n\nexport interface ConnectorConnectionClientContext extends ConnectorContext {\n readonly connectionId: string\n readonly account: ConnectorAccountCandidate\n readonly tokenSource: ConnectorTokenSource\n}\n\n/** One delivered token, bound to the credential revision that produced it. */\nexport interface ConnectorAccessToken {\n readonly accessToken: string\n readonly tokenType?: string\n /** Report this exact token as rejected so Sixb can refresh only its credential revision. */\n invalidate(): void\n}\n\n/** Live credential source owned by Sixb. Adapters must resolve a token for each request. */\nexport interface ConnectorTokenSource {\n get(): Promise<ConnectorAccessToken>\n}\n\n/**\n * OAuth-backed connector adapter. Sixb owns persistence, OAuth state, refresh coordination and UI;\n * the adapter owns provider protocol details and typed client creation.\n */\nexport interface ConnectorOAuth2Authentication {\n readonly type: \"oauth2\"\n authorizationUrl(\n context: OAuthConnectorAuthorizationContext,\n input: OAuthConnectorAuthorizationUrlInput\n ): Promise<string | URL> | string | URL\n exchangeCode(\n context: OAuthConnectorAuthorizationContext,\n input: OAuthConnectorCodeExchangeInput\n ): Promise<ConnectorOAuthCredentials> | ConnectorOAuthCredentials\n refresh(\n context: ConnectorContext,\n credentials: ConnectorOAuthCredentials\n ): Promise<ConnectorOAuthCredentials> | ConnectorOAuthCredentials\n /**\n * Revokes the grant idempotently. An already revoked or invalid grant must resolve successfully\n * so Sixb can converge after losing an earlier provider response.\n */\n revoke?(context: ConnectorContext, credentials: ConnectorOAuthCredentials): Promise<void> | void\n}\n\nexport interface OAuthConnectorAdapter<TType extends string = string, TClient = unknown> {\n readonly type: TType\n readonly authentication: ConnectorOAuth2Authentication\n readonly webhooks?: undefined\n discoverAccounts(\n context: ConnectorContext,\n credentials: ConnectorOAuthCredentials\n ): Promise<readonly ConnectorAccountCandidate[]> | readonly ConnectorAccountCandidate[]\n connect(context: ConnectorConnectionClientContext): Promise<TClient> | TClient\n}\n\nexport type AnyConnectorAdapter = ConnectorAdapter | OAuthConnectorAdapter\n\n/**\n * Inert connector definition registered with Sixb.\n *\n * Definitions are safe to export from `connectors/` modules. The runtime turns them into\n * live clients when `sixb.connector(...)` is called.\n */\nexport interface ConnectorDefinition<\n TId extends string = string,\n TAdapter extends AnyConnectorAdapter = AnyConnectorAdapter,\n> {\n readonly kind: \"connector\"\n readonly id: TId\n readonly adapter: TAdapter\n}\n\nexport type StaticConnectorDefinition = ConnectorDefinition<string, ConnectorAdapter>\n\n/** Infer the connected client type returned by a connector adapter. */\nexport type ConnectorClient<TAdapter extends AnyConnectorAdapter> = Awaited<\n ReturnType<TAdapter[\"connect\"]>\n>\n\nexport function isOAuthConnectorAdapter(\n value: AnyConnectorAdapter\n): value is OAuthConnectorAdapter {\n return \"authentication\" in value && value.authentication?.type === \"oauth2\"\n}\n\nexport function isOAuthConnectorDefinition(\n value: ConnectorDefinition\n): value is ConnectorDefinition<string, OAuthConnectorAdapter> {\n return isOAuthConnectorAdapter(value.adapter)\n}\n\nexport function isStaticConnectorDefinition(\n value: ConnectorDefinition\n): value is StaticConnectorDefinition {\n return !isOAuthConnectorDefinition(value)\n}\n\nexport function isConnectorDefinition(value: unknown): value is ConnectorDefinition {\n if (!isRecord(value)) {\n return false\n }\n\n const adapter = value.adapter\n if (\n value.kind === \"connector\" &&\n typeof value.id === \"string\" &&\n isRecord(adapter) &&\n typeof adapter.type === \"string\" &&\n typeof adapter.connect === \"function\"\n ) {\n if (adapter.authentication === undefined) return true\n const authentication = adapter.authentication\n if (!isRecord(authentication) || authentication.type !== \"oauth2\") return false\n return (\n typeof authentication.authorizationUrl === \"function\" &&\n typeof authentication.exchangeCode === \"function\" &&\n typeof authentication.refresh === \"function\" &&\n typeof adapter.discoverAccounts === \"function\"\n )\n }\n\n return false\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n}\n"
|
|
6
|
-
],
|
|
7
|
-
"mappings": ";;AAqKO,SAAS,uBAAuB,CACrC,OACgC;AAAA,EAChC,OAAO,oBAAoB,SAAS,MAAM,gBAAgB,SAAS;AAAA;AAG9D,SAAS,2BAA0B,CACxC,OAC6D;AAAA,EAC7D,OAAO,wBAAwB,MAAM,OAAO;AAAA;AAGvC,SAAS,2BAA2B,CACzC,OACoC;AAAA,EACpC,OAAO,CAAC,4BAA2B,KAAK;AAAA;AAGnC,SAAS,qBAAqB,CAAC,OAA8C;AAAA,EAClF,IAAI,CAAC,SAAS,KAAK,GAAG;AAAA,IACpB,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,UAAU,MAAM;AAAA,EACtB,IACE,MAAM,SAAS,eACf,OAAO,MAAM,OAAO,YACpB,SAAS,OAAO,KAChB,OAAO,QAAQ,SAAS,YACxB,OAAO,QAAQ,YAAY,YAC3B;AAAA,IACA,IAAI,QAAQ,mBAAmB;AAAA,MAAW,OAAO;AAAA,IACjD,MAAM,iBAAiB,QAAQ;AAAA,IAC/B,IAAI,CAAC,SAAS,cAAc,KAAK,eAAe,SAAS;AAAA,MAAU,OAAO;AAAA,IAC1E,OACE,OAAO,eAAe,qBAAqB,cAC3C,OAAO,eAAe,iBAAiB,cACvC,OAAO,eAAe,YAAY,cAClC,OAAO,QAAQ,qBAAqB;AAAA,EAExC;AAAA,EAEA,OAAO;AAAA;AAGT,SAAS,QAAQ,CAAC,OAAkD;AAAA,EAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAAA;",
|
|
8
|
-
"debugId": "30BD1F10D764311164756E2164756E21",
|
|
9
|
-
"names": []
|
|
10
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/projections/types.ts", "../src/storage/projection-runs/types.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"import type { SixbErrorCode } from \"../errors/types\"\n\n/** Error codes a projection run can persist and expose through its public contract. */\nexport const PROJECTION_RUN_FAILURE_CODES = [\n \"internal.unexpected\",\n \"runtime.cancelled\",\n \"queue.enqueue_failed\",\n \"projection.execution_failed\",\n] as const satisfies readonly [SixbErrorCode, ...SixbErrorCode[]]\n\nexport type ProjectionRunFailureCode = (typeof PROJECTION_RUN_FAILURE_CODES)[number]\n\n/**\n * Lowered, serializable definition interfaces for projection DSL.\n *\n * These are the runtime-inspectable data structures that projection builders\n * lower into. They use plain string ids (no tokens, no methods) so they can\n * be stored, serialized, and introspected by tooling.\n */\n\n/**\n * Describes how a foreign key column in a dataset resolves to a link target.\n *\n * The source can be either a projected source property or a raw dataset field.\n * Its value equals the target object's primary property value, creating an\n * implicit link between source and target.\n *\n * `targetObjectTypeId` declares the concrete target type for this projection.\n * It must be the same type or a subtype (via `extends`) of the link's declared\n * target at the ontology level. Validation of the subtype relationship happens\n * at Sixb startup (Increment 7), not at DSL build time.\n */\nexport interface ForeignKeyDescriptor {\n readonly linkId: string\n /** Object property holding the target id. Mutually exclusive with sourceField. */\n readonly sourcePropertyId?: string\n /** Dataset column holding the target id. Mutually exclusive with sourcePropertyId. */\n readonly sourceField?: string\n readonly targetObjectTypeId: string\n}\n\n/** Resolves competing source-projection and managed-edit values for projected properties. */\nexport type SourceEditConflictResolution =\n | { readonly strategy: \"editsWin\" }\n | { readonly strategy: \"mostRecent\"; readonly sourceTimestamp: string }\n\n/**\n * Lowered, serializable definition for projecting a dataset into object instances.\n *\n * Each row contributes one complete object root to an authoritative replacement snapshot, with\n * properties mapped from dataset columns to object type properties. Duplicate roots are rejected.\n * FK links are resolved from source property or dataset field values to target object primary\n * values.\n */\nexport interface ObjectProjectionDefinition {\n readonly _tag: \"ObjectProjectionDefinition\"\n readonly id: string\n readonly objectTypeId: string\n readonly datasetId: string\n /** Maps object type property id -> dataset column name. */\n readonly properties: Readonly<Record<string, string>>\n /** Maps link id -> FK descriptor. Empty `{}` when no FK links are projected. */\n readonly links: Readonly<Record<string, ForeignKeyDescriptor>>\n /** Defaults to `editsWin` when omitted by a legacy lowered definition. */\n readonly conflictResolution?: SourceEditConflictResolution\n}\n\n/**\n * Lowered, serializable definition for projecting a join dataset into link instances.\n *\n * Each row in the join dataset contributes one complete link root to an authoritative replacement\n * snapshot, identified by its source, link id, and target. Duplicate roots are rejected.\n */\nexport interface LinkProjectionDefinition {\n readonly _tag: \"LinkProjectionDefinition\"\n readonly id: string\n readonly linkId: string\n readonly sourceObjectTypeId: string\n readonly targetObjectTypeId: string\n readonly datasetId: string\n /** Dataset column holding the source object's primary property value. */\n readonly sourceField: string\n /** Dataset column holding the target object's primary property value. */\n readonly targetField: string\n}\n\n/** Dataset columns that produce one telemetry property value. */\nexport interface TelemetryProjectionPropertyMapping {\n /** Dataset column holding the telemetry value. */\n readonly valueField: string\n /** Dataset column holding the telemetry unit, when the property requires one. */\n readonly unitField?: string\n}\n\n/**\n * Lowered, serializable definition for projecting dataset rows into telemetry history.\n *\n * Each row shares one target object id and observation timestamp, then contributes up to one\n * telemetry point for every mapped property. A property-token projection is lowered to the same\n * shape with one entry, so execution and ownership have one canonical contract.\n */\nexport interface TelemetryProjectionDefinition {\n readonly _tag: \"TelemetryProjectionDefinition\"\n readonly id: string\n readonly objectTypeId: string\n readonly datasetId: string\n /** Dataset column holding the target object's primary id. */\n readonly objectIdField: string\n /** Dataset column holding the telemetry observation timestamp. */\n readonly atField: string\n /** Maps telemetry property id -> value and optional unit dataset columns. */\n readonly properties: Readonly<Record<string, TelemetryProjectionPropertyMapping>>\n}\n\n/** Union of all projection definition types. */\nexport type ProjectionDefinition =\n | ObjectProjectionDefinition\n | LinkProjectionDefinition\n | TelemetryProjectionDefinition\n\nexport interface ProjectionOwnership {\n readonly objects: readonly {\n readonly objectTypeId: string\n readonly existence: boolean\n readonly propertyIds: readonly string[]\n }[]\n readonly links: readonly {\n readonly sourceObjectTypeId: string\n readonly linkId: string\n }[]\n readonly telemetry: readonly {\n readonly objectTypeId: string\n readonly propertyId: string\n }[]\n}\n\n/** Canonical correlation between a projection kind and its materialization protocol. */\nexport type ProjectionProtocolIdentity =\n | { readonly projectionKind: \"object\"; readonly protocol: \"replacement\" }\n | { readonly projectionKind: \"link\"; readonly protocol: \"replacement\" }\n | { readonly projectionKind: \"telemetry\"; readonly protocol: \"telemetry\" }\n\nexport type ProjectionKind = ProjectionProtocolIdentity[\"projectionKind\"]\n\nexport interface ObjectProjectionTarget {\n readonly objectTypeId: string\n}\n\nexport interface LinkProjectionTarget {\n readonly sourceObjectTypeId: string\n readonly targetObjectTypeId: string\n}\n\nexport interface ProjectionTargetByKind {\n readonly object: ObjectProjectionTarget\n readonly link: LinkProjectionTarget\n readonly telemetry: ObjectProjectionTarget\n}\n\n/** Object types affected by one projection, correlated with its projection kind. */\nexport type ProjectionTarget<TKind extends ProjectionKind = ProjectionKind> =\n ProjectionTargetByKind[TKind]\n\n/**\n * Frozen semantic identity used to dispatch one registered projection.\n *\n * Dataset version metadata is attached only when a committed dataset event is routed. Keeping the\n * registry-owned fields together prevents the orchestrator from recomputing ontology semantics.\n */\nexport type ProjectionDispatchDescriptor = ProjectionDispatchDescriptorBase &\n ProjectionProtocolIdentity\n\ninterface ProjectionDispatchDescriptorBase {\n readonly projectionId: string\n readonly datasetId: string\n readonly ontologyRevision: string\n readonly projectionRevision: string\n readonly ownershipHash: string\n}\n\nexport interface ResolvedProjection<TDefinition extends ProjectionDefinition> {\n readonly projectionId: string\n readonly datasetId: string\n readonly projectionRevision: string\n readonly ownershipHash: string\n readonly ownership: ProjectionOwnership\n readonly definition: TDefinition\n}\n",
|
|
6
|
-
"import type { SixbFailure } from \"../../errors/types\"\nimport type {\n PinnedDatasetVersion,\n ProjectionExecution,\n ProjectionMaterializationIdentity,\n ProjectionRunTerminalDecision,\n} from \"../../materialization/model\"\nimport type {\n LinkProjectionTarget,\n ObjectProjectionTarget,\n ProjectionKind,\n ProjectionRunFailureCode,\n ProjectionTarget,\n} from \"../../projections/types\"\n\nexport type { ProjectionRunFailureCode } from \"../../projections/types\"\nexport { PROJECTION_RUN_FAILURE_CODES } from \"../../projections/types\"\n\nexport type ProjectionRunStatus = \"queued\" | \"running\" | \"succeeded\" | \"failed\" | \"cancelled\"\n\nexport interface ProjectionRunProgress {\n /** Physical immutable-version rows consumed, before normalization or semantic materialization. */\n readonly sourceRowsRead: number\n /** Physical rows intentionally skipped because a required mapped value was blank. */\n readonly sourceRowsSkipped: number\n}\n\nconst progressKeyFlags: Record<keyof ProjectionRunProgress, true> = {\n sourceRowsRead: true,\n sourceRowsSkipped: true,\n}\n\nexport const PROJECTION_RUN_PROGRESS_KEYS = Object.keys(\n progressKeyFlags\n) as readonly (keyof ProjectionRunProgress)[]\n\nexport function zeroProjectionRunProgress(): ProjectionRunProgress {\n const progress = {} as Record<keyof ProjectionRunProgress, number>\n for (const key of PROJECTION_RUN_PROGRESS_KEYS) progress[key] = 0\n return progress\n}\n\nexport interface ProjectionTelemetryCheckpoint {\n readonly fixedBatchSize: number\n readonly nextBatchOrdinal: number\n readonly nextRowOffset: number\n readonly inputExhausted: boolean\n}\n\n/**\n * The object a telemetry batch is waiting for, and when this run first found it missing.\n *\n * A projection's dataset can legitimately be materialized before the objects it references, so\n * the run waits instead of failing. The wait needs a start, and the run has no other durable one:\n * `startedAt` is when the run began, which on a batched projection is long before the batch that\n * cannot commit, and `attempt` counts every reclaim including the ones an unreachable queue caused.\n *\n * Cleared by any committed batch, so a run that is making progress never carries a stale wait.\n */\nexport interface ProjectionMissingTarget {\n readonly objectTypeId: string\n readonly objectId: string\n /** The batch that could not commit because of it. */\n readonly batchOrdinal: number\n readonly firstSeenAt: Date\n}\n\ninterface ProjectionRunRecordBase {\n readonly id: string\n readonly projectId: string\n readonly executionId: string\n readonly status: ProjectionRunStatus\n readonly attempt: number\n readonly progress: ProjectionRunProgress\n readonly queuedAt: Date\n readonly startedAt?: Date\n readonly finishedAt?: Date\n readonly error?: SixbFailure<ProjectionRunFailureCode>\n}\n\ntype ProjectionIdentity<TKind extends ProjectionKind> = Extract<\n ProjectionMaterializationIdentity,\n { readonly projectionKind: TKind }\n>\n\nexport type ObjectProjectionRunRecord = ProjectionRunRecordBase & {\n readonly identity: ProjectionIdentity<\"object\">\n readonly target: ObjectProjectionTarget\n readonly telemetryCheckpoint?: never\n readonly missingTarget?: never\n}\n\nexport type LinkProjectionRunRecord = ProjectionRunRecordBase & {\n readonly identity: ProjectionIdentity<\"link\">\n readonly target: LinkProjectionTarget\n readonly telemetryCheckpoint?: never\n readonly missingTarget?: never\n}\n\nexport type TelemetryProjectionRunRecord = ProjectionRunRecordBase & {\n readonly identity: ProjectionIdentity<\"telemetry\">\n readonly target: ObjectProjectionTarget\n readonly telemetryCheckpoint: ProjectionTelemetryCheckpoint\n /**\n * Only telemetry carries this: `MaterializationObjectNotFoundError` is raised by telemetry\n * validation alone, and only a batched protocol has a checkpoint to anchor the wait to.\n */\n readonly missingTarget?: ProjectionMissingTarget\n}\n\n/** Durable projection lifecycle state. The execution token is deliberately returned separately. */\nexport type ProjectionRunRecord =\n | ObjectProjectionRunRecord\n | LinkProjectionRunRecord\n | TelemetryProjectionRunRecord\n\nexport function projectionRunObjectTypesVisible(\n run: ProjectionRunRecord,\n canView: (objectTypeId: string) => boolean\n): boolean {\n const target: ProjectionTarget = run.target\n if (\"sourceObjectTypeId\" in target) {\n return canView(target.sourceObjectTypeId) && canView(target.targetObjectTypeId)\n }\n return canView(target.objectTypeId)\n}\n\ninterface ProjectionRunAdmissionBase {\n readonly id: string\n readonly projectId: string\n readonly executionId: string\n readonly queuedAt?: Date\n}\n\nexport type QueueProjectionRunInput =\n | (ProjectionRunAdmissionBase & {\n readonly identity: ProjectionIdentity<\"object\">\n readonly target: ObjectProjectionRunRecord[\"target\"]\n readonly fixedBatchSize?: never\n })\n | (ProjectionRunAdmissionBase & {\n readonly identity: ProjectionIdentity<\"link\">\n readonly target: LinkProjectionRunRecord[\"target\"]\n readonly fixedBatchSize?: never\n })\n | (ProjectionRunAdmissionBase & {\n readonly identity: ProjectionIdentity<\"telemetry\">\n readonly target: TelemetryProjectionRunRecord[\"target\"]\n readonly fixedBatchSize: number\n })\n\nexport type StartOrReclaimProjectionRunInput = QueueProjectionRunInput extends infer TInput\n ? TInput extends QueueProjectionRunInput\n ? Omit<TInput, \"executionId\" | \"queuedAt\"> & { readonly startedAt?: Date }\n : never\n : never\n\nexport interface FailProjectionRunEnqueueInput {\n readonly id: string\n readonly projectId: string\n readonly finishedAt?: Date\n readonly error: SixbFailure<ProjectionRunFailureCode>\n}\n\nexport interface ProjectionRunClaim {\n readonly run: ProjectionRunRecord\n readonly execution: ProjectionExecution\n}\n\nexport interface LockProjectionRunForMaterializationInput {\n readonly id: string\n readonly projectId: string\n readonly executionToken: string\n readonly identity: ProjectionMaterializationIdentity\n}\n\nexport interface UpdateProjectionRunInput extends LockProjectionRunForMaterializationInput {\n readonly progress: Partial<ProjectionRunProgress>\n}\n\nexport type FinishProjectionRunInput = ProjectionRunTerminalDecision &\n LockProjectionRunForMaterializationInput & {\n readonly finishedAt?: Date\n readonly progress?: Partial<ProjectionRunProgress>\n }\n\nexport interface AdvanceProjectionTelemetryCheckpointInput\n extends LockProjectionRunForMaterializationInput {\n /** Must equal the run's current nextBatchOrdinal. */\n readonly batchOrdinal: number\n /** Physical dataset rows consumed by this batch, including skipped rows. */\n readonly batchRowCount: number\n /** Physical rows intentionally skipped inside this batch. */\n readonly batchRowsSkipped: number\n /** True when this batch consumed the final row of the immutable dataset version. */\n readonly inputExhausted: boolean\n}\n\nexport interface RecordProjectionMissingTargetInput\n extends LockProjectionRunForMaterializationInput {\n readonly missingTarget: ProjectionMissingTarget\n}\n\nexport interface ListProjectionRunsInput {\n readonly projectId: string\n readonly projectionId?: string\n readonly projectionKind?: ProjectionKind\n readonly datasetId?: string\n readonly datasetVersionId?: string\n /**\n * Viewable object type ids. A run is included only if every target type is present. Omit for an\n * unrestricted internal execution; an empty set matches no runs.\n */\n readonly objectTypeIds?: readonly string[]\n readonly statuses?: readonly ProjectionRunStatus[]\n readonly startedAfter?: Date\n readonly startedBefore?: Date\n readonly limit?: number\n readonly offset?: number\n readonly order?: \"asc\" | \"desc\"\n}\n\nexport interface ListProjectionRunsResult {\n readonly runs: readonly ProjectionRunRecord[]\n readonly hasMore: boolean\n readonly total: number\n}\n\nexport interface ListLatestProjectionRunsInput {\n readonly projectId: string\n readonly projectionIds: readonly string[]\n}\n\nexport interface ListLatestProjectionRunsResult {\n readonly runs: readonly ProjectionRunRecord[]\n}\n\nexport interface ProjectionRunStorage {\n queue(input: QueueProjectionRunInput): Promise<ProjectionRunRecord>\n startOrReclaim(input: StartOrReclaimProjectionRunInput): Promise<ProjectionRunClaim>\n failEnqueue(input: FailProjectionRunEnqueueInput): Promise<ProjectionRunRecord>\n /** Transactionally fences the current execution before ontology materialization writes. */\n lockForMaterialization(\n input: LockProjectionRunForMaterializationInput\n ): Promise<ProjectionRunRecord>\n /** Updates physical source progress only. */\n update(input: UpdateProjectionRunInput): Promise<ProjectionRunRecord>\n /**\n * Advances telemetry progress atomically with the corresponding ontology commit.\n *\n * Clears any recorded missing target: a batch that commits is a batch that was not waiting.\n */\n advanceTelemetryCheckpoint(\n input: AdvanceProjectionTelemetryCheckpointInput\n ): Promise<TelemetryProjectionRunRecord>\n /** Records the object a telemetry batch is waiting for, so the wait has a durable start. */\n recordMissingTarget(\n input: RecordProjectionMissingTargetInput\n ): Promise<TelemetryProjectionRunRecord>\n /** Telemetry success also records the worker's EOF observation atomically. */\n finish(input: FinishProjectionRunInput): Promise<ProjectionRunRecord>\n getById(params: { projectId: string; id: string }): Promise<ProjectionRunRecord | null>\n list(input: ListProjectionRunsInput): Promise<ListProjectionRunsResult>\n listLatestByProjectionIds(\n input: ListLatestProjectionRunsInput\n ): Promise<ListLatestProjectionRunsResult>\n}\n\nexport type {\n LinkProjectionTarget,\n ObjectProjectionTarget,\n PinnedDatasetVersion,\n ProjectionExecution,\n ProjectionKind,\n ProjectionMaterializationIdentity,\n ProjectionTarget,\n}\n"
|
|
7
|
-
],
|
|
8
|
-
"mappings": ";;AAGO,IAAM,gCAA+B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACmBA,IAAM,mBAA8D;AAAA,EAClE,gBAAgB;AAAA,EAChB,mBAAmB;AACrB;AAEO,IAAM,gCAA+B,OAAO,KACjD,gBACF;AAEO,SAAS,0BAAyB,GAA0B;AAAA,EACjE,MAAM,WAAW,CAAC;AAAA,EAClB,WAAW,OAAO;AAAA,IAA8B,SAAS,OAAO;AAAA,EAChE,OAAO;AAAA;AA6EF,SAAS,gCAA+B,CAC7C,KACA,SACS;AAAA,EACT,MAAM,SAA2B,IAAI;AAAA,EACrC,IAAI,wBAAwB,QAAQ;AAAA,IAClC,OAAO,QAAQ,OAAO,kBAAkB,KAAK,QAAQ,OAAO,kBAAkB;AAAA,EAChF;AAAA,EACA,OAAO,QAAQ,OAAO,YAAY;AAAA;",
|
|
9
|
-
"debugId": "6C744C0A44910E5264756E2164756E21",
|
|
10
|
-
"names": []
|
|
11
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/events/errors.ts", "../src/events/definitions.ts", "../src/events/outbox-dispatcher.ts", "../src/events/service.ts", "../src/events/toStoredEvent.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * Error for event runtime invariants and failures (e.g., unknown event\n * types encountered when converting new events to their stored form).\n */\nexport class EventsError extends Error {\n readonly name = \"EventsError\"\n}\n",
|
|
6
|
-
"import { EventsError } from \"./errors\"\nimport type { ActionEvent } from \"./types/actions\"\nimport type { DatasetEvent } from \"./types/datasets\"\nimport type { DomainEvent, DomainEventDraft } from \"./types/index\"\nimport type { LinkEvent } from \"./types/links\"\nimport type { ObjectEvent } from \"./types/objects\"\nimport type { PipelineEvent } from \"./types/pipelines\"\nimport type { RuleEvent } from \"./types/rules\"\nimport type { ScheduleEvent } from \"./types/schedules\"\nimport type { SyncEvent } from \"./types/syncs\"\nimport type { TelemetryEvent } from \"./types/telemetry\"\nimport type { WorkflowEvent } from \"./types/workflows\"\n\nexport type EventDefinition<Event extends DomainEvent = DomainEvent> = {\n readonly topic: Event[\"topic\"]\n readonly partitionKey: (payload: Event[\"payload\"]) => string\n}\n\nexport type EventDefinitionGroup<Event extends DomainEvent> = {\n readonly [Type in Event[\"type\"]]: EventDefinition<Extract<Event, { type: Type }>>\n}\n\nexport type EventDefinitionMap = {\n readonly [Type in DomainEvent[\"type\"]]: EventDefinition<Extract<DomainEvent, { type: Type }>>\n}\n\nfunction defineEventGroup<Event extends DomainEvent>(\n definitions: EventDefinitionGroup<Event>\n): EventDefinitionGroup<Event> {\n return definitions\n}\n\nexport const OBJECT_EVENT_DEFINITIONS = defineEventGroup<ObjectEvent>({\n \"object.created\": {\n topic: \"objects\",\n partitionKey: (payload) => `${payload.objectTypeId}:${payload.primaryId}`,\n },\n \"object.updated\": {\n topic: \"objects\",\n partitionKey: (payload) => `${payload.objectTypeId}:${payload.primaryId}`,\n },\n \"object.deleted\": {\n topic: \"objects\",\n partitionKey: (payload) => `${payload.objectTypeId}:${payload.primaryId}`,\n },\n})\n\nexport const TELEMETRY_EVENT_DEFINITIONS = defineEventGroup<TelemetryEvent>({\n \"telemetry.appended\": {\n topic: \"telemetry\",\n partitionKey: (payload) => `${payload.objectTypeId}:${payload.objectId}:${payload.propertyId}`,\n },\n})\n\nexport const LINK_EVENT_DEFINITIONS = defineEventGroup<LinkEvent>({\n \"link.created\": {\n topic: \"links\",\n partitionKey: (payload) => `${payload.sourceTypeId}:${payload.sourceId}:${payload.linkId}`,\n },\n \"link.updated\": {\n topic: \"links\",\n partitionKey: (payload) => `${payload.sourceTypeId}:${payload.sourceId}:${payload.linkId}`,\n },\n \"link.deleted\": {\n topic: \"links\",\n partitionKey: (payload) => `${payload.sourceTypeId}:${payload.sourceId}:${payload.linkId}`,\n },\n})\n\nexport const ACTION_EVENT_DEFINITIONS = defineEventGroup<ActionEvent>({\n \"action.requested\": {\n topic: \"actions\",\n partitionKey: (payload) => payload.actionId,\n },\n \"action.completed\": {\n topic: \"actions\",\n partitionKey: (payload) => payload.actionId,\n },\n \"action.failed\": {\n topic: \"actions\",\n partitionKey: (payload) => payload.actionId,\n },\n})\n\nexport const SCHEDULE_EVENT_DEFINITIONS = defineEventGroup<ScheduleEvent>({\n \"schedule.triggered\": {\n topic: \"schedules\",\n partitionKey: (payload) => payload.scheduleId,\n },\n})\n\nexport const RULE_EVENT_DEFINITIONS = defineEventGroup<RuleEvent>({\n \"rule.triggered\": {\n topic: \"rules\",\n partitionKey: (payload) =>\n `${payload.ruleId}:${payload.subject.objectTypeId}:${payload.subject.primaryId}`,\n },\n \"rule.resolved\": {\n topic: \"rules\",\n partitionKey: (payload) =>\n `${payload.ruleId}:${payload.subject.objectTypeId}:${payload.subject.primaryId}`,\n },\n})\n\nexport const SYNC_EVENT_DEFINITIONS = defineEventGroup<SyncEvent>({\n \"sync.run.started\": {\n topic: \"syncs\",\n partitionKey: (payload) => `${payload.syncId}:${payload.runId}`,\n },\n \"sync.run.finished\": {\n topic: \"syncs\",\n partitionKey: (payload) => `${payload.syncId}:${payload.runId}`,\n },\n})\n\nexport const PIPELINE_EVENT_DEFINITIONS = defineEventGroup<PipelineEvent>({\n \"pipeline.run.started\": {\n topic: \"pipelines\",\n partitionKey: (payload) => `${payload.pipelineId}:${payload.runId}`,\n },\n \"pipeline.run.step.started\": {\n topic: \"pipelines\",\n partitionKey: (payload) => `${payload.pipelineId}:${payload.runId}`,\n },\n \"pipeline.run.step.finished\": {\n topic: \"pipelines\",\n partitionKey: (payload) => `${payload.pipelineId}:${payload.runId}`,\n },\n \"pipeline.run.finished\": {\n topic: \"pipelines\",\n partitionKey: (payload) => `${payload.pipelineId}:${payload.runId}`,\n },\n})\n\nexport const WORKFLOW_EVENT_DEFINITIONS = defineEventGroup<WorkflowEvent>({\n \"workflow.run.queued\": {\n topic: \"workflows\",\n partitionKey: (payload) => `${payload.workflowId}:${payload.runId}`,\n },\n \"workflow.run.started\": {\n topic: \"workflows\",\n partitionKey: (payload) => `${payload.workflowId}:${payload.runId}`,\n },\n \"workflow.run.node.started\": {\n topic: \"workflows\",\n partitionKey: (payload) => `${payload.workflowId}:${payload.runId}`,\n },\n \"workflow.run.waiting\": {\n topic: \"workflows\",\n partitionKey: (payload) => `${payload.workflowId}:${payload.runId}`,\n },\n \"workflow.run.node.waiting\": {\n topic: \"workflows\",\n partitionKey: (payload) => `${payload.workflowId}:${payload.runId}`,\n },\n \"workflow.run.node.finished\": {\n topic: \"workflows\",\n partitionKey: (payload) => `${payload.workflowId}:${payload.runId}`,\n },\n \"workflow.run.finished\": {\n topic: \"workflows\",\n partitionKey: (payload) => `${payload.workflowId}:${payload.runId}`,\n },\n \"workflow.intervention.requested\": {\n topic: \"workflows\",\n partitionKey: (payload) => `${payload.workflowId}:${payload.runId}`,\n },\n \"workflow.intervention.submitted\": {\n topic: \"workflows\",\n partitionKey: (payload) => `${payload.workflowId}:${payload.runId}`,\n },\n \"workflow.intervention.cancelled\": {\n topic: \"workflows\",\n partitionKey: (payload) => `${payload.workflowId}:${payload.runId}`,\n },\n \"workflow.intervention.expired\": {\n topic: \"workflows\",\n partitionKey: (payload) => `${payload.workflowId}:${payload.runId}`,\n },\n})\n\nexport const DATASET_EVENT_DEFINITIONS = defineEventGroup<DatasetEvent>({\n \"dataset.version.committed\": {\n topic: \"datasets\",\n partitionKey: (payload) => payload.datasetId,\n },\n})\n\nexport const EVENT_DEFINITIONS = {\n ...OBJECT_EVENT_DEFINITIONS,\n ...TELEMETRY_EVENT_DEFINITIONS,\n ...LINK_EVENT_DEFINITIONS,\n ...ACTION_EVENT_DEFINITIONS,\n ...SCHEDULE_EVENT_DEFINITIONS,\n ...SYNC_EVENT_DEFINITIONS,\n ...PIPELINE_EVENT_DEFINITIONS,\n ...WORKFLOW_EVENT_DEFINITIONS,\n ...DATASET_EVENT_DEFINITIONS,\n ...RULE_EVENT_DEFINITIONS,\n} as const satisfies EventDefinitionMap\n\nexport const EVENT_TYPES = Object.keys(EVENT_DEFINITIONS) as readonly DomainEvent[\"type\"][]\nexport const EVENT_TOPICS = [\n ...new Set(\n Object.values(EVENT_DEFINITIONS).map((definition): DomainEvent[\"topic\"] => definition.topic)\n ),\n] as readonly DomainEvent[\"topic\"][]\n\nexport function isDomainEventType(value: string): value is DomainEvent[\"type\"] {\n return Object.hasOwn(EVENT_DEFINITIONS, value)\n}\n\nexport function isOntologyFactType(\n value: string\n): value is ObjectEvent[\"type\"] | LinkEvent[\"type\"] | TelemetryEvent[\"type\"] {\n return (\n Object.hasOwn(OBJECT_EVENT_DEFINITIONS, value) ||\n Object.hasOwn(LINK_EVENT_DEFINITIONS, value) ||\n Object.hasOwn(TELEMETRY_EVENT_DEFINITIONS, value)\n )\n}\n\nexport function resolveEventStorage(event: DomainEventDraft): {\n readonly topic: DomainEvent[\"topic\"]\n readonly partitionKey: string\n} {\n const eventType = event.type as string\n if (!isDomainEventType(eventType)) {\n throw new EventsError(`Unknown event type: ${eventType}`)\n }\n\n const definition = EVENT_DEFINITIONS[eventType] as EventDefinition\n return {\n topic: definition.topic,\n partitionKey: definition.partitionKey(event.payload),\n }\n}\n",
|
|
7
|
-
"import { randomUUID } from \"node:crypto\"\nimport { createSixbError, serializeSixbFailure, toSixbFailure } from \"../errors/internal\"\nimport type {\n ClaimedOntologyOutboxRow,\n OntologyOutboxFailure,\n OntologyOutboxStorage,\n Storage,\n} from \"../storage\"\nimport { ONTOLOGY_OUTBOX_FAILURE_CODES } from \"../storage/ontology/outbox\"\nimport type { StableEventPublisher } from \"./service\"\n\nconst DEFAULT_BATCH_SIZE = 1_000\nconst DEFAULT_LEASE_DURATION_MS = 30_000\nconst DEFAULT_INITIAL_RETRY_DELAY_MS = 1_000\nconst DEFAULT_MAX_RETRY_DELAY_MS = 5 * 60_000\nconst DEFAULT_RETRY_JITTER_RATIO = 0.2\n// Isolating one poison row from a 1,000-row batch needs up to 21 broker calls: one failed call\n// and, at each split depth, one healthy sibling plus the failing half. Keep bounded headroom for\n// uneven splits while rescheduling unresolved groups once this pass reaches the cap.\nconst DEFAULT_MAX_ISOLATION_ATTEMPTS = 32\nconst DEFAULT_MAX_CLAIMS_PER_DRAIN = 10\nconst DEFAULT_SHUTDOWN_TIMEOUT_MS = 30_000\n\nexport interface OntologyOutboxDeliveryFailure {\n readonly occurredAt: string\n /** Exact failure persisted on every envelope represented by this report. */\n readonly failure: OntologyOutboxFailure\n readonly attempts: number\n readonly eventIds: readonly string[]\n /** Types of the undelivered envelopes. The one field both delivery paths can always report. */\n readonly eventTypes: readonly string[]\n}\n\nexport interface OntologyOutboxDispatcherOptions {\n readonly projectId: string\n readonly storage: Storage\n /** Internal publisher port. It cannot author or mutate persisted ontology facts. */\n readonly events: StableEventPublisher\n readonly batchSize?: number\n readonly leaseDurationMs?: number\n readonly initialRetryDelayMs?: number\n readonly maxRetryDelayMs?: number\n /** Symmetric jitter ratio in the inclusive range 0..1. */\n readonly retryJitterRatio?: number\n /** Maximum broker calls used to isolate poison envelopes in one claimed batch. */\n readonly maxIsolationAttempts?: number\n /** Maximum claimed batches handled by one drain pass. */\n readonly maxClaimsPerDrain?: number\n readonly shutdownTimeoutMs?: number\n readonly now?: () => Date\n readonly random?: () => number\n readonly createLeaseId?: () => string\n readonly onDeliveryFailure?: (error: unknown, failure: OntologyOutboxDeliveryFailure) => void\n readonly onError?: (error: unknown) => void\n}\n\n/**\n * One claimed batch whose unsettled rows remain recoverable during shutdown.\n *\n * Rows leave the set immediately before their lease is settled in storage. If storage settlement\n * itself fails, lease expiry remains the durable recovery path.\n */\nclass ClaimedBatch {\n private readonly unsettled = new Map<string, ClaimedOntologyOutboxRow>()\n private closed = false\n\n constructor(rows: readonly ClaimedOntologyOutboxRow[]) {\n for (const row of rows) this.unsettled.set(row.envelope.id, row)\n }\n\n take(rows: readonly ClaimedOntologyOutboxRow[]): readonly ClaimedOntologyOutboxRow[] {\n if (this.closed || rows.some((row) => !this.unsettled.has(row.envelope.id))) return []\n for (const row of rows) this.unsettled.delete(row.envelope.id)\n return rows\n }\n\n close(): readonly ClaimedOntologyOutboxRow[] {\n this.closed = true\n const rows = [...this.unsettled.values()]\n this.unsettled.clear()\n return rows\n }\n}\n\n/** Lease-based, at-least-once publisher for the authoritative ontology outbox. */\nexport class OntologyOutboxDispatcher {\n private readonly projectId: string\n private readonly storage: Storage\n private readonly events: StableEventPublisher\n private readonly batchSize: number\n private readonly leaseDurationMs: number\n private readonly initialRetryDelayMs: number\n private readonly maxRetryDelayMs: number\n private readonly retryJitterRatio: number\n private readonly maxIsolationAttempts: number\n private readonly maxClaimsPerDrain: number\n private readonly shutdownTimeoutMs: number\n private readonly now: () => Date\n private readonly random: () => number\n private readonly createLeaseId: () => string\n private readonly onDeliveryFailure?: OntologyOutboxDispatcherOptions[\"onDeliveryFailure\"]\n private readonly onError: (error: unknown) => void\n private readonly inFlight = new Set<ClaimedBatch>()\n private draining: Promise<void> | null = null\n private pendingDrain: Promise<void> | null = null\n private stopping: Promise<void> | null = null\n private stopRequested = false\n private readonly forcedStop = new AbortController()\n\n constructor(options: OntologyOutboxDispatcherOptions) {\n assertNonblank(options.projectId, \"projectId\")\n this.projectId = options.projectId\n this.storage = options.storage\n this.events = options.events\n this.batchSize = positiveInteger(options.batchSize ?? DEFAULT_BATCH_SIZE, \"batchSize\")\n this.leaseDurationMs = positiveInteger(\n options.leaseDurationMs ?? DEFAULT_LEASE_DURATION_MS,\n \"leaseDurationMs\"\n )\n this.initialRetryDelayMs = positiveInteger(\n options.initialRetryDelayMs ?? DEFAULT_INITIAL_RETRY_DELAY_MS,\n \"initialRetryDelayMs\"\n )\n this.maxRetryDelayMs = positiveInteger(\n options.maxRetryDelayMs ?? DEFAULT_MAX_RETRY_DELAY_MS,\n \"maxRetryDelayMs\"\n )\n if (this.maxRetryDelayMs < this.initialRetryDelayMs) {\n throw new Error(\n \"[Sixb] Ontology outbox dispatcher maxRetryDelayMs must be at least initialRetryDelayMs.\"\n )\n }\n this.retryJitterRatio = options.retryJitterRatio ?? DEFAULT_RETRY_JITTER_RATIO\n if (\n !Number.isFinite(this.retryJitterRatio) ||\n this.retryJitterRatio < 0 ||\n this.retryJitterRatio > 1\n ) {\n throw new Error(\"[Sixb] Ontology outbox dispatcher retryJitterRatio must be between 0 and 1.\")\n }\n this.maxIsolationAttempts = positiveInteger(\n options.maxIsolationAttempts ?? DEFAULT_MAX_ISOLATION_ATTEMPTS,\n \"maxIsolationAttempts\"\n )\n this.maxClaimsPerDrain = positiveInteger(\n options.maxClaimsPerDrain ?? DEFAULT_MAX_CLAIMS_PER_DRAIN,\n \"maxClaimsPerDrain\"\n )\n this.shutdownTimeoutMs = nonnegativeInteger(\n options.shutdownTimeoutMs ?? DEFAULT_SHUTDOWN_TIMEOUT_MS,\n \"shutdownTimeoutMs\"\n )\n this.now = options.now ?? (() => new Date())\n this.random = options.random ?? Math.random\n this.createLeaseId = options.createLeaseId ?? randomUUID\n this.onDeliveryFailure = options.onDeliveryFailure\n this.onError =\n options.onError ?? ((error) => console.error(\"[Sixb] Outbox dispatcher error:\", error))\n }\n\n /**\n * Publishes one bounded pass of currently due rows without starting an idle polling loop.\n *\n * Concurrent callers share one pass and at most one coalesced follow-up pass. This gives every\n * post-commit notification a chance to observe its own rows without serializing one pass per\n * mutation.\n */\n drain(): Promise<void> {\n if (this.stopRequested) return Promise.resolve()\n if (!this.draining) return this.startDrainPass()\n\n this.pendingDrain ??= settled(this.draining).then(() => {\n this.pendingDrain = null\n if (!this.stopRequested) return this.startDrainPass()\n })\n return this.pendingDrain\n }\n\n /** Starts a tracked, best-effort drain without extending mutation latency. */\n notify(): void {\n if (this.stopRequested) return\n void this.drain().catch((error) => this.reportError(error))\n }\n\n stop(): Promise<void> {\n this.stopping ??= this.stopOnce()\n return this.stopping\n }\n\n private async stopOnce(): Promise<void> {\n if (this.stopRequested) return\n\n // Include one final bounded pass so commits whose notifications were coalesced immediately\n // before shutdown are not left pending merely because the process is stopping.\n const gracefulDrain = this.drain().catch((error) => this.reportError(error))\n if (await settlesWithin(gracefulDrain, this.shutdownTimeoutMs)) {\n this.stopRequested = true\n return\n }\n\n this.stopRequested = true\n this.forcedStop.abort()\n await settlesWithin(\n this.rescheduleUnsettledForShutdown(),\n Math.min(this.shutdownTimeoutMs, 1_000)\n )\n this.draining = null\n this.pendingDrain = null\n }\n\n private startDrainPass(): Promise<void> {\n const pass = this.drainAvailable()\n this.draining = pass\n void settled(pass).then(() => {\n if (this.draining === pass) this.draining = null\n })\n return pass\n }\n\n private async drainAvailable(): Promise<void> {\n for (let claimCount = 0; claimCount < this.maxClaimsPerDrain; claimCount += 1) {\n if (this.stopRequested) return\n const rows = await this.claimBatch()\n if (rows.length === 0) return\n const publishedCount = await this.publishClaim(rows)\n if (this.stopRequested || publishedCount === 0 || rows.length < this.batchSize) return\n }\n\n // A healthy full slice means more due rows may remain. Reuse the existing coalescing path so\n // catch-up continues without recursion, an idle polling loop, or an unbounded individual pass.\n if (!this.stopRequested) this.notify()\n }\n\n private claimBatch(): Promise<readonly ClaimedOntologyOutboxRow[]> {\n const now = this.now().getTime()\n return this.withOutbox((outbox) =>\n outbox.claim({\n projectId: this.projectId,\n now: new Date(now).toISOString(),\n limit: this.batchSize,\n leaseId: this.createLeaseId(),\n leaseExpiresAt: new Date(now + this.leaseDurationMs).toISOString(),\n })\n )\n }\n\n private async publishClaim(rows: readonly ClaimedOntologyOutboxRow[]): Promise<number> {\n const claim = new ClaimedBatch(rows)\n const failures = new DeliveryFailureAccumulator()\n this.inFlight.add(claim)\n const pending: PublicationGroup[] = [{ rows }]\n let publishAttempts = 0\n let publishedCount = 0\n\n try {\n while (pending.length > 0 && !this.stopRequested) {\n const group = pending.shift()\n if (!group || group.rows.length === 0) continue\n if (publishAttempts >= this.maxIsolationAttempts && group.failure) {\n await this.rescheduleFailed(claim, group.rows, group.failure.error, failures)\n continue\n }\n publishAttempts += 1\n\n try {\n const publication = await publishUntilStopped(\n this.events.publishEnvelopes(group.rows.map((row) => row.envelope)),\n this.forcedStop.signal\n )\n if (publication === \"stopped\") break\n } catch (error) {\n if (group.rows.length > 1 && publishAttempts < this.maxIsolationAttempts) {\n const middle = Math.ceil(group.rows.length / 2)\n pending.unshift(\n { rows: group.rows.slice(middle), failure: { error } },\n { rows: group.rows.slice(0, middle), failure: { error } }\n )\n continue\n }\n await this.rescheduleFailed(claim, group.rows, error, failures)\n continue\n }\n\n await this.markPublished(claim, group.rows)\n publishedCount += group.rows.length\n }\n } finally {\n if (this.stopRequested) {\n await this.rescheduleClaimedForShutdown(claim.close())\n }\n this.inFlight.delete(claim)\n for (const failure of failures.list()) {\n this.reportDeliveryFailure(failure.error, failure.context)\n }\n }\n return publishedCount\n }\n\n private async markPublished(\n claim: ClaimedBatch,\n rows: readonly ClaimedOntologyOutboxRow[]\n ): Promise<void> {\n const settling = claim.take(rows)\n if (settling.length === 0) return\n try {\n await this.withOutbox((outbox) =>\n outbox.markPublished({\n projectId: this.projectId,\n ids: eventIds(settling),\n leaseId: sharedLeaseId(settling),\n publishedAt: this.now().toISOString(),\n })\n )\n } catch (error) {\n this.reportError(error)\n throw error\n }\n }\n\n private async rescheduleFailed(\n claim: ClaimedBatch,\n rows: readonly ClaimedOntologyOutboxRow[],\n error: unknown,\n failures: DeliveryFailureAccumulator\n ): Promise<void> {\n const settling = claim.take(rows)\n if (settling.length === 0) return\n const failedAt = this.now()\n\n for (const [attempts, attemptRows] of rowsByAttempts(settling)) {\n const deliveryError = createEventDeliveryError(error, attempts)\n const failure = toSixbFailure(deliveryError, {\n allowedCodes: ONTOLOGY_OUTBOX_FAILURE_CODES,\n at: failedAt,\n })\n failures.add(deliveryError, failure, failedAt.toISOString(), attempts, attemptRows)\n try {\n await this.withOutbox((outbox) =>\n outbox.reschedule({\n projectId: this.projectId,\n ids: eventIds(attemptRows),\n leaseId: sharedLeaseId(attemptRows),\n availableAt: new Date(failedAt.getTime() + this.retryDelayMs(attempts)).toISOString(),\n failure,\n })\n )\n } catch (rescheduleError) {\n this.reportError(rescheduleError)\n throw rescheduleError\n }\n }\n }\n\n private retryDelayMs(attempts: number): number {\n const exponent = Math.max(0, Math.min(52, attempts - 1))\n const exponential = Math.min(this.maxRetryDelayMs, this.initialRetryDelayMs * 2 ** exponent)\n const random = this.random()\n const unitRandom = Number.isFinite(random) ? Math.max(0, Math.min(1, random)) : 0.5\n const jitterFactor = 1 - this.retryJitterRatio + 2 * this.retryJitterRatio * unitRandom\n return Math.min(this.maxRetryDelayMs, Math.max(0, Math.round(exponential * jitterFactor)))\n }\n\n private async rescheduleClaimedForShutdown(\n rows: readonly ClaimedOntologyOutboxRow[]\n ): Promise<void> {\n if (rows.length === 0) return\n try {\n await this.withOutbox((outbox) =>\n outbox.reschedule({\n projectId: this.projectId,\n ids: eventIds(rows),\n leaseId: sharedLeaseId(rows),\n availableAt: this.now().toISOString(),\n })\n )\n } catch (error) {\n this.reportError(error)\n }\n }\n\n private async rescheduleUnsettledForShutdown(): Promise<void> {\n for (const claim of [...this.inFlight]) {\n await this.rescheduleClaimedForShutdown(claim.close())\n this.inFlight.delete(claim)\n }\n }\n\n private withOutbox<T>(run: (outbox: OntologyOutboxStorage) => Promise<T> | T): Promise<T> {\n return this.storage.transaction((tx) => run(tx.ontology.outbox))\n }\n\n private reportDeliveryFailure(error: unknown, failure: OntologyOutboxDeliveryFailure): void {\n try {\n this.onDeliveryFailure?.(error, failure)\n } catch {\n // Failure observers cannot stop delivery or create an unhandled rejection.\n }\n }\n\n private reportError(error: unknown): void {\n try {\n this.onError(error)\n } catch {\n // Error observers cannot stop delivery or create an unhandled rejection.\n }\n }\n}\n\ninterface PublicationGroup {\n readonly rows: readonly ClaimedOntologyOutboxRow[]\n readonly failure?: { readonly error: unknown }\n}\n\ninterface AccumulatedDeliveryFailure {\n readonly error: unknown\n readonly context: OntologyOutboxDeliveryFailure\n}\n\n/** Coalesces bisection failures so one claimed row is reported once per delivery attempt. */\nclass DeliveryFailureAccumulator {\n private readonly groups = new Map<\n string,\n {\n error: unknown\n failure: OntologyOutboxFailure\n occurredAt: string\n attempts: number\n eventIds: Set<string>\n eventTypes: Set<string>\n }\n >()\n\n add(\n error: unknown,\n failure: OntologyOutboxFailure,\n occurredAt: string,\n attempts: number,\n rows: readonly ClaimedOntologyOutboxRow[]\n ): void {\n const key = serializeSixbFailure(failure, ONTOLOGY_OUTBOX_FAILURE_CODES)\n const group = this.groups.get(key) ?? {\n error,\n failure,\n occurredAt,\n attempts,\n eventIds: new Set<string>(),\n eventTypes: new Set<string>(),\n }\n for (const row of rows) {\n group.eventIds.add(row.envelope.id)\n group.eventTypes.add(row.envelope.type)\n }\n this.groups.set(key, group)\n }\n\n list(): readonly AccumulatedDeliveryFailure[] {\n return [...this.groups.values()].map((group) => ({\n error: group.error,\n context: {\n occurredAt: group.occurredAt,\n failure: group.failure,\n attempts: group.attempts,\n eventIds: [...group.eventIds].sort(),\n eventTypes: [...group.eventTypes].sort(),\n },\n }))\n }\n}\n\nfunction positiveInteger(value: number, name: string): number {\n if (!Number.isSafeInteger(value) || value <= 0) {\n throw new Error(`[Sixb] Ontology outbox dispatcher ${name} must be a positive integer.`)\n }\n return value\n}\n\nfunction nonnegativeInteger(value: number, name: string): number {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new Error(`[Sixb] Ontology outbox dispatcher ${name} must be a nonnegative integer.`)\n }\n return value\n}\n\nfunction assertNonblank(value: string, name: string): void {\n if (value.trim().length === 0) {\n throw new Error(`[Sixb] Ontology outbox dispatcher ${name} must not be blank.`)\n }\n}\n\nfunction rowsByAttempts(\n rows: readonly ClaimedOntologyOutboxRow[]\n): ReadonlyMap<number, readonly ClaimedOntologyOutboxRow[]> {\n const groups = new Map<number, ClaimedOntologyOutboxRow[]>()\n for (const row of rows) {\n const group = groups.get(row.attempts) ?? []\n group.push(row)\n groups.set(row.attempts, group)\n }\n return groups\n}\n\nfunction eventIds(rows: readonly ClaimedOntologyOutboxRow[]): string[] {\n return rows.map((row) => row.envelope.id)\n}\n\nfunction sharedLeaseId(rows: readonly ClaimedOntologyOutboxRow[]): string {\n const leaseId = rows[0]?.leaseId\n if (!leaseId || rows.some((row) => row.leaseId !== leaseId)) {\n throw new Error(\"[Sixb] Claimed ontology outbox batch does not share one lease.\")\n }\n return leaseId\n}\n\nfunction createEventDeliveryError(cause: unknown, attempts: number) {\n return createSixbError(\n \"event.delivery_failed\",\n \"[Sixb] Could not deliver persisted ontology events.\",\n {\n cause,\n details: {\n attempts,\n },\n }\n )\n}\n\nasync function publishUntilStopped(\n publication: Promise<unknown>,\n signal: AbortSignal\n): Promise<\"published\" | \"stopped\"> {\n if (signal.aborted) return \"stopped\"\n\n return new Promise((resolve, reject) => {\n const stop = () => finish(() => resolve(\"stopped\"))\n const finish = (settle: () => void) => {\n signal.removeEventListener(\"abort\", stop)\n settle()\n }\n signal.addEventListener(\"abort\", stop, { once: true })\n void publication.then(\n () => finish(() => resolve(\"published\")),\n (error) => finish(() => reject(error))\n )\n })\n}\n\n/** Awaits a pass without adopting its failure, so one failed drain cannot reject the next. */\nfunction settled(promise: Promise<void>): Promise<void> {\n return promise.then(\n () => undefined,\n () => undefined\n )\n}\n\nasync function settlesWithin(promise: Promise<void>, timeoutMs: number): Promise<boolean> {\n let timer: ReturnType<typeof setTimeout> | undefined\n const timedOut = new Promise<false>((resolve) => {\n timer = setTimeout(() => resolve(false), timeoutMs)\n })\n const result = await Promise.race([\n promise.then(\n () => true as const,\n () => true as const\n ),\n timedOut,\n ])\n if (timer !== undefined) clearTimeout(timer)\n return result\n}\n",
|
|
8
|
-
"import { randomUUID } from \"node:crypto\"\nimport type { Broker, BrokerCursor, BrokerRecord, BrokerStreamDefinition } from \"../broker\"\nimport { type ErrorReporter, SixbErrorReporter } from \"../error-reporting/reporter\"\nimport { reportEventDeliveryFailure } from \"../error-reporting/reports\"\nimport { getInvalidJsonValueReason, type JsonValue } from \"../json\"\nimport type { OntologyMaterializationEvent } from \"../materialization/events\"\nimport {\n EVENT_DEFINITIONS,\n EVENT_TYPES,\n isDomainEventType,\n isOntologyFactType,\n resolveEventStorage,\n} from \"./definitions\"\nimport { EventsError } from \"./errors\"\nimport type {\n DomainEvent,\n EventActor,\n EventDraft,\n StoredAuthorableEvent,\n StoredDomainEvent,\n} from \"./types\"\n\n// Keep domain events as a short recent log. This is 2 days in milliseconds.\nexport const DEFAULT_EVENTS_RETENTION_MS = 2 * 24 * 60 * 60 * 1000\n\nexport const EVENTS_STREAM: BrokerStreamDefinition = {\n id: \"__events\",\n retention: { maxAgeMs: DEFAULT_EVENTS_RETENTION_MS },\n}\n\nexport interface DomainEventServiceOptions {\n readonly projectId: string\n readonly broker: Broker\n readonly stream?: BrokerStreamDefinition\n /** Internal failure reporter. Defaults to the console when this runtime is used standalone. */\n readonly errorReporter?: ErrorReporter\n}\n\nexport interface EventsAppendInput {\n readonly actor?: EventActor\n readonly correlationId?: string\n readonly causationId?: string\n readonly events: readonly EventDraft[]\n}\n\nexport interface EventsEmitOptions {\n /** Framework component that initiated the emission, such as `SixbPipelineWorker`. */\n readonly source: string\n}\n\nexport interface EventsReadInput {\n readonly afterCursor?: string\n readonly limit?: number\n readonly topics?: readonly DomainEvent[\"topic\"][]\n readonly types?: readonly DomainEvent[\"type\"][]\n}\n\nexport interface EventsSubscribeInput {\n /** Defaults to live-only delivery. `afterCursor` takes precedence when provided. */\n readonly from?: \"latest\" | \"earliest\"\n readonly afterCursor?: BrokerCursor\n readonly types?: readonly DomainEvent[\"type\"][]\n}\n\n/** Exact, already-identified materialization event persisted before broker publication. @internal */\nexport type StableEventEnvelope = OntologyMaterializationEvent\n\n/** Public domain-event log. Stable ontology envelopes are intentionally absent. */\nexport interface DomainEventLog {\n append(input: EventsAppendInput): Promise<readonly StoredDomainEvent[]>\n /**\n * Append events after the work that produced them has already succeeded.\n *\n * Contract: this never rejects. The caller's unit of work is done, so a delivery failure must not\n * turn a successful run into a failed one — the implementation escalates the loss instead.\n */\n emit(input: EventsAppendInput, options: EventsEmitOptions): Promise<void>\n read(input?: EventsReadInput): Promise<readonly StoredDomainEvent[]>\n latestCursor(): Promise<string | undefined>\n subscribe(\n input: EventsSubscribeInput,\n handler: (events: readonly StoredDomainEvent[]) => void\n ): Promise<() => void>\n}\n\n/** Narrow internal port used to publish envelopes already persisted in the ontology outbox. */\nexport interface StableEventPublisher {\n publishEnvelopes(envelopes: readonly StableEventEnvelope[]): Promise<readonly StoredDomainEvent[]>\n}\n\n/** Project-scoped domain event service backed by the shared broker provider. */\nexport class DomainEventService implements DomainEventLog, StableEventPublisher {\n private readonly projectId: string\n private readonly broker: Broker\n private readonly stream: BrokerStreamDefinition\n private readonly errorReporter: ErrorReporter\n private readonly ensureStreamPromises = new Map<string, Promise<void>>()\n\n constructor(options: DomainEventServiceOptions) {\n this.projectId = options.projectId\n this.broker = options.broker\n this.stream = options.stream ?? EVENTS_STREAM\n this.errorReporter = options.errorReporter ?? new SixbErrorReporter()\n }\n\n /**\n * Append events after the work that produced them has already succeeded.\n *\n * Unlike `append`, this never rejects: the caller's unit of work is done, so a broker outage must not\n * turn a successful run into a failed one. It is not a swallow either — every event Sixb publishes is\n * a potential trigger edge (a rule's `.when()`, an event schedule, a workflow's wait node), so a lost\n * batch is a handler that silently never runs. The loss is escalated to `onError` as\n * `event.delivery.failed`, or to the default console reporter when no handler was configured.\n *\n * Framework emit sites want this. Application code wants `append`, which reports failure to the\n * caller and returns the stored envelopes.\n */\n async emit(input: EventsAppendInput, _options: EventsEmitOptions): Promise<void> {\n try {\n await this.append(input)\n } catch (error) {\n try {\n const eventTypes = input.events.map((event) => event.type)\n reportEventDeliveryFailure(this.errorReporter, error, {\n projectId: this.projectId,\n eventTypes,\n })\n } catch {\n // The contract above is absolute, so escalation cannot be the thing that breaks it.\n }\n }\n }\n\n async append(input: EventsAppendInput): Promise<readonly StoredDomainEvent[]> {\n if (input.events.length === 0) {\n return []\n }\n for (const event of input.events) {\n if (isOntologyFactType(event.type)) {\n throw new EventsError(\n `Event type '${event.type}' is an authoritative ontology fact and cannot be appended directly.`\n )\n }\n }\n\n const payloads = input.events.map((event) =>\n toStoredEventPayload({\n projectId: this.projectId,\n actor: input.actor,\n correlationId: input.correlationId,\n causationId: input.causationId,\n event,\n })\n )\n\n await this.ensureStream()\n const records = await this.broker.append({\n projectId: this.projectId,\n streamId: this.stream.id,\n records: payloads.map((payload) => ({\n name: payload.type,\n key: payload.partitionKey,\n payload: toBrokerRecordPayload(payload),\n idempotencyKey: payload.idempotencyKey,\n })),\n })\n\n if (records.length !== payloads.length) {\n throw new EventsError(\n `Broker returned ${records.length} record(s) for ${payloads.length} appended event(s).`\n )\n }\n\n return records.map(hydrateEventRecord)\n }\n\n /** Publishes persisted envelopes without changing their stable event identity. @internal */\n async publishEnvelopes(\n envelopes: readonly StableEventEnvelope[]\n ): Promise<readonly StoredDomainEvent[]> {\n if (envelopes.length === 0) {\n return []\n }\n\n for (const envelope of envelopes) {\n if (envelope.projectId !== this.projectId) {\n throw new EventsError(\n `Event '${envelope.id}' belongs to project '${envelope.projectId}', not '${this.projectId}'.`\n )\n }\n if (!isDomainEventType(envelope.type)) {\n throw new EventsError(`Event '${envelope.id}' has unknown event type.`)\n }\n if (EVENT_DEFINITIONS[envelope.type].topic !== envelope.topic) {\n throw new EventsError(\n `Event '${envelope.id}' topic '${envelope.topic}' does not match type '${envelope.type}'.`\n )\n }\n }\n\n await this.ensureStream()\n const records = await this.broker.append({\n projectId: this.projectId,\n streamId: this.stream.id,\n records: envelopes.map((envelope) => ({\n name: envelope.type,\n key: envelope.partitionKey,\n payload: toBrokerRecordPayload(envelope),\n idempotencyKey: envelope.id,\n })),\n })\n\n if (records.length !== envelopes.length) {\n throw new EventsError(\n `Broker returned ${records.length} record(s) for ${envelopes.length} published event(s).`\n )\n }\n\n return records.map(hydrateEventRecord)\n }\n\n async read(input: EventsReadInput = {}): Promise<readonly StoredDomainEvent[]> {\n if (input.limit !== undefined && input.limit <= 0) {\n return []\n }\n\n const names = resolveTypeFilter(input)\n if (names && names.length === 0) {\n return []\n }\n\n await this.ensureStream()\n const page = await this.broker.read({\n projectId: this.projectId,\n streamId: this.stream.id,\n afterCursor: input.afterCursor,\n limit: input.limit,\n names,\n })\n\n return page.records.map(hydrateEventRecord)\n }\n\n async latestCursor(): Promise<string | undefined> {\n await this.ensureStream()\n return this.broker.latestCursor({\n projectId: this.projectId,\n streamId: this.stream.id,\n })\n }\n\n async subscribe(\n input: EventsSubscribeInput,\n handler: (events: readonly StoredDomainEvent[]) => void\n ): Promise<() => void> {\n await this.ensureStream()\n return this.broker.subscribe(\n {\n projectId: this.projectId,\n streamId: this.stream.id,\n from: input.from,\n afterCursor: input.afterCursor,\n names: input.types && input.types.length > 0 ? input.types : EVENT_TYPES,\n },\n (records) => {\n const events = records.map(hydrateEventRecord)\n if (events.length === 0) {\n return\n }\n\n try {\n handler(events)\n } catch {\n // Preserve fire-and-forget subscriber semantics.\n }\n }\n )\n }\n\n private ensureStream(): Promise<void> {\n const key = `${this.projectId}\\0${this.stream.id}`\n let promise = this.ensureStreamPromises.get(key)\n if (!promise) {\n promise = this.broker\n .ensureStream({\n projectId: this.projectId,\n stream: this.stream,\n })\n .catch((error) => {\n if (this.ensureStreamPromises.get(key) === promise) {\n this.ensureStreamPromises.delete(key)\n }\n throw error\n })\n this.ensureStreamPromises.set(key, promise)\n }\n return promise\n }\n}\n\nexport function createDomainEventService(options: DomainEventServiceOptions): DomainEventService {\n return new DomainEventService(options)\n}\n\ntype StoredEventPayload = Omit<StoredAuthorableEvent, \"cursor\">\n\nfunction toStoredEventPayload(params: {\n projectId: string\n actor?: EventActor\n correlationId?: string\n causationId?: string\n event: EventDraft\n}): StoredEventPayload {\n const storage = resolveEventStorage(params.event)\n const payload: Record<string, unknown> = {\n id: randomUUID(),\n schemaVersion: 1,\n projectId: params.projectId,\n occurredAt: params.event.occurredAt ?? new Date().toISOString(),\n type: params.event.type,\n topic: storage.topic,\n partitionKey: storage.partitionKey,\n payload: params.event.payload,\n }\n\n setIfDefined(payload, \"correlationId\", params.correlationId)\n setIfDefined(payload, \"causationId\", params.causationId)\n setIfDefined(payload, \"idempotencyKey\", params.event.idempotencyKey)\n setIfDefined(payload, \"actor\", params.actor)\n setIfDefined(payload, \"origin\", params.event.origin)\n setIfDefined(payload, \"metadata\", params.event.metadata)\n\n return payload as StoredEventPayload\n}\n\nfunction toBrokerRecordPayload(payload: StoredEventPayload | StableEventEnvelope): JsonValue {\n const reason = getInvalidJsonValueReason(payload, `event '${payload.type}' payload`)\n if (reason) {\n throw new EventsError(`Event '${payload.type}' cannot be stored in broker; ${reason}`)\n }\n\n return payload as unknown as JsonValue\n}\n\nfunction hydrateEventRecord(record: BrokerRecord): StoredDomainEvent {\n const payload = record.payload\n if (!isObjectRecord(payload)) {\n throw new EventsError(`Broker record at cursor '${record.cursor}' is not an event object.`)\n }\n\n const eventType = payload.type\n if (typeof eventType !== \"string\" || !isDomainEventType(eventType)) {\n throw new EventsError(`Broker record at cursor '${record.cursor}' has unknown event type.`)\n }\n\n if (record.name !== undefined && record.name !== eventType) {\n throw new EventsError(\n `Broker record name '${record.name}' does not match event type '${eventType}'.`\n )\n }\n\n return {\n ...payload,\n cursor: record.cursor,\n } as StoredDomainEvent\n}\n\nfunction resolveTypeFilter(input: {\n topics?: readonly DomainEvent[\"topic\"][]\n types?: readonly DomainEvent[\"type\"][]\n}): readonly DomainEvent[\"type\"][] {\n const topicTypes =\n input.topics && input.topics.length > 0\n ? EVENT_TYPES.filter((type) => input.topics?.includes(EVENT_DEFINITIONS[type].topic))\n : undefined\n\n if (!topicTypes) {\n return input.types && input.types.length > 0 ? input.types : EVENT_TYPES\n }\n\n if (!input.types || input.types.length === 0) {\n return topicTypes\n }\n\n const requestedTypes = new Set(input.types)\n return topicTypes.filter((type) => requestedTypes.has(type))\n}\n\nfunction isObjectRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null\n}\n\nfunction setIfDefined(target: Record<string, unknown>, key: string, value: unknown): void {\n if (value !== undefined) {\n target[key] = value\n }\n}\n",
|
|
9
|
-
"import { randomUUID } from \"node:crypto\"\nimport { resolveEventStorage } from \"./definitions\"\nimport type { EventActor, EventDraft, StoredAuthorableEvent } from \"./types/index\"\n\nexport function toStoredEvent(params: {\n projectId: string\n actor?: EventActor\n correlationId?: string\n causationId?: string\n event: EventDraft\n cursor: string\n}): StoredAuthorableEvent {\n const base = {\n id: randomUUID(),\n schemaVersion: 1 as const,\n projectId: params.projectId,\n occurredAt: params.event.occurredAt ?? new Date().toISOString(),\n correlationId: params.correlationId,\n causationId: params.causationId,\n idempotencyKey: params.event.idempotencyKey,\n actor: params.actor,\n origin: params.event.origin,\n metadata: params.event.metadata,\n cursor: params.cursor,\n }\n\n const storage = resolveEventStorage(params.event)\n return {\n ...base,\n type: params.event.type,\n topic: storage.topic,\n partitionKey: storage.partitionKey,\n payload: params.event.payload,\n } as StoredAuthorableEvent\n}\n"
|
|
10
|
-
],
|
|
11
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAIO,MAAM,qBAAoB,MAAM;AAAA,EAC5B,OAAO;AAClB;;;ACoBA,SAAS,gBAA2C,CAClD,aAC6B;AAAA,EAC7B,OAAO;AAAA;AAGF,IAAM,4BAA2B,iBAA8B;AAAA,EACpE,kBAAkB;AAAA,IAChB,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,gBAAgB,QAAQ;AAAA,EAChE;AAAA,EACA,kBAAkB;AAAA,IAChB,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,gBAAgB,QAAQ;AAAA,EAChE;AAAA,EACA,kBAAkB;AAAA,IAChB,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,gBAAgB,QAAQ;AAAA,EAChE;AACF,CAAC;AAEM,IAAM,+BAA8B,iBAAiC;AAAA,EAC1E,sBAAsB;AAAA,IACpB,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,gBAAgB,QAAQ,YAAY,QAAQ;AAAA,EACpF;AACF,CAAC;AAEM,IAAM,0BAAyB,iBAA4B;AAAA,EAChE,gBAAgB;AAAA,IACd,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,gBAAgB,QAAQ,YAAY,QAAQ;AAAA,EACpF;AAAA,EACA,gBAAgB;AAAA,IACd,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,gBAAgB,QAAQ,YAAY,QAAQ;AAAA,EACpF;AAAA,EACA,gBAAgB;AAAA,IACd,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,gBAAgB,QAAQ,YAAY,QAAQ;AAAA,EACpF;AACF,CAAC;AAEM,IAAM,4BAA2B,iBAA8B;AAAA,EACpE,oBAAoB;AAAA,IAClB,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,QAAQ;AAAA,EACrC;AAAA,EACA,oBAAoB;AAAA,IAClB,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,QAAQ;AAAA,EACrC;AAAA,EACA,iBAAiB;AAAA,IACf,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,QAAQ;AAAA,EACrC;AACF,CAAC;AAEM,IAAM,8BAA6B,iBAAgC;AAAA,EACxE,sBAAsB;AAAA,IACpB,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,QAAQ;AAAA,EACrC;AACF,CAAC;AAEM,IAAM,0BAAyB,iBAA4B;AAAA,EAChE,kBAAkB;AAAA,IAChB,OAAO;AAAA,IACP,cAAc,CAAC,YACb,GAAG,QAAQ,UAAU,QAAQ,QAAQ,gBAAgB,QAAQ,QAAQ;AAAA,EACzE;AAAA,EACA,iBAAiB;AAAA,IACf,OAAO;AAAA,IACP,cAAc,CAAC,YACb,GAAG,QAAQ,UAAU,QAAQ,QAAQ,gBAAgB,QAAQ,QAAQ;AAAA,EACzE;AACF,CAAC;AAEM,IAAM,0BAAyB,iBAA4B;AAAA,EAChE,oBAAoB;AAAA,IAClB,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,UAAU,QAAQ;AAAA,EAC1D;AAAA,EACA,qBAAqB;AAAA,IACnB,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,UAAU,QAAQ;AAAA,EAC1D;AACF,CAAC;AAEM,IAAM,8BAA6B,iBAAgC;AAAA,EACxE,wBAAwB;AAAA,IACtB,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,cAAc,QAAQ;AAAA,EAC9D;AAAA,EACA,6BAA6B;AAAA,IAC3B,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,cAAc,QAAQ;AAAA,EAC9D;AAAA,EACA,8BAA8B;AAAA,IAC5B,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,cAAc,QAAQ;AAAA,EAC9D;AAAA,EACA,yBAAyB;AAAA,IACvB,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,cAAc,QAAQ;AAAA,EAC9D;AACF,CAAC;AAEM,IAAM,8BAA6B,iBAAgC;AAAA,EACxE,uBAAuB;AAAA,IACrB,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,cAAc,QAAQ;AAAA,EAC9D;AAAA,EACA,wBAAwB;AAAA,IACtB,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,cAAc,QAAQ;AAAA,EAC9D;AAAA,EACA,6BAA6B;AAAA,IAC3B,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,cAAc,QAAQ;AAAA,EAC9D;AAAA,EACA,wBAAwB;AAAA,IACtB,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,cAAc,QAAQ;AAAA,EAC9D;AAAA,EACA,6BAA6B;AAAA,IAC3B,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,cAAc,QAAQ;AAAA,EAC9D;AAAA,EACA,8BAA8B;AAAA,IAC5B,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,cAAc,QAAQ;AAAA,EAC9D;AAAA,EACA,yBAAyB;AAAA,IACvB,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,cAAc,QAAQ;AAAA,EAC9D;AAAA,EACA,mCAAmC;AAAA,IACjC,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,cAAc,QAAQ;AAAA,EAC9D;AAAA,EACA,mCAAmC;AAAA,IACjC,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,cAAc,QAAQ;AAAA,EAC9D;AAAA,EACA,mCAAmC;AAAA,IACjC,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,cAAc,QAAQ;AAAA,EAC9D;AAAA,EACA,iCAAiC;AAAA,IAC/B,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,GAAG,QAAQ,cAAc,QAAQ;AAAA,EAC9D;AACF,CAAC;AAEM,IAAM,6BAA4B,iBAA+B;AAAA,EACtE,6BAA6B;AAAA,IAC3B,OAAO;AAAA,IACP,cAAc,CAAC,YAAY,QAAQ;AAAA,EACrC;AACF,CAAC;AAEM,IAAM,qBAAoB;AAAA,KAC5B;AAAA,KACA;AAAA,KACA;AAAA,KACA;AAAA,KACA;AAAA,KACA;AAAA,KACA;AAAA,KACA;AAAA,KACA;AAAA,KACA;AACL;AAEO,IAAM,eAAc,OAAO,KAAK,kBAAiB;AACjD,IAAM,gBAAe;AAAA,EAC1B,GAAG,IAAI,IACL,OAAO,OAAO,kBAAiB,EAAE,IAAI,CAAC,eAAqC,WAAW,KAAK,CAC7F;AACF;AAEO,SAAS,kBAAiB,CAAC,OAA6C;AAAA,EAC7E,OAAO,OAAO,OAAO,oBAAmB,KAAK;AAAA;AAGxC,SAAS,mBAAkB,CAChC,OAC2E;AAAA,EAC3E,OACE,OAAO,OAAO,2BAA0B,KAAK,KAC7C,OAAO,OAAO,yBAAwB,KAAK,KAC3C,OAAO,OAAO,8BAA6B,KAAK;AAAA;AAI7C,SAAS,oBAAmB,CAAC,OAGlC;AAAA,EACA,MAAM,YAAY,MAAM;AAAA,EACxB,IAAI,CAAC,mBAAkB,SAAS,GAAG;AAAA,IACjC,MAAM,IAAI,aAAY,uBAAuB,WAAW;AAAA,EAC1D;AAAA,EAEA,MAAM,aAAa,mBAAkB;AAAA,EACrC,OAAO;AAAA,IACL,OAAO,WAAW;AAAA,IAClB,cAAc,WAAW,aAAa,MAAM,OAAO;AAAA,EACrD;AAAA;;AC3OF;AAWA,IAAM,qBAAqB;AAC3B,IAAM,4BAA4B;AAClC,IAAM,iCAAiC;AACvC,IAAM,6BAA6B,IAAI;AACvC,IAAM,6BAA6B;AAInC,IAAM,iCAAiC;AACvC,IAAM,+BAA+B;AACrC,IAAM,8BAA8B;AAAA;AAyCpC,MAAM,aAAa;AAAA,EACA,YAAY,IAAI;AAAA,EACzB,SAAS;AAAA,EAEjB,WAAW,CAAC,MAA2C;AAAA,IACrD,WAAW,OAAO;AAAA,MAAM,KAAK,UAAU,IAAI,IAAI,SAAS,IAAI,GAAG;AAAA;AAAA,EAGjE,IAAI,CAAC,MAAgF;AAAA,IACnF,IAAI,KAAK,UAAU,KAAK,KAAK,CAAC,QAAQ,CAAC,KAAK,UAAU,IAAI,IAAI,SAAS,EAAE,CAAC;AAAA,MAAG,OAAO,CAAC;AAAA,IACrF,WAAW,OAAO;AAAA,MAAM,KAAK,UAAU,OAAO,IAAI,SAAS,EAAE;AAAA,IAC7D,OAAO;AAAA;AAAA,EAGT,KAAK,GAAwC;AAAA,IAC3C,KAAK,SAAS;AAAA,IACd,MAAM,OAAO,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC;AAAA,IACxC,KAAK,UAAU,MAAM;AAAA,IACrB,OAAO;AAAA;AAEX;AAAA;AAGO,MAAM,0BAAyB;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW,IAAI;AAAA,EACxB,WAAiC;AAAA,EACjC,eAAqC;AAAA,EACrC,WAAiC;AAAA,EACjC,gBAAgB;AAAA,EACP,aAAa,IAAI;AAAA,EAElC,WAAW,CAAC,SAA0C;AAAA,IACpD,eAAe,QAAQ,WAAW,WAAW;AAAA,IAC7C,KAAK,YAAY,QAAQ;AAAA,IACzB,KAAK,UAAU,QAAQ;AAAA,IACvB,KAAK,SAAS,QAAQ;AAAA,IACtB,KAAK,YAAY,gBAAgB,QAAQ,aAAa,oBAAoB,WAAW;AAAA,IACrF,KAAK,kBAAkB,gBACrB,QAAQ,mBAAmB,2BAC3B,iBACF;AAAA,IACA,KAAK,sBAAsB,gBACzB,QAAQ,uBAAuB,gCAC/B,qBACF;AAAA,IACA,KAAK,kBAAkB,gBACrB,QAAQ,mBAAmB,4BAC3B,iBACF;AAAA,IACA,IAAI,KAAK,kBAAkB,KAAK,qBAAqB;AAAA,MACnD,MAAM,IAAI,MACR,yFACF;AAAA,IACF;AAAA,IACA,KAAK,mBAAmB,QAAQ,oBAAoB;AAAA,IACpD,IACE,CAAC,OAAO,SAAS,KAAK,gBAAgB,KACtC,KAAK,mBAAmB,KACxB,KAAK,mBAAmB,GACxB;AAAA,MACA,MAAM,IAAI,MAAM,6EAA6E;AAAA,IAC/F;AAAA,IACA,KAAK,uBAAuB,gBAC1B,QAAQ,wBAAwB,gCAChC,sBACF;AAAA,IACA,KAAK,oBAAoB,gBACvB,QAAQ,qBAAqB,8BAC7B,mBACF;AAAA,IACA,KAAK,oBAAoB,mBACvB,QAAQ,qBAAqB,6BAC7B,mBACF;AAAA,IACA,KAAK,MAAM,QAAQ,QAAQ,MAAM,IAAI;AAAA,IACrC,KAAK,SAAS,QAAQ,UAAU,KAAK;AAAA,IACrC,KAAK,gBAAgB,QAAQ,iBAAiB;AAAA,IAC9C,KAAK,oBAAoB,QAAQ;AAAA,IACjC,KAAK,UACH,QAAQ,YAAY,CAAC,UAAU,QAAQ,MAAM,mCAAmC,KAAK;AAAA;AAAA,EAUzF,KAAK,GAAkB;AAAA,IACrB,IAAI,KAAK;AAAA,MAAe,OAAO,QAAQ,QAAQ;AAAA,IAC/C,IAAI,CAAC,KAAK;AAAA,MAAU,OAAO,KAAK,eAAe;AAAA,IAE/C,KAAK,iBAAiB,QAAQ,KAAK,QAAQ,EAAE,KAAK,MAAM;AAAA,MACtD,KAAK,eAAe;AAAA,MACpB,IAAI,CAAC,KAAK;AAAA,QAAe,OAAO,KAAK,eAAe;AAAA,KACrD;AAAA,IACD,OAAO,KAAK;AAAA;AAAA,EAId,MAAM,GAAS;AAAA,IACb,IAAI,KAAK;AAAA,MAAe;AAAA,IACnB,KAAK,MAAM,EAAE,MAAM,CAAC,UAAU,KAAK,YAAY,KAAK,CAAC;AAAA;AAAA,EAG5D,IAAI,GAAkB;AAAA,IACpB,KAAK,aAAa,KAAK,SAAS;AAAA,IAChC,OAAO,KAAK;AAAA;AAAA,OAGA,SAAQ,GAAkB;AAAA,IACtC,IAAI,KAAK;AAAA,MAAe;AAAA,IAIxB,MAAM,gBAAgB,KAAK,MAAM,EAAE,MAAM,CAAC,UAAU,KAAK,YAAY,KAAK,CAAC;AAAA,IAC3E,IAAI,MAAM,cAAc,eAAe,KAAK,iBAAiB,GAAG;AAAA,MAC9D,KAAK,gBAAgB;AAAA,MACrB;AAAA,IACF;AAAA,IAEA,KAAK,gBAAgB;AAAA,IACrB,KAAK,WAAW,MAAM;AAAA,IACtB,MAAM,cACJ,KAAK,+BAA+B,GACpC,KAAK,IAAI,KAAK,mBAAmB,IAAK,CACxC;AAAA,IACA,KAAK,WAAW;AAAA,IAChB,KAAK,eAAe;AAAA;AAAA,EAGd,cAAc,GAAkB;AAAA,IACtC,MAAM,OAAO,KAAK,eAAe;AAAA,IACjC,KAAK,WAAW;AAAA,IACX,QAAQ,IAAI,EAAE,KAAK,MAAM;AAAA,MAC5B,IAAI,KAAK,aAAa;AAAA,QAAM,KAAK,WAAW;AAAA,KAC7C;AAAA,IACD,OAAO;AAAA;AAAA,OAGK,eAAc,GAAkB;AAAA,IAC5C,SAAS,aAAa,EAAG,aAAa,KAAK,mBAAmB,cAAc,GAAG;AAAA,MAC7E,IAAI,KAAK;AAAA,QAAe;AAAA,MACxB,MAAM,OAAO,MAAM,KAAK,WAAW;AAAA,MACnC,IAAI,KAAK,WAAW;AAAA,QAAG;AAAA,MACvB,MAAM,iBAAiB,MAAM,KAAK,aAAa,IAAI;AAAA,MACnD,IAAI,KAAK,iBAAiB,mBAAmB,KAAK,KAAK,SAAS,KAAK;AAAA,QAAW;AAAA,IAClF;AAAA,IAIA,IAAI,CAAC,KAAK;AAAA,MAAe,KAAK,OAAO;AAAA;AAAA,EAG/B,UAAU,GAAiD;AAAA,IACjE,MAAM,MAAM,KAAK,IAAI,EAAE,QAAQ;AAAA,IAC/B,OAAO,KAAK,WAAW,CAAC,WACtB,OAAO,MAAM;AAAA,MACX,WAAW,KAAK;AAAA,MAChB,KAAK,IAAI,KAAK,GAAG,EAAE,YAAY;AAAA,MAC/B,OAAO,KAAK;AAAA,MACZ,SAAS,KAAK,cAAc;AAAA,MAC5B,gBAAgB,IAAI,KAAK,MAAM,KAAK,eAAe,EAAE,YAAY;AAAA,IACnE,CAAC,CACH;AAAA;AAAA,OAGY,aAAY,CAAC,MAA4D;AAAA,IACrF,MAAM,QAAQ,IAAI,aAAa,IAAI;AAAA,IACnC,MAAM,WAAW,IAAI;AAAA,IACrB,KAAK,SAAS,IAAI,KAAK;AAAA,IACvB,MAAM,UAA8B,CAAC,EAAE,KAAK,CAAC;AAAA,IAC7C,IAAI,kBAAkB;AAAA,IACtB,IAAI,iBAAiB;AAAA,IAErB,IAAI;AAAA,MACF,OAAO,QAAQ,SAAS,KAAK,CAAC,KAAK,eAAe;AAAA,QAChD,MAAM,QAAQ,QAAQ,MAAM;AAAA,QAC5B,IAAI,CAAC,SAAS,MAAM,KAAK,WAAW;AAAA,UAAG;AAAA,QACvC,IAAI,mBAAmB,KAAK,wBAAwB,MAAM,SAAS;AAAA,UACjE,MAAM,KAAK,iBAAiB,OAAO,MAAM,MAAM,MAAM,QAAQ,OAAO,QAAQ;AAAA,UAC5E;AAAA,QACF;AAAA,QACA,mBAAmB;AAAA,QAEnB,IAAI;AAAA,UACF,MAAM,cAAc,MAAM,oBACxB,KAAK,OAAO,iBAAiB,MAAM,KAAK,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,GAClE,KAAK,WAAW,MAClB;AAAA,UACA,IAAI,gBAAgB;AAAA,YAAW;AAAA,UAC/B,OAAO,OAAO;AAAA,UACd,IAAI,MAAM,KAAK,SAAS,KAAK,kBAAkB,KAAK,sBAAsB;AAAA,YACxE,MAAM,SAAS,KAAK,KAAK,MAAM,KAAK,SAAS,CAAC;AAAA,YAC9C,QAAQ,QACN,EAAE,MAAM,MAAM,KAAK,MAAM,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,GACrD,EAAE,MAAM,MAAM,KAAK,MAAM,GAAG,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,CAC1D;AAAA,YACA;AAAA,UACF;AAAA,UACA,MAAM,KAAK,iBAAiB,OAAO,MAAM,MAAM,OAAO,QAAQ;AAAA,UAC9D;AAAA;AAAA,QAGF,MAAM,KAAK,cAAc,OAAO,MAAM,IAAI;AAAA,QAC1C,kBAAkB,MAAM,KAAK;AAAA,MAC/B;AAAA,cACA;AAAA,MACA,IAAI,KAAK,eAAe;AAAA,QACtB,MAAM,KAAK,6BAA6B,MAAM,MAAM,CAAC;AAAA,MACvD;AAAA,MACA,KAAK,SAAS,OAAO,KAAK;AAAA,MAC1B,WAAW,WAAW,SAAS,KAAK,GAAG;AAAA,QACrC,KAAK,sBAAsB,QAAQ,OAAO,QAAQ,OAAO;AAAA,MAC3D;AAAA;AAAA,IAEF,OAAO;AAAA;AAAA,OAGK,cAAa,CACzB,OACA,MACe;AAAA,IACf,MAAM,WAAW,MAAM,KAAK,IAAI;AAAA,IAChC,IAAI,SAAS,WAAW;AAAA,MAAG;AAAA,IAC3B,IAAI;AAAA,MACF,MAAM,KAAK,WAAW,CAAC,WACrB,OAAO,cAAc;AAAA,QACnB,WAAW,KAAK;AAAA,QAChB,KAAK,SAAS,QAAQ;AAAA,QACtB,SAAS,cAAc,QAAQ;AAAA,QAC/B,aAAa,KAAK,IAAI,EAAE,YAAY;AAAA,MACtC,CAAC,CACH;AAAA,MACA,OAAO,OAAO;AAAA,MACd,KAAK,YAAY,KAAK;AAAA,MACtB,MAAM;AAAA;AAAA;AAAA,OAII,iBAAgB,CAC5B,OACA,MACA,OACA,UACe;AAAA,IACf,MAAM,WAAW,MAAM,KAAK,IAAI;AAAA,IAChC,IAAI,SAAS,WAAW;AAAA,MAAG;AAAA,IAC3B,MAAM,WAAW,KAAK,IAAI;AAAA,IAE1B,YAAY,UAAU,gBAAgB,eAAe,QAAQ,GAAG;AAAA,MAC9D,MAAM,gBAAgB,yBAAyB,OAAO,QAAQ;AAAA,MAC9D,MAAM,UAAU,eAAc,eAAe;AAAA,QAC3C,cAAc;AAAA,QACd,IAAI;AAAA,MACN,CAAC;AAAA,MACD,SAAS,IAAI,eAAe,SAAS,SAAS,YAAY,GAAG,UAAU,WAAW;AAAA,MAClF,IAAI;AAAA,QACF,MAAM,KAAK,WAAW,CAAC,WACrB,OAAO,WAAW;AAAA,UAChB,WAAW,KAAK;AAAA,UAChB,KAAK,SAAS,WAAW;AAAA,UACzB,SAAS,cAAc,WAAW;AAAA,UAClC,aAAa,IAAI,KAAK,SAAS,QAAQ,IAAI,KAAK,aAAa,QAAQ,CAAC,EAAE,YAAY;AAAA,UACpF;AAAA,QACF,CAAC,CACH;AAAA,QACA,OAAO,iBAAiB;AAAA,QACxB,KAAK,YAAY,eAAe;AAAA,QAChC,MAAM;AAAA;AAAA,IAEV;AAAA;AAAA,EAGM,YAAY,CAAC,UAA0B;AAAA,IAC7C,MAAM,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,WAAW,CAAC,CAAC;AAAA,IACvD,MAAM,cAAc,KAAK,IAAI,KAAK,iBAAiB,KAAK,sBAAsB,KAAK,QAAQ;AAAA,IAC3F,MAAM,SAAS,KAAK,OAAO;AAAA,IAC3B,MAAM,aAAa,OAAO,SAAS,MAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,MAAM,CAAC,IAAI;AAAA,IAChF,MAAM,eAAe,IAAI,KAAK,mBAAmB,IAAI,KAAK,mBAAmB;AAAA,IAC7E,OAAO,KAAK,IAAI,KAAK,iBAAiB,KAAK,IAAI,GAAG,KAAK,MAAM,cAAc,YAAY,CAAC,CAAC;AAAA;AAAA,OAG7E,6BAA4B,CACxC,MACe;AAAA,IACf,IAAI,KAAK,WAAW;AAAA,MAAG;AAAA,IACvB,IAAI;AAAA,MACF,MAAM,KAAK,WAAW,CAAC,WACrB,OAAO,WAAW;AAAA,QAChB,WAAW,KAAK;AAAA,QAChB,KAAK,SAAS,IAAI;AAAA,QAClB,SAAS,cAAc,IAAI;AAAA,QAC3B,aAAa,KAAK,IAAI,EAAE,YAAY;AAAA,MACtC,CAAC,CACH;AAAA,MACA,OAAO,OAAO;AAAA,MACd,KAAK,YAAY,KAAK;AAAA;AAAA;AAAA,OAIZ,+BAA8B,GAAkB;AAAA,IAC5D,WAAW,SAAS,CAAC,GAAG,KAAK,QAAQ,GAAG;AAAA,MACtC,MAAM,KAAK,6BAA6B,MAAM,MAAM,CAAC;AAAA,MACrD,KAAK,SAAS,OAAO,KAAK;AAAA,IAC5B;AAAA;AAAA,EAGM,UAAa,CAAC,KAAoE;AAAA,IACxF,OAAO,KAAK,QAAQ,YAAY,CAAC,OAAO,IAAI,GAAG,SAAS,MAAM,CAAC;AAAA;AAAA,EAGzD,qBAAqB,CAAC,OAAgB,SAA8C;AAAA,IAC1F,IAAI;AAAA,MACF,KAAK,oBAAoB,OAAO,OAAO;AAAA,MACvC,MAAM;AAAA;AAAA,EAKF,WAAW,CAAC,OAAsB;AAAA,IACxC,IAAI;AAAA,MACF,KAAK,QAAQ,KAAK;AAAA,MAClB,MAAM;AAAA;AAIZ;AAAA;AAaA,MAAM,2BAA2B;AAAA,EACd,SAAS,IAAI;AAAA,EAY9B,GAAG,CACD,OACA,SACA,YACA,UACA,MACM;AAAA,IACN,MAAM,MAAM,sBAAqB,SAAS,8BAA6B;AAAA,IACvE,MAAM,QAAQ,KAAK,OAAO,IAAI,GAAG,KAAK;AAAA,MACpC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,IAAI;AAAA,MACd,YAAY,IAAI;AAAA,IAClB;AAAA,IACA,WAAW,OAAO,MAAM;AAAA,MACtB,MAAM,SAAS,IAAI,IAAI,SAAS,EAAE;AAAA,MAClC,MAAM,WAAW,IAAI,IAAI,SAAS,IAAI;AAAA,IACxC;AAAA,IACA,KAAK,OAAO,IAAI,KAAK,KAAK;AAAA;AAAA,EAG5B,IAAI,GAA0C;AAAA,IAC5C,OAAO,CAAC,GAAG,KAAK,OAAO,OAAO,CAAC,EAAE,IAAI,CAAC,WAAW;AAAA,MAC/C,OAAO,MAAM;AAAA,MACb,SAAS;AAAA,QACP,YAAY,MAAM;AAAA,QAClB,SAAS,MAAM;AAAA,QACf,UAAU,MAAM;AAAA,QAChB,UAAU,CAAC,GAAG,MAAM,QAAQ,EAAE,KAAK;AAAA,QACnC,YAAY,CAAC,GAAG,MAAM,UAAU,EAAE,KAAK;AAAA,MACzC;AAAA,IACF,EAAE;AAAA;AAEN;AAEA,SAAS,eAAe,CAAC,OAAe,MAAsB;AAAA,EAC5D,IAAI,CAAC,OAAO,cAAc,KAAK,KAAK,SAAS,GAAG;AAAA,IAC9C,MAAM,IAAI,MAAM,qCAAqC,kCAAkC;AAAA,EACzF;AAAA,EACA,OAAO;AAAA;AAGT,SAAS,kBAAkB,CAAC,OAAe,MAAsB;AAAA,EAC/D,IAAI,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,GAAG;AAAA,IAC7C,MAAM,IAAI,MAAM,qCAAqC,qCAAqC;AAAA,EAC5F;AAAA,EACA,OAAO;AAAA;AAGT,SAAS,cAAc,CAAC,OAAe,MAAoB;AAAA,EACzD,IAAI,MAAM,KAAK,EAAE,WAAW,GAAG;AAAA,IAC7B,MAAM,IAAI,MAAM,qCAAqC,yBAAyB;AAAA,EAChF;AAAA;AAGF,SAAS,cAAc,CACrB,MAC0D;AAAA,EAC1D,MAAM,SAAS,IAAI;AAAA,EACnB,WAAW,OAAO,MAAM;AAAA,IACtB,MAAM,QAAQ,OAAO,IAAI,IAAI,QAAQ,KAAK,CAAC;AAAA,IAC3C,MAAM,KAAK,GAAG;AAAA,IACd,OAAO,IAAI,IAAI,UAAU,KAAK;AAAA,EAChC;AAAA,EACA,OAAO;AAAA;AAGT,SAAS,QAAQ,CAAC,MAAqD;AAAA,EACrE,OAAO,KAAK,IAAI,CAAC,QAAQ,IAAI,SAAS,EAAE;AAAA;AAG1C,SAAS,aAAa,CAAC,MAAmD;AAAA,EACxE,MAAM,UAAU,KAAK,IAAI;AAAA,EACzB,IAAI,CAAC,WAAW,KAAK,KAAK,CAAC,QAAQ,IAAI,YAAY,OAAO,GAAG;AAAA,IAC3D,MAAM,IAAI,MAAM,gEAAgE;AAAA,EAClF;AAAA,EACA,OAAO;AAAA;AAGT,SAAS,wBAAwB,CAAC,OAAgB,UAAkB;AAAA,EAClE,OAAO,iBACL,yBACA,uDACA;AAAA,IACE;AAAA,IACA,SAAS;AAAA,MACP;AAAA,IACF;AAAA,EACF,CACF;AAAA;AAGF,eAAe,mBAAmB,CAChC,aACA,QACkC;AAAA,EAClC,IAAI,OAAO;AAAA,IAAS,OAAO;AAAA,EAE3B,OAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AAAA,IACtC,MAAM,OAAO,MAAM,OAAO,MAAM,QAAQ,SAAS,CAAC;AAAA,IAClD,MAAM,SAAS,CAAC,WAAuB;AAAA,MACrC,OAAO,oBAAoB,SAAS,IAAI;AAAA,MACxC,OAAO;AAAA;AAAA,IAET,OAAO,iBAAiB,SAAS,MAAM,EAAE,MAAM,KAAK,CAAC;AAAA,IAChD,YAAY,KACf,MAAM,OAAO,MAAM,QAAQ,WAAW,CAAC,GACvC,CAAC,UAAU,OAAO,MAAM,OAAO,KAAK,CAAC,CACvC;AAAA,GACD;AAAA;AAIH,SAAS,OAAO,CAAC,SAAuC;AAAA,EACtD,OAAO,QAAQ,KACb,MAAG;AAAA,IAAG;AAAA,KACN,MAAG;AAAA,IAAG;AAAA,GACR;AAAA;AAGF,eAAe,aAAa,CAAC,SAAwB,WAAqC;AAAA,EACxF,IAAI;AAAA,EACJ,MAAM,WAAW,IAAI,QAAe,CAAC,YAAY;AAAA,IAC/C,QAAQ,WAAW,MAAM,QAAQ,KAAK,GAAG,SAAS;AAAA,GACnD;AAAA,EACD,MAAM,SAAS,MAAM,QAAQ,KAAK;AAAA,IAChC,QAAQ,KACN,MAAM,MACN,MAAM,IACR;AAAA,IACA;AAAA,EACF,CAAC;AAAA,EACD,IAAI,UAAU;AAAA,IAAW,aAAa,KAAK;AAAA,EAC3C,OAAO;AAAA;;ACvjBT,uBAAS;AAuBF,IAAM,+BAA8B,IAAI,KAAK,KAAK,KAAK;AAEvD,IAAM,iBAAwC;AAAA,EACnD,IAAI;AAAA,EACJ,WAAW,EAAE,UAAU,6BAA4B;AACrD;AAAA;AA+DO,MAAM,oBAAmE;AAAA,EAC7D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,uBAAuB,IAAI;AAAA,EAE5C,WAAW,CAAC,SAAoC;AAAA,IAC9C,KAAK,YAAY,QAAQ;AAAA,IACzB,KAAK,SAAS,QAAQ;AAAA,IACtB,KAAK,SAAS,QAAQ,UAAU;AAAA,IAChC,KAAK,gBAAgB,QAAQ,iBAAiB,IAAI;AAAA;AAAA,OAe9C,KAAI,CAAC,OAA0B,UAA4C;AAAA,IAC/E,IAAI;AAAA,MACF,MAAM,KAAK,OAAO,KAAK;AAAA,MACvB,OAAO,OAAO;AAAA,MACd,IAAI;AAAA,QACF,MAAM,aAAa,MAAM,OAAO,IAAI,CAAC,UAAU,MAAM,IAAI;AAAA,QACzD,4BAA2B,KAAK,eAAe,OAAO;AAAA,UACpD,WAAW,KAAK;AAAA,UAChB;AAAA,QACF,CAAC;AAAA,QACD,MAAM;AAAA;AAAA;AAAA,OAMN,OAAM,CAAC,OAAiE;AAAA,IAC5E,IAAI,MAAM,OAAO,WAAW,GAAG;AAAA,MAC7B,OAAO,CAAC;AAAA,IACV;AAAA,IACA,WAAW,SAAS,MAAM,QAAQ;AAAA,MAChC,IAAI,oBAAmB,MAAM,IAAI,GAAG;AAAA,QAClC,MAAM,IAAI,aACR,eAAe,MAAM,0EACvB;AAAA,MACF;AAAA,IACF;AAAA,IAEA,MAAM,WAAW,MAAM,OAAO,IAAI,CAAC,UACjC,qBAAqB;AAAA,MACnB,WAAW,KAAK;AAAA,MAChB,OAAO,MAAM;AAAA,MACb,eAAe,MAAM;AAAA,MACrB,aAAa,MAAM;AAAA,MACnB;AAAA,IACF,CAAC,CACH;AAAA,IAEA,MAAM,KAAK,aAAa;AAAA,IACxB,MAAM,UAAU,MAAM,KAAK,OAAO,OAAO;AAAA,MACvC,WAAW,KAAK;AAAA,MAChB,UAAU,KAAK,OAAO;AAAA,MACtB,SAAS,SAAS,IAAI,CAAC,aAAa;AAAA,QAClC,MAAM,QAAQ;AAAA,QACd,KAAK,QAAQ;AAAA,QACb,SAAS,sBAAsB,OAAO;AAAA,QACtC,gBAAgB,QAAQ;AAAA,MAC1B,EAAE;AAAA,IACJ,CAAC;AAAA,IAED,IAAI,QAAQ,WAAW,SAAS,QAAQ;AAAA,MACtC,MAAM,IAAI,aACR,mBAAmB,QAAQ,wBAAwB,SAAS,2BAC9D;AAAA,IACF;AAAA,IAEA,OAAO,QAAQ,IAAI,kBAAkB;AAAA;AAAA,OAIjC,iBAAgB,CACpB,WACuC;AAAA,IACvC,IAAI,UAAU,WAAW,GAAG;AAAA,MAC1B,OAAO,CAAC;AAAA,IACV;AAAA,IAEA,WAAW,YAAY,WAAW;AAAA,MAChC,IAAI,SAAS,cAAc,KAAK,WAAW;AAAA,QACzC,MAAM,IAAI,aACR,UAAU,SAAS,2BAA2B,SAAS,oBAAoB,KAAK,aAClF;AAAA,MACF;AAAA,MACA,IAAI,CAAC,mBAAkB,SAAS,IAAI,GAAG;AAAA,QACrC,MAAM,IAAI,aAAY,UAAU,SAAS,6BAA6B;AAAA,MACxE;AAAA,MACA,IAAI,mBAAkB,SAAS,MAAM,UAAU,SAAS,OAAO;AAAA,QAC7D,MAAM,IAAI,aACR,UAAU,SAAS,cAAc,SAAS,+BAA+B,SAAS,QACpF;AAAA,MACF;AAAA,IACF;AAAA,IAEA,MAAM,KAAK,aAAa;AAAA,IACxB,MAAM,UAAU,MAAM,KAAK,OAAO,OAAO;AAAA,MACvC,WAAW,KAAK;AAAA,MAChB,UAAU,KAAK,OAAO;AAAA,MACtB,SAAS,UAAU,IAAI,CAAC,cAAc;AAAA,QACpC,MAAM,SAAS;AAAA,QACf,KAAK,SAAS;AAAA,QACd,SAAS,sBAAsB,QAAQ;AAAA,QACvC,gBAAgB,SAAS;AAAA,MAC3B,EAAE;AAAA,IACJ,CAAC;AAAA,IAED,IAAI,QAAQ,WAAW,UAAU,QAAQ;AAAA,MACvC,MAAM,IAAI,aACR,mBAAmB,QAAQ,wBAAwB,UAAU,4BAC/D;AAAA,IACF;AAAA,IAEA,OAAO,QAAQ,IAAI,kBAAkB;AAAA;AAAA,OAGjC,KAAI,CAAC,QAAyB,CAAC,GAA0C;AAAA,IAC7E,IAAI,MAAM,UAAU,aAAa,MAAM,SAAS,GAAG;AAAA,MACjD,OAAO,CAAC;AAAA,IACV;AAAA,IAEA,MAAM,QAAQ,kBAAkB,KAAK;AAAA,IACrC,IAAI,SAAS,MAAM,WAAW,GAAG;AAAA,MAC/B,OAAO,CAAC;AAAA,IACV;AAAA,IAEA,MAAM,KAAK,aAAa;AAAA,IACxB,MAAM,OAAO,MAAM,KAAK,OAAO,KAAK;AAAA,MAClC,WAAW,KAAK;AAAA,MAChB,UAAU,KAAK,OAAO;AAAA,MACtB,aAAa,MAAM;AAAA,MACnB,OAAO,MAAM;AAAA,MACb;AAAA,IACF,CAAC;AAAA,IAED,OAAO,KAAK,QAAQ,IAAI,kBAAkB;AAAA;AAAA,OAGtC,aAAY,GAAgC;AAAA,IAChD,MAAM,KAAK,aAAa;AAAA,IACxB,OAAO,KAAK,OAAO,aAAa;AAAA,MAC9B,WAAW,KAAK;AAAA,MAChB,UAAU,KAAK,OAAO;AAAA,IACxB,CAAC;AAAA;AAAA,OAGG,UAAS,CACb,OACA,SACqB;AAAA,IACrB,MAAM,KAAK,aAAa;AAAA,IACxB,OAAO,KAAK,OAAO,UACjB;AAAA,MACE,WAAW,KAAK;AAAA,MAChB,UAAU,KAAK,OAAO;AAAA,MACtB,MAAM,MAAM;AAAA,MACZ,aAAa,MAAM;AAAA,MACnB,OAAO,MAAM,SAAS,MAAM,MAAM,SAAS,IAAI,MAAM,QAAQ;AAAA,IAC/D,GACA,CAAC,YAAY;AAAA,MACX,MAAM,SAAS,QAAQ,IAAI,kBAAkB;AAAA,MAC7C,IAAI,OAAO,WAAW,GAAG;AAAA,QACvB;AAAA,MACF;AAAA,MAEA,IAAI;AAAA,QACF,QAAQ,MAAM;AAAA,QACd,MAAM;AAAA,KAIZ;AAAA;AAAA,EAGM,YAAY,GAAkB;AAAA,IACpC,MAAM,MAAM,GAAG,KAAK,gBAAc,KAAK,OAAO;AAAA,IAC9C,IAAI,UAAU,KAAK,qBAAqB,IAAI,GAAG;AAAA,IAC/C,IAAI,CAAC,SAAS;AAAA,MACZ,UAAU,KAAK,OACZ,aAAa;AAAA,QACZ,WAAW,KAAK;AAAA,QAChB,QAAQ,KAAK;AAAA,MACf,CAAC,EACA,MAAM,CAAC,UAAU;AAAA,QAChB,IAAI,KAAK,qBAAqB,IAAI,GAAG,MAAM,SAAS;AAAA,UAClD,KAAK,qBAAqB,OAAO,GAAG;AAAA,QACtC;AAAA,QACA,MAAM;AAAA,OACP;AAAA,MACH,KAAK,qBAAqB,IAAI,KAAK,OAAO;AAAA,IAC5C;AAAA,IACA,OAAO;AAAA;AAEX;AAEO,SAAS,yBAAwB,CAAC,SAAwD;AAAA,EAC/F,OAAO,IAAI,oBAAmB,OAAO;AAAA;AAKvC,SAAS,oBAAoB,CAAC,QAMP;AAAA,EACrB,MAAM,UAAU,qBAAoB,OAAO,KAAK;AAAA,EAChD,MAAM,UAAmC;AAAA,IACvC,IAAI,YAAW;AAAA,IACf,eAAe;AAAA,IACf,WAAW,OAAO;AAAA,IAClB,YAAY,OAAO,MAAM,cAAc,IAAI,KAAK,EAAE,YAAY;AAAA,IAC9D,MAAM,OAAO,MAAM;AAAA,IACnB,OAAO,QAAQ;AAAA,IACf,cAAc,QAAQ;AAAA,IACtB,SAAS,OAAO,MAAM;AAAA,EACxB;AAAA,EAEA,aAAa,SAAS,iBAAiB,OAAO,aAAa;AAAA,EAC3D,aAAa,SAAS,eAAe,OAAO,WAAW;AAAA,EACvD,aAAa,SAAS,kBAAkB,OAAO,MAAM,cAAc;AAAA,EACnE,aAAa,SAAS,SAAS,OAAO,KAAK;AAAA,EAC3C,aAAa,SAAS,UAAU,OAAO,MAAM,MAAM;AAAA,EACnD,aAAa,SAAS,YAAY,OAAO,MAAM,QAAQ;AAAA,EAEvD,OAAO;AAAA;AAGT,SAAS,qBAAqB,CAAC,SAA8D;AAAA,EAC3F,MAAM,SAAS,2BAA0B,SAAS,UAAU,QAAQ,eAAe;AAAA,EACnF,IAAI,QAAQ;AAAA,IACV,MAAM,IAAI,aAAY,UAAU,QAAQ,qCAAqC,QAAQ;AAAA,EACvF;AAAA,EAEA,OAAO;AAAA;AAGT,SAAS,kBAAkB,CAAC,QAAyC;AAAA,EACnE,MAAM,UAAU,OAAO;AAAA,EACvB,IAAI,CAAC,eAAe,OAAO,GAAG;AAAA,IAC5B,MAAM,IAAI,aAAY,4BAA4B,OAAO,iCAAiC;AAAA,EAC5F;AAAA,EAEA,MAAM,YAAY,QAAQ;AAAA,EAC1B,IAAI,OAAO,cAAc,YAAY,CAAC,mBAAkB,SAAS,GAAG;AAAA,IAClE,MAAM,IAAI,aAAY,4BAA4B,OAAO,iCAAiC;AAAA,EAC5F;AAAA,EAEA,IAAI,OAAO,SAAS,aAAa,OAAO,SAAS,WAAW;AAAA,IAC1D,MAAM,IAAI,aACR,uBAAuB,OAAO,oCAAoC,aACpE;AAAA,EACF;AAAA,EAEA,OAAO;AAAA,OACF;AAAA,IACH,QAAQ,OAAO;AAAA,EACjB;AAAA;AAGF,SAAS,iBAAiB,CAAC,OAGQ;AAAA,EACjC,MAAM,aACJ,MAAM,UAAU,MAAM,OAAO,SAAS,IAClC,aAAY,OAAO,CAAC,SAAS,MAAM,QAAQ,SAAS,mBAAkB,MAAM,KAAK,CAAC,IAClF;AAAA,EAEN,IAAI,CAAC,YAAY;AAAA,IACf,OAAO,MAAM,SAAS,MAAM,MAAM,SAAS,IAAI,MAAM,QAAQ;AAAA,EAC/D;AAAA,EAEA,IAAI,CAAC,MAAM,SAAS,MAAM,MAAM,WAAW,GAAG;AAAA,IAC5C,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,iBAAiB,IAAI,IAAI,MAAM,KAAK;AAAA,EAC1C,OAAO,WAAW,OAAO,CAAC,SAAS,eAAe,IAAI,IAAI,CAAC;AAAA;AAG7D,SAAS,cAAc,CAAC,OAAkD;AAAA,EACxE,OAAO,OAAO,UAAU,YAAY,UAAU;AAAA;AAGhD,SAAS,YAAY,CAAC,QAAiC,KAAa,OAAsB;AAAA,EACxF,IAAI,UAAU,WAAW;AAAA,IACvB,OAAO,OAAO;AAAA,EAChB;AAAA;;AC3YF,uBAAS;AAIF,SAAS,cAAa,CAAC,QAOJ;AAAA,EACxB,MAAM,OAAO;AAAA,IACX,IAAI,YAAW;AAAA,IACf,eAAe;AAAA,IACf,WAAW,OAAO;AAAA,IAClB,YAAY,OAAO,MAAM,cAAc,IAAI,KAAK,EAAE,YAAY;AAAA,IAC9D,eAAe,OAAO;AAAA,IACtB,aAAa,OAAO;AAAA,IACpB,gBAAgB,OAAO,MAAM;AAAA,IAC7B,OAAO,OAAO;AAAA,IACd,QAAQ,OAAO,MAAM;AAAA,IACrB,UAAU,OAAO,MAAM;AAAA,IACvB,QAAQ,OAAO;AAAA,EACjB;AAAA,EAEA,MAAM,UAAU,qBAAoB,OAAO,KAAK;AAAA,EAChD,OAAO;AAAA,OACF;AAAA,IACH,MAAM,OAAO,MAAM;AAAA,IACnB,OAAO,QAAQ;AAAA,IACf,cAAc,QAAQ;AAAA,IACtB,SAAS,OAAO,MAAM;AAAA,EACxB;AAAA;",
|
|
12
|
-
"debugId": "7C263754A6F3D6BA64756E2164756E21",
|
|
13
|
-
"names": []
|
|
14
|
-
}
|