doxum 0.1.41 → 0.1.42
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 +36 -4
- 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-CNR6BS75.d.cts → contract-DovG1Yp-.d.cts} +2 -1
- package/dist/{contract-COgxO5sv.d.ts → contract-PqdXNaP8.d.ts} +2 -1
- package/dist/{dependency-DzxXGYe1.d.ts → dependency-BYiwTiBj.d.ts} +1 -1
- package/dist/{dependency-Cbf3C8eJ.d.cts → dependency-D0bo_xe_.d.cts} +1 -1
- package/dist/{driver-B7RR-VfX.js → driver-B7Hu6D0u.js} +15 -1
- package/dist/{driver-CN3dGxQI.cjs → driver-i4G4iVX0.cjs} +20 -0
- package/dist/index.cjs +137 -64
- package/dist/index.d.cts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +137 -64
- package/dist/local-sync.cjs +2 -5
- package/dist/local-sync.d.cts +1 -1
- package/dist/local-sync.d.ts +1 -1
- package/dist/local-sync.js +2 -5
- package/dist/react.cjs +38 -3
- package/dist/react.d.cts +19 -3
- package/dist/react.d.ts +19 -3
- package/dist/react.js +38 -4
- package/dist/{transform-D6njdP3k.cjs → transform-BPh55GWO.cjs} +80 -48
- package/dist/{transform-CKJ1ivhz.js → transform-BvDYPUMm.js} +80 -48
- package/package.json +1 -1
- package/skills/doxum-runtime/references/integrations.md +38 -7
- package/skills/doxum-runtime/references/invariants.md +13 -0
- package/skills/doxum-runtime/references/projections.md +22 -0
- package/skills/doxum-runtime/references/public-api.md +27 -8
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { A as ownProjections, C as snapshotProjectionValues, D as defineProcessor, E as snapshotCollectionView, M as projectionRef, N as profile, O as defineSource, S as compileProjectionDependencies, T as mapRead, _ as assertSynchronous, a as collectionChangeTouchesKey, b as ProjectionError, c as assertKeyedProjection, d as outputKind, f as createKeyRelation, g as assertScope, h as snapshotArray, i as collectionChangeIntersects, j as producerOf, k as isProjection, l as compileKeyedDependencies, m as sameArray, n as keyedAbsent, o as collectionHasStructuralChange, p as iterableMatchesArray, s as createCollectionChange, t as createKeyedTransform, u as createKeyedDependencyRuntime, v as createScheduler, w as collectionView, x as collectKeyedInvalidation, y as ProjectionDisposedError } from "./transform-
|
|
1
|
+
import { A as ownProjections, C as snapshotProjectionValues, D as defineProcessor, E as snapshotCollectionView, M as projectionRef, N as profile, O as defineSource, S as compileProjectionDependencies, T as mapRead, _ as assertSynchronous, a as collectionChangeTouchesKey, b as ProjectionError, c as assertKeyedProjection, d as outputKind, f as createKeyRelation, g as assertScope, h as snapshotArray, i as collectionChangeIntersects, j as producerOf, k as isProjection, l as compileKeyedDependencies, m as sameArray, n as keyedAbsent, o as collectionHasStructuralChange, p as iterableMatchesArray, s as createCollectionChange, t as createKeyedTransform, u as createKeyedDependencyRuntime, v as createScheduler, w as collectionView, x as collectKeyedInvalidation, y as ProjectionDisposedError } from "./transform-BvDYPUMm.js";
|
|
2
2
|
import { n as isPlainObject, r as isRecord, t as installOwn } from "./record-B2yRhYsc.js";
|
|
3
|
-
import { c as
|
|
3
|
+
import { _ as validate, c as addListener, d as fail, f as invalidValue, g as parent, h as is, i as contextOf, l as AddressIndex, m as contains$1, o as decodeChanges, p as children, r as bindContext, s as sealChanges, t as assertRuntimeWritable, u as MutationRejected } from "./driver-B7Hu6D0u.js";
|
|
4
4
|
//#region core/src/schema/model.ts
|
|
5
5
|
const schemaNodeOf = (schema) => schema;
|
|
6
6
|
const collectionEntryNode = (node) => node.kind === "map" || node.kind === "table" || node.kind === "list" ? node.value : void 0;
|
|
@@ -1622,10 +1622,7 @@ const createHistory = (input) => {
|
|
|
1622
1622
|
revision: () => revision,
|
|
1623
1623
|
subscribe: (listener) => {
|
|
1624
1624
|
if (disposed) throw new DocumentDisposedError();
|
|
1625
|
-
listeners
|
|
1626
|
-
return () => {
|
|
1627
|
-
listeners.delete(listener);
|
|
1628
|
-
};
|
|
1625
|
+
return addListener(listeners, listener);
|
|
1629
1626
|
},
|
|
1630
1627
|
undo: () => {
|
|
1631
1628
|
input.assertIdle();
|
|
@@ -2296,6 +2293,7 @@ const addRoot = (notification, listener) => {
|
|
|
2296
2293
|
};
|
|
2297
2294
|
notification.root.add(entry);
|
|
2298
2295
|
return () => {
|
|
2296
|
+
if (!entry.active) return;
|
|
2299
2297
|
entry.active = false;
|
|
2300
2298
|
if (!notification.notifying) notification.root.delete(entry);
|
|
2301
2299
|
else notification.cleanups.add(() => {
|
|
@@ -2669,7 +2667,9 @@ const select = (document, selector, equality = Object.is) => {
|
|
|
2669
2667
|
};
|
|
2670
2668
|
};
|
|
2671
2669
|
const installSubscription = () => {
|
|
2672
|
-
unsubscribeDocument
|
|
2670
|
+
const stop = unsubscribeDocument;
|
|
2671
|
+
unsubscribeDocument = void 0;
|
|
2672
|
+
stop?.();
|
|
2673
2673
|
unsubscribeDocument = dependencies.length > 0 ? context.notifications.subscribeTargets(dependencies, () => {
|
|
2674
2674
|
const result = evaluate();
|
|
2675
2675
|
if (result.rebound) installSubscription();
|
|
@@ -2689,15 +2689,22 @@ const select = (document, selector, equality = Object.is) => {
|
|
|
2689
2689
|
},
|
|
2690
2690
|
subscribe: (listener) => {
|
|
2691
2691
|
ensureCurrent();
|
|
2692
|
-
listeners
|
|
2693
|
-
if (listeners.size === 1) installSubscription();
|
|
2694
|
-
return () => {
|
|
2695
|
-
listeners.delete(listener);
|
|
2692
|
+
const unsubscribe = addListener(listeners, listener, () => {
|
|
2696
2693
|
if (!listeners.size) {
|
|
2697
|
-
unsubscribeDocument
|
|
2694
|
+
const stop = unsubscribeDocument;
|
|
2698
2695
|
unsubscribeDocument = void 0;
|
|
2696
|
+
stop?.();
|
|
2699
2697
|
}
|
|
2700
|
-
};
|
|
2698
|
+
});
|
|
2699
|
+
try {
|
|
2700
|
+
if (listeners.size === 1) installSubscription();
|
|
2701
|
+
} catch (error) {
|
|
2702
|
+
try {
|
|
2703
|
+
unsubscribe();
|
|
2704
|
+
} catch {}
|
|
2705
|
+
throw error;
|
|
2706
|
+
}
|
|
2707
|
+
return unsubscribe;
|
|
2701
2708
|
}
|
|
2702
2709
|
});
|
|
2703
2710
|
};
|
|
@@ -3687,6 +3694,33 @@ function createValueDerive(dependencies, compute, equality = Object.is) {
|
|
|
3687
3694
|
}
|
|
3688
3695
|
const derive = Object.assign(createValueDerive, { keyed: keyedDerive });
|
|
3689
3696
|
//#endregion
|
|
3697
|
+
//#region core/src/projection/cleanup.ts
|
|
3698
|
+
/** Owner-local, cancellable LIFO callbacks. Lifecycle admission stays with the owner. */
|
|
3699
|
+
const createCleanupStack = () => {
|
|
3700
|
+
const entries = /* @__PURE__ */ new Set();
|
|
3701
|
+
return {
|
|
3702
|
+
add(callback) {
|
|
3703
|
+
const entry = () => {
|
|
3704
|
+
assertSynchronous(callback());
|
|
3705
|
+
};
|
|
3706
|
+
entries.add(entry);
|
|
3707
|
+
return () => {
|
|
3708
|
+
entries.delete(entry);
|
|
3709
|
+
};
|
|
3710
|
+
},
|
|
3711
|
+
drain(failures) {
|
|
3712
|
+
for (const entry of [...entries].reverse()) {
|
|
3713
|
+
if (!entries.delete(entry)) continue;
|
|
3714
|
+
try {
|
|
3715
|
+
entry();
|
|
3716
|
+
} catch (error) {
|
|
3717
|
+
failures.push(error);
|
|
3718
|
+
}
|
|
3719
|
+
}
|
|
3720
|
+
}
|
|
3721
|
+
};
|
|
3722
|
+
};
|
|
3723
|
+
//#endregion
|
|
3690
3724
|
//#region core/src/projection/collection/changes.ts
|
|
3691
3725
|
/** Net transitions for one consumer's unconsumed interval; bounded by touched keys. */
|
|
3692
3726
|
const createCollectionChanges = () => {
|
|
@@ -4208,8 +4242,7 @@ const createCollectionOutput = (binding) => {
|
|
|
4208
4242
|
},
|
|
4209
4243
|
observe: (listener) => {
|
|
4210
4244
|
binding.check();
|
|
4211
|
-
observers
|
|
4212
|
-
return () => observers.delete(listener);
|
|
4245
|
+
return addListener(observers, listener);
|
|
4213
4246
|
},
|
|
4214
4247
|
hasConsumers: () => consumers.size > 0,
|
|
4215
4248
|
forEachConsumer: (run) => consumers.forEach((_pending, consumer) => run(consumer)),
|
|
@@ -4241,8 +4274,7 @@ const createCollectionOutput = (binding) => {
|
|
|
4241
4274
|
},
|
|
4242
4275
|
subscribe: (listener) => {
|
|
4243
4276
|
binding.check();
|
|
4244
|
-
listeners
|
|
4245
|
-
return () => listeners.delete(listener);
|
|
4277
|
+
return addListener(listeners, listener);
|
|
4246
4278
|
}
|
|
4247
4279
|
};
|
|
4248
4280
|
};
|
|
@@ -4357,8 +4389,7 @@ const createValueOutput = (binding) => {
|
|
|
4357
4389
|
},
|
|
4358
4390
|
observe: (listener) => {
|
|
4359
4391
|
binding.check();
|
|
4360
|
-
observers
|
|
4361
|
-
return () => observers.delete(listener);
|
|
4392
|
+
return addListener(observers, listener);
|
|
4362
4393
|
},
|
|
4363
4394
|
hasConsumers: () => consumers.size > 0,
|
|
4364
4395
|
forEachConsumer: (run) => consumers.forEach((_revision, consumer) => run(consumer)),
|
|
@@ -4387,8 +4418,7 @@ const createValueOutput = (binding) => {
|
|
|
4387
4418
|
},
|
|
4388
4419
|
subscribe: (listener) => {
|
|
4389
4420
|
binding.check();
|
|
4390
|
-
listeners
|
|
4391
|
-
return () => listeners.delete(listener);
|
|
4421
|
+
return addListener(listeners, listener);
|
|
4392
4422
|
}
|
|
4393
4423
|
};
|
|
4394
4424
|
};
|
|
@@ -4592,7 +4622,7 @@ const selectionAffects = (selection, change) => {
|
|
|
4592
4622
|
const createDirectReadable = (source) => Object.freeze({
|
|
4593
4623
|
current: source.current,
|
|
4594
4624
|
revision: source.revision,
|
|
4595
|
-
subscribe:
|
|
4625
|
+
subscribe: source.subscribe
|
|
4596
4626
|
});
|
|
4597
4627
|
/** Consumer-side selector tracking; it never mutates processor dependencies. */
|
|
4598
4628
|
const createSelectorReadable = (source, selector, equality = Object.is) => {
|
|
@@ -4696,15 +4726,22 @@ const createSelectorReadable = (source, selector, equality = Object.is) => {
|
|
|
4696
4726
|
},
|
|
4697
4727
|
subscribe: (listener) => {
|
|
4698
4728
|
ensureCurrent();
|
|
4699
|
-
listeners
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
listeners.delete(listener);
|
|
4703
|
-
if (!listeners.size && unsubscribeSource) {
|
|
4704
|
-
unsubscribeSource();
|
|
4729
|
+
const unsubscribe = addListener(listeners, listener, () => {
|
|
4730
|
+
if (!listeners.size) {
|
|
4731
|
+
const stop = unsubscribeSource;
|
|
4705
4732
|
unsubscribeSource = void 0;
|
|
4733
|
+
stop?.();
|
|
4706
4734
|
}
|
|
4707
|
-
};
|
|
4735
|
+
});
|
|
4736
|
+
try {
|
|
4737
|
+
installSource();
|
|
4738
|
+
} catch (error) {
|
|
4739
|
+
try {
|
|
4740
|
+
unsubscribe();
|
|
4741
|
+
} catch {}
|
|
4742
|
+
throw error;
|
|
4743
|
+
}
|
|
4744
|
+
return unsubscribe;
|
|
4708
4745
|
}
|
|
4709
4746
|
});
|
|
4710
4747
|
};
|
|
@@ -6002,7 +6039,7 @@ const createSourceRegistry = (scheduler) => {
|
|
|
6002
6039
|
//#endregion
|
|
6003
6040
|
//#region core/src/projection/readable/keyed.ts
|
|
6004
6041
|
/** Runtime-owned keyed consumer family over one materialized collection output. */
|
|
6005
|
-
const createProjectionItems = (source, checkOwner) => {
|
|
6042
|
+
const createProjectionItems = (source, checkOwner, checkSubscription) => {
|
|
6006
6043
|
if (source.kind !== "collection") throw new TypeError("Projection items require a keyed collection projection.");
|
|
6007
6044
|
let disposed = false;
|
|
6008
6045
|
const active = /* @__PURE__ */ new Map();
|
|
@@ -6131,12 +6168,12 @@ const createProjectionItems = (source, checkOwner) => {
|
|
|
6131
6168
|
subscribe: (listener) => {
|
|
6132
6169
|
check();
|
|
6133
6170
|
ensureObserved();
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
return () => {
|
|
6137
|
-
state.listeners.delete(listener);
|
|
6171
|
+
checkSubscription();
|
|
6172
|
+
const unsubscribe = addListener(state.listeners, listener, () => {
|
|
6138
6173
|
if (!state.listeners.size && !state.tracked) unregisterWaiting(state);
|
|
6139
|
-
};
|
|
6174
|
+
});
|
|
6175
|
+
if (!state.tracked && !state.ended) registerWaiting(state);
|
|
6176
|
+
return unsubscribe;
|
|
6140
6177
|
}
|
|
6141
6178
|
});
|
|
6142
6179
|
return state;
|
|
@@ -6193,8 +6230,8 @@ const createProjectionItems = (source, checkOwner) => {
|
|
|
6193
6230
|
},
|
|
6194
6231
|
subscribe: (listener) => {
|
|
6195
6232
|
check();
|
|
6196
|
-
|
|
6197
|
-
return (
|
|
6233
|
+
checkSubscription();
|
|
6234
|
+
return addListener(keyListeners, listener);
|
|
6198
6235
|
}
|
|
6199
6236
|
});
|
|
6200
6237
|
return {
|
|
@@ -6202,6 +6239,7 @@ const createProjectionItems = (source, checkOwner) => {
|
|
|
6202
6239
|
keys,
|
|
6203
6240
|
get: (key) => {
|
|
6204
6241
|
check();
|
|
6242
|
+
checkSubscription();
|
|
6205
6243
|
const current = source.current();
|
|
6206
6244
|
if (source.revision() !== settledRevision) pendingKeys.add(key);
|
|
6207
6245
|
const canonical = active.get(key);
|
|
@@ -6246,6 +6284,7 @@ const createProjectionRuntime = (options) => {
|
|
|
6246
6284
|
const materialized = /* @__PURE__ */ new WeakMap();
|
|
6247
6285
|
const publicViews = /* @__PURE__ */ new WeakMap();
|
|
6248
6286
|
const scopes = /* @__PURE__ */ new Set();
|
|
6287
|
+
const cleanups = createCleanupStack();
|
|
6249
6288
|
const rootItems = /* @__PURE__ */ new Map();
|
|
6250
6289
|
const disposeItemControllers = (registry, failures) => {
|
|
6251
6290
|
const controllers = [...registry.values()];
|
|
@@ -6275,7 +6314,7 @@ const createProjectionRuntime = (options) => {
|
|
|
6275
6314
|
const owner = definition.owner;
|
|
6276
6315
|
if (owner === void 0) return;
|
|
6277
6316
|
if (owner !== requester) throw new TypeError("Projection belongs to another scope.");
|
|
6278
|
-
if (
|
|
6317
|
+
if (requester?.status === "disposed") throw new ProjectionDisposedError();
|
|
6279
6318
|
};
|
|
6280
6319
|
const rememberScoped = (definition, requester) => {
|
|
6281
6320
|
if (requester && definition.owner === requester) requester.materialized.push(definition);
|
|
@@ -6355,25 +6394,33 @@ const createProjectionRuntime = (options) => {
|
|
|
6355
6394
|
assertOutput(output);
|
|
6356
6395
|
return output.revision();
|
|
6357
6396
|
},
|
|
6358
|
-
subscribe:
|
|
6359
|
-
|
|
6397
|
+
subscribe: (listener) => {
|
|
6398
|
+
scheduler.assertCommand();
|
|
6399
|
+
return output.subscribe(listener);
|
|
6400
|
+
},
|
|
6401
|
+
observe: (listener) => {
|
|
6402
|
+
scheduler.assertCommand();
|
|
6403
|
+
return output.observe(listener);
|
|
6404
|
+
}
|
|
6360
6405
|
});
|
|
6361
6406
|
};
|
|
6362
6407
|
const projectionItems = (projection, requester) => {
|
|
6408
|
+
scheduler.assertCommand();
|
|
6363
6409
|
const output = resolveOutput(projection, requester);
|
|
6364
6410
|
if (output.kind !== "collection") throw new TypeError("Projection items require a keyed collection projection.");
|
|
6365
6411
|
const registry = requester?.items ?? rootItems;
|
|
6366
6412
|
const existing = registry.get(output);
|
|
6367
6413
|
if (existing) return existing.items;
|
|
6368
6414
|
const controller = createProjectionItems(readableSource(projection, requester), () => {
|
|
6369
|
-
if (requester
|
|
6415
|
+
if (requester?.status === "disposed") throw new ProjectionDisposedError();
|
|
6370
6416
|
scheduler.ensureCurrent(output);
|
|
6371
6417
|
assertOutput(output);
|
|
6372
|
-
});
|
|
6418
|
+
}, scheduler.assertCommand);
|
|
6373
6419
|
registry.set(output, controller);
|
|
6374
6420
|
return controller.items;
|
|
6375
6421
|
};
|
|
6376
6422
|
const makeReadable = (projection, selector, equality, requester) => {
|
|
6423
|
+
scheduler.assertCommand();
|
|
6377
6424
|
const source = readableSource(projection, requester);
|
|
6378
6425
|
return selector ? createSelectorReadable(source, selector, equality) : createDirectReadable(source);
|
|
6379
6426
|
};
|
|
@@ -6381,8 +6428,8 @@ const createProjectionRuntime = (options) => {
|
|
|
6381
6428
|
return makeReadable(projection, selector, equality);
|
|
6382
6429
|
}
|
|
6383
6430
|
const inputAccess = (target, requester) => {
|
|
6384
|
-
scheduler.
|
|
6385
|
-
if (requester
|
|
6431
|
+
scheduler.assertCommand();
|
|
6432
|
+
if (requester?.status === "disposed") throw new ProjectionDisposedError();
|
|
6386
6433
|
const ref = projectionRef(target);
|
|
6387
6434
|
if (ref.output !== 0 || ref.producer.kind !== "source") throw new TypeError("Projection is not an input.");
|
|
6388
6435
|
if (ref.producer.source.kind !== "value-input" && ref.producer.source.kind !== "collection-input") throw new TypeError("Projection is not an input.");
|
|
@@ -6403,11 +6450,9 @@ const createProjectionRuntime = (options) => {
|
|
|
6403
6450
|
updateInput(target, valueOrRun);
|
|
6404
6451
|
}
|
|
6405
6452
|
const batch = (run, options) => scheduler.batch(run, options);
|
|
6406
|
-
const
|
|
6407
|
-
|
|
6408
|
-
|
|
6409
|
-
state.active = false;
|
|
6410
|
-
const failures = [];
|
|
6453
|
+
const releaseScope = (state, failures) => {
|
|
6454
|
+
state.status = "disposed";
|
|
6455
|
+
scopes.delete(state);
|
|
6411
6456
|
disposeScopeConsumers(state, failures);
|
|
6412
6457
|
for (let index = state.materialized.length - 1; index >= 0; index--) {
|
|
6413
6458
|
const definition = state.materialized[index];
|
|
@@ -6422,24 +6467,38 @@ const createProjectionRuntime = (options) => {
|
|
|
6422
6467
|
}
|
|
6423
6468
|
}
|
|
6424
6469
|
state.materialized.length = 0;
|
|
6425
|
-
|
|
6470
|
+
};
|
|
6471
|
+
const disposeScope = (state) => {
|
|
6472
|
+
if (state.status !== "active") return;
|
|
6473
|
+
scheduler.assertCommand();
|
|
6474
|
+
state.status = "closing";
|
|
6475
|
+
const failures = [];
|
|
6476
|
+
try {
|
|
6477
|
+
scheduler.cleanup(() => state.cleanups.drain(failures));
|
|
6478
|
+
} catch (error) {
|
|
6479
|
+
failures.push(error);
|
|
6480
|
+
} finally {
|
|
6481
|
+
scheduler.releaseOwned(() => releaseScope(state, failures));
|
|
6482
|
+
}
|
|
6426
6483
|
throwCleanupFailures(failures, "Projection scope cleanup failed.");
|
|
6427
6484
|
};
|
|
6428
6485
|
const createScope = () => {
|
|
6429
|
-
scheduler.
|
|
6486
|
+
scheduler.assertCommand();
|
|
6430
6487
|
const state = {
|
|
6431
|
-
|
|
6488
|
+
status: "active",
|
|
6489
|
+
cleanups: createCleanupStack(),
|
|
6432
6490
|
materialized: [],
|
|
6433
6491
|
subscriptions: /* @__PURE__ */ new Set(),
|
|
6434
6492
|
items: /* @__PURE__ */ new Map()
|
|
6435
6493
|
};
|
|
6436
6494
|
scopes.add(state);
|
|
6437
6495
|
const assertActive = () => {
|
|
6438
|
-
if (
|
|
6496
|
+
if (state.status === "disposed") throw new ProjectionDisposedError();
|
|
6439
6497
|
scheduler.assertActive();
|
|
6440
6498
|
};
|
|
6441
6499
|
function own(target) {
|
|
6442
6500
|
assertActive();
|
|
6501
|
+
scheduler.assertCommand();
|
|
6443
6502
|
const projections = [];
|
|
6444
6503
|
const collect = (value) => {
|
|
6445
6504
|
if (isProjection(value)) {
|
|
@@ -6509,6 +6568,11 @@ const createProjectionRuntime = (options) => {
|
|
|
6509
6568
|
},
|
|
6510
6569
|
update: scopeUpdate,
|
|
6511
6570
|
batch: scopeBatch,
|
|
6571
|
+
onDispose: (callback) => {
|
|
6572
|
+
assertActive();
|
|
6573
|
+
scheduler.assertCommand();
|
|
6574
|
+
return state.cleanups.add(callback);
|
|
6575
|
+
},
|
|
6512
6576
|
dispose: () => disposeScope(state)
|
|
6513
6577
|
});
|
|
6514
6578
|
};
|
|
@@ -6519,24 +6583,33 @@ const createProjectionRuntime = (options) => {
|
|
|
6519
6583
|
update,
|
|
6520
6584
|
batch,
|
|
6521
6585
|
scope: createScope,
|
|
6586
|
+
onDispose: (callback) => {
|
|
6587
|
+
scheduler.assertCommand();
|
|
6588
|
+
return cleanups.add(callback);
|
|
6589
|
+
},
|
|
6522
6590
|
dispose: () => {
|
|
6523
|
-
if (!scheduler.
|
|
6524
|
-
scheduler.assertIdle();
|
|
6591
|
+
if (!scheduler.beginClose()) return;
|
|
6525
6592
|
const failures = [];
|
|
6526
|
-
|
|
6527
|
-
|
|
6528
|
-
disposeScopeConsumers(scope, failures);
|
|
6529
|
-
scope.materialized.length = 0;
|
|
6530
|
-
}
|
|
6531
|
-
scopes.clear();
|
|
6532
|
-
disposeItemControllers(rootItems, failures);
|
|
6593
|
+
const owned = [...scopes].reverse();
|
|
6594
|
+
for (const scope of owned) scope.status = "closing";
|
|
6533
6595
|
try {
|
|
6534
|
-
|
|
6596
|
+
scheduler.cleanup(() => {
|
|
6597
|
+
for (const scope of owned) scope.cleanups.drain(failures);
|
|
6598
|
+
cleanups.drain(failures);
|
|
6599
|
+
});
|
|
6535
6600
|
} catch (error) {
|
|
6536
6601
|
failures.push(error);
|
|
6537
6602
|
}
|
|
6538
6603
|
try {
|
|
6539
|
-
scheduler.dispose()
|
|
6604
|
+
scheduler.dispose(() => {
|
|
6605
|
+
for (const scope of owned) {
|
|
6606
|
+
scope.status = "disposed";
|
|
6607
|
+
scope.materialized.length = 0;
|
|
6608
|
+
disposeScopeConsumers(scope, failures);
|
|
6609
|
+
}
|
|
6610
|
+
scopes.clear();
|
|
6611
|
+
disposeItemControllers(rootItems, failures);
|
|
6612
|
+
}, sources.dispose);
|
|
6540
6613
|
} catch (error) {
|
|
6541
6614
|
failures.push(error);
|
|
6542
6615
|
}
|
package/dist/local-sync.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_record = require("./record-ChYUi8PP.cjs");
|
|
3
|
-
const require_driver = require("./driver-
|
|
3
|
+
const require_driver = require("./driver-i4G4iVX0.cjs");
|
|
4
4
|
//#region core/src/local-sync/error.ts
|
|
5
5
|
var LocalSyncError = class extends Error {
|
|
6
6
|
code;
|
|
@@ -467,10 +467,7 @@ const attachLocalSync = async (input) => {
|
|
|
467
467
|
revision: () => stateRevision,
|
|
468
468
|
subscribe: (listener) => {
|
|
469
469
|
if (disposed) throw new LocalSyncError("disposed", "Local sync has been disposed.");
|
|
470
|
-
|
|
471
|
-
return () => {
|
|
472
|
-
stateListeners.delete(listener);
|
|
473
|
-
};
|
|
470
|
+
return require_driver.addListener(stateListeners, listener);
|
|
474
471
|
}
|
|
475
472
|
}),
|
|
476
473
|
flush: async () => {
|
package/dist/local-sync.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { W as ObjectSchema, g as Readable, s as DocumentRuntime } from "./contract-
|
|
1
|
+
import { W as ObjectSchema, g as Readable, s as DocumentRuntime } from "./contract-DovG1Yp-.cjs";
|
|
2
2
|
|
|
3
3
|
//#region core/src/local-sync/json.d.ts
|
|
4
4
|
type JsonPrimitive = null | boolean | number | string;
|
package/dist/local-sync.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { W as ObjectSchema, g as Readable, s as DocumentRuntime } from "./contract-
|
|
1
|
+
import { W as ObjectSchema, g as Readable, s as DocumentRuntime } from "./contract-PqdXNaP8.js";
|
|
2
2
|
|
|
3
3
|
//#region core/src/local-sync/json.d.ts
|
|
4
4
|
type JsonPrimitive = null | boolean | number | string;
|
package/dist/local-sync.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as isPlainObject, r as isRecord } from "./record-B2yRhYsc.js";
|
|
2
|
-
import { a as changeCount, n as installRuntimeWriteDriver, o as decodeChanges } from "./driver-
|
|
2
|
+
import { a as changeCount, c as addListener, n as installRuntimeWriteDriver, o as decodeChanges } from "./driver-B7Hu6D0u.js";
|
|
3
3
|
//#region core/src/local-sync/error.ts
|
|
4
4
|
var LocalSyncError = class extends Error {
|
|
5
5
|
code;
|
|
@@ -466,10 +466,7 @@ const attachLocalSync = async (input) => {
|
|
|
466
466
|
revision: () => stateRevision,
|
|
467
467
|
subscribe: (listener) => {
|
|
468
468
|
if (disposed) throw new LocalSyncError("disposed", "Local sync has been disposed.");
|
|
469
|
-
stateListeners
|
|
470
|
-
return () => {
|
|
471
|
-
stateListeners.delete(listener);
|
|
472
|
-
};
|
|
469
|
+
return addListener(stateListeners, listener);
|
|
473
470
|
}
|
|
474
471
|
}),
|
|
475
472
|
flush: async () => {
|
package/dist/react.cjs
CHANGED
|
@@ -1,9 +1,43 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
let doxum = require("doxum");
|
|
3
2
|
let react = require("react");
|
|
4
|
-
|
|
3
|
+
let doxum = require("doxum");
|
|
4
|
+
//#region react/src/projection.ts
|
|
5
5
|
const ProjectionContext = (0, react.createContext)(void 0);
|
|
6
|
-
const
|
|
6
|
+
const ManagedProjectionProvider = ({ runtime, fallback, children }) => {
|
|
7
|
+
const generation = (0, react.useRef)(0);
|
|
8
|
+
const [owner, setOwner] = (0, react.useState)();
|
|
9
|
+
(0, react.useEffect)(() => {
|
|
10
|
+
const scope = runtime.scope();
|
|
11
|
+
setOwner({
|
|
12
|
+
runtime,
|
|
13
|
+
scope,
|
|
14
|
+
generation: ++generation.current
|
|
15
|
+
});
|
|
16
|
+
return () => scope.dispose();
|
|
17
|
+
}, [runtime]);
|
|
18
|
+
if (!owner || owner.runtime !== runtime) return fallback ?? null;
|
|
19
|
+
return (0, react.createElement)(ProjectionContext.Provider, {
|
|
20
|
+
value: owner.scope,
|
|
21
|
+
key: owner.generation
|
|
22
|
+
}, children);
|
|
23
|
+
};
|
|
24
|
+
/** runtime creates an owned scope after commit; value borrows an external owner. */
|
|
25
|
+
const ProjectionProvider = (props) => {
|
|
26
|
+
if (props.runtime !== void 0) {
|
|
27
|
+
if (props.value !== void 0) throw new TypeError("ProjectionProvider accepts runtime or value, not both.");
|
|
28
|
+
return (0, react.createElement)(ManagedProjectionProvider, props);
|
|
29
|
+
}
|
|
30
|
+
if (props.value === void 0) throw new TypeError("ProjectionProvider requires runtime or value.");
|
|
31
|
+
return (0, react.createElement)(ProjectionContext.Provider, { value: props.value }, props.children);
|
|
32
|
+
};
|
|
33
|
+
/** Reads a scope supplied by a managed Provider or an explicitly injected scope. */
|
|
34
|
+
const useProjectionScope = () => {
|
|
35
|
+
const owner = (0, react.useContext)(ProjectionContext);
|
|
36
|
+
if (!owner || !("own" in owner)) throw new Error("A ProjectionScope provider is required.");
|
|
37
|
+
return owner;
|
|
38
|
+
};
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region react/src/hooks.ts
|
|
7
41
|
function useProjection(projection, selector, equality = Object.is) {
|
|
8
42
|
const owner = (0, react.useContext)(ProjectionContext);
|
|
9
43
|
if (!owner) throw new Error("ProjectionRuntime is required.");
|
|
@@ -56,4 +90,5 @@ exports.useDocumentSelector = useDocumentSelector;
|
|
|
56
90
|
exports.useHistory = useHistory;
|
|
57
91
|
exports.useInput = useInput;
|
|
58
92
|
exports.useProjection = useProjection;
|
|
93
|
+
exports.useProjectionScope = useProjectionScope;
|
|
59
94
|
exports.useReadable = useReadable;
|
package/dist/react.d.cts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import * as _$react from "react";
|
|
2
1
|
import { CollectionInput, CollectionInputDraft, DocumentSelector, HistoryState, Input, LocalHistory, ObjectSchema, OperationResult, Projection, ProjectionRuntime, ProjectionScope, Readable, ReadonlyDocument } from "doxum";
|
|
2
|
+
import { ReactElement, ReactNode } from "react";
|
|
3
3
|
|
|
4
4
|
//#region react/src/hooks.d.ts
|
|
5
|
-
declare const ProjectionProvider: _$react.Provider<ProjectionRuntime | ProjectionScope | undefined>;
|
|
6
5
|
declare function useProjection<T>(projection: Projection<T>): T;
|
|
7
6
|
declare function useProjection<T, R>(projection: Projection<T>, selector: (value: T) => R, equality?: (previous: R, next: R) => boolean): R;
|
|
8
7
|
declare function useInput<T>(input: Input<T>): readonly [T, (value: T) => void];
|
|
@@ -14,4 +13,21 @@ declare function useHistory<TCommit>(history: LocalHistory<TCommit>): HistorySta
|
|
|
14
13
|
redo(): OperationResult<TCommit>;
|
|
15
14
|
};
|
|
16
15
|
//#endregion
|
|
17
|
-
|
|
16
|
+
//#region react/src/projection.d.ts
|
|
17
|
+
type ProjectionProviderProps = {
|
|
18
|
+
readonly children?: ReactNode;
|
|
19
|
+
} & ({
|
|
20
|
+
readonly runtime: ProjectionRuntime;
|
|
21
|
+
readonly fallback?: ReactNode;
|
|
22
|
+
readonly value?: never;
|
|
23
|
+
} | {
|
|
24
|
+
readonly value: ProjectionRuntime | ProjectionScope;
|
|
25
|
+
readonly runtime?: never;
|
|
26
|
+
readonly fallback?: never;
|
|
27
|
+
});
|
|
28
|
+
/** runtime creates an owned scope after commit; value borrows an external owner. */
|
|
29
|
+
declare const ProjectionProvider: (props: ProjectionProviderProps) => ReactElement;
|
|
30
|
+
/** Reads a scope supplied by a managed Provider or an explicitly injected scope. */
|
|
31
|
+
declare const useProjectionScope: () => ProjectionScope;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { ProjectionProvider, type ProjectionProviderProps, useDocumentSelector, useHistory, useInput, useProjection, useProjectionScope, useReadable };
|
package/dist/react.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
+
import { ReactElement, ReactNode } from "react";
|
|
1
2
|
import { CollectionInput, CollectionInputDraft, DocumentSelector, HistoryState, Input, LocalHistory, ObjectSchema, OperationResult, Projection, ProjectionRuntime, ProjectionScope, Readable, ReadonlyDocument } from "doxum";
|
|
2
|
-
import * as _$react from "react";
|
|
3
3
|
|
|
4
4
|
//#region react/src/hooks.d.ts
|
|
5
|
-
declare const ProjectionProvider: _$react.Provider<ProjectionRuntime | ProjectionScope | undefined>;
|
|
6
5
|
declare function useProjection<T>(projection: Projection<T>): T;
|
|
7
6
|
declare function useProjection<T, R>(projection: Projection<T>, selector: (value: T) => R, equality?: (previous: R, next: R) => boolean): R;
|
|
8
7
|
declare function useInput<T>(input: Input<T>): readonly [T, (value: T) => void];
|
|
@@ -14,4 +13,21 @@ declare function useHistory<TCommit>(history: LocalHistory<TCommit>): HistorySta
|
|
|
14
13
|
redo(): OperationResult<TCommit>;
|
|
15
14
|
};
|
|
16
15
|
//#endregion
|
|
17
|
-
|
|
16
|
+
//#region react/src/projection.d.ts
|
|
17
|
+
type ProjectionProviderProps = {
|
|
18
|
+
readonly children?: ReactNode;
|
|
19
|
+
} & ({
|
|
20
|
+
readonly runtime: ProjectionRuntime;
|
|
21
|
+
readonly fallback?: ReactNode;
|
|
22
|
+
readonly value?: never;
|
|
23
|
+
} | {
|
|
24
|
+
readonly value: ProjectionRuntime | ProjectionScope;
|
|
25
|
+
readonly runtime?: never;
|
|
26
|
+
readonly fallback?: never;
|
|
27
|
+
});
|
|
28
|
+
/** runtime creates an owned scope after commit; value borrows an external owner. */
|
|
29
|
+
declare const ProjectionProvider: (props: ProjectionProviderProps) => ReactElement;
|
|
30
|
+
/** Reads a scope supplied by a managed Provider or an explicitly injected scope. */
|
|
31
|
+
declare const useProjectionScope: () => ProjectionScope;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { ProjectionProvider, type ProjectionProviderProps, useDocumentSelector, useHistory, useInput, useProjection, useProjectionScope, useReadable };
|
package/dist/react.js
CHANGED
|
@@ -1,8 +1,42 @@
|
|
|
1
|
+
import { createContext, createElement, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
1
2
|
import { select } from "doxum";
|
|
2
|
-
|
|
3
|
-
//#region react/src/hooks.ts
|
|
3
|
+
//#region react/src/projection.ts
|
|
4
4
|
const ProjectionContext = createContext(void 0);
|
|
5
|
-
const
|
|
5
|
+
const ManagedProjectionProvider = ({ runtime, fallback, children }) => {
|
|
6
|
+
const generation = useRef(0);
|
|
7
|
+
const [owner, setOwner] = useState();
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
const scope = runtime.scope();
|
|
10
|
+
setOwner({
|
|
11
|
+
runtime,
|
|
12
|
+
scope,
|
|
13
|
+
generation: ++generation.current
|
|
14
|
+
});
|
|
15
|
+
return () => scope.dispose();
|
|
16
|
+
}, [runtime]);
|
|
17
|
+
if (!owner || owner.runtime !== runtime) return fallback ?? null;
|
|
18
|
+
return createElement(ProjectionContext.Provider, {
|
|
19
|
+
value: owner.scope,
|
|
20
|
+
key: owner.generation
|
|
21
|
+
}, children);
|
|
22
|
+
};
|
|
23
|
+
/** runtime creates an owned scope after commit; value borrows an external owner. */
|
|
24
|
+
const ProjectionProvider = (props) => {
|
|
25
|
+
if (props.runtime !== void 0) {
|
|
26
|
+
if (props.value !== void 0) throw new TypeError("ProjectionProvider accepts runtime or value, not both.");
|
|
27
|
+
return createElement(ManagedProjectionProvider, props);
|
|
28
|
+
}
|
|
29
|
+
if (props.value === void 0) throw new TypeError("ProjectionProvider requires runtime or value.");
|
|
30
|
+
return createElement(ProjectionContext.Provider, { value: props.value }, props.children);
|
|
31
|
+
};
|
|
32
|
+
/** Reads a scope supplied by a managed Provider or an explicitly injected scope. */
|
|
33
|
+
const useProjectionScope = () => {
|
|
34
|
+
const owner = useContext(ProjectionContext);
|
|
35
|
+
if (!owner || !("own" in owner)) throw new Error("A ProjectionScope provider is required.");
|
|
36
|
+
return owner;
|
|
37
|
+
};
|
|
38
|
+
//#endregion
|
|
39
|
+
//#region react/src/hooks.ts
|
|
6
40
|
function useProjection(projection, selector, equality = Object.is) {
|
|
7
41
|
const owner = useContext(ProjectionContext);
|
|
8
42
|
if (!owner) throw new Error("ProjectionRuntime is required.");
|
|
@@ -50,4 +84,4 @@ function useHistory(history) {
|
|
|
50
84
|
]);
|
|
51
85
|
}
|
|
52
86
|
//#endregion
|
|
53
|
-
export { ProjectionProvider, useDocumentSelector, useHistory, useInput, useProjection, useReadable };
|
|
87
|
+
export { ProjectionProvider, useDocumentSelector, useHistory, useInput, useProjection, useProjectionScope, useReadable };
|