@rocicorp/zero 0.17.2025031900 → 0.17.2025032000
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-7ARRNDLF.js → chunk-MJCITZ5S.js} +103 -104
- package/out/chunk-MJCITZ5S.js.map +7 -0
- package/out/{chunk-VEVC5RHF.js → chunk-OI2PV2HL.js} +33 -22
- package/out/{chunk-VEVC5RHF.js.map → chunk-OI2PV2HL.js.map} +2 -2
- package/out/solid.js +4 -25
- package/out/solid.js.map +2 -2
- package/out/zero-cache/src/workers/syncer.d.ts +1 -1
- package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer.js +1 -0
- package/out/zero-cache/src/workers/syncer.js.map +1 -1
- package/out/zero-solid/src/solid-view.d.ts.map +1 -1
- package/out/zero.js +2 -2
- package/out/zql/src/ivm/array-view.d.ts.map +1 -1
- package/out/zql/src/ivm/array-view.js +2 -3
- package/out/zql/src/ivm/array-view.js.map +1 -1
- package/out/zql/src/ivm/schema.d.ts +2 -2
- package/out/zql/src/ivm/schema.d.ts.map +1 -1
- package/out/zql/src/ivm/take.d.ts +3 -0
- package/out/zql/src/ivm/take.d.ts.map +1 -1
- package/out/zql/src/ivm/take.js +33 -7
- package/out/zql/src/ivm/take.js.map +1 -1
- package/out/zql/src/ivm/view-apply-change.d.ts +5 -1
- package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
- package/out/zql/src/ivm/view-apply-change.js +83 -106
- package/out/zql/src/ivm/view-apply-change.js.map +1 -1
- package/package.json +1 -1
- package/out/chunk-7ARRNDLF.js.map +0 -7
package/out/advanced.js
CHANGED
|
@@ -117,7 +117,8 @@ function drainStreams(node) {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
// ../zql/src/ivm/view-apply-change.ts
|
|
120
|
-
|
|
120
|
+
var refCountSymbol = Symbol("rc");
|
|
121
|
+
function applyChange(parentEntry, change, schema, relationship, format) {
|
|
121
122
|
if (schema.isHidden) {
|
|
122
123
|
switch (change.type) {
|
|
123
124
|
case "add":
|
|
@@ -132,8 +133,7 @@ function applyChange(parentEntry, change, schema, relationship, format, refCount
|
|
|
132
133
|
{ type: change.type, node },
|
|
133
134
|
childSchema,
|
|
134
135
|
relationship2,
|
|
135
|
-
format
|
|
136
|
-
refCountMap
|
|
136
|
+
format
|
|
137
137
|
);
|
|
138
138
|
}
|
|
139
139
|
}
|
|
@@ -149,8 +149,7 @@ function applyChange(parentEntry, change, schema, relationship, format, refCount
|
|
|
149
149
|
change.child.change,
|
|
150
150
|
childSchema,
|
|
151
151
|
relationship,
|
|
152
|
-
format
|
|
153
|
-
refCountMap
|
|
152
|
+
format
|
|
154
153
|
);
|
|
155
154
|
return;
|
|
156
155
|
}
|
|
@@ -161,36 +160,25 @@ function applyChange(parentEntry, change, schema, relationship, format, refCount
|
|
|
161
160
|
const { singular, relationships: childFormats } = format;
|
|
162
161
|
switch (change.type) {
|
|
163
162
|
case "add": {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
};
|
|
163
|
+
let newEntry;
|
|
164
|
+
let rc = 1;
|
|
167
165
|
if (singular) {
|
|
168
166
|
const oldEntry = parentEntry[relationship];
|
|
169
167
|
if (oldEntry !== void 0) {
|
|
170
168
|
assert(
|
|
171
|
-
schema.compareRows(oldEntry,
|
|
169
|
+
schema.compareRows(oldEntry, change.node.row) === 0,
|
|
172
170
|
"single output already exists"
|
|
173
171
|
);
|
|
174
|
-
|
|
175
|
-
refCountMap.delete(oldEntry);
|
|
176
|
-
parentEntry[relationship] = newEntry;
|
|
177
|
-
refCountMap.set(newEntry, rc + 1);
|
|
178
|
-
} else {
|
|
179
|
-
parentEntry[relationship] = newEntry;
|
|
180
|
-
refCountMap.set(newEntry, 1);
|
|
172
|
+
rc = oldEntry[refCountSymbol] + 1;
|
|
181
173
|
}
|
|
174
|
+
newEntry = makeNewEntryWithRefCount(change.node.row, rc);
|
|
175
|
+
parentEntry[relationship] = newEntry;
|
|
182
176
|
} else {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
deleteCount = 1;
|
|
189
|
-
rc = must(refCountMap.get(view[pos])) + 1;
|
|
190
|
-
refCountMap.delete(view[pos]);
|
|
191
|
-
}
|
|
192
|
-
view.splice(pos, deleteCount, newEntry);
|
|
193
|
-
refCountMap.set(newEntry, rc);
|
|
177
|
+
newEntry = makeNewEntryAndInsert(
|
|
178
|
+
change.node.row,
|
|
179
|
+
getChildEntryList(parentEntry, relationship),
|
|
180
|
+
schema.compareRows
|
|
181
|
+
);
|
|
194
182
|
}
|
|
195
183
|
for (const [relationship2, children] of Object.entries(
|
|
196
184
|
change.node.relationships
|
|
@@ -208,8 +196,7 @@ function applyChange(parentEntry, change, schema, relationship, format, refCount
|
|
|
208
196
|
{ type: "add", node },
|
|
209
197
|
childSchema,
|
|
210
198
|
relationship2,
|
|
211
|
-
childFormat
|
|
212
|
-
refCountMap
|
|
199
|
+
childFormat
|
|
213
200
|
);
|
|
214
201
|
}
|
|
215
202
|
}
|
|
@@ -219,28 +206,17 @@ function applyChange(parentEntry, change, schema, relationship, format, refCount
|
|
|
219
206
|
if (singular) {
|
|
220
207
|
const oldEntry = parentEntry[relationship];
|
|
221
208
|
assert(oldEntry !== void 0, "node does not exist");
|
|
222
|
-
const rc =
|
|
209
|
+
const rc = oldEntry[refCountSymbol];
|
|
223
210
|
if (rc === 1) {
|
|
224
|
-
refCountMap.delete(oldEntry);
|
|
225
211
|
parentEntry[relationship] = void 0;
|
|
226
|
-
} else {
|
|
227
|
-
refCountMap.set(oldEntry, rc - 1);
|
|
228
212
|
}
|
|
213
|
+
oldEntry[refCountSymbol]--;
|
|
229
214
|
} else {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
view,
|
|
215
|
+
removeAndUpdateRefCount(
|
|
216
|
+
getChildEntryList(parentEntry, relationship),
|
|
233
217
|
change.node.row,
|
|
234
218
|
schema.compareRows
|
|
235
219
|
);
|
|
236
|
-
assert(found, "node does not exist");
|
|
237
|
-
const rc = must(refCountMap.get(view[pos]));
|
|
238
|
-
if (rc === 1) {
|
|
239
|
-
refCountMap.delete(view[pos]);
|
|
240
|
-
view.splice(pos, 1);
|
|
241
|
-
} else {
|
|
242
|
-
refCountMap.set(view[pos], rc - 1);
|
|
243
|
-
}
|
|
244
220
|
}
|
|
245
221
|
drainStreams(change.node);
|
|
246
222
|
break;
|
|
@@ -248,8 +224,7 @@ function applyChange(parentEntry, change, schema, relationship, format, refCount
|
|
|
248
224
|
case "child": {
|
|
249
225
|
let existing;
|
|
250
226
|
if (singular) {
|
|
251
|
-
|
|
252
|
-
existing = parentEntry[relationship];
|
|
227
|
+
existing = getSingularEntry(parentEntry, relationship);
|
|
253
228
|
} else {
|
|
254
229
|
const view = getChildEntryList(parentEntry, relationship);
|
|
255
230
|
const { pos, found } = binarySearch(
|
|
@@ -270,8 +245,7 @@ function applyChange(parentEntry, change, schema, relationship, format, refCount
|
|
|
270
245
|
change.child.change,
|
|
271
246
|
childSchema,
|
|
272
247
|
change.child.relationshipName,
|
|
273
|
-
childFormat
|
|
274
|
-
refCountMap
|
|
248
|
+
childFormat
|
|
275
249
|
);
|
|
276
250
|
}
|
|
277
251
|
break;
|
|
@@ -279,70 +253,47 @@ function applyChange(parentEntry, change, schema, relationship, format, refCount
|
|
|
279
253
|
case "edit": {
|
|
280
254
|
if (singular) {
|
|
281
255
|
const existing = parentEntry[relationship];
|
|
282
|
-
|
|
283
|
-
const rc =
|
|
256
|
+
assertRCEntry(existing);
|
|
257
|
+
const rc = existing[refCountSymbol];
|
|
284
258
|
const newEntry = {
|
|
285
259
|
...existing,
|
|
286
|
-
...change.node.row
|
|
260
|
+
...change.node.row,
|
|
261
|
+
[refCountSymbol]: rc
|
|
287
262
|
};
|
|
288
|
-
|
|
289
|
-
refCountMap.delete(existing);
|
|
263
|
+
existing[refCountSymbol] = 0;
|
|
290
264
|
parentEntry[relationship] = newEntry;
|
|
291
265
|
} else {
|
|
292
|
-
const view = parentEntry
|
|
293
|
-
assertEntryList(view);
|
|
266
|
+
const view = getChildEntryList(parentEntry, relationship);
|
|
294
267
|
if (schema.compareRows(change.oldNode.row, change.node.row) === 0) {
|
|
295
268
|
const { pos, found } = binarySearch(
|
|
296
269
|
view,
|
|
297
270
|
change.oldNode.row,
|
|
298
271
|
schema.compareRows
|
|
299
272
|
);
|
|
300
|
-
assert(found, "node does not
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
|
|
273
|
+
assert(found, "node does not exist");
|
|
274
|
+
const oldEntry = view[pos];
|
|
275
|
+
const rc = oldEntry[refCountSymbol];
|
|
276
|
+
oldEntry[refCountSymbol] = 0;
|
|
277
|
+
const newEntry = makeEntryPreserveRelationships(
|
|
304
278
|
change.node.row,
|
|
305
|
-
|
|
306
|
-
format.relationships
|
|
279
|
+
oldEntry,
|
|
280
|
+
format.relationships,
|
|
281
|
+
rc
|
|
307
282
|
);
|
|
308
|
-
|
|
283
|
+
view[pos] = newEntry;
|
|
309
284
|
} else {
|
|
310
|
-
const
|
|
285
|
+
const oldEntry = removeAndUpdateRefCount(
|
|
311
286
|
view,
|
|
312
287
|
change.oldNode.row,
|
|
313
288
|
schema.compareRows
|
|
314
289
|
);
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
refCountMap.set(oldEntry, rc - 1);
|
|
323
|
-
}
|
|
324
|
-
{
|
|
325
|
-
const { pos: pos2, found: found2 } = binarySearch(
|
|
326
|
-
view,
|
|
327
|
-
change.node.row,
|
|
328
|
-
schema.compareRows
|
|
329
|
-
);
|
|
330
|
-
let rc2 = 1;
|
|
331
|
-
const newEntry = makeEntryPreserveRelationships(
|
|
332
|
-
change.node.row,
|
|
333
|
-
oldEntry,
|
|
334
|
-
format.relationships
|
|
335
|
-
);
|
|
336
|
-
let deleteCount = 0;
|
|
337
|
-
if (found2) {
|
|
338
|
-
deleteCount = 1;
|
|
339
|
-
const existing = view[pos2];
|
|
340
|
-
rc2 = must(refCountMap.get(existing)) + 1;
|
|
341
|
-
refCountMap.delete(existing);
|
|
342
|
-
}
|
|
343
|
-
view.splice(pos2, deleteCount, newEntry);
|
|
344
|
-
refCountMap.set(newEntry, rc2);
|
|
345
|
-
}
|
|
290
|
+
insertAndSetRefCount(
|
|
291
|
+
view,
|
|
292
|
+
change.node.row,
|
|
293
|
+
oldEntry,
|
|
294
|
+
format.relationships,
|
|
295
|
+
schema.compareRows
|
|
296
|
+
);
|
|
346
297
|
}
|
|
347
298
|
}
|
|
348
299
|
break;
|
|
@@ -351,6 +302,49 @@ function applyChange(parentEntry, change, schema, relationship, format, refCount
|
|
|
351
302
|
unreachable(change);
|
|
352
303
|
}
|
|
353
304
|
}
|
|
305
|
+
function makeNewEntryAndInsert(newRow, view, compareRows) {
|
|
306
|
+
const { pos, found } = binarySearch(view, newRow, compareRows);
|
|
307
|
+
let deleteCount = 0;
|
|
308
|
+
let rc = 1;
|
|
309
|
+
if (found) {
|
|
310
|
+
deleteCount = 1;
|
|
311
|
+
rc = view[pos][refCountSymbol];
|
|
312
|
+
view[pos][refCountSymbol] = rc - 1;
|
|
313
|
+
rc++;
|
|
314
|
+
}
|
|
315
|
+
const newEntry = makeNewEntryWithRefCount(newRow, rc);
|
|
316
|
+
view.splice(pos, deleteCount, newEntry);
|
|
317
|
+
return newEntry;
|
|
318
|
+
}
|
|
319
|
+
function insertAndSetRefCount(view, newRow, oldEntry, relationships, compareRows) {
|
|
320
|
+
const { pos, found } = binarySearch(view, newRow, compareRows);
|
|
321
|
+
let deleteCount = 0;
|
|
322
|
+
let rc = 1;
|
|
323
|
+
if (found) {
|
|
324
|
+
deleteCount = 1;
|
|
325
|
+
const oldEntry2 = view[pos];
|
|
326
|
+
rc = oldEntry2[refCountSymbol] + 1;
|
|
327
|
+
oldEntry2[refCountSymbol] = 0;
|
|
328
|
+
}
|
|
329
|
+
const newEntry = makeEntryPreserveRelationships(
|
|
330
|
+
newRow,
|
|
331
|
+
oldEntry,
|
|
332
|
+
relationships,
|
|
333
|
+
rc
|
|
334
|
+
);
|
|
335
|
+
view.splice(pos, deleteCount, newEntry);
|
|
336
|
+
}
|
|
337
|
+
function removeAndUpdateRefCount(view, row, compareRows) {
|
|
338
|
+
const { pos, found } = binarySearch(view, row, compareRows);
|
|
339
|
+
assert(found, "node does not exist");
|
|
340
|
+
const oldEntry = view[pos];
|
|
341
|
+
const rc = oldEntry[refCountSymbol];
|
|
342
|
+
if (rc === 1) {
|
|
343
|
+
view.splice(pos, 1);
|
|
344
|
+
}
|
|
345
|
+
oldEntry[refCountSymbol]--;
|
|
346
|
+
return oldEntry;
|
|
347
|
+
}
|
|
354
348
|
function binarySearch(view, target, comparator) {
|
|
355
349
|
let low = 0;
|
|
356
350
|
let high = view.length - 1;
|
|
@@ -367,24 +361,29 @@ function binarySearch(view, target, comparator) {
|
|
|
367
361
|
}
|
|
368
362
|
return { pos: low, found: false };
|
|
369
363
|
}
|
|
370
|
-
function makeEntryPreserveRelationships(
|
|
371
|
-
const
|
|
364
|
+
function makeEntryPreserveRelationships(newRow, oldEntry, relationships, rc) {
|
|
365
|
+
const entry = makeNewEntryWithRefCount(newRow, rc);
|
|
372
366
|
for (const relationship in relationships) {
|
|
373
|
-
assert(!(relationship in
|
|
374
|
-
|
|
367
|
+
assert(!(relationship in newRow), "Relationship already exists");
|
|
368
|
+
entry[relationship] = oldEntry[relationship];
|
|
375
369
|
}
|
|
376
|
-
return
|
|
370
|
+
return entry;
|
|
377
371
|
}
|
|
378
372
|
function getChildEntryList(parentEntry, relationship) {
|
|
379
373
|
const view = parentEntry[relationship];
|
|
380
374
|
assertArray(view);
|
|
381
375
|
return view;
|
|
382
376
|
}
|
|
383
|
-
function
|
|
384
|
-
|
|
377
|
+
function assertRCEntry(v) {
|
|
378
|
+
assertNumber(v[refCountSymbol]);
|
|
379
|
+
}
|
|
380
|
+
function getSingularEntry(parentEntry, relationship) {
|
|
381
|
+
const e = parentEntry[relationship];
|
|
382
|
+
assertNumber(e[refCountSymbol]);
|
|
383
|
+
return e;
|
|
385
384
|
}
|
|
386
|
-
function
|
|
387
|
-
|
|
385
|
+
function makeNewEntryWithRefCount(row, rc) {
|
|
386
|
+
return { ...row, [refCountSymbol]: rc };
|
|
388
387
|
}
|
|
389
388
|
|
|
390
389
|
export {
|
|
@@ -405,4 +404,4 @@ export {
|
|
|
405
404
|
drainStreams,
|
|
406
405
|
applyChange
|
|
407
406
|
};
|
|
408
|
-
//# sourceMappingURL=chunk-
|
|
407
|
+
//# sourceMappingURL=chunk-MJCITZ5S.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../shared/src/asserts.ts", "../../shared/src/must.ts", "../../zql/src/ivm/data.ts", "../../zql/src/ivm/view-apply-change.ts"],
|
|
4
|
+
"sourcesContent": ["export function assert(\n b: unknown,\n msg: string | (() => string) = 'Assertion failed',\n): asserts b {\n if (!b) {\n throw new Error(typeof msg === 'string' ? msg : msg());\n }\n}\n\nexport function assertString(v: unknown): asserts v is string {\n assertType(v, 'string');\n}\n\nexport function assertNumber(v: unknown): asserts v is number {\n assertType(v, 'number');\n}\n\nexport function assertBoolean(v: unknown): asserts v is boolean {\n assertType(v, 'boolean');\n}\n\nfunction assertType(v: unknown, t: string) {\n if (typeof v !== t) {\n throwInvalidType(v, t);\n }\n}\n\nexport function assertObject(v: unknown): asserts v is Record<string, unknown> {\n if (v === null) {\n throwInvalidType(v, 'object');\n }\n assertType(v, 'object');\n}\n\nexport function assertArray(v: unknown): asserts v is unknown[] {\n if (!Array.isArray(v)) {\n throwInvalidType(v, 'array');\n }\n}\n\nexport function invalidType(v: unknown, t: string): string {\n let s = 'Invalid type: ';\n if (v === null || v === undefined) {\n s += v;\n } else {\n s += `${typeof v} \\`${v}\\``;\n }\n return s + `, expected ${t}`;\n}\n\nexport function throwInvalidType(v: unknown, t: string): never {\n throw new Error(invalidType(v, t));\n}\n\nexport function assertNotNull<T>(v: T | null): asserts v is T {\n if (v === null) {\n throw new Error('Expected non-null value');\n }\n}\n\nexport function assertUndefined<T>(\n v: T | undefined,\n msg = 'Expected undefined value',\n): asserts v is T {\n if (v !== undefined) {\n throw new Error(msg);\n }\n}\n\nexport function assertNotUndefined<T>(\n v: T | undefined,\n msg = 'Expected non undefined value',\n): asserts v is T {\n if (v === undefined) {\n throw new Error(msg);\n }\n}\n\nexport function assertInstanceof<T>(\n v: unknown,\n t: new (...args: unknown[]) => T,\n): asserts v is T {\n if (!(v instanceof t)) {\n throw new Error(`Expected instanceof ${t.name}`);\n }\n}\n\nexport function assertUint8Array(v: unknown): asserts v is Uint8Array {\n assertInstanceof(v, Uint8Array);\n}\n\nexport function unreachable(): never;\nexport function unreachable(v: never): never;\nexport function unreachable(_?: never): never {\n throw new Error('Unreachable');\n}\n\nexport function notImplemented(): never {\n throw new Error('Not implemented');\n}\n", "export function must<T>(v: T | undefined | null, msg?: string): T {\n // eslint-disable-next-line eqeqeq\n if (v == null) {\n throw new Error(msg ?? `Unexpected ${v} value`);\n }\n return v;\n}\n", "import {compareUTF8} from 'compare-utf8';\nimport {\n assertBoolean,\n assertNumber,\n assertString,\n} from '../../../shared/src/asserts.ts';\nimport type {Ordering} from '../../../zero-protocol/src/ast.ts';\nimport type {Row, Value} from '../../../zero-protocol/src/data.ts';\nimport type {Stream} from './stream.ts';\n\n/**\n * A row flowing through the pipeline, plus its relationships.\n * Relationships are generated lazily as read.\n */\nexport type Node = {\n row: Row;\n relationships: Record<string, () => Stream<Node>>;\n};\n\n/**\n * Compare two values. The values must be of the same type. This function\n * throws at runtime if the types differ.\n *\n * Note, this function considers `null === null` and\n * `undefined === undefined`. This is different than SQL. In join code,\n * null must be treated separately.\n *\n * See: https://github.com/rocicorp/mono/pull/2116/files#r1704811479\n *\n * @returns < 0 if a < b, 0 if a === b, > 0 if a > b\n */\nexport function compareValues(a: Value, b: Value): number {\n a = normalizeUndefined(a);\n b = normalizeUndefined(b);\n\n if (a === b) {\n return 0;\n }\n if (a === null) {\n return -1;\n }\n if (b === null) {\n return 1;\n }\n if (typeof a === 'boolean') {\n assertBoolean(b);\n return a ? 1 : -1;\n }\n if (typeof a === 'number') {\n assertNumber(b);\n return a - b;\n }\n if (typeof a === 'string') {\n assertString(b);\n // We compare all strings in Zero as UTF-8. This is the default on SQLite\n // and we need to match it. See:\n // https://blog.replicache.dev/blog/replicache-11-adventures-in-text-encoding.\n //\n // TODO: We could change this since SQLite supports UTF-16. Microbenchmark\n // to see if there's a big win.\n //\n // https://www.sqlite.org/c3ref/create_collation.html\n return compareUTF8(a, b);\n }\n throw new Error(`Unsupported type: ${a}`);\n}\n\nexport type NormalizedValue = Exclude<Value, undefined>;\n\n/**\n * We allow undefined to be passed for the convenience of developers, but we\n * treat it equivalently to null. It's better for perf to not create an copy\n * of input values, so we just normalize at use when necessary.\n */\nexport function normalizeUndefined(v: Value): NormalizedValue {\n return v ?? null;\n}\n\nexport type Comparator = (r1: Row, r2: Row) => number;\n\nexport function makeComparator(\n order: Ordering,\n reverse?: boolean | undefined,\n): Comparator {\n return (a, b) => {\n // Skip destructuring here since it is hot code.\n for (const ord of order) {\n const field = ord[0];\n const comp = compareValues(a[field], b[field]);\n if (comp !== 0) {\n const result = ord[1] === 'asc' ? comp : -comp;\n return reverse ? -result : result;\n }\n }\n return 0;\n };\n}\n\n/**\n * Determine if two values are equal. Note that unlike compareValues() above,\n * this function treats `null` as unequal to itself (and same for `undefined`).\n * This is required to make joins work correctly, but may not be the right\n * semantic for your application.\n */\nexport function valuesEqual(a: Value, b: Value): boolean {\n // eslint-disable-next-line eqeqeq\n if (a == null || b == null) {\n return false;\n }\n return a === b;\n}\n\nexport function drainStreams(node: Node) {\n for (const stream of Object.values(node.relationships)) {\n for (const node of stream()) {\n drainStreams(node);\n }\n }\n}\n", "import {\n assert,\n assertArray,\n assertNumber,\n unreachable,\n} from '../../../shared/src/asserts.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport type {Writable} from '../../../shared/src/writable.ts';\nimport type {Row} from '../../../zero-protocol/src/data.ts';\nimport {drainStreams, type Comparator, type Node} from './data.ts';\nimport type {SourceSchema} from './schema.ts';\nimport type {Entry, Format} from './view.ts';\n\nexport const refCountSymbol = Symbol('rc');\n\ntype RCEntry = Writable<Entry> & {[refCountSymbol]: number};\ntype RCEntryList = RCEntry[];\n\n/**\n * `applyChange` does not consume the `relationships` of `ChildChange#node`,\n * `EditChange#node` and `EditChange#oldNode`. The `ViewChange` type\n * documents and enforces this via the type system.\n */\nexport type ViewChange =\n | AddViewChange\n | RemoveViewChange\n | ChildViewChange\n | EditViewChange;\n\nexport type RowOnlyNode = {row: Row};\n\nexport type AddViewChange = {\n type: 'add';\n node: Node;\n};\n\nexport type RemoveViewChange = {\n type: 'remove';\n node: Node;\n};\n\ntype ChildViewChange = {\n type: 'child';\n node: RowOnlyNode;\n child: {\n relationshipName: string;\n change: ViewChange;\n };\n};\n\ntype EditViewChange = {\n type: 'edit';\n node: RowOnlyNode;\n oldNode: RowOnlyNode;\n};\n\n/**\n * This is a subset of WeakMap but restricted to what we need.\n * @deprecated Not used anymore. This will be removed in the future.\n */\nexport interface RefCountMap {\n get(entry: Entry): number | undefined;\n set(entry: Entry, refCount: number): void;\n delete(entry: Entry): boolean;\n}\n\nexport function applyChange(\n parentEntry: Entry,\n change: ViewChange,\n schema: SourceSchema,\n relationship: string,\n format: Format,\n): void;\n/** @deprecated Use the version without the `refCountMap` parameter. */\nexport function applyChange(\n parentEntry: Entry,\n change: ViewChange,\n schema: SourceSchema,\n relationship: string,\n format: Format,\n refCountMap?: unknown,\n): void;\nexport function applyChange(\n parentEntry: Entry,\n change: ViewChange,\n schema: SourceSchema,\n relationship: string,\n format: Format,\n): void {\n if (schema.isHidden) {\n switch (change.type) {\n case 'add':\n case 'remove':\n for (const [relationship, children] of Object.entries(\n change.node.relationships,\n )) {\n const childSchema = must(schema.relationships[relationship]);\n for (const node of children()) {\n applyChange(\n parentEntry,\n {type: change.type, node},\n childSchema,\n relationship,\n format,\n );\n }\n }\n return;\n case 'edit':\n // If hidden at this level it means that the hidden row was changed. If\n // the row was changed in such a way that it would change the\n // relationships then the edit would have been split into remove and\n // add.\n return;\n case 'child': {\n const childSchema = must(\n schema.relationships[change.child.relationshipName],\n );\n applyChange(\n parentEntry,\n change.child.change,\n childSchema,\n relationship,\n format,\n );\n return;\n }\n default:\n unreachable(change);\n }\n }\n\n const {singular, relationships: childFormats} = format;\n switch (change.type) {\n case 'add': {\n let newEntry: RCEntry;\n\n let rc = 1;\n if (singular) {\n const oldEntry = parentEntry[relationship] as RCEntry | undefined;\n if (oldEntry !== undefined) {\n assert(\n schema.compareRows(oldEntry, change.node.row) === 0,\n 'single output already exists',\n );\n // adding same again.\n rc = oldEntry[refCountSymbol] + 1;\n }\n\n newEntry = makeNewEntryWithRefCount(change.node.row, rc);\n\n (parentEntry as Writable<Entry>)[relationship] = newEntry;\n } else {\n newEntry = makeNewEntryAndInsert(\n change.node.row,\n getChildEntryList(parentEntry, relationship),\n schema.compareRows,\n );\n }\n\n for (const [relationship, children] of Object.entries(\n change.node.relationships,\n )) {\n // TODO: Is there a flag to make TypeScript complain that dictionary access might be undefined?\n const childSchema = must(schema.relationships[relationship]);\n const childFormat = childFormats[relationship];\n if (childFormat === undefined) {\n continue;\n }\n\n const newView = childFormat.singular ? undefined : ([] as RCEntryList);\n newEntry[relationship] = newView;\n\n for (const node of children()) {\n applyChange(\n newEntry,\n {type: 'add', node},\n childSchema,\n relationship,\n childFormat,\n );\n }\n }\n break;\n }\n case 'remove': {\n if (singular) {\n const oldEntry = parentEntry[relationship] as RCEntry | undefined;\n assert(oldEntry !== undefined, 'node does not exist');\n const rc = oldEntry[refCountSymbol];\n if (rc === 1) {\n (parentEntry as Writable<Entry>)[relationship] = undefined;\n }\n oldEntry[refCountSymbol]--;\n } else {\n removeAndUpdateRefCount(\n getChildEntryList(parentEntry, relationship),\n change.node.row,\n schema.compareRows,\n );\n }\n // Needed to ensure cleanup of operator state is fully done.\n drainStreams(change.node);\n break;\n }\n case 'child': {\n let existing: RCEntry;\n if (singular) {\n existing = getSingularEntry(parentEntry, relationship);\n } else {\n const view = getChildEntryList(parentEntry, relationship);\n const {pos, found} = binarySearch(\n view,\n change.node.row,\n schema.compareRows,\n );\n assert(found, 'node does not exist');\n existing = view[pos];\n }\n\n const childSchema = must(\n schema.relationships[change.child.relationshipName],\n );\n const childFormat = format.relationships[change.child.relationshipName];\n if (childFormat !== undefined) {\n applyChange(\n existing,\n change.child.change,\n childSchema,\n change.child.relationshipName,\n childFormat,\n );\n }\n break;\n }\n case 'edit': {\n if (singular) {\n const existing = parentEntry[relationship];\n assertRCEntry(existing);\n const rc = existing[refCountSymbol];\n const newEntry = {\n ...existing,\n ...change.node.row,\n [refCountSymbol]: rc,\n };\n existing[refCountSymbol] = 0;\n (parentEntry as Writable<Entry>)[relationship] = newEntry;\n } else {\n const view = getChildEntryList(parentEntry, relationship);\n // If the order changed due to the edit, we need to remove and reinsert.\n if (schema.compareRows(change.oldNode.row, change.node.row) === 0) {\n const {pos, found} = binarySearch(\n view,\n change.oldNode.row,\n schema.compareRows,\n );\n assert(found, 'node does not exist');\n const oldEntry = view[pos];\n const rc = oldEntry[refCountSymbol];\n oldEntry[refCountSymbol] = 0;\n\n const newEntry = makeEntryPreserveRelationships(\n change.node.row,\n oldEntry,\n format.relationships,\n rc,\n );\n\n view[pos] = newEntry;\n } else {\n // Remove\n const oldEntry = removeAndUpdateRefCount(\n view,\n change.oldNode.row,\n schema.compareRows,\n );\n\n // Insert\n insertAndSetRefCount(\n view,\n change.node.row,\n oldEntry,\n format.relationships,\n schema.compareRows,\n );\n }\n }\n\n break;\n }\n default:\n unreachable(change);\n }\n}\n\nfunction makeNewEntryAndInsert(\n newRow: Row,\n view: RCEntryList,\n compareRows: Comparator,\n): RCEntry {\n const {pos, found} = binarySearch(view, newRow, compareRows);\n\n let deleteCount = 0;\n let rc = 1;\n if (found) {\n deleteCount = 1;\n rc = view[pos][refCountSymbol];\n view[pos][refCountSymbol] = rc - 1;\n rc++;\n }\n\n const newEntry = makeNewEntryWithRefCount(newRow, rc);\n\n view.splice(pos, deleteCount, newEntry);\n\n return newEntry;\n}\n\nfunction insertAndSetRefCount(\n view: RCEntryList,\n newRow: Row,\n oldEntry: RCEntry,\n relationships: {[key: string]: Format},\n compareRows: Comparator,\n): void {\n const {pos, found} = binarySearch(view, newRow, compareRows);\n\n let deleteCount = 0;\n let rc = 1;\n if (found) {\n deleteCount = 1;\n const oldEntry = view[pos];\n rc = oldEntry[refCountSymbol] + 1;\n oldEntry[refCountSymbol] = 0;\n }\n\n const newEntry = makeEntryPreserveRelationships(\n newRow,\n oldEntry,\n relationships,\n rc,\n );\n\n view.splice(pos, deleteCount, newEntry);\n}\n\nfunction removeAndUpdateRefCount(\n view: RCEntryList,\n row: Row,\n compareRows: Comparator,\n): RCEntry {\n const {pos, found} = binarySearch(view, row, compareRows);\n assert(found, 'node does not exist');\n const oldEntry = view[pos];\n const rc = oldEntry[refCountSymbol];\n if (rc === 1) {\n view.splice(pos, 1);\n }\n oldEntry[refCountSymbol]--;\n\n return oldEntry;\n}\n\n// TODO: Do not return an object. It puts unnecessary pressure on the GC.\nfunction binarySearch(view: RCEntryList, target: Row, comparator: Comparator) {\n let low = 0;\n let high = view.length - 1;\n while (low <= high) {\n const mid = (low + high) >>> 1;\n const comparison = comparator(view[mid] as Row, target as Row);\n if (comparison < 0) {\n low = mid + 1;\n } else if (comparison > 0) {\n high = mid - 1;\n } else {\n return {pos: mid, found: true};\n }\n }\n return {pos: low, found: false};\n}\n\nfunction makeEntryPreserveRelationships(\n newRow: Row,\n oldEntry: RCEntry,\n relationships: {[key: string]: Format},\n rc: number,\n): RCEntry {\n const entry = makeNewEntryWithRefCount(newRow, rc);\n for (const relationship in relationships) {\n assert(!(relationship in newRow), 'Relationship already exists');\n entry[relationship] = oldEntry[relationship];\n }\n return entry;\n}\n\nfunction getChildEntryList(\n parentEntry: Entry,\n relationship: string,\n): RCEntryList {\n const view = parentEntry[relationship];\n assertArray(view);\n return view as RCEntryList;\n}\n\nfunction assertRCEntry(v: unknown): asserts v is RCEntry {\n assertNumber((v as Partial<RCEntry>)[refCountSymbol]);\n}\n\nfunction getSingularEntry(parentEntry: Entry, relationship: string): RCEntry {\n const e = parentEntry[relationship];\n assertNumber((e as Partial<RCEntry>)[refCountSymbol]);\n return e as RCEntry;\n}\n\nfunction makeNewEntryWithRefCount(row: Row, rc: number): RCEntry {\n return {...row, [refCountSymbol]: rc};\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["node", "relationship", "oldEntry"]
|
|
7
|
+
}
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
throwInvalidType,
|
|
22
22
|
unreachable,
|
|
23
23
|
valuesEqual
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-MJCITZ5S.js";
|
|
25
25
|
import {
|
|
26
26
|
__export,
|
|
27
27
|
__reExport
|
|
@@ -10132,6 +10132,8 @@ var Take = class {
|
|
|
10132
10132
|
#limit;
|
|
10133
10133
|
#partitionKey;
|
|
10134
10134
|
#partitionKeyComparator;
|
|
10135
|
+
// Fetch overlay needed for some split push cases.
|
|
10136
|
+
#rowHiddenFromFetch;
|
|
10135
10137
|
#output = throwOutput;
|
|
10136
10138
|
constructor(input, storage, limit, partitionKey) {
|
|
10137
10139
|
assert(limit >= 0);
|
|
@@ -10167,6 +10169,12 @@ var Take = class {
|
|
|
10167
10169
|
if (this.getSchema().compareRows(takeState.bound, inputNode.row) < 0) {
|
|
10168
10170
|
return;
|
|
10169
10171
|
}
|
|
10172
|
+
if (this.#rowHiddenFromFetch && this.getSchema().compareRows(
|
|
10173
|
+
this.#rowHiddenFromFetch,
|
|
10174
|
+
inputNode.row
|
|
10175
|
+
) === 0) {
|
|
10176
|
+
continue;
|
|
10177
|
+
}
|
|
10170
10178
|
yield inputNode;
|
|
10171
10179
|
}
|
|
10172
10180
|
return;
|
|
@@ -10309,14 +10317,16 @@ var Take = class {
|
|
|
10309
10317
|
type: "remove",
|
|
10310
10318
|
node: boundNode
|
|
10311
10319
|
};
|
|
10312
|
-
this.#output.push(change);
|
|
10313
10320
|
this.#setTakeState(
|
|
10314
10321
|
takeStateKey,
|
|
10315
10322
|
takeState.size,
|
|
10316
10323
|
beforeBoundNode === void 0 || compareRows(change.node.row, beforeBoundNode.row) > 0 ? change.node.row : beforeBoundNode.row,
|
|
10317
10324
|
maxBound
|
|
10318
10325
|
);
|
|
10319
|
-
this.#
|
|
10326
|
+
this.#withRowHiddenFromFetch(change.node.row, () => {
|
|
10327
|
+
this.#output.push(removeChange);
|
|
10328
|
+
});
|
|
10329
|
+
this.#output.push(change);
|
|
10320
10330
|
} else if (change.type === "remove") {
|
|
10321
10331
|
if (takeState.bound === void 0) {
|
|
10322
10332
|
return;
|
|
@@ -10487,19 +10497,21 @@ var Take = class {
|
|
|
10487
10497
|
}),
|
|
10488
10498
|
2
|
|
10489
10499
|
);
|
|
10490
|
-
this.#output.push({
|
|
10491
|
-
type: "add",
|
|
10492
|
-
node: change.node
|
|
10493
|
-
});
|
|
10494
10500
|
this.#setTakeState(
|
|
10495
10501
|
takeStateKey,
|
|
10496
10502
|
takeState.size,
|
|
10497
10503
|
newBoundNode.row,
|
|
10498
10504
|
maxBound
|
|
10499
10505
|
);
|
|
10506
|
+
this.#withRowHiddenFromFetch(change.node.row, () => {
|
|
10507
|
+
this.#output.push({
|
|
10508
|
+
type: "remove",
|
|
10509
|
+
node: oldBoundNode
|
|
10510
|
+
});
|
|
10511
|
+
});
|
|
10500
10512
|
this.#output.push({
|
|
10501
|
-
type: "
|
|
10502
|
-
node:
|
|
10513
|
+
type: "add",
|
|
10514
|
+
node: change.node
|
|
10503
10515
|
});
|
|
10504
10516
|
return;
|
|
10505
10517
|
}
|
|
@@ -10543,6 +10555,14 @@ var Take = class {
|
|
|
10543
10555
|
}
|
|
10544
10556
|
unreachable();
|
|
10545
10557
|
}
|
|
10558
|
+
#withRowHiddenFromFetch(row, fn) {
|
|
10559
|
+
this.#rowHiddenFromFetch = row;
|
|
10560
|
+
try {
|
|
10561
|
+
fn();
|
|
10562
|
+
} finally {
|
|
10563
|
+
this.#rowHiddenFromFetch = void 0;
|
|
10564
|
+
}
|
|
10565
|
+
}
|
|
10546
10566
|
#setTakeState(takeStateKey, size, bound, maxBound) {
|
|
10547
10567
|
this.#storage.set(takeStateKey, {
|
|
10548
10568
|
size,
|
|
@@ -11078,7 +11098,6 @@ var ArrayView = class {
|
|
|
11078
11098
|
onDestroy;
|
|
11079
11099
|
#dirty = false;
|
|
11080
11100
|
#complete = false;
|
|
11081
|
-
#refCountMap = /* @__PURE__ */ new WeakMap();
|
|
11082
11101
|
constructor(input, format = { singular: false, relationships: {} }, queryComplete = true) {
|
|
11083
11102
|
this.#input = input;
|
|
11084
11103
|
this.#schema = input.getSchema();
|
|
@@ -11128,22 +11147,14 @@ var ArrayView = class {
|
|
|
11128
11147
|
{ type: "add", node },
|
|
11129
11148
|
this.#schema,
|
|
11130
11149
|
"",
|
|
11131
|
-
this.#format
|
|
11132
|
-
this.#refCountMap
|
|
11150
|
+
this.#format
|
|
11133
11151
|
);
|
|
11134
11152
|
}
|
|
11135
11153
|
this.flush();
|
|
11136
11154
|
}
|
|
11137
11155
|
push(change) {
|
|
11138
11156
|
this.#dirty = true;
|
|
11139
|
-
applyChange(
|
|
11140
|
-
this.#root,
|
|
11141
|
-
change,
|
|
11142
|
-
this.#schema,
|
|
11143
|
-
"",
|
|
11144
|
-
this.#format,
|
|
11145
|
-
this.#refCountMap
|
|
11146
|
-
);
|
|
11157
|
+
applyChange(this.#root, change, this.#schema, "", this.#format);
|
|
11147
11158
|
}
|
|
11148
11159
|
flush() {
|
|
11149
11160
|
if (!this.#dirty) {
|
|
@@ -14515,7 +14526,7 @@ function makeMessage(message, context, logLevel) {
|
|
|
14515
14526
|
}
|
|
14516
14527
|
|
|
14517
14528
|
// ../zero-client/src/client/version.ts
|
|
14518
|
-
var version2 = "0.17.
|
|
14529
|
+
var version2 = "0.17.2025032000";
|
|
14519
14530
|
|
|
14520
14531
|
// ../zero-client/src/client/log-options.ts
|
|
14521
14532
|
var LevelFilterLogSink = class {
|
|
@@ -16791,4 +16802,4 @@ export {
|
|
|
16791
16802
|
escapeLike,
|
|
16792
16803
|
Zero
|
|
16793
16804
|
};
|
|
16794
|
-
//# sourceMappingURL=chunk-
|
|
16805
|
+
//# sourceMappingURL=chunk-OI2PV2HL.js.map
|