@rocicorp/zero 0.25.0-canary.14 → 0.25.0-canary.17
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/out/shared/src/deep-merge.d.ts +6 -4
- package/out/shared/src/deep-merge.d.ts.map +1 -1
- package/out/shared/src/deep-merge.js +2 -1
- package/out/shared/src/deep-merge.js.map +1 -1
- package/out/shared/src/record-proxy.d.ts +13 -0
- package/out/shared/src/record-proxy.d.ts.map +1 -0
- package/out/shared/src/record-proxy.js +59 -0
- package/out/shared/src/record-proxy.js.map +1 -0
- package/out/z2s/src/compiler.d.ts.map +1 -1
- package/out/z2s/src/compiler.js +4 -2
- package/out/z2s/src/compiler.js.map +1 -1
- package/out/zero/package.json.js +1 -1
- package/out/zero/src/pg.js +4 -3
- package/out/zero/src/server.js +4 -3
- package/out/zero/src/zero.js +11 -3
- package/out/zero/src/zero.js.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.js +20 -13
- package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +16 -0
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +28 -0
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/server/otel-diag-logger.d.ts.map +1 -1
- package/out/zero-cache/src/server/otel-diag-logger.js +1 -22
- package/out/zero-cache/src/server/otel-diag-logger.js.map +1 -1
- package/out/zero-cache/src/server/otel-start.d.ts.map +1 -1
- package/out/zero-cache/src/server/otel-start.js +1 -5
- package/out/zero-cache/src/server/otel-start.js.map +1 -1
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +6 -1
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.js +3 -2
- package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +8 -9
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +17 -11
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +2 -2
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js +19 -4
- package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +1 -7
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-client/src/client/crud-impl.d.ts +11 -0
- package/out/zero-client/src/client/crud-impl.d.ts.map +1 -0
- package/out/zero-client/src/client/crud-impl.js +102 -0
- package/out/zero-client/src/client/crud-impl.js.map +1 -0
- package/out/zero-client/src/client/crud.d.ts +7 -40
- package/out/zero-client/src/client/crud.d.ts.map +1 -1
- package/out/zero-client/src/client/crud.js +21 -107
- package/out/zero-client/src/client/crud.js.map +1 -1
- package/out/zero-client/src/client/custom.d.ts +2 -2
- package/out/zero-client/src/client/custom.d.ts.map +1 -1
- package/out/zero-client/src/client/custom.js +5 -50
- package/out/zero-client/src/client/custom.js.map +1 -1
- package/out/zero-client/src/client/ivm-branch.d.ts.map +1 -1
- package/out/zero-client/src/client/ivm-branch.js +20 -13
- package/out/zero-client/src/client/ivm-branch.js.map +1 -1
- package/out/zero-client/src/client/make-mutate-property.d.ts +1 -1
- package/out/zero-client/src/client/make-mutate-property.d.ts.map +1 -1
- package/out/zero-client/src/client/make-mutate-property.js.map +1 -1
- package/out/zero-client/src/client/make-replicache-mutators.d.ts.map +1 -1
- package/out/zero-client/src/client/make-replicache-mutators.js +14 -7
- package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero.d.ts +9 -7
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +11 -4
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-client/src/mod.d.ts +7 -6
- package/out/zero-client/src/mod.d.ts.map +1 -1
- package/out/zero-react/src/use-query.d.ts +6 -4
- package/out/zero-react/src/use-query.d.ts.map +1 -1
- package/out/zero-react/src/use-query.js +2 -1
- package/out/zero-react/src/use-query.js.map +1 -1
- package/out/zero-server/src/custom.d.ts +44 -5
- package/out/zero-server/src/custom.d.ts.map +1 -1
- package/out/zero-server/src/custom.js +98 -35
- package/out/zero-server/src/custom.js.map +1 -1
- package/out/zero-server/src/zql-database.d.ts +1 -1
- package/out/zero-server/src/zql-database.d.ts.map +1 -1
- package/out/zero-server/src/zql-database.js +5 -13
- package/out/zero-server/src/zql-database.js.map +1 -1
- package/out/zero-solid/src/solid-view.d.ts +7 -2
- package/out/zero-solid/src/solid-view.d.ts.map +1 -1
- package/out/zero-solid/src/solid-view.js +3 -32
- package/out/zero-solid/src/solid-view.js.map +1 -1
- package/out/zero-solid/src/use-query.d.ts +5 -3
- package/out/zero-solid/src/use-query.d.ts.map +1 -1
- package/out/zero-solid/src/use-query.js +5 -1
- package/out/zero-solid/src/use-query.js.map +1 -1
- package/out/zero-types/src/schema.d.ts +4 -4
- package/out/zql/src/builder/builder.d.ts.map +1 -1
- package/out/zql/src/builder/builder.js +1 -11
- package/out/zql/src/builder/builder.js.map +1 -1
- package/out/zql/src/error.js +1 -10
- package/out/zql/src/error.js.map +1 -1
- package/out/zql/src/ivm/array-view.d.ts +1 -1
- package/out/zql/src/ivm/array-view.d.ts.map +1 -1
- package/out/zql/src/ivm/array-view.js +2 -0
- package/out/zql/src/ivm/array-view.js.map +1 -1
- package/out/zql/src/ivm/exists.d.ts +3 -2
- package/out/zql/src/ivm/exists.d.ts.map +1 -1
- package/out/zql/src/ivm/exists.js +25 -23
- package/out/zql/src/ivm/exists.js.map +1 -1
- package/out/zql/src/ivm/fan-in.d.ts +3 -3
- package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-in.js +6 -5
- package/out/zql/src/ivm/fan-in.js.map +1 -1
- package/out/zql/src/ivm/fan-out.d.ts +2 -2
- package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-out.js +5 -5
- package/out/zql/src/ivm/fan-out.js.map +1 -1
- package/out/zql/src/ivm/filter-operators.d.ts +5 -5
- package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
- package/out/zql/src/ivm/filter-operators.js +8 -8
- package/out/zql/src/ivm/filter-operators.js.map +1 -1
- package/out/zql/src/ivm/filter-push.d.ts +2 -1
- package/out/zql/src/ivm/filter-push.d.ts.map +1 -1
- package/out/zql/src/ivm/filter-push.js +5 -5
- package/out/zql/src/ivm/filter-push.js.map +1 -1
- package/out/zql/src/ivm/filter.d.ts +2 -2
- package/out/zql/src/ivm/filter.d.ts.map +1 -1
- package/out/zql/src/ivm/filter.js +4 -4
- package/out/zql/src/ivm/filter.js.map +1 -1
- package/out/zql/src/ivm/flipped-join.d.ts.map +1 -1
- package/out/zql/src/ivm/flipped-join.js +100 -83
- package/out/zql/src/ivm/flipped-join.js.map +1 -1
- package/out/zql/src/ivm/join.d.ts.map +1 -1
- package/out/zql/src/ivm/join.js +52 -50
- package/out/zql/src/ivm/join.js.map +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +4 -4
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
- package/out/zql/src/ivm/memory-source.d.ts +3 -3
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +7 -4
- package/out/zql/src/ivm/memory-source.js.map +1 -1
- package/out/zql/src/ivm/operator.d.ts +10 -3
- package/out/zql/src/ivm/operator.d.ts.map +1 -1
- package/out/zql/src/ivm/operator.js.map +1 -1
- package/out/zql/src/ivm/push-accumulated.d.ts +1 -1
- package/out/zql/src/ivm/push-accumulated.d.ts.map +1 -1
- package/out/zql/src/ivm/push-accumulated.js +8 -8
- package/out/zql/src/ivm/push-accumulated.js.map +1 -1
- package/out/zql/src/ivm/skip.d.ts +1 -1
- package/out/zql/src/ivm/skip.d.ts.map +1 -1
- package/out/zql/src/ivm/skip.js +8 -3
- package/out/zql/src/ivm/skip.js.map +1 -1
- package/out/zql/src/ivm/source.d.ts +15 -7
- package/out/zql/src/ivm/source.d.ts.map +1 -1
- package/out/zql/src/ivm/stream.d.ts +2 -0
- package/out/zql/src/ivm/stream.d.ts.map +1 -1
- package/out/zql/src/ivm/stream.js +5 -14
- package/out/zql/src/ivm/stream.js.map +1 -1
- package/out/zql/src/ivm/take.d.ts +1 -1
- package/out/zql/src/ivm/take.d.ts.map +1 -1
- package/out/zql/src/ivm/take.js +164 -147
- package/out/zql/src/ivm/take.js.map +1 -1
- package/out/zql/src/ivm/union-fan-in.d.ts +2 -2
- package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-in.js +7 -7
- package/out/zql/src/ivm/union-fan-in.js.map +1 -1
- package/out/zql/src/ivm/union-fan-out.d.ts +1 -1
- package/out/zql/src/ivm/union-fan-out.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-out.js +3 -3
- package/out/zql/src/ivm/union-fan-out.js.map +1 -1
- package/out/zql/src/mutate/crud.d.ts +139 -0
- package/out/zql/src/mutate/crud.d.ts.map +1 -0
- package/out/zql/src/mutate/crud.js +53 -0
- package/out/zql/src/mutate/crud.js.map +1 -0
- package/out/zql/src/mutate/custom.d.ts +12 -53
- package/out/zql/src/mutate/custom.d.ts.map +1 -1
- package/out/zql/src/mutate/custom.js +1 -5
- package/out/zql/src/mutate/custom.js.map +1 -1
- package/out/zql/src/mutate/mutator-registry.d.ts +33 -32
- package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator-registry.js +26 -25
- package/out/zql/src/mutate/mutator-registry.js.map +1 -1
- package/out/zql/src/mutate/mutator.d.ts +48 -58
- package/out/zql/src/mutate/mutator.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator.js +12 -8
- package/out/zql/src/mutate/mutator.js.map +1 -1
- package/out/zql/src/planner/planner-builder.d.ts +2 -1
- package/out/zql/src/planner/planner-builder.d.ts.map +1 -1
- package/out/zql/src/planner/planner-builder.js +5 -5
- package/out/zql/src/planner/planner-builder.js.map +1 -1
- package/out/zql/src/planner/planner-graph.d.ts +3 -1
- package/out/zql/src/planner/planner-graph.d.ts.map +1 -1
- package/out/zql/src/planner/planner-graph.js +5 -5
- package/out/zql/src/planner/planner-graph.js.map +1 -1
- package/out/zql/src/query/abstract-query.d.ts +2 -3
- package/out/zql/src/query/abstract-query.d.ts.map +1 -1
- package/out/zql/src/query/abstract-query.js +0 -3
- package/out/zql/src/query/abstract-query.js.map +1 -1
- package/out/zql/src/query/create-builder.d.ts.map +1 -1
- package/out/zql/src/query/create-builder.js +7 -36
- package/out/zql/src/query/create-builder.js.map +1 -1
- package/out/zql/src/query/measure-push-operator.d.ts +1 -1
- package/out/zql/src/query/measure-push-operator.d.ts.map +1 -1
- package/out/zql/src/query/measure-push-operator.js +2 -2
- package/out/zql/src/query/measure-push-operator.js.map +1 -1
- package/out/zql/src/query/query-impl.d.ts +2 -2
- package/out/zql/src/query/query-impl.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.js.map +1 -1
- package/out/zql/src/query/query-registry.d.ts +87 -79
- package/out/zql/src/query/query-registry.d.ts.map +1 -1
- package/out/zql/src/query/query-registry.js +44 -38
- package/out/zql/src/query/query-registry.js.map +1 -1
- package/out/zql/src/query/query.d.ts +3 -18
- package/out/zql/src/query/query.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.d.ts +2 -2
- package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.js.map +1 -1
- package/out/zql/src/query/static-query.d.ts +1 -0
- package/out/zql/src/query/static-query.d.ts.map +1 -1
- package/out/zql/src/query/static-query.js +2 -2
- package/out/zql/src/query/static-query.js.map +1 -1
- package/out/zqlite/src/internal/sql-inline.d.ts +13 -0
- package/out/zqlite/src/internal/sql-inline.d.ts.map +1 -0
- package/out/zqlite/src/internal/sql-inline.js +45 -0
- package/out/zqlite/src/internal/sql-inline.js.map +1 -0
- package/out/zqlite/src/sqlite-cost-model.d.ts.map +1 -1
- package/out/zqlite/src/sqlite-cost-model.js +2 -2
- package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
- package/out/zqlite/src/table-source.d.ts +3 -2
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +5 -2
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"union-fan-in.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/union-fan-in.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AAExC,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,MAAM,EACZ,MAAM,eAAe,CAAC;AAMvB,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAQ,KAAK,MAAM,EAAC,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAEpD,qBAAa,UAAW,YAAW,QAAQ;;gBAO7B,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE;IAgEhD,OAAO,IAAI,IAAI;IAMf,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC;IAOhD,SAAS,IAAI,YAAY;
|
|
1
|
+
{"version":3,"file":"union-fan-in.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/union-fan-in.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AAExC,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,MAAM,EACZ,MAAM,eAAe,CAAC;AAMvB,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAQ,KAAK,MAAM,EAAC,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAEpD,qBAAa,UAAW,YAAW,QAAQ;;gBAO7B,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE;IAgEhD,OAAO,IAAI,IAAI;IAMf,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC;IAOhD,SAAS,IAAI,YAAY;IAIxB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC;IAgEzD,oBAAoB;IAKnB,iBAAiB,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC;IAuBrE,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAGhC;AAED,wBAAiB,YAAY,CAC3B,OAAO,EAAE,QAAQ,CAAC,IAAI,GAAG,OAAO,CAAC,EAAE,EACnC,UAAU,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,KAAK,MAAM,GACvC,gBAAgB,CAAC,IAAI,GAAG,OAAO,CAAC,CAuElC"}
|
|
@@ -77,9 +77,9 @@ class UnionFanIn {
|
|
|
77
77
|
getSchema() {
|
|
78
78
|
return this.#schema;
|
|
79
79
|
}
|
|
80
|
-
push(change, pusher) {
|
|
80
|
+
*push(change, pusher) {
|
|
81
81
|
if (!this.#fanOutPushStarted) {
|
|
82
|
-
this.#pushInternalChange(change, pusher);
|
|
82
|
+
yield* this.#pushInternalChange(change, pusher);
|
|
83
83
|
} else {
|
|
84
84
|
this.#accumulatedPushes.push(change);
|
|
85
85
|
}
|
|
@@ -105,9 +105,9 @@ class UnionFanIn {
|
|
|
105
105
|
* 4. Edits will always come through as child changes as flip join will flip them into children.
|
|
106
106
|
* An edit that would result in a remove or add will have been split into an add/remove pair rather than being an edit.
|
|
107
107
|
*/
|
|
108
|
-
|
|
108
|
+
*#pushInternalChange(change, pusher) {
|
|
109
109
|
if (change.type === "child") {
|
|
110
|
-
this.#output.push(change, this);
|
|
110
|
+
yield* this.#output.push(change, this);
|
|
111
111
|
return;
|
|
112
112
|
}
|
|
113
113
|
assert(change.type === "add" || change.type === "remove");
|
|
@@ -129,13 +129,13 @@ class UnionFanIn {
|
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
assert(hadMatch, "Pusher was not one of the inputs to union-fan-in!");
|
|
132
|
-
this.#output.push(change, this);
|
|
132
|
+
yield* this.#output.push(change, this);
|
|
133
133
|
}
|
|
134
134
|
fanOutStartedPushing() {
|
|
135
135
|
assert(this.#fanOutPushStarted === false);
|
|
136
136
|
this.#fanOutPushStarted = true;
|
|
137
137
|
}
|
|
138
|
-
fanOutDonePushing(fanOutChangeType) {
|
|
138
|
+
*fanOutDonePushing(fanOutChangeType) {
|
|
139
139
|
assert(this.#fanOutPushStarted);
|
|
140
140
|
this.#fanOutPushStarted = false;
|
|
141
141
|
if (this.#inputs.length === 0) {
|
|
@@ -144,7 +144,7 @@ class UnionFanIn {
|
|
|
144
144
|
if (this.#accumulatedPushes.length === 0) {
|
|
145
145
|
return;
|
|
146
146
|
}
|
|
147
|
-
pushAccumulatedChanges(
|
|
147
|
+
yield* pushAccumulatedChanges(
|
|
148
148
|
this.#accumulatedPushes,
|
|
149
149
|
this.#output,
|
|
150
150
|
this,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"union-fan-in.js","sources":["../../../../../zql/src/ivm/union-fan-in.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport type {Writable} from '../../../shared/src/writable.ts';\nimport type {Change} from './change.ts';\nimport type {Constraint} from './constraint.ts';\nimport type {Node} from './data.ts';\nimport {\n throwOutput,\n type FetchRequest,\n type Input,\n type InputBase,\n type Operator,\n type Output,\n} from './operator.ts';\nimport {\n makeAddEmptyRelationships,\n mergeRelationships,\n pushAccumulatedChanges,\n} from './push-accumulated.ts';\nimport type {SourceSchema} from './schema.ts';\nimport {first, type Stream} from './stream.ts';\nimport type {UnionFanOut} from './union-fan-out.ts';\n\nexport class UnionFanIn implements Operator {\n readonly #inputs: readonly Input[];\n readonly #schema: SourceSchema;\n #fanOutPushStarted: boolean = false;\n #output: Output = throwOutput;\n #accumulatedPushes: Change[] = [];\n\n constructor(fanOut: UnionFanOut, inputs: Input[]) {\n this.#inputs = inputs;\n const fanOutSchema = fanOut.getSchema();\n fanOut.setFanIn(this);\n\n const schema: Writable<SourceSchema> = {\n tableName: fanOutSchema.tableName,\n columns: fanOutSchema.columns,\n primaryKey: fanOutSchema.primaryKey,\n relationships: {\n ...fanOutSchema.relationships,\n },\n isHidden: fanOutSchema.isHidden,\n system: fanOutSchema.system,\n compareRows: fanOutSchema.compareRows,\n sort: fanOutSchema.sort,\n };\n\n // now go through inputs and merge relationships\n const relationshipsFromBranches: Set<string> = new Set();\n for (const input of inputs) {\n const inputSchema = input.getSchema();\n assert(\n schema.tableName === inputSchema.tableName,\n `Table name mismatch in union fan-in: ${schema.tableName} !== ${inputSchema.tableName}`,\n );\n assert(\n schema.primaryKey === inputSchema.primaryKey,\n `Primary key mismatch in union fan-in`,\n );\n assert(\n schema.system === inputSchema.system,\n `System mismatch in union fan-in: ${schema.system} !== ${inputSchema.system}`,\n );\n assert(\n schema.compareRows === inputSchema.compareRows,\n `compareRows mismatch in union fan-in`,\n );\n assert(schema.sort === inputSchema.sort, `Sort mismatch in union fan-in`);\n\n for (const [relName, relSchema] of Object.entries(\n inputSchema.relationships,\n )) {\n if (relName in fanOutSchema.relationships) {\n continue;\n }\n\n // All branches will have unique relationship names except for relationships\n // that come in from `fanOut`.\n assert(\n !relationshipsFromBranches.has(relName),\n `Relationship ${relName} exists in multiple upstream inputs to union fan-in`,\n );\n schema.relationships[relName] = relSchema;\n relationshipsFromBranches.add(relName);\n }\n\n input.setOutput(this);\n }\n\n this.#schema = schema;\n this.#inputs = inputs;\n }\n\n destroy(): void {\n for (const input of this.#inputs) {\n input.destroy();\n }\n }\n\n fetch(req: FetchRequest): Stream<Node | 'yield'> {\n const iterables = this.#inputs.map(input => input.fetch(req));\n return mergeFetches(iterables, (l, r) =>\n this.#schema.compareRows(l.row, r.row),\n );\n }\n\n getSchema(): SourceSchema {\n return this.#schema;\n }\n\n push(change: Change, pusher: InputBase): void {\n if (!this.#fanOutPushStarted) {\n this.#pushInternalChange(change, pusher);\n } else {\n this.#accumulatedPushes.push(change);\n }\n }\n\n /**\n * An internal change means that a change was received inside the fan-out/fan-in sub-graph.\n *\n * These changes always come from children of a flip-join as no other push generating operators\n * currently exist between union-fan-in and union-fan-out. All other pushes\n * enter into union-fan-out before reaching union-fan-in.\n *\n * - normal joins for `exists` come before `union-fan-out`\n * - joins for `related` come after `union-fan-out`\n * - take comes after `union-fan-out`\n *\n * The algorithm for deciding whether or not to forward a push that came from inside the ufo/ufi sub-graph:\n * 1. If the change is a `child` change we can forward it. This is because all child branches in the ufo/ufi sub-graph are unique.\n * 2. If the change is `add` we can forward it iff no `fetches` for the row return any results.\n * If another branch has it, the add was already emitted in the past.\n * 3. If the change is `remove` we can forward it iff no `fetches` for the row return any results.\n * If no other branches have the change, the remove can be sent as the value is no longer present.\n * If other branches have it, the last branch the processes the remove will send the remove.\n * 4. Edits will always come through as child changes as flip join will flip them into children.\n * An edit that would result in a remove or add will have been split into an add/remove pair rather than being an edit.\n */\n #pushInternalChange(change: Change, pusher: InputBase): void {\n if (change.type === 'child') {\n this.#output.push(change, this);\n return;\n }\n\n assert(change.type === 'add' || change.type === 'remove');\n\n let hadMatch = false;\n for (const input of this.#inputs) {\n if (input === pusher) {\n hadMatch = true;\n continue;\n }\n\n const constraint: Writable<Constraint> = {};\n for (const key of this.#schema.primaryKey) {\n constraint[key] = change.node.row[key];\n }\n const fetchResult = input.fetch({\n constraint,\n });\n\n if (first(fetchResult) !== undefined) {\n // Another branch has the row, so the add/remove is not needed.\n return;\n }\n }\n\n assert(hadMatch, 'Pusher was not one of the inputs to union-fan-in!');\n\n // No other branches have the row, so we can push the change.\n this.#output.push(change, this);\n }\n\n fanOutStartedPushing() {\n assert(this.#fanOutPushStarted === false);\n this.#fanOutPushStarted = true;\n }\n\n fanOutDonePushing(fanOutChangeType: Change['type']) {\n assert(this.#fanOutPushStarted);\n this.#fanOutPushStarted = false;\n if (this.#inputs.length === 0) {\n return;\n }\n\n if (this.#accumulatedPushes.length === 0) {\n // It is possible for no forks to pass along the push.\n // E.g., if no filters match in any fork.\n return;\n }\n\n pushAccumulatedChanges(\n this.#accumulatedPushes,\n this.#output,\n this,\n fanOutChangeType,\n mergeRelationships,\n makeAddEmptyRelationships(this.#schema),\n );\n }\n\n setOutput(output: Output): void {\n this.#output = output;\n }\n}\n\nexport function* mergeFetches(\n fetches: Iterable<Node | 'yield'>[],\n comparator: (l: Node, r: Node) => number,\n): IterableIterator<Node | 'yield'> {\n const iterators = fetches.map(i => i[Symbol.iterator]());\n let threw = false;\n try {\n const current: (Node | null)[] = [];\n let lastNodeYielded: Node | undefined;\n for (let i = 0; i < iterators.length; i++) {\n const iter = iterators[i];\n let result = iter.next();\n // yield yields when initializing\n while (!result.done && result.value === 'yield') {\n yield result.value;\n result = iter.next();\n }\n current[i] = result.done ? null : (result.value as Node);\n }\n while (current.some(c => c !== null)) {\n const min = current.reduce(\n (acc: [Node, number] | undefined, c, i): [Node, number] | undefined => {\n if (c === null) {\n return acc;\n }\n if (acc === undefined || comparator(c, acc[0]) < 0) {\n return [c, i];\n }\n return acc;\n },\n undefined,\n );\n\n assert(min !== undefined, 'min is undefined');\n const [minNode, minIndex] = min;\n const iter = iterators[minIndex];\n let result = iter.next();\n while (!result.done && result.value === 'yield') {\n yield result.value;\n result = iter.next();\n }\n current[minIndex] = result.done ? null : (result.value as Node);\n if (\n lastNodeYielded !== undefined &&\n comparator(lastNodeYielded, minNode) === 0\n ) {\n continue;\n }\n lastNodeYielded = minNode;\n yield minNode;\n }\n } catch (e) {\n threw = true;\n for (const iter of iterators) {\n try {\n iter.throw?.(e);\n } catch (_cleanupError) {\n // error in the iter.throw cleanup,\n // catch so other iterators are cleaned up\n }\n }\n throw e;\n } finally {\n if (!threw) {\n for (const iter of iterators) {\n try {\n iter.return?.();\n } catch (_cleanupError) {\n // error in the iter.return cleanup,\n // catch so other iterators are cleaned up\n }\n }\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"union-fan-in.js","sources":["../../../../../zql/src/ivm/union-fan-in.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport type {Writable} from '../../../shared/src/writable.ts';\nimport type {Change} from './change.ts';\nimport type {Constraint} from './constraint.ts';\nimport type {Node} from './data.ts';\nimport {\n throwOutput,\n type FetchRequest,\n type Input,\n type InputBase,\n type Operator,\n type Output,\n} from './operator.ts';\nimport {\n makeAddEmptyRelationships,\n mergeRelationships,\n pushAccumulatedChanges,\n} from './push-accumulated.ts';\nimport type {SourceSchema} from './schema.ts';\nimport {first, type Stream} from './stream.ts';\nimport type {UnionFanOut} from './union-fan-out.ts';\n\nexport class UnionFanIn implements Operator {\n readonly #inputs: readonly Input[];\n readonly #schema: SourceSchema;\n #fanOutPushStarted: boolean = false;\n #output: Output = throwOutput;\n #accumulatedPushes: Change[] = [];\n\n constructor(fanOut: UnionFanOut, inputs: Input[]) {\n this.#inputs = inputs;\n const fanOutSchema = fanOut.getSchema();\n fanOut.setFanIn(this);\n\n const schema: Writable<SourceSchema> = {\n tableName: fanOutSchema.tableName,\n columns: fanOutSchema.columns,\n primaryKey: fanOutSchema.primaryKey,\n relationships: {\n ...fanOutSchema.relationships,\n },\n isHidden: fanOutSchema.isHidden,\n system: fanOutSchema.system,\n compareRows: fanOutSchema.compareRows,\n sort: fanOutSchema.sort,\n };\n\n // now go through inputs and merge relationships\n const relationshipsFromBranches: Set<string> = new Set();\n for (const input of inputs) {\n const inputSchema = input.getSchema();\n assert(\n schema.tableName === inputSchema.tableName,\n `Table name mismatch in union fan-in: ${schema.tableName} !== ${inputSchema.tableName}`,\n );\n assert(\n schema.primaryKey === inputSchema.primaryKey,\n `Primary key mismatch in union fan-in`,\n );\n assert(\n schema.system === inputSchema.system,\n `System mismatch in union fan-in: ${schema.system} !== ${inputSchema.system}`,\n );\n assert(\n schema.compareRows === inputSchema.compareRows,\n `compareRows mismatch in union fan-in`,\n );\n assert(schema.sort === inputSchema.sort, `Sort mismatch in union fan-in`);\n\n for (const [relName, relSchema] of Object.entries(\n inputSchema.relationships,\n )) {\n if (relName in fanOutSchema.relationships) {\n continue;\n }\n\n // All branches will have unique relationship names except for relationships\n // that come in from `fanOut`.\n assert(\n !relationshipsFromBranches.has(relName),\n `Relationship ${relName} exists in multiple upstream inputs to union fan-in`,\n );\n schema.relationships[relName] = relSchema;\n relationshipsFromBranches.add(relName);\n }\n\n input.setOutput(this);\n }\n\n this.#schema = schema;\n this.#inputs = inputs;\n }\n\n destroy(): void {\n for (const input of this.#inputs) {\n input.destroy();\n }\n }\n\n fetch(req: FetchRequest): Stream<Node | 'yield'> {\n const iterables = this.#inputs.map(input => input.fetch(req));\n return mergeFetches(iterables, (l, r) =>\n this.#schema.compareRows(l.row, r.row),\n );\n }\n\n getSchema(): SourceSchema {\n return this.#schema;\n }\n\n *push(change: Change, pusher: InputBase): Stream<'yield'> {\n if (!this.#fanOutPushStarted) {\n yield* this.#pushInternalChange(change, pusher);\n } else {\n this.#accumulatedPushes.push(change);\n }\n }\n\n /**\n * An internal change means that a change was received inside the fan-out/fan-in sub-graph.\n *\n * These changes always come from children of a flip-join as no other push generating operators\n * currently exist between union-fan-in and union-fan-out. All other pushes\n * enter into union-fan-out before reaching union-fan-in.\n *\n * - normal joins for `exists` come before `union-fan-out`\n * - joins for `related` come after `union-fan-out`\n * - take comes after `union-fan-out`\n *\n * The algorithm for deciding whether or not to forward a push that came from inside the ufo/ufi sub-graph:\n * 1. If the change is a `child` change we can forward it. This is because all child branches in the ufo/ufi sub-graph are unique.\n * 2. If the change is `add` we can forward it iff no `fetches` for the row return any results.\n * If another branch has it, the add was already emitted in the past.\n * 3. If the change is `remove` we can forward it iff no `fetches` for the row return any results.\n * If no other branches have the change, the remove can be sent as the value is no longer present.\n * If other branches have it, the last branch the processes the remove will send the remove.\n * 4. Edits will always come through as child changes as flip join will flip them into children.\n * An edit that would result in a remove or add will have been split into an add/remove pair rather than being an edit.\n */\n *#pushInternalChange(change: Change, pusher: InputBase): Stream<'yield'> {\n if (change.type === 'child') {\n yield* this.#output.push(change, this);\n return;\n }\n\n assert(change.type === 'add' || change.type === 'remove');\n\n let hadMatch = false;\n for (const input of this.#inputs) {\n if (input === pusher) {\n hadMatch = true;\n continue;\n }\n\n const constraint: Writable<Constraint> = {};\n for (const key of this.#schema.primaryKey) {\n constraint[key] = change.node.row[key];\n }\n const fetchResult = input.fetch({\n constraint,\n });\n\n if (first(fetchResult) !== undefined) {\n // Another branch has the row, so the add/remove is not needed.\n return;\n }\n }\n\n assert(hadMatch, 'Pusher was not one of the inputs to union-fan-in!');\n\n // No other branches have the row, so we can push the change.\n yield* this.#output.push(change, this);\n }\n\n fanOutStartedPushing() {\n assert(this.#fanOutPushStarted === false);\n this.#fanOutPushStarted = true;\n }\n\n *fanOutDonePushing(fanOutChangeType: Change['type']): Stream<'yield'> {\n assert(this.#fanOutPushStarted);\n this.#fanOutPushStarted = false;\n if (this.#inputs.length === 0) {\n return;\n }\n\n if (this.#accumulatedPushes.length === 0) {\n // It is possible for no forks to pass along the push.\n // E.g., if no filters match in any fork.\n return;\n }\n\n yield* pushAccumulatedChanges(\n this.#accumulatedPushes,\n this.#output,\n this,\n fanOutChangeType,\n mergeRelationships,\n makeAddEmptyRelationships(this.#schema),\n );\n }\n\n setOutput(output: Output): void {\n this.#output = output;\n }\n}\n\nexport function* mergeFetches(\n fetches: Iterable<Node | 'yield'>[],\n comparator: (l: Node, r: Node) => number,\n): IterableIterator<Node | 'yield'> {\n const iterators = fetches.map(i => i[Symbol.iterator]());\n let threw = false;\n try {\n const current: (Node | null)[] = [];\n let lastNodeYielded: Node | undefined;\n for (let i = 0; i < iterators.length; i++) {\n const iter = iterators[i];\n let result = iter.next();\n // yield yields when initializing\n while (!result.done && result.value === 'yield') {\n yield result.value;\n result = iter.next();\n }\n current[i] = result.done ? null : (result.value as Node);\n }\n while (current.some(c => c !== null)) {\n const min = current.reduce(\n (acc: [Node, number] | undefined, c, i): [Node, number] | undefined => {\n if (c === null) {\n return acc;\n }\n if (acc === undefined || comparator(c, acc[0]) < 0) {\n return [c, i];\n }\n return acc;\n },\n undefined,\n );\n\n assert(min !== undefined, 'min is undefined');\n const [minNode, minIndex] = min;\n const iter = iterators[minIndex];\n let result = iter.next();\n while (!result.done && result.value === 'yield') {\n yield result.value;\n result = iter.next();\n }\n current[minIndex] = result.done ? null : (result.value as Node);\n if (\n lastNodeYielded !== undefined &&\n comparator(lastNodeYielded, minNode) === 0\n ) {\n continue;\n }\n lastNodeYielded = minNode;\n yield minNode;\n }\n } catch (e) {\n threw = true;\n for (const iter of iterators) {\n try {\n iter.throw?.(e);\n } catch (_cleanupError) {\n // error in the iter.throw cleanup,\n // catch so other iterators are cleaned up\n }\n }\n throw e;\n } finally {\n if (!threw) {\n for (const iter of iterators) {\n try {\n iter.return?.();\n } catch (_cleanupError) {\n // error in the iter.return cleanup,\n // catch so other iterators are cleaned up\n }\n }\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@ export declare class UnionFanOut implements Operator {
|
|
|
8
8
|
#private;
|
|
9
9
|
constructor(input: Input);
|
|
10
10
|
setFanIn(fanIn: UnionFanIn): void;
|
|
11
|
-
push(change: Change):
|
|
11
|
+
push(change: Change): Stream<'yield'>;
|
|
12
12
|
setOutput(output: Output): void;
|
|
13
13
|
getSchema(): SourceSchema;
|
|
14
14
|
fetch(req: FetchRequest): Stream<Node | 'yield'>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"union-fan-out.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/union-fan-out.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAC,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;AACzE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,mBAAmB,CAAC;AAElD,qBAAa,WAAY,YAAW,QAAQ;;gBAM9B,KAAK,EAAE,KAAK;IAKxB,QAAQ,CAAC,KAAK,EAAE,UAAU;
|
|
1
|
+
{"version":3,"file":"union-fan-out.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/union-fan-out.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAC,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;AACzE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,mBAAmB,CAAC;AAElD,qBAAa,WAAY,YAAW,QAAQ;;gBAM9B,KAAK,EAAE,KAAK;IAKxB,QAAQ,CAAC,KAAK,EAAE,UAAU;IAKzB,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC;IAQtC,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI/B,SAAS,IAAI,YAAY;IAIzB,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC;IAIhD,OAAO,IAAI,IAAI;CAUhB"}
|
|
@@ -13,12 +13,12 @@ class UnionFanOut {
|
|
|
13
13
|
assert(!this.#unionFanIn, "FanIn already set for this FanOut");
|
|
14
14
|
this.#unionFanIn = fanIn;
|
|
15
15
|
}
|
|
16
|
-
push(change) {
|
|
16
|
+
*push(change) {
|
|
17
17
|
must(this.#unionFanIn).fanOutStartedPushing();
|
|
18
18
|
for (const output of this.#outputs) {
|
|
19
|
-
output.push(change, this);
|
|
19
|
+
yield* output.push(change, this);
|
|
20
20
|
}
|
|
21
|
-
must(this.#unionFanIn).fanOutDonePushing(change.type);
|
|
21
|
+
yield* must(this.#unionFanIn).fanOutDonePushing(change.type);
|
|
22
22
|
}
|
|
23
23
|
setOutput(output) {
|
|
24
24
|
this.#outputs.push(output);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"union-fan-out.js","sources":["../../../../../zql/src/ivm/union-fan-out.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport type {Change} from './change.ts';\nimport type {Node} from './data.ts';\nimport type {FetchRequest, Input, Operator, Output} from './operator.ts';\nimport type {SourceSchema} from './schema.ts';\nimport type {Stream} from './stream.ts';\nimport type {UnionFanIn} from './union-fan-in.ts';\n\nexport class UnionFanOut implements Operator {\n #destroyCount: number = 0;\n #unionFanIn?: UnionFanIn;\n readonly #input: Input;\n readonly #outputs: Output[] = [];\n\n constructor(input: Input) {\n this.#input = input;\n input.setOutput(this);\n }\n\n setFanIn(fanIn: UnionFanIn) {\n assert(!this.#unionFanIn, 'FanIn already set for this FanOut');\n this.#unionFanIn = fanIn;\n }\n\n push(change: Change):
|
|
1
|
+
{"version":3,"file":"union-fan-out.js","sources":["../../../../../zql/src/ivm/union-fan-out.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport type {Change} from './change.ts';\nimport type {Node} from './data.ts';\nimport type {FetchRequest, Input, Operator, Output} from './operator.ts';\nimport type {SourceSchema} from './schema.ts';\nimport type {Stream} from './stream.ts';\nimport type {UnionFanIn} from './union-fan-in.ts';\n\nexport class UnionFanOut implements Operator {\n #destroyCount: number = 0;\n #unionFanIn?: UnionFanIn;\n readonly #input: Input;\n readonly #outputs: Output[] = [];\n\n constructor(input: Input) {\n this.#input = input;\n input.setOutput(this);\n }\n\n setFanIn(fanIn: UnionFanIn) {\n assert(!this.#unionFanIn, 'FanIn already set for this FanOut');\n this.#unionFanIn = fanIn;\n }\n\n *push(change: Change): Stream<'yield'> {\n must(this.#unionFanIn).fanOutStartedPushing();\n for (const output of this.#outputs) {\n yield* output.push(change, this);\n }\n yield* must(this.#unionFanIn).fanOutDonePushing(change.type);\n }\n\n setOutput(output: Output): void {\n this.#outputs.push(output);\n }\n\n getSchema(): SourceSchema {\n return this.#input.getSchema();\n }\n\n fetch(req: FetchRequest): Stream<Node | 'yield'> {\n return this.#input.fetch(req);\n }\n\n destroy(): void {\n if (this.#destroyCount < this.#outputs.length) {\n ++this.#destroyCount;\n if (this.#destroyCount === this.#outputs.length) {\n this.#input.destroy();\n }\n } else {\n throw new Error('FanOut already destroyed once for each output');\n }\n }\n}\n"],"names":[],"mappings":";;AASO,MAAM,YAAgC;AAAA,EAC3C,gBAAwB;AAAA,EACxB;AAAA,EACS;AAAA,EACA,WAAqB,CAAA;AAAA,EAE9B,YAAY,OAAc;AACxB,SAAK,SAAS;AACd,UAAM,UAAU,IAAI;AAAA,EACtB;AAAA,EAEA,SAAS,OAAmB;AAC1B,WAAO,CAAC,KAAK,aAAa,mCAAmC;AAC7D,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,CAAC,KAAK,QAAiC;AACrC,SAAK,KAAK,WAAW,EAAE,qBAAA;AACvB,eAAW,UAAU,KAAK,UAAU;AAClC,aAAO,OAAO,KAAK,QAAQ,IAAI;AAAA,IACjC;AACA,WAAO,KAAK,KAAK,WAAW,EAAE,kBAAkB,OAAO,IAAI;AAAA,EAC7D;AAAA,EAEA,UAAU,QAAsB;AAC9B,SAAK,SAAS,KAAK,MAAM;AAAA,EAC3B;AAAA,EAEA,YAA0B;AACxB,WAAO,KAAK,OAAO,UAAA;AAAA,EACrB;AAAA,EAEA,MAAM,KAA2C;AAC/C,WAAO,KAAK,OAAO,MAAM,GAAG;AAAA,EAC9B;AAAA,EAEA,UAAgB;AACd,QAAI,KAAK,gBAAgB,KAAK,SAAS,QAAQ;AAC7C,QAAE,KAAK;AACP,UAAI,KAAK,kBAAkB,KAAK,SAAS,QAAQ;AAC/C,aAAK,OAAO,QAAA;AAAA,MACd;AAAA,IACF,OAAO;AACL,YAAM,IAAI,MAAM,+CAA+C;AAAA,IACjE;AAAA,EACF;AACF;"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import type { Expand } from '../../../shared/src/expand.ts';
|
|
2
|
+
import type { SchemaValueToTSType } from '../../../zero-types/src/schema-value.ts';
|
|
3
|
+
import type { Schema, TableSchema } from '../../../zero-types/src/schema.ts';
|
|
4
|
+
import type { MutateCRUD } from './custom.ts';
|
|
5
|
+
export type SchemaCRUD<S extends Schema> = {
|
|
6
|
+
[Table in keyof S['tables']]: TableCRUD<S['tables'][Table]>;
|
|
7
|
+
};
|
|
8
|
+
export type TableCRUD<S extends TableSchema> = {
|
|
9
|
+
/**
|
|
10
|
+
* Writes a row if a row with the same primary key doesn't already exist.
|
|
11
|
+
* Non-primary-key fields that are 'optional' can be omitted or set to
|
|
12
|
+
* `undefined`. Such fields will be assigned the value `null` optimistically
|
|
13
|
+
* and then the default value as defined by the server.
|
|
14
|
+
*/
|
|
15
|
+
insert: (value: InsertValue<S>) => Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Writes a row unconditionally, overwriting any existing row with the same
|
|
18
|
+
* primary key. Non-primary-key fields that are 'optional' can be omitted or
|
|
19
|
+
* set to `undefined`. Such fields will be assigned the value `null`
|
|
20
|
+
* optimistically and then the default value as defined by the server.
|
|
21
|
+
*/
|
|
22
|
+
upsert: (value: UpsertValue<S>) => Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Updates a row with the same primary key. If no such row exists, this
|
|
25
|
+
* function does nothing. All non-primary-key fields can be omitted or set to
|
|
26
|
+
* `undefined`. Such fields will be left unchanged from previous value.
|
|
27
|
+
*/
|
|
28
|
+
update: (value: UpdateValue<S>) => Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Deletes the row with the specified primary key. If no such row exists, this
|
|
31
|
+
* function does nothing.
|
|
32
|
+
*/
|
|
33
|
+
delete: (id: DeleteID<S>) => Promise<void>;
|
|
34
|
+
};
|
|
35
|
+
export type CRUDKind = keyof TableCRUD<TableSchema>;
|
|
36
|
+
export declare const CRUD_KINDS: readonly ["insert", "upsert", "update", "delete"];
|
|
37
|
+
export type DeleteID<S extends TableSchema> = Expand<PrimaryKeyFields<S>>;
|
|
38
|
+
type PrimaryKeyFields<S extends TableSchema> = {
|
|
39
|
+
[K in Extract<S['primaryKey'][number], keyof S['columns']>]: SchemaValueToTSType<S['columns'][K]>;
|
|
40
|
+
};
|
|
41
|
+
export type InsertValue<S extends TableSchema> = Expand<PrimaryKeyFields<S> & {
|
|
42
|
+
[K in keyof S['columns'] as S['columns'][K] extends {
|
|
43
|
+
optional: true;
|
|
44
|
+
} ? K : never]?: SchemaValueToTSType<S['columns'][K]> | undefined;
|
|
45
|
+
} & {
|
|
46
|
+
[K in keyof S['columns'] as S['columns'][K] extends {
|
|
47
|
+
optional: true;
|
|
48
|
+
} ? never : K]: SchemaValueToTSType<S['columns'][K]>;
|
|
49
|
+
}>;
|
|
50
|
+
export type UpsertValue<S extends TableSchema> = InsertValue<S>;
|
|
51
|
+
export type UpdateValue<S extends TableSchema> = Expand<PrimaryKeyFields<S> & {
|
|
52
|
+
[K in keyof S['columns']]?: SchemaValueToTSType<S['columns'][K]> | undefined;
|
|
53
|
+
}>;
|
|
54
|
+
/**
|
|
55
|
+
* This is the type of the generated mutate.<name>.<verb> function.
|
|
56
|
+
*/
|
|
57
|
+
export type TableMutator<TS extends TableSchema> = {
|
|
58
|
+
/**
|
|
59
|
+
* Writes a row if a row with the same primary key doesn't already exist.
|
|
60
|
+
* Non-primary-key fields that are 'optional' can be omitted or set to
|
|
61
|
+
* `undefined`. Such fields will be assigned the value `null` optimistically
|
|
62
|
+
* and then the default value as defined by the server.
|
|
63
|
+
*/
|
|
64
|
+
insert: (value: InsertValue<TS>) => Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Writes a row unconditionally, overwriting any existing row with the same
|
|
67
|
+
* primary key. Non-primary-key fields that are 'optional' can be omitted or
|
|
68
|
+
* set to `undefined`. Such fields will be assigned the value `null`
|
|
69
|
+
* optimistically and then the default value as defined by the server.
|
|
70
|
+
*/
|
|
71
|
+
upsert: (value: UpsertValue<TS>) => Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Updates a row with the same primary key. If no such row exists, this
|
|
74
|
+
* function does nothing. All non-primary-key fields can be omitted or set to
|
|
75
|
+
* `undefined`. Such fields will be left unchanged from previous value.
|
|
76
|
+
*/
|
|
77
|
+
update: (value: UpdateValue<TS>) => Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Deletes the row with the specified primary key. If no such row exists, this
|
|
80
|
+
* function does nothing.
|
|
81
|
+
*/
|
|
82
|
+
delete: (id: DeleteID<TS>) => Promise<void>;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* A function that executes a CRUD operation.
|
|
86
|
+
* Client and server provide different implementations.
|
|
87
|
+
*/
|
|
88
|
+
export type CRUDExecutor = (table: string, kind: CRUDKind, args: unknown) => Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* Creates a MutateCRUD function from a schema and executor.
|
|
91
|
+
* This is the shared implementation used by both client and server.
|
|
92
|
+
*
|
|
93
|
+
* @param schema - The Zero schema
|
|
94
|
+
* @param executor - A function that executes CRUD operations
|
|
95
|
+
* @returns A MutateCRUD function that can be called with CRUDMutateRequest objects
|
|
96
|
+
*/
|
|
97
|
+
export declare function makeMutateCRUDFunction<S extends Schema>(schema: S, executor: CRUDExecutor): MutateCRUD<S>;
|
|
98
|
+
export type CRUDMutator<TSchema extends Schema, TTable extends keyof TSchema['tables'] & string, TKind extends keyof TableMutator<TSchema['tables'][TTable]>, TArgs extends Parameters<TableMutator<TSchema['tables'][TTable]>[TKind]>[0]> = {
|
|
99
|
+
(args: TArgs): CRUDMutateRequest<TSchema, TTable, TKind, TArgs>;
|
|
100
|
+
/**
|
|
101
|
+
* Type-only phantom property to surface mutator types in a covariant position.
|
|
102
|
+
*/
|
|
103
|
+
['~']: Expand<CRUDMutatorTypes<TSchema, TTable, TKind, TArgs>>;
|
|
104
|
+
};
|
|
105
|
+
export type CRUDMutatorTypes<TSchema extends Schema, TTable extends keyof TSchema['tables'] & string, TKind extends keyof TableMutator<TSchema['tables'][TTable]>, TArgs extends Parameters<TableMutator<TSchema['tables'][TTable]>[TKind]>[0]> = 'CRUDMutator' & CRUDMutateRequest<TSchema, TTable, TKind, TArgs>;
|
|
106
|
+
export type CRUDMutateRequest<TSchema extends Schema, TTable extends keyof TSchema['tables'], TKind extends keyof TableMutator<TSchema['tables'][TTable]>, TArgs extends Parameters<TableMutator<TSchema['tables'][TTable]>[TKind]>[0]> = {
|
|
107
|
+
readonly schema: TSchema;
|
|
108
|
+
readonly table: TTable;
|
|
109
|
+
readonly kind: TKind;
|
|
110
|
+
readonly args: TArgs;
|
|
111
|
+
};
|
|
112
|
+
export type AnyCRUDMutateRequest = CRUDMutateRequest<any, any, CRUDKind, any>;
|
|
113
|
+
export type TableCRUDMutators<TSchema extends Schema, TTable extends keyof TSchema['tables'] & string> = {
|
|
114
|
+
[K in keyof TableMutator<TSchema['tables'][TTable]>]: CRUDMutator<TSchema, TTable, K, Parameters<TableMutator<TSchema['tables'][TTable]>[K]>[0]>;
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Creates a table CRUD builder that returns `CRUDMutateRequest` objects.
|
|
118
|
+
* These request objects can be passed to `tx.mutate(request)`.
|
|
119
|
+
*/
|
|
120
|
+
export declare function makeTableCRUDRequestBuilder<S extends Schema, T extends keyof S['tables'] & string>(schema: S, table: T): TableCRUDMutators<S, T>;
|
|
121
|
+
/**
|
|
122
|
+
* Creates a schema CRUD builder where each table has methods that return
|
|
123
|
+
* `CRUDMutateRequest` objects. These can be passed to `tx.mutate(request)`.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
*
|
|
127
|
+
* ```ts
|
|
128
|
+
* const crud = createCRUDBuilder(schema);
|
|
129
|
+
*
|
|
130
|
+
* // Inside a custom mutator:
|
|
131
|
+
* await tx.mutate(crud.user.insert({name: 'Alice'}));
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
export declare function createCRUDBuilder<S extends Schema>(schema: S): SchemaCRUDMutators<S>;
|
|
135
|
+
export type SchemaCRUDMutators<S extends Schema> = {
|
|
136
|
+
[T in keyof S['tables'] & string]: TableCRUDMutators<S, T>;
|
|
137
|
+
};
|
|
138
|
+
export {};
|
|
139
|
+
//# sourceMappingURL=crud.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crud.d.ts","sourceRoot":"","sources":["../../../../../zql/src/mutate/crud.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { recordProxy } from "../../../shared/src/record-proxy.js";
|
|
2
|
+
const CRUD_KINDS = ["insert", "upsert", "update", "delete"];
|
|
3
|
+
function makeMutateCRUDFunction(schema, executor) {
|
|
4
|
+
const mutate = (request) => {
|
|
5
|
+
const { table, kind, args } = request;
|
|
6
|
+
return executor(table, kind, args);
|
|
7
|
+
};
|
|
8
|
+
if (schema.enableLegacyMutators === true) {
|
|
9
|
+
for (const tableName of Object.keys(schema.tables)) {
|
|
10
|
+
mutate[tableName] = void 0;
|
|
11
|
+
}
|
|
12
|
+
return recordProxy(
|
|
13
|
+
mutate,
|
|
14
|
+
(_value, tableName) => makeTableCRUD(tableName, executor)
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
return mutate;
|
|
18
|
+
}
|
|
19
|
+
function makeTableCRUD(tableName, executor) {
|
|
20
|
+
return Object.fromEntries(
|
|
21
|
+
CRUD_KINDS.map((kind) => [
|
|
22
|
+
kind,
|
|
23
|
+
(value) => executor(tableName, kind, value)
|
|
24
|
+
])
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
function makeTableCRUDRequestBuilder(schema, table) {
|
|
28
|
+
return Object.fromEntries(
|
|
29
|
+
CRUD_KINDS.map((kind) => [
|
|
30
|
+
kind,
|
|
31
|
+
(args) => ({ schema, table, kind, args })
|
|
32
|
+
])
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
function createCRUDBuilder(schema) {
|
|
36
|
+
return recordProxy(
|
|
37
|
+
schema.tables,
|
|
38
|
+
(_tableSchema, tableName) => makeTableCRUDRequestBuilder(
|
|
39
|
+
schema,
|
|
40
|
+
tableName
|
|
41
|
+
),
|
|
42
|
+
(prop) => {
|
|
43
|
+
throw new Error(`Table ${prop} does not exist in schema`);
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
CRUD_KINDS,
|
|
49
|
+
createCRUDBuilder,
|
|
50
|
+
makeMutateCRUDFunction,
|
|
51
|
+
makeTableCRUDRequestBuilder
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=crud.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crud.js","sources":["../../../../../zql/src/mutate/crud.ts"],"sourcesContent":["import type {Expand} from '../../../shared/src/expand.ts';\nimport {recordProxy} from '../../../shared/src/record-proxy.ts';\nimport type {SchemaValueToTSType} from '../../../zero-types/src/schema-value.ts';\nimport type {Schema, TableSchema} from '../../../zero-types/src/schema.ts';\nimport type {MutateCRUD} from './custom.ts';\n\nexport type SchemaCRUD<S extends Schema> = {\n [Table in keyof S['tables']]: TableCRUD<S['tables'][Table]>;\n};\n\nexport type TableCRUD<S extends TableSchema> = {\n /**\n * Writes a row if a row with the same primary key doesn't already exist.\n * Non-primary-key fields that are 'optional' can be omitted or set to\n * `undefined`. Such fields will be assigned the value `null` optimistically\n * and then the default value as defined by the server.\n */\n insert: (value: InsertValue<S>) => Promise<void>;\n\n /**\n * Writes a row unconditionally, overwriting any existing row with the same\n * primary key. Non-primary-key fields that are 'optional' can be omitted or\n * set to `undefined`. Such fields will be assigned the value `null`\n * optimistically and then the default value as defined by the server.\n */\n upsert: (value: UpsertValue<S>) => Promise<void>;\n\n /**\n * Updates a row with the same primary key. If no such row exists, this\n * function does nothing. All non-primary-key fields can be omitted or set to\n * `undefined`. Such fields will be left unchanged from previous value.\n */\n update: (value: UpdateValue<S>) => Promise<void>;\n\n /**\n * Deletes the row with the specified primary key. If no such row exists, this\n * function does nothing.\n */\n delete: (id: DeleteID<S>) => Promise<void>;\n};\n\nexport type CRUDKind = keyof TableCRUD<TableSchema>;\n\nexport const CRUD_KINDS = ['insert', 'upsert', 'update', 'delete'] as const;\n\nexport type DeleteID<S extends TableSchema> = Expand<PrimaryKeyFields<S>>;\n\ntype PrimaryKeyFields<S extends TableSchema> = {\n [K in Extract<\n S['primaryKey'][number],\n keyof S['columns']\n >]: SchemaValueToTSType<S['columns'][K]>;\n};\n\nexport type InsertValue<S extends TableSchema> = Expand<\n PrimaryKeyFields<S> & {\n [K in keyof S['columns'] as S['columns'][K] extends {optional: true}\n ? K\n : never]?: SchemaValueToTSType<S['columns'][K]> | undefined;\n } & {\n [K in keyof S['columns'] as S['columns'][K] extends {optional: true}\n ? never\n : K]: SchemaValueToTSType<S['columns'][K]>;\n }\n>;\n\nexport type UpsertValue<S extends TableSchema> = InsertValue<S>;\n\nexport type UpdateValue<S extends TableSchema> = Expand<\n PrimaryKeyFields<S> & {\n [K in keyof S['columns']]?:\n | SchemaValueToTSType<S['columns'][K]>\n | undefined;\n }\n>;\n\n/**\n * This is the type of the generated mutate.<name>.<verb> function.\n */\nexport type TableMutator<TS extends TableSchema> = {\n /**\n * Writes a row if a row with the same primary key doesn't already exist.\n * Non-primary-key fields that are 'optional' can be omitted or set to\n * `undefined`. Such fields will be assigned the value `null` optimistically\n * and then the default value as defined by the server.\n */\n insert: (value: InsertValue<TS>) => Promise<void>;\n\n /**\n * Writes a row unconditionally, overwriting any existing row with the same\n * primary key. Non-primary-key fields that are 'optional' can be omitted or\n * set to `undefined`. Such fields will be assigned the value `null`\n * optimistically and then the default value as defined by the server.\n */\n upsert: (value: UpsertValue<TS>) => Promise<void>;\n\n /**\n * Updates a row with the same primary key. If no such row exists, this\n * function does nothing. All non-primary-key fields can be omitted or set to\n * `undefined`. Such fields will be left unchanged from previous value.\n */\n update: (value: UpdateValue<TS>) => Promise<void>;\n\n /**\n * Deletes the row with the specified primary key. If no such row exists, this\n * function does nothing.\n */\n delete: (id: DeleteID<TS>) => Promise<void>;\n};\n\n/**\n * A function that executes a CRUD operation.\n * Client and server provide different implementations.\n */\nexport type CRUDExecutor = (\n table: string,\n kind: CRUDKind,\n args: unknown,\n) => Promise<void>;\n\n/**\n * Creates a MutateCRUD function from a schema and executor.\n * This is the shared implementation used by both client and server.\n *\n * @param schema - The Zero schema\n * @param executor - A function that executes CRUD operations\n * @returns A MutateCRUD function that can be called with CRUDMutateRequest objects\n */\nexport function makeMutateCRUDFunction<S extends Schema>(\n schema: S,\n executor: CRUDExecutor,\n): MutateCRUD<S> {\n // Create a callable function that accepts CRUDMutateRequest\n const mutate = (request: AnyCRUDMutateRequest) => {\n const {table, kind, args} = request;\n return executor(table, kind, args);\n };\n\n // Only add table properties when enableLegacyMutators is true\n if (schema.enableLegacyMutators === true) {\n // Add table names as keys so the proxy can discover them\n for (const tableName of Object.keys(schema.tables)) {\n (mutate as unknown as Record<string, undefined>)[tableName] = undefined;\n }\n\n // Wrap in proxy that lazily creates and caches table CRUD objects\n return recordProxy(\n mutate as unknown as Record<string, undefined>,\n (_value, tableName) => makeTableCRUD(tableName, executor),\n ) as unknown as MutateCRUD<S>;\n }\n\n return mutate as MutateCRUD<S>;\n}\n\n/**\n * Creates a TableCRUD object that delegates to the executor.\n */\nfunction makeTableCRUD(\n tableName: string,\n executor: CRUDExecutor,\n): TableCRUD<TableSchema> {\n return Object.fromEntries(\n CRUD_KINDS.map(kind => [\n kind,\n (value: unknown) => executor(tableName, kind, value),\n ]),\n ) as TableCRUD<TableSchema>;\n}\n\nexport type CRUDMutator<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TKind extends keyof TableMutator<TSchema['tables'][TTable]>,\n TArgs extends Parameters<TableMutator<TSchema['tables'][TTable]>[TKind]>[0],\n> = {\n (args: TArgs): CRUDMutateRequest<TSchema, TTable, TKind, TArgs>;\n\n /**\n * Type-only phantom property to surface mutator types in a covariant position.\n */\n ['~']: Expand<CRUDMutatorTypes<TSchema, TTable, TKind, TArgs>>;\n};\n\nexport type CRUDMutatorTypes<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TKind extends keyof TableMutator<TSchema['tables'][TTable]>,\n TArgs extends Parameters<TableMutator<TSchema['tables'][TTable]>[TKind]>[0],\n> = 'CRUDMutator' & CRUDMutateRequest<TSchema, TTable, TKind, TArgs>;\n\nexport type CRUDMutateRequest<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'],\n TKind extends keyof TableMutator<TSchema['tables'][TTable]>,\n TArgs extends Parameters<TableMutator<TSchema['tables'][TTable]>[TKind]>[0],\n> = {\n readonly schema: TSchema;\n readonly table: TTable;\n readonly kind: TKind;\n readonly args: TArgs;\n};\n\n// oxlint-disable-next-line no-explicit-any\nexport type AnyCRUDMutateRequest = CRUDMutateRequest<any, any, CRUDKind, any>;\n\nexport type TableCRUDMutators<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n> = {\n [K in keyof TableMutator<TSchema['tables'][TTable]>]: CRUDMutator<\n TSchema,\n TTable,\n K,\n Parameters<TableMutator<TSchema['tables'][TTable]>[K]>[0]\n >;\n};\n\n/**\n * Creates a table CRUD builder that returns `CRUDMutateRequest` objects.\n * These request objects can be passed to `tx.mutate(request)`.\n */\nexport function makeTableCRUDRequestBuilder<\n S extends Schema,\n T extends keyof S['tables'] & string,\n>(schema: S, table: T): TableCRUDMutators<S, T> {\n return Object.fromEntries(\n CRUD_KINDS.map(kind => [\n kind,\n (args: unknown) => ({schema, table, kind, args}),\n ]),\n ) as TableCRUDMutators<S, T>;\n}\n\n/**\n * Creates a schema CRUD builder where each table has methods that return\n * `CRUDMutateRequest` objects. These can be passed to `tx.mutate(request)`.\n *\n * @example\n *\n * ```ts\n * const crud = createCRUDBuilder(schema);\n *\n * // Inside a custom mutator:\n * await tx.mutate(crud.user.insert({name: 'Alice'}));\n * ```\n */\nexport function createCRUDBuilder<S extends Schema>(\n schema: S,\n): SchemaCRUDMutators<S> {\n return recordProxy(\n schema.tables,\n (_tableSchema, tableName) =>\n makeTableCRUDRequestBuilder(\n schema,\n tableName as keyof S['tables'] & string,\n ),\n prop => {\n throw new Error(`Table ${prop} does not exist in schema`);\n },\n ) as unknown as SchemaCRUDMutators<S>;\n}\n\nexport type SchemaCRUDMutators<S extends Schema> = {\n [T in keyof S['tables'] & string]: TableCRUDMutators<S, T>;\n};\n"],"names":[],"mappings":";AA2CO,MAAM,aAAa,CAAC,UAAU,UAAU,UAAU,QAAQ;AAqF1D,SAAS,uBACd,QACA,UACe;AAEf,QAAM,SAAS,CAAC,YAAkC;AAChD,UAAM,EAAC,OAAO,MAAM,KAAA,IAAQ;AAC5B,WAAO,SAAS,OAAO,MAAM,IAAI;AAAA,EACnC;AAGA,MAAI,OAAO,yBAAyB,MAAM;AAExC,eAAW,aAAa,OAAO,KAAK,OAAO,MAAM,GAAG;AACjD,aAAgD,SAAS,IAAI;AAAA,IAChE;AAGA,WAAO;AAAA,MACL;AAAA,MACA,CAAC,QAAQ,cAAc,cAAc,WAAW,QAAQ;AAAA,IAAA;AAAA,EAE5D;AAEA,SAAO;AACT;AAKA,SAAS,cACP,WACA,UACwB;AACxB,SAAO,OAAO;AAAA,IACZ,WAAW,IAAI,CAAA,SAAQ;AAAA,MACrB;AAAA,MACA,CAAC,UAAmB,SAAS,WAAW,MAAM,KAAK;AAAA,IAAA,CACpD;AAAA,EAAA;AAEL;AAsDO,SAAS,4BAGd,QAAW,OAAmC;AAC9C,SAAO,OAAO;AAAA,IACZ,WAAW,IAAI,CAAA,SAAQ;AAAA,MACrB;AAAA,MACA,CAAC,UAAmB,EAAC,QAAQ,OAAO,MAAM,KAAA;AAAA,IAAI,CAC/C;AAAA,EAAA;AAEL;AAeO,SAAS,kBACd,QACuB;AACvB,SAAO;AAAA,IACL,OAAO;AAAA,IACP,CAAC,cAAc,cACb;AAAA,MACE;AAAA,MACA;AAAA,IAAA;AAAA,IAEJ,CAAA,SAAQ;AACN,YAAM,IAAI,MAAM,SAAS,IAAI,2BAA2B;AAAA,IAC1D;AAAA,EAAA;AAEJ;"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import type { Expand } from '../../../shared/src/expand.ts';
|
|
2
1
|
import type { AST } from '../../../zero-protocol/src/ast.ts';
|
|
3
2
|
import type { DefaultSchema, DefaultWrappedTransaction } from '../../../zero-types/src/default-types.ts';
|
|
4
|
-
import type {
|
|
5
|
-
import type { Schema, TableSchema } from '../../../zero-types/src/schema.ts';
|
|
3
|
+
import type { Schema } from '../../../zero-types/src/schema.ts';
|
|
6
4
|
import type { ServerSchema } from '../../../zero-types/src/server-schema.ts';
|
|
7
5
|
import type { Format } from '../ivm/view.ts';
|
|
8
6
|
import type { HumanReadable, Query, RunOptions } from '../query/query.ts';
|
|
9
7
|
import type { SchemaQuery } from '../query/schema-query.ts';
|
|
8
|
+
import type { CRUDMutateRequest, SchemaCRUD } from './crud.ts';
|
|
9
|
+
export type { DeleteID, InsertValue, SchemaCRUD, TableCRUD, UpdateValue, UpsertValue, } from './crud.ts';
|
|
10
10
|
type ClientID = string;
|
|
11
11
|
/**
|
|
12
12
|
* A base transaction interface that any Transaction<S, T> is assignable to.
|
|
@@ -32,7 +32,7 @@ export interface TransactionBase<S extends Schema> {
|
|
|
32
32
|
* The reason for the transaction.
|
|
33
33
|
*/
|
|
34
34
|
readonly reason: TransactionReason;
|
|
35
|
-
readonly mutate:
|
|
35
|
+
readonly mutate: MutateCRUD<S>;
|
|
36
36
|
readonly query: SchemaQuery<S>;
|
|
37
37
|
run<TTable extends keyof S['tables'] & string, TReturn>(query: Query<TTable, S, TReturn>, options?: RunOptions): Promise<HumanReadable<TReturn>>;
|
|
38
38
|
}
|
|
@@ -64,54 +64,13 @@ export interface DBTransaction<T> extends Queryable {
|
|
|
64
64
|
interface Queryable {
|
|
65
65
|
query: (query: string, args: unknown[]) => Promise<Iterable<Row>>;
|
|
66
66
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
* and then the default value as defined by the server.
|
|
76
|
-
*/
|
|
77
|
-
insert: (value: InsertValue<S>) => Promise<void>;
|
|
78
|
-
/**
|
|
79
|
-
* Writes a row unconditionally, overwriting any existing row with the same
|
|
80
|
-
* primary key. Non-primary-key fields that are 'optional' can be omitted or
|
|
81
|
-
* set to `undefined`. Such fields will be assigned the value `null`
|
|
82
|
-
* optimistically and then the default value as defined by the server.
|
|
83
|
-
*/
|
|
84
|
-
upsert: (value: UpsertValue<S>) => Promise<void>;
|
|
85
|
-
/**
|
|
86
|
-
* Updates a row with the same primary key. If no such row exists, this
|
|
87
|
-
* function does nothing. All non-primary-key fields can be omitted or set to
|
|
88
|
-
* `undefined`. Such fields will be left unchanged from previous value.
|
|
89
|
-
*/
|
|
90
|
-
update: (value: UpdateValue<S>) => Promise<void>;
|
|
91
|
-
/**
|
|
92
|
-
* Deletes the row with the specified primary key. If no such row exists, this
|
|
93
|
-
* function does nothing.
|
|
94
|
-
*/
|
|
95
|
-
delete: (id: DeleteID<S>) => Promise<void>;
|
|
96
|
-
};
|
|
97
|
-
export type DeleteID<S extends TableSchema> = Expand<PrimaryKeyFields<S>>;
|
|
98
|
-
type PrimaryKeyFields<S extends TableSchema> = {
|
|
99
|
-
[K in Extract<S['primaryKey'][number], keyof S['columns']>]: SchemaValueToTSType<S['columns'][K]>;
|
|
100
|
-
};
|
|
101
|
-
export type InsertValue<S extends TableSchema> = Expand<PrimaryKeyFields<S> & {
|
|
102
|
-
[K in keyof S['columns'] as S['columns'][K] extends {
|
|
103
|
-
optional: true;
|
|
104
|
-
} ? K : never]?: SchemaValueToTSType<S['columns'][K]> | undefined;
|
|
105
|
-
} & {
|
|
106
|
-
[K in keyof S['columns'] as S['columns'][K] extends {
|
|
107
|
-
optional: true;
|
|
108
|
-
} ? never : K]: SchemaValueToTSType<S['columns'][K]>;
|
|
109
|
-
}>;
|
|
110
|
-
export type UpsertValue<S extends TableSchema> = InsertValue<S>;
|
|
111
|
-
export type UpdateValue<S extends TableSchema> = Expand<PrimaryKeyFields<S> & {
|
|
112
|
-
[K in keyof S['columns']]?: SchemaValueToTSType<S['columns'][K]> | undefined;
|
|
113
|
-
}>;
|
|
67
|
+
/**
|
|
68
|
+
* The type of `tx.mutate` which is:
|
|
69
|
+
* 1. A callable function that accepts a `CRUDMutateRequest`
|
|
70
|
+
* 2. When `enableLegacyMutators` is true, also an object with CRUD methods per table
|
|
71
|
+
*/
|
|
72
|
+
export type MutateCRUD<S extends Schema> = {
|
|
73
|
+
(request: CRUDMutateRequest<S, any, any, any>): Promise<void>;
|
|
74
|
+
} & (S['enableLegacyMutators'] extends true ? SchemaCRUD<S> : {});
|
|
114
75
|
export declare function customMutatorKey(sep: string, parts: string[]): string;
|
|
115
|
-
export declare function splitMutatorKey(key: string, sep: string | RegExp): string[];
|
|
116
|
-
export {};
|
|
117
76
|
//# sourceMappingURL=custom.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom.d.ts","sourceRoot":"","sources":["../../../../../zql/src/mutate/custom.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,
|
|
1
|
+
{"version":3,"file":"custom.d.ts","sourceRoot":"","sources":["../../../../../zql/src/mutate/custom.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,11 +8,7 @@ function customMutatorKey(sep, parts) {
|
|
|
8
8
|
}
|
|
9
9
|
return parts.join(sep);
|
|
10
10
|
}
|
|
11
|
-
function splitMutatorKey(key, sep) {
|
|
12
|
-
return key.split(sep);
|
|
13
|
-
}
|
|
14
11
|
export {
|
|
15
|
-
customMutatorKey
|
|
16
|
-
splitMutatorKey
|
|
12
|
+
customMutatorKey
|
|
17
13
|
};
|
|
18
14
|
//# sourceMappingURL=custom.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom.js","sources":["../../../../../zql/src/mutate/custom.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport type {
|
|
1
|
+
{"version":3,"file":"custom.js","sources":["../../../../../zql/src/mutate/custom.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport type {AST} from '../../../zero-protocol/src/ast.ts';\nimport type {\n DefaultSchema,\n DefaultWrappedTransaction,\n} from '../../../zero-types/src/default-types.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {ServerSchema} from '../../../zero-types/src/server-schema.ts';\nimport type {Format} from '../ivm/view.ts';\nimport type {HumanReadable, Query, RunOptions} from '../query/query.ts';\nimport type {SchemaQuery} from '../query/schema-query.ts';\nimport type {CRUDMutateRequest, SchemaCRUD} from './crud.ts';\nexport type {\n DeleteID,\n InsertValue,\n SchemaCRUD,\n TableCRUD,\n UpdateValue,\n UpsertValue,\n} from './crud.ts';\n\ntype ClientID = string;\n\n/**\n * A base transaction interface that any Transaction<S, T> is assignable to.\n * Used in places where the schema type doesn't need to be preserved,\n * like the public signature of Mutator.fn.\n */\nexport interface AnyTransaction {\n readonly location: Location;\n readonly clientID: string;\n readonly mutationID: number;\n readonly reason: TransactionReason;\n}\n\nexport type Location = 'client' | 'server';\nexport type TransactionReason = 'optimistic' | 'rebase' | 'authoritative';\n\nexport interface TransactionBase<S extends Schema> {\n readonly location: Location;\n readonly clientID: ClientID;\n /**\n * The ID of the mutation that is being applied.\n */\n readonly mutationID: number;\n\n /**\n * The reason for the transaction.\n */\n readonly reason: TransactionReason;\n\n readonly mutate: MutateCRUD<S>;\n readonly query: SchemaQuery<S>;\n\n run<TTable extends keyof S['tables'] & string, TReturn>(\n query: Query<TTable, S, TReturn>,\n options?: RunOptions,\n ): Promise<HumanReadable<TReturn>>;\n}\n\nexport type Transaction<\n S extends Schema = DefaultSchema,\n TWrappedTransaction = DefaultWrappedTransaction,\n> = ServerTransaction<S, TWrappedTransaction> | ClientTransaction<S>;\n\nexport interface ServerTransaction<\n S extends Schema = DefaultSchema,\n TWrappedTransaction = DefaultWrappedTransaction,\n> extends TransactionBase<S> {\n readonly location: 'server';\n readonly reason: 'authoritative';\n readonly dbTransaction: DBTransaction<TWrappedTransaction>;\n}\n\n/**\n * An instance of this is passed to custom mutator implementations and\n * allows reading and writing to the database and IVM at the head at which the\n * mutator is being applied.\n */\nexport interface ClientTransaction<S extends Schema = DefaultSchema>\n extends TransactionBase<S> {\n readonly location: 'client';\n readonly reason: 'optimistic' | 'rebase';\n}\n\nexport interface Row {\n [column: string]: unknown;\n}\n\nexport interface DBConnection<TWrappedTransaction> {\n transaction: <T>(\n cb: (tx: DBTransaction<TWrappedTransaction>) => Promise<T>,\n ) => Promise<T>;\n}\n\nexport interface DBTransaction<T> extends Queryable {\n readonly wrappedTransaction: T;\n runQuery<TReturn>(\n ast: AST,\n format: Format,\n schema: Schema,\n serverSchema: ServerSchema,\n ): Promise<HumanReadable<TReturn>>;\n}\n\ninterface Queryable {\n query: (query: string, args: unknown[]) => Promise<Iterable<Row>>;\n}\n\n/**\n * The type of `tx.mutate` which is:\n * 1. A callable function that accepts a `CRUDMutateRequest`\n * 2. When `enableLegacyMutators` is true, also an object with CRUD methods per table\n */\nexport type MutateCRUD<S extends Schema> = {\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n (request: CRUDMutateRequest<S, any, any, any>): Promise<void>;\n} & (S['enableLegacyMutators'] extends true ? SchemaCRUD<S> : {});\n\nexport function customMutatorKey(sep: string, parts: string[]) {\n for (const part of parts) {\n assert(\n !part.includes(sep),\n `mutator names/namespaces must not include a ${sep}`,\n );\n }\n return parts.join(sep);\n}\n"],"names":[],"mappings":";AAuHO,SAAS,iBAAiB,KAAa,OAAiB;AAC7D,aAAW,QAAQ,OAAO;AACxB;AAAA,MACE,CAAC,KAAK,SAAS,GAAG;AAAA,MAClB,+CAA+C,GAAG;AAAA,IAAA;AAAA,EAEtD;AACA,SAAO,MAAM,KAAK,GAAG;AACvB;"}
|