doxum 0.1.20 → 0.1.22
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/README.md +31 -4
- package/dist/{access-B9XDWjHy.js → access-CZXv_DIF.js} +238 -54
- package/dist/access-CZXv_DIF.js.map +1 -0
- package/dist/{access-EQ-XiFyl.cjs → access-D64MFRSm.cjs} +287 -55
- package/dist/access-D64MFRSm.cjs.map +1 -0
- package/dist/{advanced-Bcle5C2M.js → advanced-BTStm2cW.js} +29 -25
- package/dist/advanced-BTStm2cW.js.map +1 -0
- package/dist/{advanced-Du3O8O1A.d.ts → advanced-CqrR_4dh.d.ts} +3 -3
- package/dist/{advanced-CSjF-u_k.d.cts → advanced-CyR5o3Xr.d.cts} +3 -3
- package/dist/{advanced-BIGP86NL.cjs → advanced-GKZ-CZ6a.cjs} +29 -25
- package/dist/advanced-GKZ-CZ6a.cjs.map +1 -0
- package/dist/advanced.cjs +1 -1
- package/dist/advanced.d.cts +1 -1
- package/dist/advanced.d.ts +1 -1
- package/dist/advanced.js +1 -1
- package/dist/{contract-BlEl8Ibo.d.ts → contract-CRrZ-3sF.d.cts} +68 -36
- package/dist/{contract-BDQth1pe.d.cts → contract-CxiNcqMn.d.ts} +68 -36
- package/dist/{driver-DRoWiadc.cjs → driver-BC06FEMF.cjs} +2 -2
- package/dist/{driver-DRoWiadc.cjs.map → driver-BC06FEMF.cjs.map} +1 -1
- package/dist/{driver-DiN-0Mnc.js → driver-BqRjwFmU.js} +2 -2
- package/dist/{driver-DiN-0Mnc.js.map → driver-BqRjwFmU.js.map} +1 -1
- package/dist/index.cjs +482 -119
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +480 -117
- package/dist/index.js.map +1 -1
- package/dist/{integration-DL6dLuu1.cjs → integration-BqDw7e2w.cjs} +3 -4
- package/dist/{integration-DL6dLuu1.cjs.map → integration-BqDw7e2w.cjs.map} +1 -1
- package/dist/{integration-DHxVpbxc.js → integration-CSXaF8HP.js} +2 -3
- package/dist/{integration-DHxVpbxc.js.map → integration-CSXaF8HP.js.map} +1 -1
- package/dist/integration.cjs +5 -4
- package/dist/integration.d.cts +1 -1
- package/dist/integration.d.ts +1 -1
- package/dist/integration.js +4 -3
- package/dist/{issue-DVaGQGeP.js → issue-9U6YLYz3.js} +91 -20
- package/dist/issue-9U6YLYz3.js.map +1 -0
- package/dist/{issue-DhrNdQNg.cjs → issue-Bo0FIO3b.cjs} +116 -27
- package/dist/issue-Bo0FIO3b.cjs.map +1 -0
- package/dist/local-sync.cjs +2 -2
- package/dist/local-sync.d.cts +1 -1
- package/dist/local-sync.d.ts +1 -1
- package/dist/local-sync.js +2 -2
- package/dist/{notification-AXT94XYC.js → notification-CrZHVx3a.js} +3 -59
- package/dist/notification-CrZHVx3a.js.map +1 -0
- package/dist/{notification-DGv-_G9t.cjs → notification-DFoA9bQY.cjs} +3 -77
- package/dist/notification-DFoA9bQY.cjs.map +1 -0
- package/dist/react.cjs +4 -3
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +3 -2
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
- package/skills/doxum-runtime/SKILL.md +7 -0
- package/skills/doxum-runtime/references/guide.en.md +14 -2
- package/skills/doxum-runtime/references/guide.zh-CN.md +13 -2
- package/skills/doxum-runtime/references/projections.en.md +5 -0
- package/skills/doxum-runtime/references/projections.zh-CN.md +5 -0
- package/dist/access-B9XDWjHy.js.map +0 -1
- package/dist/access-EQ-XiFyl.cjs.map +0 -1
- package/dist/advanced-BIGP86NL.cjs.map +0 -1
- package/dist/advanced-Bcle5C2M.js.map +0 -1
- package/dist/issue-DVaGQGeP.js.map +0 -1
- package/dist/issue-DhrNdQNg.cjs.map +0 -1
- package/dist/notification-AXT94XYC.js.map +0 -1
- package/dist/notification-DGv-_G9t.cjs.map +0 -1
package/README.md
CHANGED
|
@@ -100,9 +100,9 @@ capabilities while retaining selection, subscription and projection support.
|
|
|
100
100
|
- `map(field(...))`, `map(object(...))`, `map(variant(...))` expose
|
|
101
101
|
`get/has/ids/put/remove/replace`. `put` is an upsert; removing a missing key is a no-op.
|
|
102
102
|
- `table(object(...))` retains `{ ids, byId }` data and exposes
|
|
103
|
-
`get/has/ids/create/remove/move/replace`.
|
|
103
|
+
`get/has/ids/create/remove/move/reorder/replace`.
|
|
104
104
|
- `list(field(...), { keyOf })` retains a plain array and exposes
|
|
105
|
-
`get/has/ids/insert/remove/move/replace`.
|
|
105
|
+
`get/has/ids/insert/remove/move/reorder/replace`.
|
|
106
106
|
- `tree(field(...))` retains `{ rootId?, nodes }` and exposes topology reads plus
|
|
107
107
|
`insert/remove/move/replace`.
|
|
108
108
|
- `variant(tag, branches)` has a readonly discriminant and whole-value branch replacement.
|
|
@@ -116,6 +116,20 @@ Doxum; it does not detect validator mutation or conversion. `parse(model, unknow
|
|
|
116
116
|
validates and copies schema structure while sharing readonly payloads. Strict parsing
|
|
117
117
|
requires validators for atomic fields; typed in-memory fields can omit them.
|
|
118
118
|
|
|
119
|
+
A tree may be empty, but payload presence follows the payload field schema exactly.
|
|
120
|
+
`tree(field<T>())` requires every existing node to own a `value` property;
|
|
121
|
+
`tree(optional(field<T>()))` is the explicit sparse-payload form. This is independent
|
|
122
|
+
from `optional(tree(...))`, which controls whether the whole tree member may be absent.
|
|
123
|
+
Missing and present-`undefined` payloads remain distinct when the payload field is optional.
|
|
124
|
+
|
|
125
|
+
Ordered table/list drafts accept either one key or a key selection in
|
|
126
|
+
`move(key | readonly key[], anchor?)`. A selection is moved as one block while
|
|
127
|
+
preserving its current canonical relative order; the anchor is resolved after the
|
|
128
|
+
selection is removed. Use `reorder(keys)` when the caller already owns the complete
|
|
129
|
+
final order: it requires an exact permutation of current membership and changes no
|
|
130
|
+
member values. Whole-collection `replace(value)` remains a distinct replacement
|
|
131
|
+
operation and is not an order primitive.
|
|
132
|
+
|
|
119
133
|
Collection `replace` has two forms: `replace(id, value)` replaces one existing
|
|
120
134
|
table/list/tree member without changing order or topology, while `replace(value)`
|
|
121
135
|
replaces the entire map/table/list/tree. Use top-level `replace(parent, key, value)`
|
|
@@ -269,8 +283,21 @@ runtime.update(overrides, draft => {
|
|
|
269
283
|
and eventful external sources. External sources declare `kind: 'value'` or
|
|
270
284
|
`kind: 'collection'`; collection invalidation remains keyed internally. Schema
|
|
271
285
|
`map`, `table`, and `list(field, { keyOf })` paths are all observed as keyed
|
|
272
|
-
collection projections.
|
|
273
|
-
|
|
286
|
+
collection projections. Trees expose structural observation without a second
|
|
287
|
+
projection protocol: `path.tree.rootId` is a scalar source,
|
|
288
|
+
`path.tree.nodes` is a keyed collection source, and
|
|
289
|
+
`path.tree.nodes.item(id)` is a single-node value source. A schema `list` uses its
|
|
290
|
+
`keyOf` identity and publishes in document order; ordinary array-valued `field(...)`
|
|
291
|
+
nodes remain scalar values.
|
|
292
|
+
|
|
293
|
+
Document projection sources route committed groups directly to their observed
|
|
294
|
+
targets, merge affected locations for the current projection batch, then combine the
|
|
295
|
+
previously published snapshot with the canonical final value. A touched tree node
|
|
296
|
+
replaces only that node structure and the necessary ancestor containers; unchanged
|
|
297
|
+
tree-node snapshots keep their identity. Whole aggregate tree values still use the
|
|
298
|
+
public `{ rootId?, nodes: Record }` shape, so changing a node may shallow-copy the
|
|
299
|
+
`nodes` record, while native `tree.nodes` observation remains keyed and touches only
|
|
300
|
+
changed nodes.
|
|
274
301
|
|
|
275
302
|
For retained state, reverse indexes and keyed patches, use the isolated advanced
|
|
276
303
|
entry point. Whole-value processors use `incremental(...)`; keyed collection
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as profile, C as validate, D as index, E as equal, F as matches, I as moveSelection, M as installList, N as keys, O as indexedKeys, P as listSequence, T as isRecord, a as compiledShape, b as contains, g as resolveLocated, i as AddressIndex, j as installKeys, k as insert$2, m as resolveChild, n as fail, u as nodeAt, w as isPlainObject, x as parent, y as children, z as valid } from "./issue-9U6YLYz3.js";
|
|
2
2
|
//#region core/src/schema-value.ts
|
|
3
3
|
var ParseError = class extends TypeError {
|
|
4
4
|
issues;
|
|
@@ -103,14 +103,29 @@ const checkValue = (node, value, address = [], strict = false) => {
|
|
|
103
103
|
return;
|
|
104
104
|
}
|
|
105
105
|
if (!validate(value)) return issue(address, "Invalid tree structure.", "invalid-tree");
|
|
106
|
-
|
|
107
|
-
const
|
|
108
|
-
if (
|
|
109
|
-
const failure = checkValue(node.value, entry.value, [...address, id], strict);
|
|
110
|
-
if (failure) return failure;
|
|
111
|
-
}
|
|
106
|
+
for (const id of Object.keys(value.nodes)) {
|
|
107
|
+
const failure = checkTreePayload(node.value, value.nodes[id], [...address, id], strict);
|
|
108
|
+
if (failure) return failure;
|
|
112
109
|
}
|
|
113
110
|
};
|
|
111
|
+
const checkTreePayload = (node, value, address, strict = false) => {
|
|
112
|
+
if (!isRecord(value)) return issue(address, "Invalid tree node.", "invalid-tree");
|
|
113
|
+
const present = Object.prototype.hasOwnProperty.call(value, "value");
|
|
114
|
+
if (!present && !node.optional) return issue(address, "Tree node value is required.");
|
|
115
|
+
return present ? checkValue(node, value.value, address, strict) : void 0;
|
|
116
|
+
};
|
|
117
|
+
const copyTreeNode = (value) => {
|
|
118
|
+
profile.copy.treeNode();
|
|
119
|
+
return {
|
|
120
|
+
...value,
|
|
121
|
+
children: [...value.children]
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
const equalTreeNode = (left, right) => {
|
|
125
|
+
if (left === right) return true;
|
|
126
|
+
if (!left || !right) return false;
|
|
127
|
+
return left.parentId === right.parentId && equal(left.children, right.children) && Object.hasOwn(left, "value") === Object.hasOwn(right, "value") && Object.is(left.value, right.value);
|
|
128
|
+
};
|
|
114
129
|
/** Copy editable structure; atomic payloads retain their immutable ownership contract. */
|
|
115
130
|
const copyValue = (node, value) => {
|
|
116
131
|
if (value === void 0 || node.kind === "field") return value;
|
|
@@ -139,10 +154,7 @@ const copyValue = (node, value) => {
|
|
|
139
154
|
const entries = value.nodes;
|
|
140
155
|
return {
|
|
141
156
|
...value,
|
|
142
|
-
nodes: Object.fromEntries(Object.entries(entries).map(([id, n]) => [id,
|
|
143
|
-
...n,
|
|
144
|
-
children: [...n.children]
|
|
145
|
-
}]))
|
|
157
|
+
nodes: Object.fromEntries(Object.entries(entries).map(([id, n]) => [id, copyTreeNode(n)]))
|
|
146
158
|
};
|
|
147
159
|
}
|
|
148
160
|
return value;
|
|
@@ -166,7 +178,7 @@ const equalValue = (node, left, right) => {
|
|
|
166
178
|
if (node.kind === "tree" && isRecord(left) && isRecord(right)) {
|
|
167
179
|
if (left.rootId !== right.rootId) return false;
|
|
168
180
|
const a = left.nodes, b = right.nodes;
|
|
169
|
-
return Object.keys(a).length === Object.keys(b).length && Object.keys(a).every((id) => Object.hasOwn(b, id) &&
|
|
181
|
+
return Object.keys(a).length === Object.keys(b).length && Object.keys(a).every((id) => Object.hasOwn(b, id) && equalTreeNode(a[id], b[id]));
|
|
170
182
|
}
|
|
171
183
|
if (node.kind === "map" && isRecord(left) && isRecord(right)) {
|
|
172
184
|
const keys = Object.keys(left);
|
|
@@ -235,12 +247,12 @@ function insert$1(session, container, value, position) {
|
|
|
235
247
|
session.validate(node.value, value, at);
|
|
236
248
|
const id = node.keyOf(value);
|
|
237
249
|
if (typeof id !== "string") return fail(at, "invalid-list-key", "List key must be a string.");
|
|
238
|
-
const items = current, keys$
|
|
239
|
-
if (keys$
|
|
240
|
-
if (!valid(keys$
|
|
250
|
+
const items = current, keys$1 = keys(items, node.keyOf);
|
|
251
|
+
if (keys$1.index(id) >= 0) return fail(at, "duplicate-list-item", "List key already exists.");
|
|
252
|
+
if (!valid(keys$1, position)) return fail(at, "invalid-anchor", "Unknown list anchor.");
|
|
241
253
|
session.recorder.order(container);
|
|
242
254
|
session.recorder.member(container, id, session.definition(container, id), -1);
|
|
243
|
-
insert$2(items, index(keys$
|
|
255
|
+
insert$2(items, index(keys$1, position), value);
|
|
244
256
|
session.invalidate();
|
|
245
257
|
}
|
|
246
258
|
function replace$2(session, container, id, value) {
|
|
@@ -338,21 +350,185 @@ const move$1 = (session, container, id, position) => {
|
|
|
338
350
|
};
|
|
339
351
|
//#endregion
|
|
340
352
|
//#region core/src/mutation/operations/order.ts
|
|
341
|
-
|
|
342
|
-
const { at, node
|
|
353
|
+
const assertOrdered = (container) => {
|
|
354
|
+
const { at, node } = container;
|
|
343
355
|
if (node.kind !== "table" && node.kind !== "list") return fail(at, "invalid-collection", "Expected an ordered container.");
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
356
|
+
return node;
|
|
357
|
+
};
|
|
358
|
+
const plannedOrder = (at, current, selection, position) => {
|
|
359
|
+
const plan = moveSelection(current, selection, position);
|
|
360
|
+
switch (plan.kind) {
|
|
361
|
+
case "ok": return plan.order;
|
|
362
|
+
case "duplicate": return fail(at, "invalid-key", "Moved keys must be unique.");
|
|
363
|
+
case "missing": return fail(at, "missing-entity", "Ordered key does not exist.");
|
|
364
|
+
case "invalid-anchor": return fail(at, "invalid-anchor", "Unknown order anchor.");
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
function move(session, container, ids, position) {
|
|
368
|
+
const node = assertOrdered(container);
|
|
369
|
+
const selection = typeof ids === "string" ? [ids] : ids;
|
|
370
|
+
if (!selection.length) return;
|
|
371
|
+
if (node.kind === "table") {
|
|
372
|
+
const order = container.value.ids;
|
|
373
|
+
const next = plannedOrder(container.at, order, selection, position);
|
|
374
|
+
if (equal(order, next)) return;
|
|
375
|
+
session.recorder.order(container);
|
|
376
|
+
installKeys(order, next);
|
|
377
|
+
} else {
|
|
378
|
+
const items = container.value;
|
|
379
|
+
const sequence = listSequence(items, node.keyOf);
|
|
380
|
+
const next = plannedOrder(container.at, sequence.order, selection, position);
|
|
381
|
+
if (equal(sequence.order, next)) return;
|
|
382
|
+
session.recorder.order(container);
|
|
383
|
+
installList(items, node.keyOf, sequence, next);
|
|
384
|
+
}
|
|
385
|
+
session.invalidate();
|
|
386
|
+
}
|
|
387
|
+
function reorder(session, container, next) {
|
|
388
|
+
const node = assertOrdered(container);
|
|
389
|
+
if (node.kind === "table") {
|
|
390
|
+
const current = container.value.ids;
|
|
391
|
+
if (!matches(next, current)) return fail(container.at, "invalid-collection", "Order must contain every key exactly once.");
|
|
392
|
+
if (equal(current, next)) return;
|
|
393
|
+
session.recorder.order(container);
|
|
394
|
+
installKeys(current, next);
|
|
395
|
+
} else {
|
|
396
|
+
const items = container.value;
|
|
397
|
+
const sequence = listSequence(items, node.keyOf);
|
|
398
|
+
if (!matches(next, sequence.order)) return fail(container.at, "invalid-collection", "Order must contain every key exactly once.");
|
|
399
|
+
if (equal(sequence.order, next)) return;
|
|
400
|
+
session.recorder.order(container);
|
|
401
|
+
installList(items, node.keyOf, sequence, next);
|
|
402
|
+
}
|
|
353
403
|
session.invalidate();
|
|
354
404
|
}
|
|
355
405
|
//#endregion
|
|
406
|
+
//#region core/src/impact-target.ts
|
|
407
|
+
const treeRootSegment = "rootId";
|
|
408
|
+
const treeNodesSegment = "nodes";
|
|
409
|
+
const ordinaryNamespace = "\0value";
|
|
410
|
+
const treeNamespace = "\0tree";
|
|
411
|
+
const tree = (at, selection) => ({
|
|
412
|
+
kind: "value",
|
|
413
|
+
at,
|
|
414
|
+
tree: selection
|
|
415
|
+
});
|
|
416
|
+
const address = (target) => "at" in target ? target.at : target.address;
|
|
417
|
+
const id = (target) => target.kind === "collection" && "id" in target ? target.id : void 0;
|
|
418
|
+
const belongs = (target, schema) => !("schema" in target) || target.schema === schema;
|
|
419
|
+
const treeTarget = (target) => "tree" in target ? target.tree : void 0;
|
|
420
|
+
const sameTreeTarget = (left, right) => {
|
|
421
|
+
if (!left || !right) return left === right;
|
|
422
|
+
if (left.kind !== right.kind) return false;
|
|
423
|
+
return left.kind !== "node" || right.kind === "node" && left.id === right.id;
|
|
424
|
+
};
|
|
425
|
+
const same = (left, right) => {
|
|
426
|
+
if ("schema" in left && "schema" in right && left.schema !== right.schema) return false;
|
|
427
|
+
if (!sameTreeTarget(treeTarget(left), treeTarget(right))) return false;
|
|
428
|
+
if (left.kind !== right.kind) return false;
|
|
429
|
+
const leftAddress = address(left);
|
|
430
|
+
const rightAddress = address(right);
|
|
431
|
+
if (leftAddress.length !== rightAddress.length) return false;
|
|
432
|
+
for (let index = 0; index < leftAddress.length; index += 1) if (leftAddress[index] !== rightAddress[index]) return false;
|
|
433
|
+
return left.kind !== "collection" || id(left) === id(right);
|
|
434
|
+
};
|
|
435
|
+
const indexedAddress = (target) => {
|
|
436
|
+
const tree = treeTarget(target);
|
|
437
|
+
if (tree?.kind === "root") return [
|
|
438
|
+
treeNamespace,
|
|
439
|
+
...address(target),
|
|
440
|
+
treeRootSegment
|
|
441
|
+
];
|
|
442
|
+
if (tree?.kind === "nodes") return [
|
|
443
|
+
treeNamespace,
|
|
444
|
+
...address(target),
|
|
445
|
+
treeNodesSegment
|
|
446
|
+
];
|
|
447
|
+
if (tree?.kind === "node") return [
|
|
448
|
+
treeNamespace,
|
|
449
|
+
...address(target),
|
|
450
|
+
treeNodesSegment,
|
|
451
|
+
tree.id
|
|
452
|
+
];
|
|
453
|
+
const key = id(target);
|
|
454
|
+
return key === void 0 ? [ordinaryNamespace, ...address(target)] : [
|
|
455
|
+
ordinaryNamespace,
|
|
456
|
+
...address(target),
|
|
457
|
+
key
|
|
458
|
+
];
|
|
459
|
+
};
|
|
460
|
+
const visitChangedLocations = (changes, value, order) => {
|
|
461
|
+
for (const change of changes.changes) {
|
|
462
|
+
if (change.kind === "reset") continue;
|
|
463
|
+
if (change.kind === "members") {
|
|
464
|
+
for (const member of change.members) {
|
|
465
|
+
value([
|
|
466
|
+
ordinaryNamespace,
|
|
467
|
+
...change.at,
|
|
468
|
+
member.key
|
|
469
|
+
]);
|
|
470
|
+
value([
|
|
471
|
+
treeNamespace,
|
|
472
|
+
...change.at,
|
|
473
|
+
member.key
|
|
474
|
+
]);
|
|
475
|
+
}
|
|
476
|
+
if (change.order) order([ordinaryNamespace, ...change.at]);
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
value([ordinaryNamespace, ...change.at]);
|
|
480
|
+
if (change.before !== change.after) value([
|
|
481
|
+
treeNamespace,
|
|
482
|
+
...change.at,
|
|
483
|
+
treeRootSegment
|
|
484
|
+
]);
|
|
485
|
+
for (const node of change.nodes) value([
|
|
486
|
+
treeNamespace,
|
|
487
|
+
...change.at,
|
|
488
|
+
treeNodesSegment,
|
|
489
|
+
node.id
|
|
490
|
+
]);
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
const affected = (target, values, orders) => {
|
|
494
|
+
const at = indexedAddress(target);
|
|
495
|
+
return id(target) !== void 0 ? values.hasAncestor(at) : values.overlaps(at) || orders.hasDescendant(at);
|
|
496
|
+
};
|
|
497
|
+
/** Targets are classified once; commit matching never builds a reverse impact index. */
|
|
498
|
+
var SubscriptionIndex = class {
|
|
499
|
+
ordinary = new AddressIndex();
|
|
500
|
+
membership = new AddressIndex();
|
|
501
|
+
constructor(schema) {
|
|
502
|
+
this.schema = schema;
|
|
503
|
+
}
|
|
504
|
+
add(target, value) {
|
|
505
|
+
if (!belongs(target, this.schema)) return;
|
|
506
|
+
(id(target) === void 0 ? this.ordinary : this.membership).add(indexedAddress(target), value);
|
|
507
|
+
}
|
|
508
|
+
delete(target, value) {
|
|
509
|
+
if (!belongs(target, this.schema)) return;
|
|
510
|
+
(id(target) === void 0 ? this.ordinary : this.membership).delete(indexedAddress(target), value);
|
|
511
|
+
}
|
|
512
|
+
collect(changes, visit) {
|
|
513
|
+
const values = this.ordinary.query(visit);
|
|
514
|
+
const members = this.membership.query(visit, "descendants");
|
|
515
|
+
const orders = this.ordinary.query(visit, "ancestors");
|
|
516
|
+
if (changes.changes.some((change) => change.kind === "reset")) {
|
|
517
|
+
values([]);
|
|
518
|
+
members([]);
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
521
|
+
visitChangedLocations(changes, (at) => {
|
|
522
|
+
values(at);
|
|
523
|
+
members(at);
|
|
524
|
+
}, orders);
|
|
525
|
+
}
|
|
526
|
+
clear() {
|
|
527
|
+
this.ordinary.clear();
|
|
528
|
+
this.membership.clear();
|
|
529
|
+
}
|
|
530
|
+
};
|
|
531
|
+
//#endregion
|
|
356
532
|
//#region core/src/access/scope.ts
|
|
357
533
|
const locations = /* @__PURE__ */ new WeakMap();
|
|
358
534
|
const locationOf = (value) => locations.get(value);
|
|
@@ -374,6 +550,7 @@ const collect = (context, at, kind = "value", id) => {
|
|
|
374
550
|
...id === void 0 ? {} : { id }
|
|
375
551
|
});
|
|
376
552
|
};
|
|
553
|
+
const collectTree = (context, at, selection) => context.dependencies?.record(tree(at, selection));
|
|
377
554
|
const snapshot = (value) => {
|
|
378
555
|
const location = value && typeof value === "object" ? locationOf(value) : void 0;
|
|
379
556
|
if (!location) return value;
|
|
@@ -546,9 +723,13 @@ const createAccess = (context, initial = []) => {
|
|
|
546
723
|
if (!location || !Object.hasOwn(location.parent, location.key)) return void 0;
|
|
547
724
|
return childAccess(target, id, location.node, location.parent[location.key]);
|
|
548
725
|
};
|
|
549
|
-
if (property === "move") return (
|
|
726
|
+
if (property === "move") return (ids, position) => {
|
|
550
727
|
const writable = writableCollection(target, node);
|
|
551
|
-
move(context.session, writable,
|
|
728
|
+
move(context.session, writable, ids, position);
|
|
729
|
+
};
|
|
730
|
+
if (property === "reorder") return (ids) => {
|
|
731
|
+
const writable = writableCollection(target, node);
|
|
732
|
+
reorder(context.session, writable, ids);
|
|
552
733
|
};
|
|
553
734
|
};
|
|
554
735
|
const tableMethod = (target, property, node) => {
|
|
@@ -608,18 +789,38 @@ const createAccess = (context, initial = []) => {
|
|
|
608
789
|
const writable = writableTree(target, node);
|
|
609
790
|
replace$1(context.session, writable, valueOrId, value);
|
|
610
791
|
};
|
|
611
|
-
const current = () =>
|
|
612
|
-
|
|
613
|
-
|
|
792
|
+
const current = () => collectionValue(target, node);
|
|
793
|
+
if (property === "rootId") return () => {
|
|
794
|
+
collectTree(context, at, { kind: "root" });
|
|
795
|
+
return current().rootId;
|
|
614
796
|
};
|
|
615
|
-
if (property === "rootId") return () => current().rootId;
|
|
616
797
|
if (property === "get") return (id) => {
|
|
798
|
+
collectTree(context, at, {
|
|
799
|
+
kind: "node",
|
|
800
|
+
id
|
|
801
|
+
});
|
|
617
802
|
const value = current();
|
|
618
803
|
return contains(value, id) ? value.nodes[id].value : void 0;
|
|
619
804
|
};
|
|
620
|
-
if (property === "has") return (id) =>
|
|
621
|
-
|
|
805
|
+
if (property === "has") return (id) => {
|
|
806
|
+
collectTree(context, at, {
|
|
807
|
+
kind: "node",
|
|
808
|
+
id
|
|
809
|
+
});
|
|
810
|
+
return contains(current(), id);
|
|
811
|
+
};
|
|
812
|
+
if (property === "parent") return (id) => {
|
|
813
|
+
collectTree(context, at, {
|
|
814
|
+
kind: "node",
|
|
815
|
+
id
|
|
816
|
+
});
|
|
817
|
+
return parent(current(), id);
|
|
818
|
+
};
|
|
622
819
|
if (property === "children") return (id) => {
|
|
820
|
+
collectTree(context, at, {
|
|
821
|
+
kind: "node",
|
|
822
|
+
id
|
|
823
|
+
});
|
|
623
824
|
const children$1 = children(current(), id);
|
|
624
825
|
return children$1 ? [...children$1] : void 0;
|
|
625
826
|
};
|
|
@@ -699,23 +900,6 @@ const createAccess = (context, initial = []) => {
|
|
|
699
900
|
}
|
|
700
901
|
return access(root);
|
|
701
902
|
};
|
|
702
|
-
const collectionAccess = (context, at) => {
|
|
703
|
-
const value = createAccess(context, at);
|
|
704
|
-
if (value === void 0) return {
|
|
705
|
-
get: () => {
|
|
706
|
-
assertActive(context);
|
|
707
|
-
},
|
|
708
|
-
has: () => {
|
|
709
|
-
assertActive(context);
|
|
710
|
-
return false;
|
|
711
|
-
},
|
|
712
|
-
ids: () => {
|
|
713
|
-
assertActive(context);
|
|
714
|
-
return [];
|
|
715
|
-
}
|
|
716
|
-
};
|
|
717
|
-
return value;
|
|
718
|
-
};
|
|
719
903
|
//#endregion
|
|
720
904
|
//#region core/src/runtime/contract.ts
|
|
721
905
|
var DocumentReentrancyError = class extends Error {
|
|
@@ -769,6 +953,6 @@ const readWith = (runtime, run, dependencies) => {
|
|
|
769
953
|
}
|
|
770
954
|
};
|
|
771
955
|
//#endregion
|
|
772
|
-
export { DocumentReentrancyError as a,
|
|
956
|
+
export { equalValue as C, equalTreeNode as S, checkKey as _, DocumentReentrancyError as a, copyTreeNode as b, replace as c, affected as d, belongs as f, ParseError as g, visitChangedLocations as h, DocumentDisposedError as i, snapshot as l, same as m, bindRuntimeAccess as n, TransactionRejected as o, indexedAddress as p, readWith as r, createAccess as s, accessOf as t, SubscriptionIndex as u, checkTreePayload as v, parse as w, copyValue as x, checkValue as y };
|
|
773
957
|
|
|
774
|
-
//# sourceMappingURL=access-
|
|
958
|
+
//# sourceMappingURL=access-CZXv_DIF.js.map
|