@rocicorp/zero 0.6.2024112102 → 0.7.2024120100
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/advanced.js +1 -1
- package/out/{chunk-QB7G63C6.js → chunk-4XX2NVJ7.js} +737 -738
- package/out/{chunk-QB7G63C6.js.map → chunk-4XX2NVJ7.js.map} +4 -4
- package/out/{chunk-5UY46OAF.js → chunk-C7M3BJ3Z.js} +16 -8
- package/out/chunk-C7M3BJ3Z.js.map +7 -0
- package/out/shared/src/expand.js +2 -0
- package/out/shared/src/expand.js.map +1 -0
- package/out/shared/src/immutable.js +2 -0
- package/out/shared/src/immutable.js.map +1 -0
- package/out/{zero-cache/src/config/config.d.ts → shared/src/options.d.ts} +3 -5
- package/out/shared/src/options.d.ts.map +1 -0
- package/out/{zero-cache/src/config/config.js → shared/src/options.js} +26 -26
- package/out/shared/src/options.js.map +1 -0
- package/out/shared/src/sorted-entries.js +6 -0
- package/out/shared/src/sorted-entries.js.map +1 -0
- package/out/shared/src/writable.js +2 -0
- package/out/shared/src/writable.js.map +1 -0
- package/out/solid.js +2 -2
- package/out/zero/src/build-schema.d.ts +3 -0
- package/out/zero/src/build-schema.d.ts.map +1 -0
- package/out/zero/src/build-schema.js +3 -0
- package/out/zero/src/build-schema.js.map +1 -0
- package/out/zero-cache/src/auth/load-schema.d.ts +8 -0
- package/out/zero-cache/src/auth/load-schema.d.ts.map +1 -0
- package/out/zero-cache/src/auth/load-schema.js +35 -0
- package/out/zero-cache/src/auth/load-schema.js.map +1 -0
- package/out/zero-cache/src/auth/read-authorizer.d.ts +25 -0
- package/out/zero-cache/src/auth/read-authorizer.d.ts.map +1 -0
- package/out/zero-cache/src/auth/read-authorizer.js +126 -0
- package/out/zero-cache/src/auth/read-authorizer.js.map +1 -0
- package/out/zero-cache/src/auth/write-authorizer.d.ts +20 -0
- package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -0
- package/out/zero-cache/src/auth/write-authorizer.js +320 -0
- package/out/zero-cache/src/auth/write-authorizer.js.map +1 -0
- package/out/zero-cache/src/config/zero-config.d.ts +14 -4
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +27 -14
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/server/main.js +7 -0
- package/out/zero-cache/src/server/main.js.map +1 -1
- package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/server/replicator.js +4 -3
- package/out/zero-cache/src/server/replicator.js.map +1 -1
- package/out/zero-cache/src/server/runtime.d.ts +3 -0
- package/out/zero-cache/src/server/runtime.d.ts.map +1 -0
- package/out/zero-cache/src/server/runtime.js +19 -0
- package/out/zero-cache/src/server/runtime.js.map +1 -0
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +7 -6
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts +7 -6
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js +19 -33
- package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
- package/out/zero-cache/src/services/replicator/replicator.d.ts +1 -1
- package/out/zero-cache/src/services/replicator/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/replicator.js +2 -2
- package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.js +11 -8
- package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +17 -8
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js +357 -94
- package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts +15 -10
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js +42 -23
- package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
- 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 +2 -2
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts +22 -0
- package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/cvr.js +33 -7
- package/out/zero-cache/src/services/view-syncer/schema/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/init.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/init.js +44 -5
- package/out/zero-cache/src/services/view-syncer/schema/init.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/types.d.ts +1 -0
- package/out/zero-cache/src/services/view-syncer/schema/types.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/types.js +3 -0
- package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js +5 -0
- 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 +9 -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 +167 -50
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/row-key.d.ts +6 -0
- package/out/zero-cache/src/types/row-key.d.ts.map +1 -1
- package/out/zero-cache/src/types/row-key.js +16 -1
- package/out/zero-cache/src/types/row-key.js.map +1 -1
- package/out/zero-cache/src/workers/connection.d.ts +2 -3
- package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connection.js +4 -3
- package/out/zero-cache/src/workers/connection.js.map +1 -1
- package/out/zero-cache/src/workers/replicator.d.ts +3 -1
- package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/workers/replicator.js +2 -0
- package/out/zero-cache/src/workers/replicator.js.map +1 -1
- package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer.js +13 -3
- package/out/zero-cache/src/workers/syncer.js.map +1 -1
- package/out/zero-client/src/client/options.d.ts +37 -8
- package/out/zero-client/src/client/options.d.ts.map +1 -1
- package/out/zero-client/src/client/reload-error-handler.d.ts +16 -1
- package/out/zero-client/src/client/reload-error-handler.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.d.ts +7 -55
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/mod.d.ts +2 -2
- package/out/zero-client/src/mod.d.ts.map +1 -1
- package/out/zero-protocol/src/ast-hash.js +14 -0
- package/out/zero-protocol/src/ast-hash.js.map +1 -0
- package/out/zero-protocol/src/ast.d.ts +9 -9
- package/out/zero-protocol/src/ast.d.ts.map +1 -1
- package/out/zero-protocol/src/ast.js +11 -12
- package/out/zero-protocol/src/ast.js.map +1 -1
- package/out/zero-protocol/src/down.d.ts +4 -4
- package/out/zero-protocol/src/poke.d.ts +16 -8
- package/out/zero-protocol/src/poke.d.ts.map +1 -1
- package/out/zero-protocol/src/poke.js +8 -2
- package/out/zero-protocol/src/poke.js.map +1 -1
- package/out/zero-schema/src/build-schema.d.ts +14 -0
- package/out/zero-schema/src/build-schema.d.ts.map +1 -0
- package/out/zero-schema/src/build-schema.js +55 -0
- package/out/zero-schema/src/build-schema.js.map +1 -0
- package/out/zero-schema/src/compiled-permissions.d.ts +480 -0
- package/out/zero-schema/src/compiled-permissions.d.ts.map +1 -0
- package/out/zero-schema/src/compiled-permissions.js +20 -0
- package/out/zero-schema/src/compiled-permissions.js.map +1 -0
- package/out/zero-schema/src/mod.d.ts +1 -1
- package/out/zero-schema/src/mod.d.ts.map +1 -1
- package/out/zero-schema/src/normalize-table-schema.d.ts +19 -17
- package/out/zero-schema/src/normalize-table-schema.d.ts.map +1 -1
- package/out/zero-schema/src/normalize-table-schema.js +92 -0
- package/out/zero-schema/src/normalize-table-schema.js.map +1 -0
- package/out/zero-schema/src/normalized-schema.d.ts +6 -1
- package/out/zero-schema/src/normalized-schema.d.ts.map +1 -1
- package/out/zero-schema/src/normalized-schema.js +31 -0
- package/out/zero-schema/src/normalized-schema.js.map +1 -0
- package/out/zero-schema/src/permissions.d.ts +32 -0
- package/out/zero-schema/src/permissions.d.ts.map +1 -0
- package/out/zero-schema/src/schema-config.d.ts +43 -0
- package/out/zero-schema/src/schema-config.d.ts.map +1 -0
- package/out/zero-schema/src/schema-config.js +79 -0
- package/out/zero-schema/src/schema-config.js.map +1 -0
- package/out/zero-schema/src/schema.js +4 -0
- package/out/zero-schema/src/schema.js.map +1 -0
- package/out/zero-schema/src/table-schema.d.ts +15 -20
- package/out/zero-schema/src/table-schema.d.ts.map +1 -1
- package/out/zero-schema/src/table-schema.js +15 -2
- package/out/zero-schema/src/table-schema.js.map +1 -1
- package/out/zero.js +4 -4
- package/out/zql/src/builder/builder.d.ts +2 -2
- package/out/zql/src/builder/builder.d.ts.map +1 -1
- package/out/zql/src/builder/builder.js +15 -17
- package/out/zql/src/builder/builder.js.map +1 -1
- package/out/zql/src/builder/filter.d.ts +25 -2
- package/out/zql/src/builder/filter.d.ts.map +1 -1
- package/out/zql/src/builder/filter.js +91 -1
- package/out/zql/src/builder/filter.js.map +1 -1
- package/out/zql/src/ivm/array-view.js +70 -0
- package/out/zql/src/ivm/array-view.js.map +1 -0
- package/out/zql/src/ivm/change.d.ts +18 -6
- package/out/zql/src/ivm/change.d.ts.map +1 -1
- package/out/zql/src/ivm/change.js +1 -1
- package/out/zql/src/ivm/change.js.map +1 -1
- package/out/zql/src/ivm/constraint.d.ts +14 -0
- package/out/zql/src/ivm/constraint.d.ts.map +1 -0
- package/out/zql/src/ivm/constraint.js +60 -0
- package/out/zql/src/ivm/constraint.js.map +1 -0
- package/out/zql/src/ivm/exists.d.ts.map +1 -1
- package/out/zql/src/ivm/exists.js +19 -2
- package/out/zql/src/ivm/exists.js.map +1 -1
- package/out/zql/src/ivm/join.d.ts +11 -5
- package/out/zql/src/ivm/join.d.ts.map +1 -1
- package/out/zql/src/ivm/join.js +49 -95
- package/out/zql/src/ivm/join.js.map +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 -13
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
- package/out/zql/src/ivm/memory-source.d.ts +5 -22
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +61 -83
- package/out/zql/src/ivm/memory-source.js.map +1 -1
- package/out/zql/src/ivm/operator.d.ts +7 -10
- package/out/zql/src/ivm/operator.d.ts.map +1 -1
- package/out/zql/src/ivm/operator.js +1 -1
- package/out/zql/src/ivm/operator.js.map +1 -1
- package/out/zql/src/ivm/take.d.ts +3 -1
- package/out/zql/src/ivm/take.d.ts.map +1 -1
- package/out/zql/src/ivm/take.js +95 -95
- package/out/zql/src/ivm/take.js.map +1 -1
- package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
- package/out/zql/src/ivm/view-apply-change.js +168 -0
- package/out/zql/src/ivm/view-apply-change.js.map +1 -0
- package/out/zql/src/ivm/view.js +2 -0
- package/out/zql/src/ivm/view.js.map +1 -0
- package/out/zql/src/query/auth-query.d.ts +3 -5
- package/out/zql/src/query/auth-query.d.ts.map +1 -1
- package/out/zql/src/query/auth-query.js +30 -0
- package/out/zql/src/query/auth-query.js.map +1 -0
- package/out/zql/src/query/dnf.js +57 -0
- package/out/zql/src/query/dnf.js.map +1 -0
- package/out/zql/src/query/expression.js +155 -0
- package/out/zql/src/query/expression.js.map +1 -0
- package/out/zql/src/query/query-impl.d.ts +4 -1
- package/out/zql/src/query/query-impl.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.js +353 -0
- package/out/zql/src/query/query-impl.js.map +1 -0
- package/out/zql/src/query/query-internal.js +2 -0
- package/out/zql/src/query/query-internal.js.map +1 -0
- package/out/zql/src/query/query.js +3 -0
- package/out/zql/src/query/query.js.map +1 -0
- package/out/zql/src/query/typed-view.js +2 -0
- package/out/zql/src/query/typed-view.js.map +1 -0
- package/out/zqlite/src/table-source.d.ts +2 -11
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +33 -82
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +5 -3
- package/out/chunk-5UY46OAF.js.map +0 -7
- package/out/zero-cache/src/auth/load-authorization.d.ts +0 -4
- package/out/zero-cache/src/auth/load-authorization.d.ts.map +0 -1
- package/out/zero-cache/src/auth/load-authorization.js +0 -20
- package/out/zero-cache/src/auth/load-authorization.js.map +0 -1
- package/out/zero-cache/src/config/config.d.ts.map +0 -1
- package/out/zero-cache/src/config/config.js.map +0 -1
- package/out/zero-cache/src/services/mutagen/write-authorizer.d.ts +0 -21
- package/out/zero-cache/src/services/mutagen/write-authorizer.d.ts.map +0 -1
- package/out/zero-cache/src/services/mutagen/write-authorizer.js +0 -168
- package/out/zero-cache/src/services/mutagen/write-authorizer.js.map +0 -1
- package/out/zero-schema/src/authorization.d.ts +0 -25
- package/out/zero-schema/src/authorization.d.ts.map +0 -1
- package/out/zero-schema/src/compiled-authorization.d.ts +0 -561
- package/out/zero-schema/src/compiled-authorization.d.ts.map +0 -1
- package/out/zero-schema/src/compiled-authorization.js +0 -15
- package/out/zero-schema/src/compiled-authorization.js.map +0 -1
package/out/zql/src/ivm/join.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { assert, unreachable } from '../../../shared/src/asserts.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { first, take } from './stream.js';
|
|
2
|
+
import { valuesEqual } from './data.js';
|
|
3
|
+
import { take } from './stream.js';
|
|
5
4
|
/**
|
|
6
5
|
* The Join operator joins the output from two upstream inputs. Zero's join
|
|
7
6
|
* is a little different from SQL's join in that we output hierarchical data,
|
|
@@ -23,6 +22,7 @@ export class Join {
|
|
|
23
22
|
#output = null;
|
|
24
23
|
constructor({ parent, child, storage, parentKey, childKey, relationshipName, hidden, }) {
|
|
25
24
|
assert(parent !== child, 'Parent and child must be different operators');
|
|
25
|
+
assert(parentKey.length === childKey.length, 'The parentKey and childKey keys must have same length');
|
|
26
26
|
this.#parent = parent;
|
|
27
27
|
this.#child = child;
|
|
28
28
|
this.#storage = storage;
|
|
@@ -86,64 +86,25 @@ export class Join {
|
|
|
86
86
|
break;
|
|
87
87
|
case 'edit': {
|
|
88
88
|
// When an edit comes in we need to:
|
|
89
|
-
// -
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const newKeyValue = normalizeUndefined(change.row[this.#parentKey]);
|
|
98
|
-
if (newKeyValue !== oldKeyValue) {
|
|
99
|
-
const childrenToRemoveStream = this.#child.cleanup({
|
|
100
|
-
constraint: {
|
|
101
|
-
key: this.#childKey,
|
|
102
|
-
value: oldKeyValue,
|
|
103
|
-
},
|
|
89
|
+
// - If the value of the join key did not change we can forward
|
|
90
|
+
// as an edit but with relationships added
|
|
91
|
+
// - Otherwise we convert to a remove and add
|
|
92
|
+
if (rowEqualsForCompoundKey(change.oldNode.row, change.node.row, this.#parentKey)) {
|
|
93
|
+
this.#output.push({
|
|
94
|
+
type: 'edit',
|
|
95
|
+
oldNode: this.#processParentNode(change.oldNode.row, change.oldNode.relationships, 'cleanup'),
|
|
96
|
+
node: this.#processParentNode(change.node.row, change.node.relationships, 'fetch'),
|
|
104
97
|
});
|
|
105
|
-
for (const childNode of childrenToRemoveStream) {
|
|
106
|
-
this.#output.push({
|
|
107
|
-
type: 'child',
|
|
108
|
-
// This is the new row since we already changed it in the edit above.
|
|
109
|
-
row: change.row,
|
|
110
|
-
child: {
|
|
111
|
-
relationshipName: this.#relationshipName,
|
|
112
|
-
change: {
|
|
113
|
-
type: 'remove',
|
|
114
|
-
node: childNode,
|
|
115
|
-
},
|
|
116
|
-
},
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
const childrenToAddStream = this.#child.fetch({
|
|
120
|
-
constraint: {
|
|
121
|
-
key: this.#childKey,
|
|
122
|
-
value: newKeyValue,
|
|
123
|
-
},
|
|
124
|
-
});
|
|
125
|
-
for (const childNode of childrenToAddStream) {
|
|
126
|
-
this.#output.push({
|
|
127
|
-
type: 'child',
|
|
128
|
-
row: change.row,
|
|
129
|
-
child: {
|
|
130
|
-
relationshipName: this.#relationshipName,
|
|
131
|
-
change: {
|
|
132
|
-
type: 'add',
|
|
133
|
-
node: childNode,
|
|
134
|
-
},
|
|
135
|
-
},
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
98
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
99
|
+
else {
|
|
100
|
+
this.#pushParent({
|
|
101
|
+
type: 'remove',
|
|
102
|
+
node: change.oldNode,
|
|
103
|
+
});
|
|
104
|
+
this.#pushParent({
|
|
105
|
+
type: 'add',
|
|
106
|
+
node: change.node,
|
|
107
|
+
});
|
|
147
108
|
}
|
|
148
109
|
break;
|
|
149
110
|
}
|
|
@@ -155,10 +116,7 @@ export class Join {
|
|
|
155
116
|
const pushChildChange = (childRow, change) => {
|
|
156
117
|
assert(this.#output, 'Output not set');
|
|
157
118
|
const parentNodes = this.#parent.fetch({
|
|
158
|
-
constraint:
|
|
159
|
-
key: this.#parentKey,
|
|
160
|
-
value: childRow[this.#childKey],
|
|
161
|
-
},
|
|
119
|
+
constraint: Object.fromEntries(this.#parentKey.map((key, i) => [key, childRow[this.#childKey[i]]])),
|
|
162
120
|
});
|
|
163
121
|
for (const parentNode of parentNodes) {
|
|
164
122
|
const childChange = {
|
|
@@ -181,10 +139,9 @@ export class Join {
|
|
|
181
139
|
pushChildChange(change.row, change);
|
|
182
140
|
break;
|
|
183
141
|
case 'edit': {
|
|
184
|
-
const childRow = change.row;
|
|
185
|
-
const oldChildRow = change.
|
|
186
|
-
if (
|
|
187
|
-
normalizeUndefined(childRow[this.#childKey])) {
|
|
142
|
+
const childRow = change.node.row;
|
|
143
|
+
const oldChildRow = change.oldNode.row;
|
|
144
|
+
if (rowEqualsForCompoundKey(oldChildRow, childRow, this.#childKey)) {
|
|
188
145
|
// The child row was edited in a way that does not change the relationship.
|
|
189
146
|
// We can therefore just push the change down (wrapped in a child change).
|
|
190
147
|
pushChildChange(childRow, change);
|
|
@@ -193,25 +150,13 @@ export class Join {
|
|
|
193
150
|
// The child row was edited in a way that changes the relationship. We
|
|
194
151
|
// therefore treat this as a remove from the old row followed by an
|
|
195
152
|
// add to the new row.
|
|
196
|
-
const { relationships } = must(first(this.#child.fetch({
|
|
197
|
-
constraint: {
|
|
198
|
-
key: this.#childKey,
|
|
199
|
-
value: oldChildRow[this.#childKey],
|
|
200
|
-
},
|
|
201
|
-
})));
|
|
202
153
|
pushChildChange(oldChildRow, {
|
|
203
154
|
type: 'remove',
|
|
204
|
-
node:
|
|
205
|
-
row: oldChildRow,
|
|
206
|
-
relationships,
|
|
207
|
-
},
|
|
155
|
+
node: change.oldNode,
|
|
208
156
|
});
|
|
209
157
|
pushChildChange(childRow, {
|
|
210
158
|
type: 'add',
|
|
211
|
-
node:
|
|
212
|
-
row: childRow,
|
|
213
|
-
relationships,
|
|
214
|
-
},
|
|
159
|
+
node: change.node,
|
|
215
160
|
});
|
|
216
161
|
}
|
|
217
162
|
break;
|
|
@@ -221,22 +166,21 @@ export class Join {
|
|
|
221
166
|
}
|
|
222
167
|
}
|
|
223
168
|
#processParentNode(parentNodeRow, parentNodeRelations, mode) {
|
|
224
|
-
const parentKeyValue = normalizeUndefined(parentNodeRow[this.#parentKey]);
|
|
225
169
|
// This storage key tracks the primary keys seen for each unique
|
|
226
170
|
// value joined on. This is used to know when to cleanup a child's state.
|
|
227
|
-
const storageKey = makeStorageKey(
|
|
171
|
+
const storageKey = makeStorageKey(this.#parentKey, this.#parent.getSchema().primaryKey, parentNodeRow);
|
|
228
172
|
let method = mode;
|
|
229
173
|
if (mode === 'cleanup') {
|
|
230
174
|
const [, second] = take(this.#storage.scan({
|
|
231
|
-
prefix:
|
|
175
|
+
prefix: makeStorageKeyPrefix(parentNodeRow, this.#parentKey),
|
|
232
176
|
}), 2);
|
|
233
177
|
method = second ? 'fetch' : 'cleanup';
|
|
234
178
|
}
|
|
235
179
|
const childStream = this.#child[method]({
|
|
236
|
-
constraint:
|
|
237
|
-
key
|
|
238
|
-
|
|
239
|
-
|
|
180
|
+
constraint: Object.fromEntries(this.#childKey.map((key, i) => [
|
|
181
|
+
key,
|
|
182
|
+
parentNodeRow[this.#parentKey[i]],
|
|
183
|
+
])),
|
|
240
184
|
});
|
|
241
185
|
if (mode === 'fetch') {
|
|
242
186
|
this.#storage.set(storageKey, true);
|
|
@@ -255,18 +199,28 @@ export class Join {
|
|
|
255
199
|
}
|
|
256
200
|
}
|
|
257
201
|
/** Exported for testing. */
|
|
258
|
-
export function
|
|
202
|
+
export function makeStorageKeyForValues(values) {
|
|
259
203
|
const json = JSON.stringify(['pKeySet', ...values]);
|
|
260
204
|
return json.substring(1, json.length - 1) + ',';
|
|
261
205
|
}
|
|
262
|
-
|
|
263
|
-
|
|
206
|
+
/** Exported for testing. */
|
|
207
|
+
export function makeStorageKeyPrefix(row, key) {
|
|
208
|
+
return makeStorageKeyForValues(key.map(k => row[k]));
|
|
264
209
|
}
|
|
265
|
-
|
|
266
|
-
|
|
210
|
+
/** Exported for testing. */
|
|
211
|
+
export function makeStorageKey(key, primaryKey, row) {
|
|
212
|
+
const values = key.map(k => row[k]);
|
|
267
213
|
for (const key of primaryKey) {
|
|
268
|
-
|
|
214
|
+
values.push(row[key]);
|
|
215
|
+
}
|
|
216
|
+
return makeStorageKeyForValues(values);
|
|
217
|
+
}
|
|
218
|
+
function rowEqualsForCompoundKey(a, b, key) {
|
|
219
|
+
for (let i = 0; i < key.length; i++) {
|
|
220
|
+
if (!valuesEqual(a[key[i]], b[key[i]])) {
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
269
223
|
}
|
|
270
|
-
return
|
|
224
|
+
return true;
|
|
271
225
|
}
|
|
272
226
|
//# sourceMappingURL=join.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"join.js","sourceRoot":"","sources":["../../../../../zql/src/ivm/join.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAE,WAAW,EAAC,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"join.js","sourceRoot":"","sources":["../../../../../zql/src/ivm/join.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maybe-split-and-push-edit-change.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/maybe-split-and-push-edit-change.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,oCAAoC,CAAC;AAC5D,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,eAAe,CAAC;AAE1C;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,EAChC,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"maybe-split-and-push-edit-change.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/maybe-split-and-push-edit-change.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,oCAAoC,CAAC;AAC5D,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,eAAe,CAAC;AAE1C;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,EAChC,MAAM,EAAE,MAAM,QAkBf"}
|
|
@@ -4,30 +4,21 @@
|
|
|
4
4
|
* pushes the appropriate changes to the output based on the predicate.
|
|
5
5
|
*/
|
|
6
6
|
export function maybeSplitAndPushEditChange(change, predicate, output) {
|
|
7
|
-
const oldWasPresent = predicate(change.
|
|
8
|
-
const newIsPresent = predicate(change.row);
|
|
7
|
+
const oldWasPresent = predicate(change.oldNode.row);
|
|
8
|
+
const newIsPresent = predicate(change.node.row);
|
|
9
9
|
if (oldWasPresent && newIsPresent) {
|
|
10
10
|
output.push(change);
|
|
11
11
|
}
|
|
12
12
|
else if (oldWasPresent && !newIsPresent) {
|
|
13
|
-
// The relationships are empty at this point and that is fine since
|
|
14
|
-
// splitAndPushEditChange is only used by operators that are before the Join
|
|
15
|
-
// operator.
|
|
16
13
|
output.push({
|
|
17
14
|
type: 'remove',
|
|
18
|
-
node:
|
|
19
|
-
row: change.oldRow,
|
|
20
|
-
relationships: {},
|
|
21
|
-
},
|
|
15
|
+
node: change.oldNode,
|
|
22
16
|
});
|
|
23
17
|
}
|
|
24
18
|
else if (!oldWasPresent && newIsPresent) {
|
|
25
19
|
output.push({
|
|
26
20
|
type: 'add',
|
|
27
|
-
node:
|
|
28
|
-
row: change.row,
|
|
29
|
-
relationships: {},
|
|
30
|
-
},
|
|
21
|
+
node: change.node,
|
|
31
22
|
});
|
|
32
23
|
}
|
|
33
24
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maybe-split-and-push-edit-change.js","sourceRoot":"","sources":["../../../../../zql/src/ivm/maybe-split-and-push-edit-change.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CACzC,MAAkB,EAClB,SAAgC,EAChC,MAAc;IAEd,MAAM,aAAa,GAAG,SAAS,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"maybe-split-and-push-edit-change.js","sourceRoot":"","sources":["../../../../../zql/src/ivm/maybe-split-and-push-edit-change.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CACzC,MAAkB,EAClB,SAAgC,EAChC,MAAc;IAEd,MAAM,aAAa,GAAG,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpD,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEhD,IAAI,aAAa,IAAI,YAAY,EAAE,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;SAAM,IAAI,aAAa,IAAI,CAAC,YAAY,EAAE,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,MAAM,CAAC,OAAO;SACrB,CAAC,CAAC;IACL,CAAC;SAAM,IAAI,CAAC,aAAa,IAAI,YAAY,EAAE,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,MAAM,CAAC,IAAI;SAClB,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { Condition, Ordering
|
|
1
|
+
import type { Condition, Ordering } from '../../../zero-protocol/src/ast.js';
|
|
2
2
|
import type { Row } from '../../../zero-protocol/src/data.js';
|
|
3
3
|
import type { PrimaryKey } from '../../../zero-protocol/src/primary-key.js';
|
|
4
|
-
import { type Comparator, type Node } from './data.js';
|
|
5
|
-
import type { Constraint, FetchRequest } from './operator.js';
|
|
6
4
|
import type { SchemaValue } from '../../../zero-schema/src/table-schema.js';
|
|
5
|
+
import { type Constraint } from './constraint.js';
|
|
6
|
+
import { type Comparator, type Node } from './data.js';
|
|
7
|
+
import { type FetchRequest } from './operator.js';
|
|
7
8
|
import type { Source, SourceChange, SourceInput } from './source.js';
|
|
8
9
|
import type { Stream } from './stream.js';
|
|
9
10
|
export type Overlay = {
|
|
@@ -56,7 +57,7 @@ export declare function generateWithStart(it: Iterator<Node>, req: FetchRequest,
|
|
|
56
57
|
* @param overlay - the overlay values to splice in
|
|
57
58
|
* @param compare - the comparator to use to find the position for the overlay
|
|
58
59
|
*/
|
|
59
|
-
export declare function generateWithOverlay(startAt: Row | undefined, rows: Iterable<Row>, constraint: Constraint | undefined, overlay: Overlay | undefined, compare: Comparator): Generator<{
|
|
60
|
+
export declare function generateWithOverlay(startAt: Row | undefined, rows: Iterable<Row>, constraint: Constraint | undefined, overlay: Overlay | undefined, compare: Comparator, filterPredicate?: (row: Row) => boolean | undefined): Generator<{
|
|
60
61
|
row: Record<string, import("../../../shared/src/json.js").ReadonlyJSONValue | undefined>;
|
|
61
62
|
relationships: {};
|
|
62
63
|
}, void, unknown>;
|
|
@@ -68,22 +69,4 @@ export declare function generateWithOverlayInner(rowIterator: Iterable<Row>, ove
|
|
|
68
69
|
row: Record<string, import("../../../shared/src/json.js").ReadonlyJSONValue | undefined>;
|
|
69
70
|
relationships: {};
|
|
70
71
|
}, void, unknown>;
|
|
71
|
-
/**
|
|
72
|
-
* Only returns optional filters if:
|
|
73
|
-
* 1. It's a simple condition
|
|
74
|
-
* 2. It's an `and` condition with only simple conditions inside of it
|
|
75
|
-
* 3. It's an `or` that is a no-op.
|
|
76
|
-
*
|
|
77
|
-
* Otherwise the filters are dropped.
|
|
78
|
-
*
|
|
79
|
-
* This is a short term solution until we update `fetch` to pass
|
|
80
|
-
* the constraints rather than making them static in `connect`.
|
|
81
|
-
*
|
|
82
|
-
* The below way of doing things over-fetches as the optional filters
|
|
83
|
-
* are widened to cover all branches of the pipeline.
|
|
84
|
-
*/
|
|
85
|
-
export declare function filterOptionalFilters(optionalFilters: Condition | undefined): {
|
|
86
|
-
filters: SimpleCondition[];
|
|
87
|
-
allApplied: boolean;
|
|
88
|
-
};
|
|
89
72
|
//# sourceMappingURL=memory-source.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-source.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/memory-source.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"memory-source.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/memory-source.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,SAAS,EACT,QAAQ,EAET,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAC,GAAG,EAAQ,MAAM,oCAAoC,CAAC;AACnE,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,2CAA2C,CAAC;AAC1E,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,0CAA0C,CAAC;AAQ1E,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAGL,KAAK,UAAU,EACf,KAAK,IAAI,EACV,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAC,KAAK,YAAY,EAA0B,MAAM,eAAe,CAAC;AAEzE,OAAO,KAAK,EAAC,MAAM,EAAE,YAAY,EAAE,WAAW,EAAC,MAAM,aAAa,CAAC;AACnE,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AAExC,MAAM,MAAM,OAAO,GAAG;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,YAAY,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,GAAG,EAAE,GAAG,GAAG,SAAS,CAAC;IACrB,MAAM,EAAE,GAAG,GAAG,SAAS,CAAC;CACzB,CAAC;AAqBF;;;;;;GAMG;AACH,qBAAa,YAAa,YAAW,MAAM;;gBAWvC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACpC,UAAU,EAAE,UAAU;IAgBxB,aAAa;;;;;IAoBb,OAAO,CACL,IAAI,EAAE,QAAQ,EACd,eAAe,CAAC,EAAE,SAAS,GAAG,SAAS,GACtC,WAAW;IA4Fd,YAAY,IAAI,MAAM,EAAE;IAuIxB,IAAI,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;CAkFjC;AAsBD;;;;;;;;;GASG;AACH,wBAAiB,iBAAiB,CAChC,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,EAClB,GAAG,EAAE,YAAY,EACjB,OAAO,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,KAAK,MAAM,GACpC,MAAM,CAAC,IAAI,CAAC,CA0Bd;AAED;;;;;;;;;;;GAWG;AACH,wBAAiB,mBAAmB,CAClC,OAAO,EAAE,GAAG,GAAG,SAAS,EACxB,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,EACnB,UAAU,EAAE,UAAU,GAAG,SAAS,EAClC,OAAO,EAAE,OAAO,GAAG,SAAS,EAC5B,OAAO,EAAE,UAAU,EACnB,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,GAAG,SAAS;;;kBAUpD;AAiDD,OAAO,EAAC,kBAAkB,IAAI,yBAAyB,EAAC,CAAC;AAEzD,iBAAS,kBAAkB,CACzB,EAAC,GAAG,EAAE,MAAM,EAAC,EAAE,QAAQ,EACvB,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,UAAU,GAClB,QAAQ,CAOV;AAED,OAAO,EAAC,qBAAqB,IAAI,4BAA4B,EAAC,CAAC;AAE/D,iBAAS,qBAAqB,CAC5B,EAAC,GAAG,EAAE,MAAM,EAAC,EAAE,QAAQ,EACvB,UAAU,EAAE,UAAU,GACrB,QAAQ,CAUV;AAeD,wBAAiB,wBAAwB,CACvC,WAAW,EAAE,QAAQ,CAAC,GAAG,CAAC,EAC1B,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,KAAK,MAAM;;;kBA0BtC"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { BTree } from '../../../btree/src/mod.js';
|
|
2
2
|
import { assert, unreachable } from '../../../shared/src/asserts.js';
|
|
3
|
+
import { hasOwn } from '../../../shared/src/has-own.js';
|
|
3
4
|
import { assertOrderingIncludesPK } from '../builder/builder.js';
|
|
4
|
-
import { createPredicate } from '../builder/filter.js';
|
|
5
|
-
import {
|
|
5
|
+
import { createPredicate, transformFilters, } from '../builder/filter.js';
|
|
6
|
+
import { constraintMatchesPrimaryKey, constraintMatchesRow, } from './constraint.js';
|
|
7
|
+
import { compareValues, makeComparator, } from './data.js';
|
|
6
8
|
import { LookaheadIterator } from './lookahead-iterator.js';
|
|
9
|
+
import {} from './operator.js';
|
|
7
10
|
/**
|
|
8
11
|
* A `MemorySource` is a source that provides data to the pipeline from an
|
|
9
12
|
* in-memory data source.
|
|
@@ -52,8 +55,7 @@ export class MemorySource {
|
|
|
52
55
|
};
|
|
53
56
|
}
|
|
54
57
|
connect(sort, optionalFilters) {
|
|
55
|
-
const
|
|
56
|
-
const predicates = filteredOptionalFilters.filters.map(c => createPredicate(c));
|
|
58
|
+
const transformedFilters = transformFilters(optionalFilters);
|
|
57
59
|
const input = {
|
|
58
60
|
getSchema: () => schema,
|
|
59
61
|
fetch: req => this.#fetch(req, connection),
|
|
@@ -64,14 +66,19 @@ export class MemorySource {
|
|
|
64
66
|
destroy: () => {
|
|
65
67
|
this.#disconnect(input);
|
|
66
68
|
},
|
|
67
|
-
appliedFilters:
|
|
69
|
+
appliedFilters: !transformedFilters.conditionsRemoved,
|
|
68
70
|
};
|
|
69
71
|
const connection = {
|
|
70
72
|
input,
|
|
71
73
|
output: undefined,
|
|
72
74
|
sort,
|
|
73
75
|
compareRows: makeComparator(sort),
|
|
74
|
-
|
|
76
|
+
filters: transformedFilters.filters
|
|
77
|
+
? {
|
|
78
|
+
condition: transformedFilters.filters,
|
|
79
|
+
predicate: createPredicate(transformedFilters.filters),
|
|
80
|
+
}
|
|
81
|
+
: undefined,
|
|
75
82
|
};
|
|
76
83
|
const schema = this.#getSchema(connection);
|
|
77
84
|
assertOrderingIncludesPK(sort, this.#primaryKey);
|
|
@@ -139,13 +146,16 @@ export class MemorySource {
|
|
|
139
146
|
// If there is a constraint, we need an index sorted by it first.
|
|
140
147
|
const indexSort = [];
|
|
141
148
|
if (req.constraint) {
|
|
142
|
-
|
|
149
|
+
for (const key of Object.keys(req.constraint)) {
|
|
150
|
+
indexSort.push([key, 'asc']);
|
|
151
|
+
}
|
|
143
152
|
}
|
|
144
153
|
// For the special case of constraining by PK, we don't need to worry about
|
|
145
154
|
// any requested sort since there can only be one result. Otherwise we also
|
|
146
155
|
// need the index sorted by the requested sort.
|
|
147
156
|
if (this.#primaryKey.length > 1 ||
|
|
148
|
-
req.constraint
|
|
157
|
+
!req.constraint ||
|
|
158
|
+
!constraintMatchesPrimaryKey(req.constraint, this.#primaryKey)) {
|
|
149
159
|
indexSort.push(...requestedSort);
|
|
150
160
|
}
|
|
151
161
|
const index = this.#getOrCreateIndex(indexSort, from);
|
|
@@ -158,23 +168,14 @@ export class MemorySource {
|
|
|
158
168
|
overlay = this.#overlay;
|
|
159
169
|
}
|
|
160
170
|
}
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
const matchesConstraintAndFilters = (row) => matchesConstraint(row) && matchesFilters(row);
|
|
170
|
-
// If there is an overlay for this output, does it match the requested
|
|
171
|
-
// constraints and filters?
|
|
172
|
-
if (overlay) {
|
|
173
|
-
// TODO: This looks wrong given that we can have edit changes in the overlay.
|
|
174
|
-
if (!matchesConstraintAndFilters(overlay.change.row)) {
|
|
175
|
-
overlay = undefined;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
171
|
+
const { constraint } = req;
|
|
172
|
+
const matchesConstraint = constraint
|
|
173
|
+
? (row) => constraintMatchesRow(constraint, row)
|
|
174
|
+
: (_) => true;
|
|
175
|
+
const predicate = conn.filters?.predicate;
|
|
176
|
+
const matchesConstraintAndFilters = predicate
|
|
177
|
+
? (row) => matchesConstraint(row) && predicate(row)
|
|
178
|
+
: matchesConstraint;
|
|
178
179
|
const nextLowerKey = (row) => {
|
|
179
180
|
if (!row) {
|
|
180
181
|
return undefined;
|
|
@@ -202,9 +203,7 @@ export class MemorySource {
|
|
|
202
203
|
// There's no problem supporting startAt outside of constraints, but I
|
|
203
204
|
// don't think we have a use case for this – if we see it, it's probably
|
|
204
205
|
// a bug.
|
|
205
|
-
|
|
206
|
-
assert(false, 'Start row must match constraint');
|
|
207
|
-
}
|
|
206
|
+
assert(matchesConstraint(startAt), 'Start row must match constraint');
|
|
208
207
|
}
|
|
209
208
|
if (req.start.basis === 'before') {
|
|
210
209
|
startAt = nextLowerKey(startAt);
|
|
@@ -224,8 +223,8 @@ export class MemorySource {
|
|
|
224
223
|
if (req.constraint) {
|
|
225
224
|
scanStart = {};
|
|
226
225
|
for (const [key, dir] of indexSort) {
|
|
227
|
-
if (
|
|
228
|
-
scanStart[key] = req.constraint
|
|
226
|
+
if (hasOwn(req.constraint, key)) {
|
|
227
|
+
scanStart[key] = req.constraint[key];
|
|
229
228
|
}
|
|
230
229
|
else {
|
|
231
230
|
scanStart[key] = dir === 'asc' ? minValue : maxValue;
|
|
@@ -238,10 +237,10 @@ export class MemorySource {
|
|
|
238
237
|
const withOverlay = generateWithOverlay(startAt,
|
|
239
238
|
// 😬 - btree library doesn't support ideas like start "before" this
|
|
240
239
|
// key.
|
|
241
|
-
data.keys(scanStart), req.constraint, overlay, comparator);
|
|
240
|
+
data.keys(scanStart), req.constraint, overlay, comparator, conn.filters?.predicate);
|
|
242
241
|
const withConstraint = generateWithConstraint(generateWithStart(withOverlay, req, comparator), req.constraint);
|
|
243
|
-
yield* conn.
|
|
244
|
-
? generateWithFilter(withConstraint,
|
|
242
|
+
yield* conn.filters
|
|
243
|
+
? generateWithFilter(withConstraint, conn.filters.predicate)
|
|
245
244
|
: withConstraint;
|
|
246
245
|
}
|
|
247
246
|
#cleanup(req, connection) {
|
|
@@ -253,24 +252,34 @@ export class MemorySource {
|
|
|
253
252
|
switch (change.type) {
|
|
254
253
|
case 'add':
|
|
255
254
|
if (data.has(change.row)) {
|
|
256
|
-
throw new Error(`Row already exists
|
|
255
|
+
throw new Error(`Row already exists ${JSON.stringify(change)}`);
|
|
257
256
|
}
|
|
258
257
|
break;
|
|
259
258
|
case 'remove':
|
|
260
259
|
if (!data.has(change.row)) {
|
|
261
|
-
throw new Error(`Row not found
|
|
260
|
+
throw new Error(`Row not found ${JSON.stringify(change)}`);
|
|
262
261
|
}
|
|
263
262
|
break;
|
|
264
263
|
case 'edit':
|
|
265
264
|
if (!data.has(change.oldRow)) {
|
|
266
|
-
throw new Error(`Row not found
|
|
265
|
+
throw new Error(`Row not found ${JSON.stringify(change)}`);
|
|
267
266
|
}
|
|
268
267
|
break;
|
|
269
268
|
default:
|
|
270
269
|
unreachable(change);
|
|
271
270
|
}
|
|
272
271
|
const outputChange = change.type === 'edit'
|
|
273
|
-
?
|
|
272
|
+
? {
|
|
273
|
+
type: change.type,
|
|
274
|
+
oldNode: {
|
|
275
|
+
row: change.oldRow,
|
|
276
|
+
relationships: {},
|
|
277
|
+
},
|
|
278
|
+
node: {
|
|
279
|
+
row: change.row,
|
|
280
|
+
relationships: {},
|
|
281
|
+
},
|
|
282
|
+
}
|
|
274
283
|
: {
|
|
275
284
|
type: change.type,
|
|
276
285
|
node: {
|
|
@@ -318,8 +327,7 @@ export class MemorySource {
|
|
|
318
327
|
}
|
|
319
328
|
function* generateWithConstraint(it, constraint) {
|
|
320
329
|
for (const node of it) {
|
|
321
|
-
if (constraint &&
|
|
322
|
-
!valuesEqual(node.row[constraint.key], constraint.value)) {
|
|
330
|
+
if (constraint && !constraintMatchesRow(constraint, node.row)) {
|
|
323
331
|
break;
|
|
324
332
|
}
|
|
325
333
|
yield node;
|
|
@@ -382,11 +390,11 @@ export function* generateWithStart(it, req, compare) {
|
|
|
382
390
|
* @param overlay - the overlay values to splice in
|
|
383
391
|
* @param compare - the comparator to use to find the position for the overlay
|
|
384
392
|
*/
|
|
385
|
-
export function* generateWithOverlay(startAt, rows, constraint, overlay, compare) {
|
|
386
|
-
const overlays = computeOverlays(startAt, constraint, overlay, compare);
|
|
393
|
+
export function* generateWithOverlay(startAt, rows, constraint, overlay, compare, filterPredicate) {
|
|
394
|
+
const overlays = computeOverlays(startAt, constraint, overlay, compare, filterPredicate);
|
|
387
395
|
yield* generateWithOverlayInner(rows, overlays, compare);
|
|
388
396
|
}
|
|
389
|
-
function computeOverlays(startAt, constraint, overlay, compare) {
|
|
397
|
+
function computeOverlays(startAt, constraint, overlay, compare, filterPredicate) {
|
|
390
398
|
let overlays = {
|
|
391
399
|
add: undefined,
|
|
392
400
|
remove: undefined,
|
|
@@ -417,6 +425,9 @@ function computeOverlays(startAt, constraint, overlay, compare) {
|
|
|
417
425
|
if (constraint) {
|
|
418
426
|
overlays = overlaysForConstraint(overlays, constraint);
|
|
419
427
|
}
|
|
428
|
+
if (filterPredicate) {
|
|
429
|
+
overlays = overlaysForFilterPredicate(overlays, filterPredicate);
|
|
430
|
+
}
|
|
420
431
|
return overlays;
|
|
421
432
|
}
|
|
422
433
|
export { overlaysForStartAt as overlaysForStartAtForTest };
|
|
@@ -429,7 +440,7 @@ function overlaysForStartAt({ add, remove }, startAt, compare) {
|
|
|
429
440
|
}
|
|
430
441
|
export { overlaysForConstraint as overlaysForConstraintForTest };
|
|
431
442
|
function overlaysForConstraint({ add, remove }, constraint) {
|
|
432
|
-
const undefinedIfDoesntMatchConstraint = (row) => row === undefined || !
|
|
443
|
+
const undefinedIfDoesntMatchConstraint = (row) => row === undefined || !constraintMatchesRow(constraint, row)
|
|
433
444
|
? undefined
|
|
434
445
|
: row;
|
|
435
446
|
return {
|
|
@@ -437,6 +448,13 @@ function overlaysForConstraint({ add, remove }, constraint) {
|
|
|
437
448
|
remove: undefinedIfDoesntMatchConstraint(remove),
|
|
438
449
|
};
|
|
439
450
|
}
|
|
451
|
+
function overlaysForFilterPredicate({ add, remove }, filterPredicate) {
|
|
452
|
+
const undefinedIfDoesntMatchFilter = (row) => row === undefined || !filterPredicate(row) ? undefined : row;
|
|
453
|
+
return {
|
|
454
|
+
add: undefinedIfDoesntMatchFilter(add),
|
|
455
|
+
remove: undefinedIfDoesntMatchFilter(remove),
|
|
456
|
+
};
|
|
457
|
+
}
|
|
440
458
|
export function* generateWithOverlayInner(rowIterator, overlays, compare) {
|
|
441
459
|
let addOverlayYielded = false;
|
|
442
460
|
let removeOverlaySkipped = false;
|
|
@@ -494,44 +512,4 @@ function compareBounds(a, b) {
|
|
|
494
512
|
}
|
|
495
513
|
return compareValues(a, b);
|
|
496
514
|
}
|
|
497
|
-
/**
|
|
498
|
-
* Only returns optional filters if:
|
|
499
|
-
* 1. It's a simple condition
|
|
500
|
-
* 2. It's an `and` condition with only simple conditions inside of it
|
|
501
|
-
* 3. It's an `or` that is a no-op.
|
|
502
|
-
*
|
|
503
|
-
* Otherwise the filters are dropped.
|
|
504
|
-
*
|
|
505
|
-
* This is a short term solution until we update `fetch` to pass
|
|
506
|
-
* the constraints rather than making them static in `connect`.
|
|
507
|
-
*
|
|
508
|
-
* The below way of doing things over-fetches as the optional filters
|
|
509
|
-
* are widened to cover all branches of the pipeline.
|
|
510
|
-
*/
|
|
511
|
-
export function filterOptionalFilters(optionalFilters) {
|
|
512
|
-
if (optionalFilters) {
|
|
513
|
-
if (optionalFilters.type === 'or' &&
|
|
514
|
-
optionalFilters.conditions.length === 1) {
|
|
515
|
-
optionalFilters = optionalFilters.conditions[0];
|
|
516
|
-
}
|
|
517
|
-
if (optionalFilters.type === 'and') {
|
|
518
|
-
const filters = optionalFilters.conditions.filter(c => c.type === 'simple');
|
|
519
|
-
return {
|
|
520
|
-
filters,
|
|
521
|
-
allApplied: filters.length === optionalFilters.conditions.length,
|
|
522
|
-
};
|
|
523
|
-
}
|
|
524
|
-
if (optionalFilters.type === 'simple') {
|
|
525
|
-
return {
|
|
526
|
-
filters: [optionalFilters],
|
|
527
|
-
allApplied: true,
|
|
528
|
-
};
|
|
529
|
-
}
|
|
530
|
-
return { filters: [], allApplied: false };
|
|
531
|
-
}
|
|
532
|
-
return {
|
|
533
|
-
filters: [],
|
|
534
|
-
allApplied: true,
|
|
535
|
-
};
|
|
536
|
-
}
|
|
537
515
|
//# sourceMappingURL=memory-source.js.map
|