@sixb/core 0.1.9 → 0.1.10
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 +8 -8
- package/dist/agents/index.js +16 -15
- package/dist/agents/index.js.map +1 -1
- package/dist/bootstrap/index.js +20 -19
- 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-k3cqkkn2.js → chunk-1824gssz.js} +30 -65
- package/dist/chunk-1824gssz.js.map +12 -0
- package/dist/{chunk-h1gfhhbh.js → chunk-28ja2cjs.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-kxwa347f.js → chunk-3qms4nax.js} +2 -2
- package/dist/{chunk-kxwa347f.js.map → chunk-3qms4nax.js.map} +3 -3
- package/dist/{chunk-emyyk7dx.js → chunk-5c7ga8zz.js} +22 -145
- package/dist/chunk-5c7ga8zz.js.map +12 -0
- package/dist/{chunk-hpr1r6av.js → chunk-5p1v802y.js} +46 -39
- package/dist/{chunk-hpr1r6av.js.map → chunk-5p1v802y.js.map} +4 -4
- package/dist/{chunk-zcnq6105.js → chunk-85cd7e8c.js} +2 -1
- package/dist/chunk-85cd7e8c.js.map +10 -0
- package/dist/{chunk-1enhpacz.js → chunk-976rxdpx.js} +5 -5
- package/dist/{chunk-3f7veca0.js → chunk-9x8dybsb.js} +3 -3
- package/dist/chunk-9x8dybsb.js.map +10 -0
- package/dist/{chunk-r29fxdhn.js → chunk-aa6z4a19.js} +160 -44
- package/dist/chunk-aa6z4a19.js.map +12 -0
- package/dist/{chunk-r4tfx1sf.js → chunk-agbbygvh.js} +4 -4
- package/dist/{chunk-jjy0fhrn.js → chunk-b0ec55a1.js} +20 -3
- package/dist/chunk-b0ec55a1.js.map +12 -0
- package/dist/{chunk-xfbydgzy.js → chunk-bn138h9w.js} +7 -8
- package/dist/{chunk-xfbydgzy.js.map → chunk-bn138h9w.js.map} +3 -3
- 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-0w35wavj.js → chunk-g7knyczr.js} +1 -1
- 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-0rdrecsb.js → chunk-kfee1h52.js} +116 -32
- package/dist/chunk-kfee1h52.js.map +13 -0
- package/dist/{chunk-ypbtykv6.js → chunk-nmbxcaqx.js} +1 -1
- package/dist/{chunk-3tgwrcyh.js → chunk-nt99sxd6.js} +2 -2
- package/dist/{chunk-3tgwrcyh.js.map → chunk-nt99sxd6.js.map} +3 -3
- package/dist/{chunk-vf691g1r.js → chunk-p5vcsw9c.js} +2 -2
- package/dist/{chunk-mjbk2djy.js → chunk-p6a4npdx.js} +211 -106
- package/dist/{chunk-mjbk2djy.js.map → chunk-p6a4npdx.js.map} +9 -8
- package/dist/{chunk-3frsnm7x.js → chunk-qma80ych.js} +4 -6
- package/dist/chunk-qma80ych.js.map +11 -0
- package/dist/{chunk-qhcpj9wc.js → chunk-qyeptdyv.js} +96 -2
- package/dist/chunk-qyeptdyv.js.map +15 -0
- package/dist/{chunk-52hbv0ak.js → chunk-r7fj830t.js} +101 -48
- package/dist/chunk-r7fj830t.js.map +36 -0
- package/dist/{chunk-xyr8kppc.js → chunk-rtk71jzp.js} +1 -1
- package/dist/{chunk-m3z3x9v0.js → chunk-t1f4f1ve.js} +1 -1
- package/dist/chunk-v2vcg0w6.js +151 -0
- package/dist/chunk-v2vcg0w6.js.map +11 -0
- package/dist/connectors/connections/authorizations.d.ts.map +1 -1
- package/dist/connectors/connections/contracts.d.ts +3 -0
- package/dist/connectors/connections/contracts.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.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/service.d.ts +2 -2
- package/dist/events/service.d.ts.map +1 -1
- package/dist/execution/agent.js +16 -15
- package/dist/execution/agent.js.map +1 -1
- package/dist/execution/primitive.js +16 -15
- package/dist/execution/primitive.js.map +2 -2
- package/dist/execution/request.js +16 -15
- 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 +30 -28
- 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 +36 -0
- package/dist/lake-storage/types.d.ts.map +1 -1
- package/dist/logging/internal.js +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 +5 -5
- 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/execution/index.js +5 -5
- package/dist/objects/index.js +9 -9
- package/dist/objects/query/index.js +5 -5
- package/dist/pipelines/index.js +6 -6
- package/dist/pipelines/run-dispatch.d.ts.map +1 -1
- package/dist/projections/internal.js +6 -8
- 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 +4 -4
- package/dist/storage/connector-connections/in-memory.d.ts.map +1 -1
- package/dist/storage/connector-connections/provider/runs.d.ts.map +1 -1
- package/dist/storage/connector-connections/provider.js +2 -2
- package/dist/storage/connector-connections/provider.js.map +3 -3
- package/dist/storage/connector-connections/types.d.ts +3 -2
- 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 +4 -4
- 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/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 +8 -7
- 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 +1459 -951
- package/dist/testing/index.js.map +9 -8
- package/dist/testing/lake-changes-contract.d.ts +6 -0
- package/dist/testing/lake-changes-contract.d.ts.map +1 -0
- 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 +54 -9
- 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 +17 -16
- 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/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/contracts.ts +3 -0
- package/src/connectors/connections/request.ts +56 -22
- package/src/connectors/connections/runs.ts +1 -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/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 +73 -0
- package/src/lake-storage/index.ts +4 -0
- package/src/lake-storage/types.ts +40 -0
- package/src/logging/service.ts +1 -1
- package/src/materialization/index.ts +2 -0
- package/src/materialization/model.ts +14 -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/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 +3 -1
- package/src/storage/connector-connections/provider/runs.ts +3 -1
- package/src/storage/connector-connections/types.ts +3 -2
- 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 +26 -1
- 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/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 +18 -1
- package/src/testing/index.ts +1 -0
- package/src/testing/lake-changes-contract.ts +240 -0
- package/src/testing/materializer-storage-contract.ts +172 -1
- package/src/testing/ontology-storage-contract.ts +7 -0
- 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-52hbv0ak.js.map +0 -36
- 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-h1gfhhbh.js.map → chunk-28ja2cjs.js.map} +0 -0
- /package/dist/{chunk-1enhpacz.js.map → chunk-976rxdpx.js.map} +0 -0
- /package/dist/{chunk-r4tfx1sf.js.map → chunk-agbbygvh.js.map} +0 -0
- /package/dist/{chunk-0w35wavj.js.map → chunk-g7knyczr.js.map} +0 -0
- /package/dist/{chunk-ypbtykv6.js.map → chunk-nmbxcaqx.js.map} +0 -0
- /package/dist/{chunk-vf691g1r.js.map → chunk-p5vcsw9c.js.map} +0 -0
- /package/dist/{chunk-xyr8kppc.js.map → chunk-rtk71jzp.js.map} +0 -0
- /package/dist/{chunk-m3z3x9v0.js.map → chunk-t1f4f1ve.js.map} +0 -0
|
@@ -10,14 +10,12 @@ var PROJECTION_RUN_FAILURE_CODES2 = [
|
|
|
10
10
|
// src/storage/projection-runs/types.ts
|
|
11
11
|
var progressKeyFlags = {
|
|
12
12
|
sourceRowsRead: true,
|
|
13
|
-
sourceRowsSkipped: true
|
|
13
|
+
sourceRowsSkipped: true,
|
|
14
|
+
sourceChangesRead: true
|
|
14
15
|
};
|
|
15
16
|
var PROJECTION_RUN_PROGRESS_KEYS2 = Object.keys(progressKeyFlags);
|
|
16
17
|
function zeroProjectionRunProgress2() {
|
|
17
|
-
|
|
18
|
-
for (const key of PROJECTION_RUN_PROGRESS_KEYS2)
|
|
19
|
-
progress[key] = 0;
|
|
20
|
-
return progress;
|
|
18
|
+
return { sourceRowsRead: 0, sourceRowsSkipped: 0 };
|
|
21
19
|
}
|
|
22
20
|
function projectionRunObjectTypesVisible2(run, canView) {
|
|
23
21
|
const target = run.target;
|
|
@@ -29,4 +27,4 @@ function projectionRunObjectTypesVisible2(run, canView) {
|
|
|
29
27
|
|
|
30
28
|
export { PROJECTION_RUN_FAILURE_CODES2, PROJECTION_RUN_PROGRESS_KEYS2, zeroProjectionRunProgress2, projectionRunObjectTypesVisible2 };
|
|
31
29
|
|
|
32
|
-
//# debugId=
|
|
30
|
+
//# debugId=20098923B6EB738064756E2164756E21
|
|
@@ -0,0 +1,11 @@
|
|
|
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 /** Maximum complete change records consumed by one incremental attempt; not a recovery cursor. */\n readonly sourceChangesRead?: number\n}\n\nconst progressKeyFlags: Record<keyof ProjectionRunProgress, true> = {\n sourceRowsRead: true,\n sourceRowsSkipped: true,\n sourceChangesRead: true,\n}\n\nexport const PROJECTION_RUN_PROGRESS_KEYS = Object.keys(\n progressKeyFlags\n) as readonly (keyof ProjectionRunProgress)[]\n\nexport function zeroProjectionRunProgress(): ProjectionRunProgress {\n return { sourceRowsRead: 0, sourceRowsSkipped: 0 }\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;;;ACqBA,IAAM,mBAA8D;AAAA,EAClE,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,mBAAmB;AACrB;AAEO,IAAM,gCAA+B,OAAO,KACjD,gBACF;AAEO,SAAS,0BAAyB,GAA0B;AAAA,EACjE,OAAO,EAAE,gBAAgB,GAAG,mBAAmB,EAAE;AAAA;AA6E5C,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": "20098923B6EB738064756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
|
@@ -18,6 +18,32 @@ import {
|
|
|
18
18
|
import {
|
|
19
19
|
stableJsonStringify2
|
|
20
20
|
} from "./chunk-wy0qdqfm.js";
|
|
21
|
+
// src/lake-storage/changes.ts
|
|
22
|
+
function resolveDatasetChangeColumns2(input, before, after) {
|
|
23
|
+
for (const value of [input.datasetId, input.fromVersionId, input.toVersionId]) {
|
|
24
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
25
|
+
throw new LakeStorageError2("[LakeStorage] Change reads require explicit dataset and version ids.");
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (input.keyColumns.length === 0 || new Set(input.keyColumns).size !== input.keyColumns.length || input.columns.length === 0 || new Set(input.columns).size !== input.columns.length || input.columns.some((column) => typeof column !== "string" || column.length === 0) || input.keyColumns.some((column) => !input.columns.includes(column))) {
|
|
29
|
+
throw new LakeStorageError2("[LakeStorage] Change reads require distinct columns including every key column.");
|
|
30
|
+
}
|
|
31
|
+
if (!before || !after)
|
|
32
|
+
return null;
|
|
33
|
+
const oldColumns = new Map(before.schema.columns.map((column) => [column.name, column]));
|
|
34
|
+
const newColumns = new Map(after.schema.columns.map((column) => [column.name, column]));
|
|
35
|
+
const columns = [];
|
|
36
|
+
for (const name of input.columns) {
|
|
37
|
+
const previous = oldColumns.get(name);
|
|
38
|
+
const next = newColumns.get(name);
|
|
39
|
+
if (!previous || !next || previous.type !== next.type)
|
|
40
|
+
return null;
|
|
41
|
+
if (input.keyColumns.includes(name) && next.type !== "string")
|
|
42
|
+
return null;
|
|
43
|
+
columns.push(next);
|
|
44
|
+
}
|
|
45
|
+
return columns;
|
|
46
|
+
}
|
|
21
47
|
// src/lake-storage/definition-updates.ts
|
|
22
48
|
var SCHEMA_UPDATE_V1_POLICY = "Dataset definition updates V1 support only adding nullable columns.";
|
|
23
49
|
function planDatasetDefinitionUpdate2(existing, requested) {
|
|
@@ -154,6 +180,7 @@ function throwUnsupportedSchemaUpdate(datasetId, detail) {
|
|
|
154
180
|
}
|
|
155
181
|
// src/lake-storage/in-memory.ts
|
|
156
182
|
import { randomUUID } from "crypto";
|
|
183
|
+
import { isDeepStrictEqual } from "util";
|
|
157
184
|
|
|
158
185
|
// src/lake-storage/merge.ts
|
|
159
186
|
async function retryDatasetMergeCommit2(merge, commit, run) {
|
|
@@ -512,6 +539,73 @@ ${details}`);
|
|
|
512
539
|
yield selectColumns(row, input.columns);
|
|
513
540
|
}
|
|
514
541
|
}
|
|
542
|
+
async readChanges(input) {
|
|
543
|
+
input.signal?.throwIfAborted();
|
|
544
|
+
const before = await this.getVersion(input.datasetId, input.fromVersionId);
|
|
545
|
+
const after = await this.getVersion(input.datasetId, input.toVersionId);
|
|
546
|
+
if (!resolveDatasetChangeColumns2(input, before, after))
|
|
547
|
+
return null;
|
|
548
|
+
const previous = this.rowsByVersionId.get(input.fromVersionId);
|
|
549
|
+
const next = this.rowsByVersionId.get(input.toVersionId);
|
|
550
|
+
const index = (rows) => {
|
|
551
|
+
const result = new Map;
|
|
552
|
+
for (const row of rows) {
|
|
553
|
+
input.signal?.throwIfAborted();
|
|
554
|
+
const values = input.keyColumns.map((column) => row[column]);
|
|
555
|
+
if (values.some((value) => typeof value !== "string" || value.trim().length === 0))
|
|
556
|
+
return null;
|
|
557
|
+
const key = JSON.stringify(values);
|
|
558
|
+
if (result.has(key))
|
|
559
|
+
return null;
|
|
560
|
+
result.set(key, row);
|
|
561
|
+
}
|
|
562
|
+
return result;
|
|
563
|
+
};
|
|
564
|
+
const oldRows = index(previous);
|
|
565
|
+
const newRows = index(next);
|
|
566
|
+
if (!oldRows || !newRows)
|
|
567
|
+
return null;
|
|
568
|
+
let pending = [];
|
|
569
|
+
for (const [key, row] of oldRows) {
|
|
570
|
+
const newRow = newRows.get(key);
|
|
571
|
+
if (!newRow || input.columns.some((column) => !isDeepStrictEqual(row[column] ?? null, newRow[column] ?? null))) {
|
|
572
|
+
pending.push({
|
|
573
|
+
before: selectColumns(row, input.columns),
|
|
574
|
+
after: newRow ? selectColumns(newRow, input.columns) : null
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
for (const [key, row] of newRows) {
|
|
579
|
+
if (!oldRows.has(key))
|
|
580
|
+
pending.push({ before: null, after: selectColumns(row, input.columns) });
|
|
581
|
+
}
|
|
582
|
+
let closed = false;
|
|
583
|
+
const changeCount = pending.length;
|
|
584
|
+
return {
|
|
585
|
+
fromRowCount: previous.length,
|
|
586
|
+
toRowCount: next.length,
|
|
587
|
+
changeCount,
|
|
588
|
+
changes: async function* () {
|
|
589
|
+
if (closed)
|
|
590
|
+
throw new LakeStorageError2("[LakeStorage] Change reader is closed.");
|
|
591
|
+
try {
|
|
592
|
+
for (let i = 0;i < changeCount; i++) {
|
|
593
|
+
input.signal?.throwIfAborted();
|
|
594
|
+
if (closed)
|
|
595
|
+
throw new LakeStorageError2("[LakeStorage] Change reader is closed.");
|
|
596
|
+
yield structuredClone(pending[i]);
|
|
597
|
+
}
|
|
598
|
+
} finally {
|
|
599
|
+
closed = true;
|
|
600
|
+
pending = [];
|
|
601
|
+
}
|
|
602
|
+
}(),
|
|
603
|
+
async close() {
|
|
604
|
+
closed = true;
|
|
605
|
+
pending = [];
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
}
|
|
515
609
|
async commitWrite(options) {
|
|
516
610
|
return this.withDatasetCommitLock(options.write.dataset.id, () => this.commitWriteUnlocked(options));
|
|
517
611
|
}
|
|
@@ -687,6 +781,6 @@ ${details}`);
|
|
|
687
781
|
}
|
|
688
782
|
}
|
|
689
783
|
}
|
|
690
|
-
export { planDatasetDefinitionUpdate2, mergeStrictDatasetDefinition2, assertLakeDatasetDefinitionsCompatible2, retryDatasetMergeCommit2, datasetSequenceChange2, reconcileDatasetSequences2, assertUnsequencedDatasetWrite2, hasDatasetInputChanges2, InMemoryLakeStorage2 };
|
|
784
|
+
export { resolveDatasetChangeColumns2, planDatasetDefinitionUpdate2, mergeStrictDatasetDefinition2, assertLakeDatasetDefinitionsCompatible2, retryDatasetMergeCommit2, datasetSequenceChange2, reconcileDatasetSequences2, assertUnsequencedDatasetWrite2, hasDatasetInputChanges2, InMemoryLakeStorage2 };
|
|
691
785
|
|
|
692
|
-
//# debugId=
|
|
786
|
+
//# debugId=8B7567B39BAB0B9A64756E2164756E21
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/lake-storage/changes.ts", "../src/lake-storage/definition-updates.ts", "../src/lake-storage/in-memory.ts", "../src/lake-storage/merge.ts", "../src/lake-storage/source-ordering.ts", "../src/lake-storage/version-inputs.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { DatasetColumnDefinition } from \"../datasets\"\nimport { LakeStorageError } from \"./errors\"\nimport type { DatasetVersion, ReadDatasetChangesInput } from \"./types\"\n\n/** Shared eligibility checks for providers comparing pinned row images. */\nexport function resolveDatasetChangeColumns(\n input: ReadDatasetChangesInput,\n before: DatasetVersion | null,\n after: DatasetVersion | null\n): readonly DatasetColumnDefinition[] | null {\n for (const value of [input.datasetId, input.fromVersionId, input.toVersionId]) {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new LakeStorageError(\n \"[LakeStorage] Change reads require explicit dataset and version ids.\"\n )\n }\n }\n if (\n input.keyColumns.length === 0 ||\n new Set(input.keyColumns).size !== input.keyColumns.length ||\n input.columns.length === 0 ||\n new Set(input.columns).size !== input.columns.length ||\n input.columns.some((column) => typeof column !== \"string\" || column.length === 0) ||\n input.keyColumns.some((column) => !input.columns.includes(column))\n ) {\n throw new LakeStorageError(\n \"[LakeStorage] Change reads require distinct columns including every key column.\"\n )\n }\n if (!before || !after) return null\n const oldColumns = new Map(before.schema.columns.map((column) => [column.name, column]))\n const newColumns = new Map(after.schema.columns.map((column) => [column.name, column]))\n const columns: DatasetColumnDefinition[] = []\n for (const name of input.columns) {\n const previous = oldColumns.get(name)\n const next = newColumns.get(name)\n if (!previous || !next || previous.type !== next.type) return null\n // Projection identities are nonblank strings. Other key types keep the full-read path.\n if (input.keyColumns.includes(name) && next.type !== \"string\") return null\n columns.push(next)\n }\n return columns\n}\n",
|
|
6
|
+
"import type { DatasetColumnDefinition, DatasetDefinition } from \"../datasets\"\nimport { assertDatasetDefinition } from \"../datasets/validation\"\nimport { LakeStorageError } from \"./errors\"\nimport type { LakeStorage } from \"./types\"\n\nexport type DatasetSchemaUpdatePlan =\n | { readonly kind: \"none\" }\n | {\n readonly kind: \"addNullableColumns\"\n readonly columns: readonly DatasetColumnDefinition[]\n }\n\nexport interface DatasetMetadataUpdatePlan {\n readonly descriptionChanged: boolean\n readonly partitionByChanged: boolean\n}\n\nexport interface DatasetDefinitionUpdatePlan {\n readonly existing: DatasetDefinition\n readonly requested: DatasetDefinition\n readonly definition: DatasetDefinition\n readonly schema: DatasetSchemaUpdatePlan\n readonly metadata: DatasetMetadataUpdatePlan\n readonly changed: boolean\n}\n\nconst SCHEMA_UPDATE_V1_POLICY =\n \"Dataset definition updates V1 support only adding nullable columns.\"\n\n/**\n * Build a provider-neutral update plan for two versions of the same dataset\n * definition. Core owns the definition diff; storage providers own how much of\n * the plan they can apply.\n */\nexport function planDatasetDefinitionUpdate(\n existing: DatasetDefinition,\n requested: DatasetDefinition\n): DatasetDefinitionUpdatePlan {\n assertSameDataset(existing, requested)\n assertDatasetDefinition(requested, (message) => new LakeStorageError(`[SixbLake] ${message}`))\n if (existing.sequenceBy !== requested.sequenceBy) {\n throw new LakeStorageError(\n `[SixbLake] Dataset '${requested.id}' sequenceBy is immutable. Create a new dataset and backfill to adopt or change source ordering.`\n )\n }\n assertPrimaryKeyUnchanged(existing, requested)\n\n const addedColumns = getAddedColumnsAfterValidatingExistingColumns(existing, requested)\n assertAddedColumnsAreNullable(requested.id, addedColumns)\n\n const schema = toSchemaUpdatePlan(addedColumns)\n const definition = mergeDatasetDefinition(existing, requested, addedColumns)\n const metadata: DatasetMetadataUpdatePlan = {\n descriptionChanged: existing.description !== definition.description,\n partitionByChanged: !areStringArraysEqual(existing.partitionBy, definition.partitionBy),\n }\n\n return {\n existing: structuredClone(existing),\n requested: structuredClone(requested),\n definition,\n schema,\n metadata,\n changed: schema.kind !== \"none\" || metadata.descriptionChanged || metadata.partitionByChanged,\n }\n}\n\n/**\n * Strict providers can use this helper when they do not support schema\n * evolution. Metadata-only compatible additions are still merged.\n */\nexport function mergeStrictDatasetDefinition(options: {\n readonly existing?: DatasetDefinition | null\n readonly next: DatasetDefinition\n}): DatasetDefinition {\n assertDatasetDefinition(options.next, (message) => new LakeStorageError(`[SixbLake] ${message}`))\n if (!options.existing) {\n return structuredClone(options.next)\n }\n\n const plan = planDatasetDefinitionUpdate(options.existing, options.next)\n if (plan.schema.kind !== \"none\") {\n throw new LakeStorageError(\n `[SixbLake] Dataset '${options.next.id}' cannot be redefined with an incompatible schema.`\n )\n }\n\n return structuredClone(plan.definition)\n}\n\nexport interface AssertLakeDatasetDefinitionsCompatibleOptions {\n readonly lakeStorage: LakeStorage\n readonly definitions: readonly DatasetDefinition[]\n}\n\nexport async function assertLakeDatasetDefinitionsCompatible(\n options: AssertLakeDatasetDefinitionsCompatibleOptions\n): Promise<void> {\n await options.lakeStorage.assertDatasetDefinitionsCompatible(options.definitions)\n}\n\nfunction assertSameDataset(existing: DatasetDefinition, requested: DatasetDefinition): void {\n if (existing.id !== requested.id) {\n throw new LakeStorageError(\n `[SixbLake] Cannot update dataset '${existing.id}' with definition for '${requested.id}'.`\n )\n }\n}\n\nfunction assertPrimaryKeyUnchanged(\n existing: DatasetDefinition,\n requested: DatasetDefinition\n): void {\n const existingPrimaryKey = existing.primaryKey\n const requestedPrimaryKey = requested.primaryKey\n const unchanged =\n existingPrimaryKey === undefined || requestedPrimaryKey === undefined\n ? existingPrimaryKey === requestedPrimaryKey\n : areDefinitionValuesEqual(existingPrimaryKey, requestedPrimaryKey)\n\n if (!unchanged) {\n throw new LakeStorageError(\n `[SixbLake] Dataset '${requested.id}' cannot be redefined with an incompatible primaryKey. Primary keys are immutable.`\n )\n }\n}\n\nfunction getAddedColumnsAfterValidatingExistingColumns(\n existing: DatasetDefinition,\n requested: DatasetDefinition\n): readonly DatasetColumnDefinition[] {\n const existingColumns = existing.schema.columns\n const requestedColumnsByName = new Map(\n requested.schema.columns.map((column) => [column.name, column])\n )\n\n // Existing columns are matched by name, not position. Developers can reorder\n // declarations for readability without implying a storage-level schema change.\n for (const existingColumn of existingColumns) {\n const requestedColumn = requestedColumnsByName.get(existingColumn.name)\n if (requestedColumn === undefined) {\n throwUnsupportedSchemaUpdate(\n requested.id,\n `dropping column '${existingColumn.name}' is not supported`\n )\n }\n\n assertExistingColumnUnchanged(requested.id, existingColumn, requestedColumn)\n }\n\n const existingColumnNames = new Set(existingColumns.map((column) => column.name))\n return requested.schema.columns.filter((column) => !existingColumnNames.has(column.name))\n}\n\nfunction assertAddedColumnsAreNullable(\n datasetId: string,\n addedColumns: readonly DatasetColumnDefinition[]\n): void {\n for (const column of addedColumns) {\n // Existing rows have no value for a new column. Until DatasetDefinition\n // supports defaults or backfills, only nullable columns are safe to add.\n if (!isNullable(column)) {\n throwUnsupportedSchemaUpdate(\n datasetId,\n `adding required column '${column.name}' is not supported`\n )\n }\n }\n}\n\nfunction assertExistingColumnUnchanged(\n datasetId: string,\n existing: DatasetColumnDefinition,\n requested: DatasetColumnDefinition\n): void {\n if (existing.type !== requested.type) {\n throwUnsupportedSchemaUpdate(\n datasetId,\n `changing column '${existing.name}' type from '${existing.type}' to '${requested.type}' is not supported`\n )\n }\n\n if (isNullable(existing) !== isNullable(requested)) {\n throwUnsupportedSchemaUpdate(\n datasetId,\n `changing column '${existing.name}' nullability is not supported`\n )\n }\n}\n\nfunction toSchemaUpdatePlan(\n addedColumns: readonly DatasetColumnDefinition[]\n): DatasetSchemaUpdatePlan {\n if (addedColumns.length === 0) {\n return { kind: \"none\" }\n }\n\n return {\n kind: \"addNullableColumns\",\n columns: cloneColumns(addedColumns),\n }\n}\n\nfunction mergeDatasetDefinition(\n existing: DatasetDefinition,\n requested: DatasetDefinition,\n addedColumns: readonly DatasetColumnDefinition[]\n): DatasetDefinition {\n assertCompatibleMetadataField(\n requested.id,\n \"description\",\n existing.description,\n requested.description\n )\n assertCompatibleMetadataField(\n requested.id,\n \"partitionBy\",\n existing.partitionBy,\n requested.partitionBy\n )\n\n const columns = [...cloneColumns(existing.schema.columns), ...cloneColumns(addedColumns)]\n const primaryKey = existing.primaryKey\n const partitionBy = requested.partitionBy ?? existing.partitionBy\n const description = requested.description ?? existing.description\n\n return {\n kind: \"dataset\",\n id: requested.id,\n schema: { columns },\n ...(primaryKey !== undefined ? { primaryKey: structuredClone(primaryKey) } : {}),\n ...(existing.sequenceBy !== undefined ? { sequenceBy: existing.sequenceBy } : {}),\n ...(partitionBy !== undefined ? { partitionBy: [...partitionBy] } : {}),\n ...(description !== undefined ? { description } : {}),\n }\n}\n\nfunction assertCompatibleMetadataField(\n datasetId: string,\n field: \"description\" | \"partitionBy\",\n existing: string | readonly string[] | undefined,\n requested: string | readonly string[] | undefined\n): void {\n if (\n existing === undefined ||\n requested === undefined ||\n areDefinitionValuesEqual(existing, requested)\n ) {\n return\n }\n\n throw new LakeStorageError(\n `[SixbLake] Dataset '${datasetId}' cannot be redefined with an incompatible ${field}.`\n )\n}\n\nfunction areStringArraysEqual(\n left: readonly string[] | undefined,\n right: readonly string[] | undefined\n): boolean {\n if (left === undefined || right === undefined) {\n return left === right\n }\n\n return left.length === right.length && left.every((value, index) => value === right[index])\n}\n\nfunction areDefinitionValuesEqual(\n left: string | readonly string[],\n right: string | readonly string[]\n): boolean {\n if (typeof left === \"string\" || typeof right === \"string\") {\n return left === right\n }\n\n return areStringArraysEqual(left, right)\n}\n\nfunction isNullable(column: DatasetColumnDefinition): boolean {\n return column.nullable === true\n}\n\nfunction cloneColumns(\n columns: readonly DatasetColumnDefinition[]\n): readonly DatasetColumnDefinition[] {\n return columns.map((column) => ({ ...column }))\n}\n\nfunction throwUnsupportedSchemaUpdate(datasetId: string, detail: string): never {\n throw new LakeStorageError(\n `[SixbLake] Dataset '${datasetId}' cannot apply schema update because ${detail}. ${SCHEMA_UPDATE_V1_POLICY}`\n )\n}\n",
|
|
7
|
+
"import { randomUUID } from \"node:crypto\"\nimport { isDeepStrictEqual } from \"node:util\"\nimport type { DatasetDefinition, DatasetSchema, MergeChange } from \"../datasets\"\nimport { getDatasetRowValidationError } from \"../datasets/validation\"\nimport { resolveDatasetChangeColumns } from \"./changes\"\nimport { mergeStrictDatasetDefinition } from \"./definition-updates\"\nimport { LakeConcurrencyError, LakeStorageError } from \"./errors\"\nimport type {\n BeginDatasetMergeInput,\n CommitDatasetMergeInput,\n DatasetMergeCommitResult,\n LakeMergeSession,\n} from \"./merge\"\nimport { retryDatasetMergeCommit } from \"./merge\"\nimport {\n cloneDatasetMergeChange,\n encodeDatasetPrimaryKey,\n getDatasetMergeChangeValidationError,\n getDatasetPrimaryKeyColumns,\n} from \"./merge-validation\"\nimport {\n assertUnsequencedDatasetWrite,\n type DatasetSequenceState,\n datasetSequenceChange,\n reconcileDatasetSequences,\n} from \"./source-ordering\"\nimport type {\n BeginDatasetWriteInput,\n CommitDatasetWriteInput,\n DatasetCatalogState,\n DatasetChanges,\n DatasetRow,\n DatasetRowChange,\n DatasetVersion,\n DatasetWriteCommitResult,\n DatasetWriteMode,\n LakeStorage,\n LakeWriteSession,\n ReadDatasetChangesInput,\n ReadDatasetRowsInput,\n} from \"./types\"\nimport { hasDatasetInputChanges } from \"./version-inputs\"\n\nfunction cloneDatasetDefinition(definition: DatasetDefinition): DatasetDefinition {\n return structuredClone(definition)\n}\n\nfunction cloneDatasetVersion(version: DatasetVersion): DatasetVersion {\n return {\n ...structuredClone(version),\n createdAt: new Date(version.createdAt),\n }\n}\n\nfunction cloneRow(row: DatasetRow): DatasetRow {\n return structuredClone(row)\n}\n\nfunction selectColumns(row: DatasetRow, columns?: readonly string[]): DatasetRow {\n if (!columns || columns.length === 0) {\n return cloneRow(row)\n }\n\n const selected: Record<string, unknown> = {}\n for (const column of columns) {\n selected[column] = row[column]\n }\n return selected\n}\n\n// Canonical content key for unchanged-write detection. JSON.stringify\n// serializes Date values via toJSON, matching how rows persist as JSON;\n// missing and undefined nullable values normalize to null. The unchanged-write\n// semantics are pinned by the shared lake-storage contract suite.\nfunction rowContentKey(row: DatasetRow, schema: DatasetSchema): string {\n return JSON.stringify(schema.columns.map((column) => row[column.name] ?? null))\n}\n\n// Order-insensitive multiset equality over canonical row keys.\nfunction sameRowContent(left: readonly string[], right: readonly string[]): boolean {\n if (left.length !== right.length) {\n return false\n }\n\n const sortedLeft = [...left].sort()\n const sortedRight = [...right].sort()\n return sortedLeft.every((key, index) => key === sortedRight[index])\n}\n\nfunction assertDatasetId(datasetId: string): void {\n if (datasetId.trim().length === 0) {\n throw new LakeStorageError(\"[LakeStorage] Dataset id must not be empty\")\n }\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\nclass InMemoryLakeWriteSession implements LakeWriteSession {\n private readonly rows: DatasetRow[] = []\n private readonly primaryKeys = new Set<string>()\n private closed = false\n\n constructor(\n private readonly storage: InMemoryLakeStorage,\n private readonly input: BeginDatasetWriteInput\n ) {}\n\n async writeRows(rows: Iterable<DatasetRow> | AsyncIterable<DatasetRow>): Promise<void> {\n this.assertOpen()\n\n const stagedRows: DatasetRow[] = []\n const stagedPrimaryKeys = new Set<string>()\n for await (const row of rows) {\n const validationError = getDatasetRowValidationError(row, this.input.dataset)\n if (validationError) {\n throw new LakeStorageError(`[LakeStorage] ${validationError}`)\n }\n\n if (getDatasetPrimaryKeyColumns(this.input.dataset) !== null) {\n const primaryKey = encodeDatasetPrimaryKey(this.input.dataset, row)\n if (this.primaryKeys.has(primaryKey) || stagedPrimaryKeys.has(primaryKey)) {\n throw new LakeStorageError(\n `[LakeStorage] Dataset '${this.input.dataset.id}' write contains duplicate primary key ${primaryKey}.`\n )\n }\n stagedPrimaryKeys.add(primaryKey)\n }\n\n stagedRows.push(cloneRow(row))\n }\n\n this.rows.push(...stagedRows)\n for (const primaryKey of stagedPrimaryKeys) {\n this.primaryKeys.add(primaryKey)\n }\n }\n\n async commit(input?: CommitDatasetWriteInput): Promise<DatasetWriteCommitResult> {\n this.assertOpen()\n this.closed = true\n return this.storage.commitWrite({\n write: this.input,\n rows: this.rows,\n commit: input,\n })\n }\n\n async abort(): Promise<void> {\n this.closed = true\n this.rows.length = 0\n }\n\n private assertOpen(): void {\n if (this.closed) {\n throw new LakeStorageError(\"[LakeStorage] Write session is already closed\")\n }\n }\n}\n\nclass InMemoryLakeMergeSession implements LakeMergeSession {\n private readonly changes: MergeChange<DatasetRow, DatasetRow>[] = []\n private closed = false\n\n constructor(\n private readonly storage: InMemoryLakeStorage,\n private readonly input: BeginDatasetMergeInput,\n private readonly baseVersionId: string | null\n ) {}\n\n async writeChanges(\n changes:\n | Iterable<MergeChange<DatasetRow, DatasetRow>>\n | AsyncIterable<MergeChange<DatasetRow, DatasetRow>>\n ): Promise<void> {\n this.assertOpen()\n\n const stagedChanges: MergeChange<DatasetRow, DatasetRow>[] = []\n for await (const change of changes) {\n const validationError = getDatasetMergeChangeValidationError(change, this.input.dataset)\n if (validationError) {\n throw new LakeStorageError(`[LakeStorage] ${validationError}`)\n }\n stagedChanges.push(cloneDatasetMergeChange(change))\n }\n this.changes.push(...stagedChanges)\n }\n\n async commit(input?: CommitDatasetMergeInput): Promise<DatasetMergeCommitResult> {\n this.assertOpen()\n this.closed = true\n return retryDatasetMergeCommit(this.input, input, async (rebase) =>\n this.storage.commitMerge({\n merge: this.input,\n baseVersionId: rebase\n ? ((await this.storage.getLatestVersion(this.input.dataset.id))?.versionId ?? null)\n : this.baseVersionId,\n changes: this.changes,\n commit: input,\n })\n )\n }\n\n async abort(): Promise<void> {\n this.closed = true\n this.changes.length = 0\n }\n\n private assertOpen(): void {\n if (this.closed) {\n throw new LakeStorageError(\"[LakeStorage] Merge session is already closed\")\n }\n }\n}\n\nexport class InMemoryLakeStorage implements LakeStorage {\n private readonly datasets = new Map<string, DatasetDefinition>()\n private readonly versionsByDataset = new Map<string, DatasetVersion[]>()\n private readonly rowsByVersionId = new Map<string, readonly DatasetRow[]>()\n private readonly sequencesByVersionId = new Map<string, Map<string, DatasetSequenceState>>()\n private readonly latestVersionIdByDataset = new Map<string, string>()\n private readonly commitLocks = new Map<string, Promise<void>>()\n\n async createDataset(definition: DatasetDefinition): Promise<DatasetDefinition> {\n assertDatasetId(definition.id)\n const existing = this.datasets.get(definition.id)\n const stored = mergeStrictDatasetDefinition({\n existing,\n next: definition,\n })\n this.datasets.set(definition.id, stored)\n return cloneDatasetDefinition(stored)\n }\n\n async assertDatasetDefinitionsCompatible(\n definitions: readonly DatasetDefinition[]\n ): Promise<void> {\n const failures: string[] = []\n\n for (const definition of definitions) {\n try {\n assertDatasetId(definition.id)\n const existing = this.datasets.get(definition.id)\n if (!existing) {\n continue\n }\n\n mergeStrictDatasetDefinition({\n existing,\n next: definition,\n })\n } catch (error) {\n failures.push(`- ${definition.id}: ${errorMessage(error)}`)\n }\n }\n\n if (failures.length > 0) {\n const details = failures.join(\"\\n\")\n throw new LakeStorageError(\n `[SixbLake] Lake dataset definition check failed for ${failures.length} dataset(s).\\n${details}`\n )\n }\n }\n\n async getDataset(datasetId: string): Promise<DatasetDefinition | null> {\n const definition = this.datasets.get(datasetId)\n return definition ? cloneDatasetDefinition(definition) : null\n }\n\n async listDatasets(): Promise<readonly DatasetDefinition[]> {\n return [...this.datasets.values()].map((definition) => cloneDatasetDefinition(definition))\n }\n\n async listDatasetCatalogState(\n datasetIds: readonly string[]\n ): Promise<readonly DatasetCatalogState[]> {\n return Promise.all(\n datasetIds.map(async (datasetId) => {\n if (!this.datasets.has(datasetId)) {\n return { datasetId, materialized: false, latestVersion: null }\n }\n\n const latest = await this.getLatestVersion(datasetId)\n return {\n datasetId,\n materialized: true,\n latestVersion: latest\n ? {\n datasetId: latest.datasetId,\n versionId: latest.versionId,\n mode: latest.mode,\n createdAt: latest.createdAt,\n ...(latest.rowCount !== undefined ? { rowCount: latest.rowCount } : {}),\n }\n : null,\n }\n })\n )\n }\n\n async listVersions(datasetId: string, limit?: number): Promise<readonly DatasetVersion[]> {\n const versions = [...(this.versionsByDataset.get(datasetId) ?? [])]\n .sort((left, right) => right.createdAt.getTime() - left.createdAt.getTime())\n .map((version) => cloneDatasetVersion(version))\n\n return limit === undefined ? versions : versions.slice(0, Math.max(0, limit))\n }\n\n async beginWrite(input: BeginDatasetWriteInput): Promise<LakeWriteSession> {\n const definition = await this.getDataset(input.dataset.id)\n if (!definition) {\n throw new LakeStorageError(`[LakeStorage] Unknown dataset '${input.dataset.id}'`)\n }\n\n assertUnsequencedDatasetWrite(definition)\n return new InMemoryLakeWriteSession(this, {\n ...input,\n dataset: definition,\n mode: input.mode ?? \"snapshot\",\n })\n }\n\n async beginMerge(input: BeginDatasetMergeInput): Promise<LakeMergeSession> {\n const definition = await this.getDataset(input.dataset.id)\n if (!definition) {\n throw new LakeStorageError(`[LakeStorage] Unknown dataset '${input.dataset.id}'`)\n }\n if (getDatasetPrimaryKeyColumns(definition) === null) {\n throw new LakeStorageError(\n `[LakeStorage] Dataset '${definition.id}' must define a primaryKey before it can be merged.`\n )\n }\n\n const latestVersion = await this.getLatestVersion(definition.id)\n if (\n input.expectedLatestVersionId !== undefined &&\n latestVersion?.versionId !== input.expectedLatestVersionId\n ) {\n throw new LakeConcurrencyError(\n `[LakeStorage] Optimistic merge start failed for dataset '${definition.id}': expected latest version '${input.expectedLatestVersionId}', found '${latestVersion?.versionId ?? \"none\"}'`\n )\n }\n return new InMemoryLakeMergeSession(\n this,\n {\n ...input,\n dataset: definition,\n },\n latestVersion?.versionId ?? null\n )\n }\n\n async getLatestVersion(datasetId: string): Promise<DatasetVersion | null> {\n const latestVersionId = this.latestVersionIdByDataset.get(datasetId)\n if (!latestVersionId) {\n return null\n }\n\n return this.getVersion(datasetId, latestVersionId)\n }\n\n async getVersion(datasetId: string, versionId: string): Promise<DatasetVersion | null> {\n const versions = this.versionsByDataset.get(datasetId) ?? []\n const version = versions.find((candidate) => candidate.versionId === versionId)\n return version ? cloneDatasetVersion(version) : null\n }\n\n async *readRows(input: ReadDatasetRowsInput): AsyncIterable<DatasetRow> {\n const definition = this.datasets.get(input.datasetId)\n if (!definition) {\n throw new LakeStorageError(`[LakeStorage] Unknown dataset '${input.datasetId}'`)\n }\n\n const version =\n input.versionId === undefined\n ? await this.getLatestVersion(input.datasetId)\n : await this.getVersion(input.datasetId, input.versionId)\n\n if (!version) {\n throw new LakeStorageError(\n `[LakeStorage] No committed version found for dataset '${input.datasetId}'`\n )\n }\n\n const offset = Math.max(0, input.offset ?? 0)\n const limit = input.limit === undefined ? undefined : Math.max(0, input.limit)\n const rows = this.rowsByVersionId\n .get(version.versionId)\n ?.slice(offset, limit === undefined ? undefined : offset + limit)\n\n for (const row of rows ?? []) {\n yield selectColumns(row, input.columns)\n }\n }\n\n async readChanges(input: ReadDatasetChangesInput): Promise<DatasetChanges | null> {\n input.signal?.throwIfAborted()\n const before = await this.getVersion(input.datasetId, input.fromVersionId)\n const after = await this.getVersion(input.datasetId, input.toVersionId)\n if (!resolveDatasetChangeColumns(input, before, after)) return null\n const previous = this.rowsByVersionId.get(input.fromVersionId)!\n const next = this.rowsByVersionId.get(input.toVersionId)!\n const index = (rows: readonly DatasetRow[]) => {\n const result = new Map<string, DatasetRow>()\n for (const row of rows) {\n input.signal?.throwIfAborted()\n const values = input.keyColumns.map((column) => row[column])\n if (values.some((value) => typeof value !== \"string\" || value.trim().length === 0))\n return null\n const key = JSON.stringify(values)\n if (result.has(key)) return null\n result.set(key, row)\n }\n return result\n }\n const oldRows = index(previous)\n const newRows = index(next)\n if (!oldRows || !newRows) return null\n let pending: DatasetRowChange[] = []\n for (const [key, row] of oldRows) {\n const newRow = newRows.get(key)\n if (\n !newRow ||\n input.columns.some(\n (column) => !isDeepStrictEqual(row[column] ?? null, newRow[column] ?? null)\n )\n ) {\n pending.push({\n before: selectColumns(row, input.columns),\n after: newRow ? selectColumns(newRow, input.columns) : null,\n })\n }\n }\n for (const [key, row] of newRows) {\n if (!oldRows.has(key))\n pending.push({ before: null, after: selectColumns(row, input.columns) })\n }\n let closed = false\n const changeCount = pending.length\n return {\n fromRowCount: previous.length,\n toRowCount: next.length,\n changeCount,\n changes: (async function* () {\n if (closed) throw new LakeStorageError(\"[LakeStorage] Change reader is closed.\")\n try {\n for (let i = 0; i < changeCount; i++) {\n input.signal?.throwIfAborted()\n if (closed) throw new LakeStorageError(\"[LakeStorage] Change reader is closed.\")\n yield structuredClone(pending[i]!)\n }\n } finally {\n closed = true\n pending = []\n }\n })(),\n async close() {\n closed = true\n pending = []\n },\n }\n }\n\n async commitWrite(options: {\n write: BeginDatasetWriteInput\n rows: readonly DatasetRow[]\n commit?: CommitDatasetWriteInput\n }): Promise<DatasetWriteCommitResult> {\n return this.withDatasetCommitLock(options.write.dataset.id, () =>\n this.commitWriteUnlocked(options)\n )\n }\n\n async commitMerge(options: {\n merge: BeginDatasetMergeInput\n baseVersionId: string | null\n changes: readonly MergeChange<DatasetRow, DatasetRow>[]\n commit?: CommitDatasetMergeInput\n }): Promise<DatasetMergeCommitResult> {\n return this.withDatasetCommitLock(options.merge.dataset.id, async () => {\n const definition = this.datasets.get(options.merge.dataset.id)\n if (!definition) {\n throw new LakeStorageError(`[LakeStorage] Unknown dataset '${options.merge.dataset.id}'`)\n }\n\n const latestVersion = await this.getLatestVersion(options.merge.dataset.id)\n options.commit?.signal?.throwIfAborted()\n const actualVersionId = latestVersion?.versionId ?? null\n if (actualVersionId !== options.baseVersionId) {\n throw new LakeConcurrencyError(\n `[LakeStorage] Optimistic merge commit failed for dataset '${options.merge.dataset.id}': expected latest version '${options.baseVersionId ?? \"none\"}', found '${actualVersionId ?? \"none\"}'`\n )\n }\n\n const previousRows = this.rowsByVersionId.get(latestVersion?.versionId ?? \"\") ?? []\n const previousByKey = this.rowsByPrimaryKey(previousRows, definition)\n const finalChanges = new Map<string, MergeChange<DatasetRow, DatasetRow>>()\n const ordered =\n definition.sequenceBy === undefined\n ? undefined\n : reconcileDatasetSequences(\n definition,\n this.sequencesByVersionId.get(actualVersionId ?? \"\") ?? new Map(),\n options.changes.map((change) => datasetSequenceChange(definition, change))\n )\n if (ordered) {\n for (const [key, index] of ordered.accepted) finalChanges.set(key, options.changes[index]!)\n } else {\n for (const change of options.changes) {\n const value = change.kind === \"upsert\" ? change.row : change.key\n finalChanges.set(encodeDatasetPrimaryKey(definition, value), change)\n }\n }\n\n const nextByKey = new Map(previousByKey)\n for (const [primaryKey, change] of finalChanges) {\n if (change.kind === \"upsert\") {\n nextByKey.set(primaryKey, cloneRow(change.row))\n } else {\n nextByKey.delete(primaryKey)\n }\n }\n\n const createInitialVersion = options.commit?.createInitialVersion && latestVersion === null\n if (\n !createInitialVersion &&\n (ordered\n ? ordered.accepted.size === 0\n : this.sameKeyedRowContent(previousByKey, nextByKey, definition.schema))\n ) {\n return {\n outcome: \"unchanged\",\n version: latestVersion ? cloneDatasetVersion(latestVersion) : null,\n }\n }\n\n const visibleRows = [...nextByKey.values()]\n const versionId = `ver_${randomUUID()}`\n const version: DatasetVersion = {\n datasetId: options.merge.dataset.id,\n versionId,\n parentVersionId: latestVersion?.versionId,\n mode: \"merge\",\n createdAt: new Date(),\n schema: definition.schema,\n producer: options.merge.producer ? structuredClone(options.merge.producer) : undefined,\n inputs: options.merge.inputs ? structuredClone(options.merge.inputs) : undefined,\n rowCount: visibleRows.length,\n sizeBytes: new TextEncoder().encode(\n visibleRows.map((row) => JSON.stringify(row)).join(\"\\n\")\n ).byteLength,\n }\n\n const versions = this.versionsByDataset.get(options.merge.dataset.id) ?? []\n versions.push(version)\n this.versionsByDataset.set(options.merge.dataset.id, versions)\n this.rowsByVersionId.set(\n versionId,\n visibleRows.map((row) => cloneRow(row))\n )\n this.latestVersionIdByDataset.set(options.merge.dataset.id, versionId)\n if (ordered) this.sequencesByVersionId.set(versionId, ordered.states)\n\n return { outcome: \"created\", version: cloneDatasetVersion(version) }\n })\n }\n\n private async commitWriteUnlocked(options: {\n write: BeginDatasetWriteInput\n rows: readonly DatasetRow[]\n commit?: CommitDatasetWriteInput\n }): Promise<DatasetWriteCommitResult> {\n const definition = this.datasets.get(options.write.dataset.id)\n if (!definition) {\n throw new LakeStorageError(`[LakeStorage] Unknown dataset '${options.write.dataset.id}'`)\n }\n\n const mode = options.write.mode ?? \"snapshot\"\n assertUnsequencedDatasetWrite(definition)\n const latestVersion = await this.getLatestVersion(options.write.dataset.id)\n\n if (options.commit?.expectedLatestVersionId !== undefined) {\n const actual = latestVersion?.versionId ?? null\n if (actual !== options.commit.expectedLatestVersionId) {\n throw new LakeConcurrencyError(\n `[LakeStorage] Optimistic commit failed for dataset '${options.write.dataset.id}': expected latest version '${options.commit.expectedLatestVersionId ?? \"none\"}', found '${actual ?? \"none\"}'`\n )\n }\n }\n\n this.assertKeyedWriteIsUnique(mode, options.rows, latestVersion, definition)\n\n // Content-identical snapshots and empty appends reuse the latest version\n // unless explicitly supplied input lineage has changed.\n if (\n latestVersion &&\n !hasDatasetInputChanges(latestVersion.inputs, options.write.inputs) &&\n this.isUnchangedWrite(mode, latestVersion, options.rows, definition.schema)\n ) {\n return { ...latestVersion, outcome: \"unchanged\" }\n }\n\n const versionId = `ver_${randomUUID()}`\n const visibleRows =\n mode === \"append\"\n ? [...(this.rowsByVersionId.get(latestVersion?.versionId ?? \"\") ?? []), ...options.rows]\n : [...options.rows]\n\n const sizeBytes = new TextEncoder().encode(\n visibleRows.map((row) => JSON.stringify(row)).join(\"\\n\")\n ).byteLength\n\n const version: DatasetVersion = {\n datasetId: options.write.dataset.id,\n versionId,\n parentVersionId: mode === \"append\" ? latestVersion?.versionId : undefined,\n mode,\n createdAt: new Date(),\n schema: definition.schema,\n producer: options.write.producer ? structuredClone(options.write.producer) : undefined,\n inputs: options.write.inputs ? structuredClone(options.write.inputs) : undefined,\n rowCount: visibleRows.length,\n sizeBytes,\n }\n\n const versions = this.versionsByDataset.get(options.write.dataset.id) ?? []\n versions.push(version)\n this.versionsByDataset.set(options.write.dataset.id, versions)\n this.rowsByVersionId.set(\n versionId,\n visibleRows.map((row) => cloneRow(row))\n )\n this.latestVersionIdByDataset.set(options.write.dataset.id, versionId)\n\n return { ...cloneDatasetVersion(version), outcome: \"created\" }\n }\n\n private isUnchangedWrite(\n mode: DatasetWriteMode,\n latestVersion: DatasetVersion,\n rows: readonly DatasetRow[],\n schema: DatasetSchema\n ): boolean {\n if (mode === \"append\") {\n return rows.length === 0\n }\n\n const previousRows = this.rowsByVersionId.get(latestVersion.versionId) ?? []\n return sameRowContent(\n rows.map((row) => rowContentKey(row, schema)),\n previousRows.map((row) => rowContentKey(row, schema))\n )\n }\n\n private assertKeyedWriteIsUnique(\n mode: DatasetWriteMode,\n rows: readonly DatasetRow[],\n latestVersion: DatasetVersion | null,\n definition: DatasetDefinition\n ): void {\n if (getDatasetPrimaryKeyColumns(definition) === null) {\n return\n }\n\n const stagedByKey = this.rowsByPrimaryKey(rows, definition)\n if (mode !== \"append\" || latestVersion === null) {\n return\n }\n\n const previousRows = this.rowsByVersionId.get(latestVersion.versionId) ?? []\n const previousByKey = this.rowsByPrimaryKey(previousRows, definition)\n for (const primaryKey of stagedByKey.keys()) {\n if (previousByKey.has(primaryKey)) {\n throw new LakeStorageError(\n `[LakeStorage] Dataset '${definition.id}' append contains duplicate primary key ${primaryKey}.`\n )\n }\n }\n }\n\n private rowsByPrimaryKey(\n rows: readonly DatasetRow[],\n definition: DatasetDefinition\n ): Map<string, DatasetRow> {\n const byKey = new Map<string, DatasetRow>()\n for (const row of rows) {\n const primaryKey = encodeDatasetPrimaryKey(definition, row)\n if (byKey.has(primaryKey)) {\n throw new LakeStorageError(\n `[LakeStorage] Dataset '${definition.id}' contains duplicate primary key ${primaryKey}.`\n )\n }\n byKey.set(primaryKey, row)\n }\n return byKey\n }\n\n private sameKeyedRowContent(\n left: ReadonlyMap<string, DatasetRow>,\n right: ReadonlyMap<string, DatasetRow>,\n schema: DatasetSchema\n ): boolean {\n if (left.size !== right.size) {\n return false\n }\n for (const [primaryKey, leftRow] of left) {\n const rightRow = right.get(primaryKey)\n if (\n rightRow === undefined ||\n rowContentKey(leftRow, schema) !== rowContentKey(rightRow, schema)\n ) {\n return false\n }\n }\n return true\n }\n\n private async withDatasetCommitLock<T>(datasetId: string, run: () => Promise<T>): Promise<T> {\n const previous = this.commitLocks.get(datasetId) ?? Promise.resolve()\n const ready = previous.catch(() => {})\n let release!: () => void\n const next = new Promise<void>((resolve) => {\n release = resolve\n })\n const current = ready.then(() => next)\n this.commitLocks.set(datasetId, current)\n\n await ready\n try {\n return await run()\n } finally {\n release()\n if (this.commitLocks.get(datasetId) === current) {\n this.commitLocks.delete(datasetId)\n }\n }\n }\n}\n",
|
|
8
|
+
"import type { DatasetDefinition, MergeChange } from \"../datasets\"\nimport { LakeConcurrencyError } from \"./errors\"\nimport type { DatasetProducer, DatasetRow, DatasetVersion, DatasetVersionRef } from \"./types\"\n\nexport interface BeginDatasetMergeInput {\n /** Stored definition for the keyed dataset whose latest version is captured by `beginMerge`. */\n readonly dataset: DatasetDefinition\n /** Optional caller guard checked against the same latest version captured by the session. */\n readonly expectedLatestVersionId?: string\n readonly producer?: DatasetProducer\n readonly inputs?: readonly DatasetVersionRef[]\n}\n\nexport interface CommitDatasetMergeInput {\n readonly commitMessage?: string\n /** Create an addressable first version even without changes; reuse an existing version on no-op. */\n readonly createInitialVersion?: boolean\n /** Retry sequenced merges up to three times total; ignored when an explicit version guard is set. */\n readonly retryOnConflict?: boolean\n /** Checked before each attempt; a durable commit is never cancelled retroactively. */\n readonly signal?: AbortSignal\n}\n\n/** Providers retain their staging session throughout this bounded commit loop. */\nexport async function retryDatasetMergeCommit(\n merge: BeginDatasetMergeInput,\n commit: CommitDatasetMergeInput | undefined,\n run: (rebase: boolean) => Promise<DatasetMergeCommitResult>\n): Promise<DatasetMergeCommitResult> {\n const attempts =\n commit?.retryOnConflict &&\n merge.dataset.sequenceBy !== undefined &&\n merge.expectedLatestVersionId === undefined\n ? 3\n : 1\n for (let attempt = 0; ; attempt += 1) {\n commit?.signal?.throwIfAborted()\n try {\n return await run(attempt > 0)\n } catch (error) {\n if (!(error instanceof LakeConcurrencyError) || attempts === 1) throw error\n if (attempt + 1 === attempts) {\n throw new LakeConcurrencyError(\n `[SixbLake] Dataset '${merge.dataset.id}' merge exhausted ${attempts} concurrency attempts. No changes from this operation were committed.`,\n { cause: error }\n )\n }\n }\n }\n}\n\n/**\n * A merge can be unchanged before the dataset has a first version, so its result carries the\n * version separately instead of extending `DatasetVersion` like ordinary write commits do.\n */\nexport type DatasetMergeCommitResult =\n | { readonly outcome: \"created\"; readonly version: DatasetVersion }\n | { readonly outcome: \"unchanged\"; readonly version: DatasetVersion | null }\n\nexport interface LakeMergeSession {\n /**\n * Stage ordered complete-row upserts and exact primary-key deletes. With sequenceBy, deletes\n * require a sequence, stale changes are ignored, and conflicting ties abort the whole merge.\n */\n writeChanges(\n changes:\n | Iterable<MergeChange<DatasetRow, DatasetRow>>\n | AsyncIterable<MergeChange<DatasetRow, DatasetRow>>\n ): Promise<void>\n /** Commit against the captured version; opt-in retries rebase sequenced changes on a fresh head. */\n commit(input?: CommitDatasetMergeInput): Promise<DatasetMergeCommitResult>\n abort(): Promise<void>\n}\n",
|
|
9
|
+
"import { createHash } from \"node:crypto\"\nimport type { DatasetDefinition, MergeChange } from \"../datasets\"\nimport { datasetSequenceValue } from \"../datasets/sequence\"\nimport { stableJsonStringify } from \"../json\"\nimport { normalizeDecimalValue } from \"../ontology/decimal\"\nimport { LakeStorageError } from \"./errors\"\nimport { encodeDatasetPrimaryKey } from \"./merge-validation\"\nimport type { DatasetRow } from \"./types\"\n\n/** Current source revision; a null content digest is a deletion tombstone. */\nexport interface DatasetSequenceState {\n readonly sequence: string\n readonly content: string | null\n}\n\nexport interface DatasetSequenceChange extends DatasetSequenceState {\n readonly key: string\n}\n\nexport function datasetSequenceChange(\n dataset: DatasetDefinition,\n change: MergeChange<DatasetRow, DatasetRow>\n): DatasetSequenceChange {\n const value = change.kind === \"upsert\" ? change.row[dataset.sequenceBy ?? \"\"] : change.sequence\n return {\n key: encodeDatasetPrimaryKey(dataset, change.kind === \"upsert\" ? change.row : change.key),\n sequence: datasetSequenceValue(dataset, value).toString(),\n content: change.kind === \"delete\" ? null : rowDigest(dataset, change.row),\n }\n}\n\n/** Process in submission order against a private copy; conflicts publish no partial state. */\nexport function reconcileDatasetSequences(\n dataset: DatasetDefinition,\n previous: ReadonlyMap<string, DatasetSequenceState>,\n changes: readonly DatasetSequenceChange[]\n): { states: Map<string, DatasetSequenceState>; accepted: Map<string, number> } {\n const states = new Map(previous)\n const accepted = new Map<string, number>()\n for (const [index, change] of changes.entries()) {\n const current = states.get(change.key)\n if (current) {\n const difference = BigInt(change.sequence) - BigInt(current.sequence)\n if (difference < 0n) continue\n if (difference === 0n) {\n if (current.content !== change.content) {\n throw new LakeStorageError(\n `[SixbLake] Dataset '${dataset.id}' has conflicting content at source sequence '${change.sequence}' for key ${change.key}.`\n )\n }\n continue\n }\n }\n states.set(change.key, { sequence: change.sequence, content: change.content })\n accepted.set(change.key, index)\n }\n return { states, accepted }\n}\n\nfunction rowDigest(dataset: DatasetDefinition, row: DatasetRow): string {\n const content: Record<string, unknown> = Object.create(null)\n for (const column of dataset.schema.columns) {\n const value = row[column.name]\n // Nullable additions and omitted/undefined/null values have identical content.\n if (value == null) continue\n switch (column.type) {\n case \"int64\":\n content[column.name] = BigInt(value as string | number).toString()\n break\n case \"timestamp\":\n content[column.name] = new Date(value as string | Date).toISOString()\n break\n case \"date\":\n content[column.name] = new Date(value as string | Date).toISOString().slice(0, 10)\n break\n case \"decimal\":\n content[column.name] = normalizeDecimalValue(value as string)\n break\n default:\n content[column.name] = value\n }\n }\n return createHash(\"sha256\")\n .update(stableJsonStringify(JSON.parse(JSON.stringify(content))))\n .digest(\"hex\")\n}\n\n/** Until row reconciliation is supported, replacement writes must not erase source history. */\nexport function assertUnsequencedDatasetWrite(dataset: DatasetDefinition): void {\n if (dataset.sequenceBy !== undefined) {\n throw new LakeStorageError(\n `[SixbLake] Dataset '${dataset.id}' declares sequenceBy; use beginMerge with source-ordered changes.`\n )\n }\n}\n",
|
|
10
|
+
"import type { DatasetVersionRef } from \"./types\"\n\n/** Input lineage participates in write identity when the caller supplies it. */\nexport function hasDatasetInputChanges(\n previous: readonly DatasetVersionRef[] | undefined,\n next: readonly DatasetVersionRef[] | undefined\n): boolean {\n if (next === undefined) return false\n const keys = (refs: readonly DatasetVersionRef[]) =>\n new Set(refs.map((ref) => JSON.stringify([ref.datasetId, ref.versionId])))\n const before = keys(previous ?? [])\n const after = keys(next)\n return before.size !== after.size || [...after].some((key) => !before.has(key))\n}\n"
|
|
11
|
+
],
|
|
12
|
+
"mappings": "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",
|
|
13
|
+
"debugId": "8B7567B39BAB0B9A64756E2164756E21",
|
|
14
|
+
"names": []
|
|
15
|
+
}
|