@party-stack/ontology 0.19.1 → 0.21.0
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 -0
- package/lib/OntologyPullConfig.d.ts +4 -17
- package/lib/OntologyPullConfig.d.ts.map +1 -1
- package/lib/authentication.d.ts +1068 -0
- package/lib/authentication.d.ts.map +1 -0
- package/lib/authentication.js +55 -0
- package/lib/authentication.js.map +1 -0
- package/lib/cli/index.js +19 -45
- package/lib/cli/index.js.map +1 -1
- package/lib/cli/pull.d.ts.map +1 -1
- package/lib/cli/pull.js +16 -29
- package/lib/cli/pull.js.map +1 -1
- package/lib/client.d.ts +11 -0
- package/lib/client.d.ts.map +1 -0
- package/lib/client.js +21 -0
- package/lib/client.js.map +1 -0
- package/lib/examples/blog.d.ts +2 -387
- package/lib/examples/blog.js +1 -353
- package/lib/examples/blog.live-queries.d.ts +1 -1
- package/lib/examples/blog.live-queries.d.ts.map +1 -1
- package/lib/examples/blog.live-queries.js +1 -1
- package/lib/examples/blog.live-queries.js.map +1 -1
- package/lib/examples/generated/collections.d.ts +7 -0
- package/lib/examples/generated/collections.d.ts.map +1 -0
- package/lib/examples/generated/collections.js +12 -0
- package/lib/examples/generated/collections.js.map +1 -0
- package/lib/examples/generated/live.d.ts +2 -2
- package/lib/examples/generated/live.d.ts.map +1 -1
- package/lib/examples/generated/live.js.map +1 -1
- package/lib/http.d.ts +13 -0
- package/lib/http.d.ts.map +1 -0
- package/lib/http.js +29 -0
- package/lib/http.js.map +1 -0
- package/lib/index.d.ts +19 -25
- package/lib/index.js +9 -15
- package/lib/json/index.d.ts +1 -16
- package/lib/json/index.js +2 -132
- package/lib/live/LiveOntology.d.ts +114 -50
- package/lib/live/LiveOntology.d.ts.map +1 -1
- package/lib/live/LiveOntology.js +23 -103
- package/lib/live/LiveOntology.js.map +1 -1
- package/lib/live/actions/createLiveOntologyAction.d.ts +15 -16
- package/lib/live/actions/createLiveOntologyAction.d.ts.map +1 -1
- package/lib/live/actions/createLiveOntologyAction.js +3 -11
- package/lib/live/actions/createLiveOntologyAction.js.map +1 -1
- package/lib/live/actions/types.d.ts +21 -0
- package/lib/live/actions/types.d.ts.map +1 -0
- package/lib/live/attachments/createLiveOntologyAttachments.d.ts +30 -19
- package/lib/live/attachments/createLiveOntologyAttachments.d.ts.map +1 -1
- package/lib/live/attachments/createLiveOntologyAttachments.js +43 -60
- package/lib/live/attachments/createLiveOntologyAttachments.js.map +1 -1
- package/lib/live/attachments/types.d.ts +4 -3
- package/lib/live/index.d.ts +10 -10
- package/lib/live/index.js +5 -6
- package/lib/live/mutators/createReadTx.d.ts +5 -0
- package/lib/live/mutators/createReadTx.d.ts.map +1 -0
- package/lib/live/mutators/createReadTx.js +19 -0
- package/lib/live/mutators/createReadTx.js.map +1 -0
- package/lib/live/mutators/types.d.ts +7 -2
- package/lib/live/mutators/types.d.ts.map +1 -1
- package/lib/live/objects/types.d.ts +6 -0
- package/lib/live/objects/types.d.ts.map +1 -0
- package/lib/live/outbox/types.d.ts +24 -15
- package/lib/live/outbox/types.d.ts.map +1 -1
- package/lib/live/outbox/types.js +1 -11
- package/lib/live/pins.d.ts +51 -0
- package/lib/live/pins.d.ts.map +1 -0
- package/lib/live/pins.js +113 -0
- package/lib/live/pins.js.map +1 -0
- package/lib/live/storageBackend.d.ts +50 -0
- package/lib/live/storageBackend.d.ts.map +1 -0
- package/lib/live/storageBackend.js +42 -0
- package/lib/live/storageBackend.js.map +1 -0
- package/lib/local.d.ts +15 -0
- package/lib/local.d.ts.map +1 -0
- package/lib/local.js +19 -0
- package/lib/local.js.map +1 -0
- package/lib/meta/generated/collections.d.ts +7 -0
- package/lib/meta/generated/collections.d.ts.map +1 -0
- package/lib/meta/generated/collections.js +15 -0
- package/lib/meta/generated/collections.js.map +1 -0
- package/lib/meta/generated/live.d.ts +3 -3
- package/lib/meta/generated/live.d.ts.map +1 -1
- package/lib/meta/generated/live.js +2 -2
- package/lib/meta/generated/live.js.map +1 -1
- package/lib/meta/pull.d.ts +5 -9
- package/lib/meta/pull.d.ts.map +1 -1
- package/lib/meta/pull.js +5 -43
- package/lib/meta/pull.js.map +1 -1
- package/lib/query.d.ts +1 -0
- package/lib/query.js +2 -0
- package/lib/runtime/host.d.ts +35 -0
- package/lib/runtime/host.d.ts.map +1 -0
- package/lib/runtime/host.js +39 -0
- package/lib/runtime/host.js.map +1 -0
- package/lib/runtime/index.d.ts +2 -0
- package/lib/runtime/index.js +1 -0
- package/lib/runtime/live.d.ts +25 -0
- package/lib/runtime/live.d.ts.map +1 -0
- package/lib/runtime/live.js +31 -0
- package/lib/runtime/live.js.map +1 -0
- package/lib/runtime/resource.d.ts +24 -0
- package/lib/runtime/resource.d.ts.map +1 -0
- package/lib/runtime/resource.js +127 -0
- package/lib/runtime/resource.js.map +1 -0
- package/lib/runtime/transactions.d.ts +27 -0
- package/lib/runtime/transactions.d.ts.map +1 -0
- package/lib/runtime/transactions.js +188 -0
- package/lib/runtime/transactions.js.map +1 -0
- package/lib/runtime/view.d.ts +25 -0
- package/lib/runtime/view.d.ts.map +1 -0
- package/lib/runtime/view.js +256 -0
- package/lib/runtime/view.js.map +1 -0
- package/lib/tanstack/collections.d.ts +73 -0
- package/lib/tanstack/collections.d.ts.map +1 -0
- package/lib/tanstack/collections.js +495 -0
- package/lib/tanstack/collections.js.map +1 -0
- package/lib/tanstack/createLocalCollection.d.ts +14 -0
- package/lib/tanstack/createLocalCollection.d.ts.map +1 -0
- package/lib/tanstack/createLocalCollection.js +9 -0
- package/lib/tanstack/createLocalCollection.js.map +1 -0
- package/lib/tanstack/descriptors.d.ts +33 -0
- package/lib/tanstack/descriptors.d.ts.map +1 -0
- package/lib/tanstack/descriptors.js +38 -0
- package/lib/tanstack/descriptors.js.map +1 -0
- package/lib/tanstack/diagnostics.d.ts +23 -0
- package/lib/tanstack/diagnostics.d.ts.map +1 -0
- package/lib/tanstack/diagnostics.js +14 -0
- package/lib/tanstack/diagnostics.js.map +1 -0
- package/lib/tanstack/index.d.ts +6 -0
- package/lib/tanstack/index.js +6 -0
- package/lib/tanstack/localCollection.d.ts +14 -0
- package/lib/tanstack/localCollection.d.ts.map +1 -0
- package/lib/tanstack/localCollection.js +73 -0
- package/lib/tanstack/localCollection.js.map +1 -0
- package/lib/tanstack/subset.d.ts +28 -0
- package/lib/tanstack/subset.d.ts.map +1 -0
- package/lib/tanstack/subset.js +290 -0
- package/lib/tanstack/subset.js.map +1 -0
- package/lib/testing/sqlite.d.ts +40 -0
- package/lib/testing/sqlite.d.ts.map +1 -0
- package/lib/testing/sqlite.js +409 -0
- package/lib/testing/sqlite.js.map +1 -0
- package/lib/testing/sqliteBackend.d.ts +68 -0
- package/lib/testing/sqliteBackend.d.ts.map +1 -0
- package/lib/testing/sqliteBackend.js +34 -0
- package/lib/testing/sqliteBackend.js.map +1 -0
- package/lib/utils/index.d.ts +1 -8
- package/lib/utils/index.js +2 -5
- package/lib/utils/values.d.ts +1 -33
- package/lib/worker.d.ts +19 -0
- package/lib/worker.d.ts.map +1 -0
- package/lib/worker.js +46 -0
- package/lib/worker.js.map +1 -0
- package/package.json +54 -19
- package/lib/_virtual/_rolldown/runtime.js +0 -13
- package/lib/cli/format.d.ts +0 -4
- package/lib/cli/format.d.ts.map +0 -1
- package/lib/cli/format.js +0 -19
- package/lib/cli/format.js.map +0 -1
- package/lib/cli/generate.d.ts +0 -10
- package/lib/cli/generate.d.ts.map +0 -1
- package/lib/cli/generate.js +0 -108
- package/lib/cli/generate.js.map +0 -1
- package/lib/examples/blog.d.ts.map +0 -1
- package/lib/examples/blog.js.map +0 -1
- package/lib/generate/builders.d.ts +0 -12
- package/lib/generate/builders.d.ts.map +0 -1
- package/lib/generate/builders.js +0 -58
- package/lib/generate/builders.js.map +0 -1
- package/lib/generate/constants.d.ts +0 -5
- package/lib/generate/constants.d.ts.map +0 -1
- package/lib/generate/constants.js +0 -28
- package/lib/generate/constants.js.map +0 -1
- package/lib/generate/index.d.ts +0 -6
- package/lib/generate/index.js +0 -6
- package/lib/generate/live.d.ts +0 -12
- package/lib/generate/live.d.ts.map +0 -1
- package/lib/generate/live.js +0 -48
- package/lib/generate/live.js.map +0 -1
- package/lib/generate/ontology.d.ts +0 -8
- package/lib/generate/ontology.d.ts.map +0 -1
- package/lib/generate/ontology.js +0 -501
- package/lib/generate/ontology.js.map +0 -1
- package/lib/generate/types.d.ts +0 -17
- package/lib/generate/types.d.ts.map +0 -1
- package/lib/generate/types.js +0 -216
- package/lib/generate/types.js.map +0 -1
- package/lib/generate/utils/buildJsDocs.d.ts +0 -10
- package/lib/generate/utils/buildJsDocs.d.ts.map +0 -1
- package/lib/generate/utils/buildJsDocs.js +0 -16
- package/lib/generate/utils/buildJsDocs.js.map +0 -1
- package/lib/infer.d.ts +0 -222
- package/lib/infer.d.ts.map +0 -1
- package/lib/infer.js +0 -14
- package/lib/infer.js.map +0 -1
- package/lib/installation/createMetaOntologyConfiguration.d.ts +0 -10
- package/lib/installation/createMetaOntologyConfiguration.d.ts.map +0 -1
- package/lib/installation/createMetaOntologyConfiguration.js +0 -16
- package/lib/installation/createMetaOntologyConfiguration.js.map +0 -1
- package/lib/installation/createOntologyBackendInstallation.d.ts +0 -5
- package/lib/installation/createOntologyBackendInstallation.d.ts.map +0 -1
- package/lib/installation/createOntologyBackendInstallation.js +0 -221
- package/lib/installation/createOntologyBackendInstallation.js.map +0 -1
- package/lib/installation/index.d.ts +0 -4
- package/lib/installation/index.js +0 -3
- package/lib/installation/types.d.ts +0 -94
- package/lib/installation/types.d.ts.map +0 -1
- package/lib/ir/generated/builders.d.ts +0 -380
- package/lib/ir/generated/builders.d.ts.map +0 -1
- package/lib/ir/generated/builders.js +0 -186
- package/lib/ir/generated/builders.js.map +0 -1
- package/lib/ir/generated/constants.d.ts +0 -265
- package/lib/ir/generated/constants.d.ts.map +0 -1
- package/lib/ir/generated/constants.js +0 -165
- package/lib/ir/generated/constants.js.map +0 -1
- package/lib/ir/generated/types.d.ts +0 -416
- package/lib/ir/generated/types.d.ts.map +0 -1
- package/lib/ir/index.d.ts +0 -4
- package/lib/ir/index.js +0 -3
- package/lib/ir/schema.d.ts +0 -2246
- package/lib/ir/schema.d.ts.map +0 -1
- package/lib/ir/schema.js +0 -1187
- package/lib/ir/schema.js.map +0 -1
- package/lib/ir/validate.d.ts +0 -8
- package/lib/ir/validate.d.ts.map +0 -1
- package/lib/ir/validate.js +0 -623
- package/lib/ir/validate.js.map +0 -1
- package/lib/json/index.d.ts.map +0 -1
- package/lib/json/index.js.map +0 -1
- package/lib/lenses.d.ts +0 -21
- package/lib/lenses.d.ts.map +0 -1
- package/lib/lenses.js +0 -110
- package/lib/lenses.js.map +0 -1
- package/lib/live/OntologyBackendAdapter.d.ts +0 -100
- package/lib/live/OntologyBackendAdapter.d.ts.map +0 -1
- package/lib/live/OntologyBackendAdapter.js +0 -1
- package/lib/live/actions/createLiveOntologyActions.d.ts +0 -28
- package/lib/live/actions/createLiveOntologyActions.d.ts.map +0 -1
- package/lib/live/actions/createLiveOntologyActions.js +0 -139
- package/lib/live/actions/createLiveOntologyActions.js.map +0 -1
- package/lib/live/actions/prepareActionParameters.d.ts +0 -19
- package/lib/live/actions/prepareActionParameters.d.ts.map +0 -1
- package/lib/live/actions/prepareActionParameters.js +0 -213
- package/lib/live/actions/prepareActionParameters.js.map +0 -1
- package/lib/live/attachments/attachmentSources.d.ts +0 -10
- package/lib/live/attachments/attachmentSources.d.ts.map +0 -1
- package/lib/live/attachments/attachmentSources.js +0 -64
- package/lib/live/attachments/attachmentSources.js.map +0 -1
- package/lib/live/attachments/unsupportedOntologyAttachmentsAdapter.d.ts +0 -5
- package/lib/live/attachments/unsupportedOntologyAttachmentsAdapter.d.ts.map +0 -1
- package/lib/live/attachments/unsupportedOntologyAttachmentsAdapter.js +0 -6
- package/lib/live/attachments/unsupportedOntologyAttachmentsAdapter.js.map +0 -1
- package/lib/live/expression.d.ts +0 -23
- package/lib/live/expression.d.ts.map +0 -1
- package/lib/live/expression.js +0 -160
- package/lib/live/expression.js.map +0 -1
- package/lib/live/mutators/OntologyEdits.d.ts +0 -15
- package/lib/live/mutators/OntologyEdits.d.ts.map +0 -1
- package/lib/live/mutators/OntologyEdits.js +0 -65
- package/lib/live/mutators/OntologyEdits.js.map +0 -1
- package/lib/live/mutators/createMutatorTx.d.ts +0 -11
- package/lib/live/mutators/createMutatorTx.d.ts.map +0 -1
- package/lib/live/mutators/createMutatorTx.js +0 -61
- package/lib/live/mutators/createMutatorTx.js.map +0 -1
- package/lib/live/mutators/runOptimisticAction.d.ts +0 -19
- package/lib/live/mutators/runOptimisticAction.d.ts.map +0 -1
- package/lib/live/mutators/runOptimisticAction.js +0 -30
- package/lib/live/mutators/runOptimisticAction.js.map +0 -1
- package/lib/live/objects/OntologyObject.d.ts +0 -4
- package/lib/live/objects/OntologyObject.d.ts.map +0 -1
- package/lib/live/objects/OntologyObject.js +0 -1
- package/lib/live/objects/createLiveOntologyObjectCollection.d.ts +0 -17
- package/lib/live/objects/createLiveOntologyObjectCollection.d.ts.map +0 -1
- package/lib/live/objects/createLiveOntologyObjectCollection.js +0 -55
- package/lib/live/objects/createLiveOntologyObjectCollection.js.map +0 -1
- package/lib/live/objects/ontologyObjectCollectionId.d.ts +0 -4
- package/lib/live/objects/ontologyObjectCollectionId.d.ts.map +0 -1
- package/lib/live/objects/ontologyObjectCollectionId.js +0 -8
- package/lib/live/objects/ontologyObjectCollectionId.js.map +0 -1
- package/lib/live/outbox/createOntologyOutbox.d.ts +0 -23
- package/lib/live/outbox/createOntologyOutbox.d.ts.map +0 -1
- package/lib/live/outbox/createOntologyOutbox.js +0 -292
- package/lib/live/outbox/createOntologyOutbox.js.map +0 -1
- package/lib/live/outbox/leaderExecutor.d.ts +0 -20
- package/lib/live/outbox/leaderExecutor.d.ts.map +0 -1
- package/lib/live/outbox/leaderExecutor.js +0 -130
- package/lib/live/outbox/leaderExecutor.js.map +0 -1
- package/lib/live/outbox/outboxService.d.ts +0 -7
- package/lib/live/outbox/outboxService.d.ts.map +0 -1
- package/lib/live/outbox/outboxService.js +0 -68
- package/lib/live/outbox/outboxService.js.map +0 -1
- package/lib/live/outbox/projectionManager.d.ts +0 -31
- package/lib/live/outbox/projectionManager.d.ts.map +0 -1
- package/lib/live/outbox/projectionManager.js +0 -127
- package/lib/live/outbox/projectionManager.js.map +0 -1
- package/lib/live/outbox/repository.d.ts +0 -31
- package/lib/live/outbox/repository.d.ts.map +0 -1
- package/lib/live/outbox/repository.js +0 -196
- package/lib/live/outbox/repository.js.map +0 -1
- package/lib/live/outbox/service.d.ts +0 -61
- package/lib/live/outbox/service.d.ts.map +0 -1
- package/lib/live/outbox/service.js +0 -6
- package/lib/live/outbox/service.js.map +0 -1
- package/lib/live/outbox/types.js.map +0 -1
- package/lib/live/waitForCollectionReady.d.ts +0 -5
- package/lib/live/waitForCollectionReady.d.ts.map +0 -1
- package/lib/live/waitForCollectionReady.js +0 -49
- package/lib/live/waitForCollectionReady.js.map +0 -1
- package/lib/meta/createLocalMetaOntologyBackendAdapter.d.ts +0 -7
- package/lib/meta/createLocalMetaOntologyBackendAdapter.d.ts.map +0 -1
- package/lib/meta/createLocalMetaOntologyBackendAdapter.js +0 -44
- package/lib/meta/createLocalMetaOntologyBackendAdapter.js.map +0 -1
- package/lib/meta/generated/constants.d.ts +0 -265
- package/lib/meta/generated/constants.d.ts.map +0 -1
- package/lib/meta/generated/constants.js +0 -165
- package/lib/meta/generated/constants.js.map +0 -1
- package/lib/meta/generated/types.d.ts +0 -417
- package/lib/meta/generated/types.d.ts.map +0 -1
- package/lib/meta/generated/types.js +0 -1
- package/lib/meta/ontology.d.ts +0 -26
- package/lib/meta/ontology.d.ts.map +0 -1
- package/lib/meta/ontology.js +0 -111
- package/lib/meta/ontology.js.map +0 -1
- package/lib/utils/links.d.ts +0 -49
- package/lib/utils/links.d.ts.map +0 -1
- package/lib/utils/links.js +0 -13
- package/lib/utils/links.js.map +0 -1
- package/lib/utils/paths.d.ts +0 -6
- package/lib/utils/paths.d.ts.map +0 -1
- package/lib/utils/paths.js +0 -42
- package/lib/utils/paths.js.map +0 -1
- package/lib/utils/provide.d.ts +0 -4
- package/lib/utils/provide.d.ts.map +0 -1
- package/lib/utils/provide.js +0 -9
- package/lib/utils/provide.js.map +0 -1
- package/lib/utils/targets.d.ts +0 -37
- package/lib/utils/targets.d.ts.map +0 -1
- package/lib/utils/targets.js +0 -1
- package/lib/utils/typeNames.d.ts +0 -28
- package/lib/utils/typeNames.d.ts.map +0 -1
- package/lib/utils/typeNames.js +0 -1
- package/lib/utils/types.d.ts +0 -12
- package/lib/utils/types.d.ts.map +0 -1
- package/lib/utils/types.js +0 -48
- package/lib/utils/types.js.map +0 -1
- package/lib/utils/uncertain.d.ts +0 -11
- package/lib/utils/uncertain.d.ts.map +0 -1
- package/lib/utils/uncertain.js +0 -14
- package/lib/utils/uncertain.js.map +0 -1
- package/lib/utils/validation.d.ts +0 -7
- package/lib/utils/validation.d.ts.map +0 -1
- package/lib/utils/validation.js +0 -1
- package/lib/utils/values.d.ts.map +0 -1
- /package/lib/{installation → live/actions}/types.js +0 -0
- /package/lib/{ir/generated → live/objects}/types.js +0 -0
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
import { registerCollectionDemands } from "./diagnostics.js";
|
|
2
|
+
import { analyzeOntologySubset, analyzeStorageSubset, ontologySubset, storageSubset } from "./subset.js";
|
|
3
|
+
import { Runtime } from "@party-stack/runtime";
|
|
4
|
+
import { Deferred, Effect, Exit, Fiber, Queue, Scope, Stream } from "effect";
|
|
5
|
+
import { BasicIndex, IR, collectionOptions, createCollection, whenSyncAccepted } from "@tanstack/db";
|
|
6
|
+
import { Table } from "@party-stack/ontology-storage/tables";
|
|
7
|
+
import { coversSubset } from "@party-stack/ontology-backend/subset";
|
|
8
|
+
import { readVisibleRevision } from "@party-stack/ontology-replica/infrastructure";
|
|
9
|
+
//#region src/tanstack/collections.ts
|
|
10
|
+
function lookupKeys(subset, primaryKey) {
|
|
11
|
+
if (!primaryKey || subset.offset || subset.cursor || subset.where?.type !== "func") return;
|
|
12
|
+
const { name, args } = subset.where;
|
|
13
|
+
const field = (value) => value?.type === "ref" && IR.getPropRefPropertyPath(value).length === 1 && IR.getPropRefPropertyPath(value)[0] === primaryKey;
|
|
14
|
+
const key = (value) => typeof value === "string" || typeof value === "number" && Number.isFinite(value);
|
|
15
|
+
if (name === "eq") {
|
|
16
|
+
const value = field(args[0]) ? args[1] : field(args[1]) ? args[0] : void 0;
|
|
17
|
+
return value?.type === "val" && key(value.value) ? [value.value] : void 0;
|
|
18
|
+
}
|
|
19
|
+
if (name === "in" && field(args[0]) && args[1]?.type === "val") {
|
|
20
|
+
const values = args[1].value;
|
|
21
|
+
return Array.isArray(values) && values.every(key) ? values : void 0;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** Options creators are Effects: their callback fibers and subscriptions belong to the caller's scope. */
|
|
25
|
+
const persistedCollectionOptions = (options) => collectionOptionsImpl(options);
|
|
26
|
+
const collectionOptionsImpl = Effect.fnUntraced(function* (options, native) {
|
|
27
|
+
const observing = options.observe !== void 0 || native !== void 0;
|
|
28
|
+
const scope = yield* Effect.scope;
|
|
29
|
+
const context = yield* Effect.context();
|
|
30
|
+
let active = true;
|
|
31
|
+
yield* Effect.addFinalizer(() => Effect.sync(() => {
|
|
32
|
+
active = false;
|
|
33
|
+
}));
|
|
34
|
+
const run = (effect, owner = scope) => !active || owner.state._tag === "Closed" ? Promise.reject(/* @__PURE__ */ new Error("Collection scope is closed.")) : Effect.runPromiseWith(context)(Effect.flatMap(Effect.forkIn(effect, owner, { startImmediately: observing }), Fiber.join));
|
|
35
|
+
let refresh;
|
|
36
|
+
let queried = false;
|
|
37
|
+
const persist = options.persist ? async ({ transaction, collection }) => {
|
|
38
|
+
await run(options.persist(transaction.mutations.filter((mutation) => mutation.collection === collection)));
|
|
39
|
+
await refresh?.();
|
|
40
|
+
} : () => Promise.reject(/* @__PURE__ */ new Error("This collection is read-only. Use ontology actions to mutate it."));
|
|
41
|
+
return {
|
|
42
|
+
id: options.id,
|
|
43
|
+
getKey: options.getKey,
|
|
44
|
+
defaultIndexType: BasicIndex,
|
|
45
|
+
autoIndex: "eager",
|
|
46
|
+
defaultStringCollation: { stringSort: "lexical" },
|
|
47
|
+
syncMode: "on-demand",
|
|
48
|
+
startSync: true,
|
|
49
|
+
onInsert: persist,
|
|
50
|
+
onUpdate: persist,
|
|
51
|
+
onDelete: persist,
|
|
52
|
+
sync: {
|
|
53
|
+
rowUpdateMode: "full",
|
|
54
|
+
supportsOrderedWindow: options.supportsOrderedWindow,
|
|
55
|
+
sync: ({ begin, write, commit, markReady, fail, collection }) => {
|
|
56
|
+
const runScope = Effect.runSync(Scope.fork(scope));
|
|
57
|
+
let alive = true;
|
|
58
|
+
let tail;
|
|
59
|
+
const releasing = /* @__PURE__ */ new Set();
|
|
60
|
+
const demands = /* @__PURE__ */ new Map();
|
|
61
|
+
const observations = /* @__PURE__ */ new Map();
|
|
62
|
+
const releaseDiagnostics = options.describeSubset ? registerCollectionDemands(collection, () => [...demands.values()].map(({ subset, received, settled }) => ({
|
|
63
|
+
...options.describeSubset(subset),
|
|
64
|
+
subscription: subset.subscription,
|
|
65
|
+
received,
|
|
66
|
+
ready: settled
|
|
67
|
+
}))) : void 0;
|
|
68
|
+
const codec = Table.make({ name: "collection-value" });
|
|
69
|
+
const fingerprint = (value) => {
|
|
70
|
+
try {
|
|
71
|
+
return codec.encode(value);
|
|
72
|
+
} catch {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
const installed = new Map([...collection.entries()].map(([key, value]) => [key, fingerprint(value)]));
|
|
77
|
+
const dirtyKeys = /* @__PURE__ */ new Set();
|
|
78
|
+
let reconcileInstalled = installed.size > 0;
|
|
79
|
+
const stop = (error) => {
|
|
80
|
+
if (!alive || !active) return;
|
|
81
|
+
alive = false;
|
|
82
|
+
fail(error);
|
|
83
|
+
for (const demand of demands.values()) demand.release();
|
|
84
|
+
const closing = Effect.runPromise(Scope.close(runScope, Exit.void));
|
|
85
|
+
releasing.add(closing);
|
|
86
|
+
closing.finally(() => releasing.delete(closing)).catch(() => void 0);
|
|
87
|
+
};
|
|
88
|
+
const writeRows = async (rows, changed) => {
|
|
89
|
+
if (!active || !alive) return;
|
|
90
|
+
const stale = /* @__PURE__ */ new Set();
|
|
91
|
+
for (const key of changed ?? installed.keys()) if (installed.has(key) && !rows.has(key)) stale.add(key);
|
|
92
|
+
const updates = (changed ? [...changed].flatMap((key) => rows.has(key) ? [[key, rows.get(key)]] : []) : [...rows]).filter(([key, value]) => {
|
|
93
|
+
const encoded = fingerprint(value);
|
|
94
|
+
return encoded === void 0 || installed.get(key) !== encoded;
|
|
95
|
+
});
|
|
96
|
+
if (observing && [...demands.values()].some((demand) => !demand.received)) {
|
|
97
|
+
if (stale.size) reconcileInstalled = true;
|
|
98
|
+
stale.clear();
|
|
99
|
+
} else if (reconcileInstalled) {
|
|
100
|
+
for (const key of installed.keys()) if (!rows.has(key)) stale.add(key);
|
|
101
|
+
reconcileInstalled = false;
|
|
102
|
+
}
|
|
103
|
+
if (!updates.length && !stale.size) return;
|
|
104
|
+
begin();
|
|
105
|
+
for (const [key, value] of updates) write({
|
|
106
|
+
type: installed.has(key) ? "update" : "insert",
|
|
107
|
+
value
|
|
108
|
+
});
|
|
109
|
+
for (const key of stale) write({
|
|
110
|
+
type: "delete",
|
|
111
|
+
key
|
|
112
|
+
});
|
|
113
|
+
const receipt = commit();
|
|
114
|
+
await whenSyncAccepted(receipt);
|
|
115
|
+
for (const key of stale) installed.delete(key);
|
|
116
|
+
for (const [key, value] of updates) installed.set(key, fingerprint(value));
|
|
117
|
+
};
|
|
118
|
+
const load = () => {
|
|
119
|
+
const work = async () => {
|
|
120
|
+
if (!active || !alive) return;
|
|
121
|
+
const changed = observing ? new Set(dirtyKeys) : void 0;
|
|
122
|
+
dirtyKeys.clear();
|
|
123
|
+
const rows = /* @__PURE__ */ new Map();
|
|
124
|
+
if (observing) for (const demand of demands.values()) {
|
|
125
|
+
if (!demand.received) continue;
|
|
126
|
+
for (const [key, value] of demand.rows) rows.set(key, value);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
if (typeof options.load !== "function") for (const row of await run(options.load)) rows.set(row.key, row.value);
|
|
130
|
+
for (const [key, demand] of demands) {
|
|
131
|
+
if (typeof options.load !== "function") break;
|
|
132
|
+
const loaded = await run(options.load(demand.subset));
|
|
133
|
+
if (demands.get(key) !== demand) continue;
|
|
134
|
+
for (const row of loaded) rows.set(row.key, row.value);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
await writeRows(rows, changed);
|
|
138
|
+
};
|
|
139
|
+
let start;
|
|
140
|
+
const next = new Promise((resolve, reject) => {
|
|
141
|
+
start = () => {
|
|
142
|
+
work().then(resolve, reject);
|
|
143
|
+
};
|
|
144
|
+
});
|
|
145
|
+
const previous = tail;
|
|
146
|
+
tail = next;
|
|
147
|
+
const finish = () => {
|
|
148
|
+
if (tail === next) tail = void 0;
|
|
149
|
+
};
|
|
150
|
+
next.then(finish, finish);
|
|
151
|
+
if (previous) previous.then(start, start);
|
|
152
|
+
else if (observing) start();
|
|
153
|
+
else Promise.resolve().then(start);
|
|
154
|
+
return next;
|
|
155
|
+
};
|
|
156
|
+
const close = (owner) => {
|
|
157
|
+
const closing = Effect.runPromise(Scope.close(owner, Exit.void));
|
|
158
|
+
releasing.add(closing);
|
|
159
|
+
closing.then(() => releasing.delete(closing), (error) => {
|
|
160
|
+
releasing.delete(closing);
|
|
161
|
+
stop(error);
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
const publishObservation = async (group, batch) => {
|
|
165
|
+
if (!alive || !active || observations.get(group.key) !== group) return;
|
|
166
|
+
let changed = false;
|
|
167
|
+
if (batch) {
|
|
168
|
+
if (batch.reset) {
|
|
169
|
+
for (const key of group.rows.keys()) dirtyKeys.add(key);
|
|
170
|
+
changed = group.rows.size > 0;
|
|
171
|
+
group.rows.clear();
|
|
172
|
+
}
|
|
173
|
+
for (const key of batch.removed) {
|
|
174
|
+
if (!group.rows.delete(key)) continue;
|
|
175
|
+
dirtyKeys.add(key);
|
|
176
|
+
changed = true;
|
|
177
|
+
}
|
|
178
|
+
for (const row of batch.rows) {
|
|
179
|
+
dirtyKeys.add(row.key);
|
|
180
|
+
group.rows.set(row.key, row.value);
|
|
181
|
+
changed = true;
|
|
182
|
+
}
|
|
183
|
+
group.revision = batch.revision;
|
|
184
|
+
}
|
|
185
|
+
let admitted = false;
|
|
186
|
+
for (const member of group.members) {
|
|
187
|
+
if (member.received || group.revision === void 0 || group.revision < member.requiredRevision) continue;
|
|
188
|
+
member.received = true;
|
|
189
|
+
admitted = true;
|
|
190
|
+
for (const key of group.rows.keys()) dirtyKeys.add(key);
|
|
191
|
+
}
|
|
192
|
+
const published = [...group.members].filter((member) => member.received);
|
|
193
|
+
if (changed || admitted || reconcileInstalled) await load();
|
|
194
|
+
for (const member of published) {
|
|
195
|
+
if (!alive || !active || !group.members.has(member)) continue;
|
|
196
|
+
if (member.keys?.every((key) => group.rows.has(key))) Effect.runSync(Deferred.succeed(member.available, void 0));
|
|
197
|
+
Effect.runSync(Deferred.succeed(member.observed, void 0));
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
const observeNative = Effect.fnUntraced(function* (demand) {
|
|
201
|
+
const revision = yield* native.revision;
|
|
202
|
+
const joined = yield* Effect.uninterruptible(Effect.gen(function* () {
|
|
203
|
+
if (demands.get(demand.subset) !== demand) return;
|
|
204
|
+
const key = native.key(demand.subset);
|
|
205
|
+
let group = observations.get(key);
|
|
206
|
+
const created = !group;
|
|
207
|
+
if (!group) {
|
|
208
|
+
group = {
|
|
209
|
+
key,
|
|
210
|
+
scope: Scope.forkUnsafe(runScope),
|
|
211
|
+
rows: /* @__PURE__ */ new Map(),
|
|
212
|
+
members: /* @__PURE__ */ new Set()
|
|
213
|
+
};
|
|
214
|
+
observations.set(key, group);
|
|
215
|
+
}
|
|
216
|
+
const current = group;
|
|
217
|
+
demand.rows = current.rows;
|
|
218
|
+
demand.requiredRevision = revision;
|
|
219
|
+
demand.group = current;
|
|
220
|
+
current.members.add(demand);
|
|
221
|
+
if (created) yield* Stream.runForEach(native.observe(demand.subset), (batch) => Effect.tryPromise({
|
|
222
|
+
try: () => publishObservation(current, batch),
|
|
223
|
+
catch: (cause) => cause
|
|
224
|
+
}).pipe(Effect.withSpan("Ontology.collection.publish", { attributes: {
|
|
225
|
+
collection: options.id,
|
|
226
|
+
rows: batch.rows.length,
|
|
227
|
+
removed: batch.removed.length,
|
|
228
|
+
reset: batch.reset
|
|
229
|
+
} }))).pipe(Effect.catch((error) => Effect.sync(() => {
|
|
230
|
+
if (observations.get(key) !== current) return;
|
|
231
|
+
for (const member of current.members) Effect.runSync(Deferred.fail(member.observed, error));
|
|
232
|
+
stop(error);
|
|
233
|
+
})), Effect.interruptible, Effect.forkIn(current.scope, { startImmediately: true }));
|
|
234
|
+
return {
|
|
235
|
+
current,
|
|
236
|
+
created
|
|
237
|
+
};
|
|
238
|
+
}));
|
|
239
|
+
if (!joined) return;
|
|
240
|
+
const { current, created } = joined;
|
|
241
|
+
if (!created && current.revision !== void 0 && current.revision >= revision) yield* Effect.tryPromise({
|
|
242
|
+
try: () => publishObservation(current),
|
|
243
|
+
catch: (cause) => cause
|
|
244
|
+
});
|
|
245
|
+
yield* Deferred.await(demand.observed);
|
|
246
|
+
});
|
|
247
|
+
refresh = load;
|
|
248
|
+
const watcher = run(Effect.forkIn(Stream.runForEach(observing ? Stream.empty : options.changes, () => queried && (demands.size || typeof options.load !== "function") ? Effect.tryPromise({
|
|
249
|
+
try: load,
|
|
250
|
+
catch: (cause) => cause
|
|
251
|
+
}) : Effect.void).pipe(Effect.catch((error) => Effect.sync(() => {
|
|
252
|
+
stop(error);
|
|
253
|
+
}))), runScope, { startImmediately: true }), runScope);
|
|
254
|
+
markReady();
|
|
255
|
+
return {
|
|
256
|
+
loadSubset: (subset) => {
|
|
257
|
+
if (subset.signal?.aborted) return Promise.resolve();
|
|
258
|
+
queried = true;
|
|
259
|
+
const keys = lookupKeys(subset, options.primaryKey);
|
|
260
|
+
let cached = [...demands.values()].some((demand) => demand.settled && !demand.subset.where && demand.subset.limit === void 0 && !demand.subset.offset && !demand.subset.cursor) || [...demands.values()].some((demand) => demand.settled && options.covers?.(subset, demand.subset)) || keys && keys.every((key) => collection.has(key) && [...demands.values()].some((demand) => demand.settled && demand.rows.has(key)));
|
|
261
|
+
const key = subset;
|
|
262
|
+
let demand = demands.get(key);
|
|
263
|
+
if (!demand) {
|
|
264
|
+
if (!demands.size) reconcileInstalled = true;
|
|
265
|
+
const child = Effect.runSync(Scope.fork(runScope));
|
|
266
|
+
const acquire = options.acquireDemand;
|
|
267
|
+
demand = {
|
|
268
|
+
scope: child,
|
|
269
|
+
subset,
|
|
270
|
+
rows: /* @__PURE__ */ new Map(),
|
|
271
|
+
received: false,
|
|
272
|
+
settled: false,
|
|
273
|
+
ready: Promise.resolve(),
|
|
274
|
+
available: Effect.runSync(Deferred.make()),
|
|
275
|
+
observed: Effect.runSync(Deferred.make()),
|
|
276
|
+
keys,
|
|
277
|
+
release: () => {
|
|
278
|
+
subset.signal?.removeEventListener("abort", demand.release);
|
|
279
|
+
if (!demand || demands.get(key) !== demand) return;
|
|
280
|
+
if (demand.received) for (const rowKey of demand.rows.keys()) dirtyKeys.add(rowKey);
|
|
281
|
+
demands.delete(key);
|
|
282
|
+
const group = demand.group;
|
|
283
|
+
group?.members.delete(demand);
|
|
284
|
+
if (group && !group.members.size) {
|
|
285
|
+
observations.delete(group.key);
|
|
286
|
+
close(group.scope);
|
|
287
|
+
}
|
|
288
|
+
close(child);
|
|
289
|
+
if (alive && active && demands.size) load().catch(stop);
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
demands.set(key, demand);
|
|
293
|
+
subset.signal?.addEventListener("abort", demand.release, { once: true });
|
|
294
|
+
demand.ready = run(Scope.provide(Effect.gen(function* () {
|
|
295
|
+
const acquisition = typeof acquire === "function" ? acquire(subset) : acquire;
|
|
296
|
+
const acquiring = observing && acquisition ? yield* Effect.forkIn(acquisition, child, { startImmediately: true }) : void 0;
|
|
297
|
+
if (!observing && acquisition) yield* acquisition;
|
|
298
|
+
if (native) {
|
|
299
|
+
const observed = yield* Effect.forkIn(observeNative(demand), child, { startImmediately: true });
|
|
300
|
+
yield* Effect.all([Fiber.join(observed), ...acquiring ? [Fiber.join(acquiring)] : []], {
|
|
301
|
+
concurrency: "unbounded",
|
|
302
|
+
discard: true
|
|
303
|
+
});
|
|
304
|
+
} else if (options.observe) {
|
|
305
|
+
const ready = yield* Deferred.make();
|
|
306
|
+
yield* Stream.runForEach(options.observe(subset), (batch) => Effect.tryPromise({
|
|
307
|
+
try: async () => {
|
|
308
|
+
if (!demand || demands.get(key) !== demand) return;
|
|
309
|
+
const first = !demand.received;
|
|
310
|
+
let changed = false;
|
|
311
|
+
demand.received = true;
|
|
312
|
+
if (batch.reset) {
|
|
313
|
+
for (const rowKey of demand.rows.keys()) {
|
|
314
|
+
dirtyKeys.add(rowKey);
|
|
315
|
+
changed = true;
|
|
316
|
+
}
|
|
317
|
+
demand.rows.clear();
|
|
318
|
+
}
|
|
319
|
+
for (const removed of batch.removed) {
|
|
320
|
+
if (!demand.rows.delete(removed)) continue;
|
|
321
|
+
dirtyKeys.add(removed);
|
|
322
|
+
changed = true;
|
|
323
|
+
}
|
|
324
|
+
for (const row of batch.rows) {
|
|
325
|
+
dirtyKeys.add(row.key);
|
|
326
|
+
demand.rows.set(row.key, row.value);
|
|
327
|
+
changed = true;
|
|
328
|
+
}
|
|
329
|
+
if (first || changed || reconcileInstalled) await load();
|
|
330
|
+
if (keys?.every((key) => demand.rows.has(key))) Effect.runSync(Deferred.succeed(demand.available, void 0));
|
|
331
|
+
Effect.runSync(Deferred.succeed(ready, void 0));
|
|
332
|
+
},
|
|
333
|
+
catch: (cause) => cause
|
|
334
|
+
}).pipe(Effect.withSpan("Ontology.collection.publish", { attributes: {
|
|
335
|
+
collection: options.id,
|
|
336
|
+
rows: batch.rows.length,
|
|
337
|
+
removed: batch.removed.length,
|
|
338
|
+
reset: batch.reset
|
|
339
|
+
} }))).pipe(Effect.catch((error) => Effect.gen(function* () {
|
|
340
|
+
yield* Deferred.fail(ready, error);
|
|
341
|
+
if (alive && active && demands.get(key) === demand) stop(error);
|
|
342
|
+
})), Effect.forkIn(child, { startImmediately: true }));
|
|
343
|
+
yield* Effect.all([Deferred.await(ready), ...acquiring ? [Fiber.join(acquiring)] : []], {
|
|
344
|
+
concurrency: "unbounded",
|
|
345
|
+
discard: true
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
}), child), child);
|
|
349
|
+
demand.ready.catch((error) => {
|
|
350
|
+
if ((cached || demand.settled) && demands.get(key) === demand && !subset.signal?.aborted) stop(error);
|
|
351
|
+
demand.release();
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
const current = demand;
|
|
355
|
+
cached ||= Boolean(keys?.every((key) => current.rows.has(key) && collection.has(key)));
|
|
356
|
+
if (native && !current.received) cached = false;
|
|
357
|
+
const completed = Promise.race([current.ready, ...keys ? [run(Deferred.await(current.available), current.scope)] : []]).then(async () => {
|
|
358
|
+
await load();
|
|
359
|
+
current.settled = true;
|
|
360
|
+
});
|
|
361
|
+
if (cached) {
|
|
362
|
+
completed.catch((error) => {
|
|
363
|
+
if (demands.get(key) === current && !subset.signal?.aborted) stop(error);
|
|
364
|
+
});
|
|
365
|
+
return true;
|
|
366
|
+
}
|
|
367
|
+
return completed;
|
|
368
|
+
},
|
|
369
|
+
unloadSubset: (subset) => {
|
|
370
|
+
demands.get(subset)?.release();
|
|
371
|
+
},
|
|
372
|
+
cleanup: async () => {
|
|
373
|
+
releaseDiagnostics?.();
|
|
374
|
+
alive = false;
|
|
375
|
+
refresh = void 0;
|
|
376
|
+
await watcher.then((fiber) => Effect.runPromise(Fiber.interrupt(fiber)), () => void 0);
|
|
377
|
+
await Promise.all([...releasing, ...[...demands.values()].map((demand) => {
|
|
378
|
+
demand.subset.signal?.removeEventListener("abort", demand.release);
|
|
379
|
+
return Effect.runPromise(Scope.close(demand.scope, Exit.void));
|
|
380
|
+
})]);
|
|
381
|
+
demands.clear();
|
|
382
|
+
observations.clear();
|
|
383
|
+
dirtyKeys.clear();
|
|
384
|
+
await Effect.runPromise(Scope.close(runScope, Exit.void));
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
});
|
|
391
|
+
const localListeners = /* @__PURE__ */ new WeakMap();
|
|
392
|
+
const localChanges = (tables) => {
|
|
393
|
+
let listeners = localListeners.get(tables);
|
|
394
|
+
if (!listeners) localListeners.set(tables, listeners = /* @__PURE__ */ new Set());
|
|
395
|
+
const current = listeners;
|
|
396
|
+
return {
|
|
397
|
+
changes: Stream.callback((queue) => Effect.acquireRelease(Effect.sync(() => {
|
|
398
|
+
const listener = () => {
|
|
399
|
+
Queue.offerUnsafe(queue, void 0);
|
|
400
|
+
};
|
|
401
|
+
current.add(listener);
|
|
402
|
+
return listener;
|
|
403
|
+
}), (listener) => Effect.sync(() => {
|
|
404
|
+
current.delete(listener);
|
|
405
|
+
})), {
|
|
406
|
+
bufferSize: 1,
|
|
407
|
+
strategy: "sliding"
|
|
408
|
+
}),
|
|
409
|
+
notify: Effect.sync(() => {
|
|
410
|
+
for (const listener of current) listener();
|
|
411
|
+
})
|
|
412
|
+
};
|
|
413
|
+
};
|
|
414
|
+
const localCollectionOptions = Effect.fnUntraced(function* (options) {
|
|
415
|
+
const runtime = yield* Runtime;
|
|
416
|
+
const local = localChanges(runtime.tables);
|
|
417
|
+
const table = Table.make({
|
|
418
|
+
name: JSON.stringify([
|
|
419
|
+
"local",
|
|
420
|
+
runtime.owner,
|
|
421
|
+
runtime.namespace,
|
|
422
|
+
options.name
|
|
423
|
+
]),
|
|
424
|
+
version: options.schemaVersion
|
|
425
|
+
});
|
|
426
|
+
return yield* persistedCollectionOptions({
|
|
427
|
+
id: `party-stack:${runtime.owner}:${runtime.namespace}:${options.name}`,
|
|
428
|
+
getKey: options.getKey,
|
|
429
|
+
load: (subset) => runtime.tables.query(table, storageSubset(subset)),
|
|
430
|
+
changes: local.changes,
|
|
431
|
+
persist: (mutations) => runtime.tables.transaction((tx) => Effect.gen(function* () {
|
|
432
|
+
for (const mutation of mutations) if (mutation.type === "delete") yield* tx.delete(table, mutation.key);
|
|
433
|
+
else yield* tx.put(table, mutation.key, mutation.modified);
|
|
434
|
+
})).pipe(Effect.tap(() => local.notify))
|
|
435
|
+
});
|
|
436
|
+
});
|
|
437
|
+
const replicatedCollectionOptions = Effect.fnUntraced(function* (options) {
|
|
438
|
+
const subsetCodec = Table.make({ name: "native-observation-subset" });
|
|
439
|
+
const revision = readVisibleRevision(options.replica);
|
|
440
|
+
const observe = (subset) => options.replica.observeSubset(ontologySubset(subset, options.replica.ir, options.objectType)).pipe(Stream.map((batch) => ({
|
|
441
|
+
...batch,
|
|
442
|
+
rows: batch.rows.map((row) => ({
|
|
443
|
+
key: row.key,
|
|
444
|
+
value: row.value
|
|
445
|
+
}))
|
|
446
|
+
})));
|
|
447
|
+
return yield* collectionOptionsImpl({
|
|
448
|
+
id: options.id,
|
|
449
|
+
getKey: options.getKey,
|
|
450
|
+
primaryKey: options.replica.ir.objectTypes.find((type) => type.name === options.objectType)?.primaryKey,
|
|
451
|
+
supportsOrderedWindow: (subset) => analyzeOntologySubset(subset, options.replica.ir, options.objectType).orderedWindowExact,
|
|
452
|
+
covers: (requested, held) => coversSubset({
|
|
453
|
+
objectType: options.objectType,
|
|
454
|
+
query: storageSubset(requested, options.replica.ir, options.objectType)
|
|
455
|
+
}, {
|
|
456
|
+
objectType: options.objectType,
|
|
457
|
+
query: storageSubset(held, options.replica.ir, options.objectType)
|
|
458
|
+
}),
|
|
459
|
+
describeSubset: (subset) => ({
|
|
460
|
+
objectType: options.objectType,
|
|
461
|
+
...analyzeStorageSubset(subset, options.replica.ir, options.objectType),
|
|
462
|
+
requested: {
|
|
463
|
+
where: subset.where,
|
|
464
|
+
orderBy: subset.orderBy,
|
|
465
|
+
limit: subset.limit,
|
|
466
|
+
offset: subset.offset,
|
|
467
|
+
cursor: subset.cursor
|
|
468
|
+
}
|
|
469
|
+
}),
|
|
470
|
+
load: (subset) => Effect.map(options.replica.readSubset(ontologySubset(subset, options.replica.ir, options.objectType)), (rows) => rows.map((row) => ({
|
|
471
|
+
key: row.key,
|
|
472
|
+
value: row.value
|
|
473
|
+
}))),
|
|
474
|
+
changes: Stream.empty,
|
|
475
|
+
observe,
|
|
476
|
+
acquireDemand: (subset) => options.localOnly ? options.replica.demand.acquire(ontologySubset(subset, options.replica.ir, options.objectType), { localOnly: true }) : options.replica.demand.acquire(ontologySubset(subset, options.replica.ir, options.objectType))
|
|
477
|
+
}, revision ? {
|
|
478
|
+
key: (subset) => subsetCodec.encode(ontologySubset(subset, options.replica.ir, options.objectType)),
|
|
479
|
+
revision,
|
|
480
|
+
observe
|
|
481
|
+
} : void 0);
|
|
482
|
+
});
|
|
483
|
+
const scopedCollection = (options, client) => client ? Effect.sync(() => client.collection(collectionOptions(options))) : Effect.acquireRelease(Effect.sync(() => createCollection(options)), (collection) => Effect.promise(async () => {
|
|
484
|
+
await collection.cleanup({ dependents: true });
|
|
485
|
+
}));
|
|
486
|
+
const makeLocalCollection = Effect.fn("Ontology.localCollection")(function* (options) {
|
|
487
|
+
return yield* scopedCollection(yield* localCollectionOptions(options));
|
|
488
|
+
});
|
|
489
|
+
const makeReplicatedCollection = Effect.fn("Ontology.replicatedCollection")(function* (options, client) {
|
|
490
|
+
return yield* scopedCollection(yield* replicatedCollectionOptions(options), client);
|
|
491
|
+
});
|
|
492
|
+
//#endregion
|
|
493
|
+
export { localCollectionOptions, makeLocalCollection, makeReplicatedCollection, persistedCollectionOptions, replicatedCollectionOptions, scopedCollection };
|
|
494
|
+
|
|
495
|
+
//# sourceMappingURL=collections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collections.js","names":[],"sources":["../../src/tanstack/collections.ts"],"sourcesContent":["import { coversSubset } from \"@party-stack/ontology-backend/subset\";\nimport { readVisibleRevision } from \"@party-stack/ontology-replica/infrastructure\";\nimport { Table } from \"@party-stack/ontology-storage/tables\";\nimport { Runtime } from \"@party-stack/runtime\";\nimport { BasicIndex, createCollection, collectionOptions, whenSyncAccepted, IR } from \"@tanstack/db\";\nimport { Deferred, Effect, Exit, Fiber, Scope, Stream, Queue } from \"effect\";\nimport { registerCollectionDemands, type CollectionDemandDiagnostic } from \"./diagnostics.js\";\nimport { analyzeOntologySubset, analyzeStorageSubset, storageSubset, ontologySubset } from \"./subset.js\";\nimport type { ReplicaService } from \"@party-stack/ontology-replica\";\nimport type { Key } from \"@party-stack/ontology-storage\";\nimport type { TablesService } from \"@party-stack/ontology-storage/tables\";\nimport type { CollectionConfig, DbClient, LoadSubsetOptions } from \"@tanstack/db\";\n\ninterface Change<A> {\n readonly key: Key;\n readonly type: \"insert\" | \"update\" | \"delete\";\n readonly modified: A;\n}\n// A present primary-key row is a complete answer, unlike an empty filtered\n// cache. Only reuse rows held by another successfully acquired live demand.\nfunction lookupKeys(subset: LoadSubsetOptions, primaryKey: string | undefined): readonly Key[] | undefined {\n if (!primaryKey || subset.offset || subset.cursor || subset.where?.type !== \"func\") return;\n const { name, args } = subset.where;\n const field = (value: IR.BasicExpression | undefined) =>\n value?.type === \"ref\" &&\n IR.getPropRefPropertyPath(value).length === 1 &&\n IR.getPropRefPropertyPath(value)[0] === primaryKey;\n const key = (value: unknown): value is Key =>\n typeof value === \"string\" || (typeof value === \"number\" && Number.isFinite(value));\n if (name === \"eq\") {\n const value = field(args[0]) ? args[1] : field(args[1]) ? args[0] : undefined;\n return value?.type === \"val\" && key(value.value) ? [value.value] : undefined;\n }\n if (name === \"in\" && field(args[0]) && args[1]?.type === \"val\") {\n const values: unknown = args[1].value;\n return Array.isArray(values) && values.every(key) ? values : undefined;\n }\n return;\n}\ninterface RowsBatch<A> {\n readonly reset: boolean;\n readonly rows: readonly { key: Key; value: A }[];\n readonly removed: readonly Key[];\n}\ninterface NativeObservations<A> {\n readonly key: (subset: LoadSubsetOptions) => string;\n readonly revision: Effect.Effect<number, unknown>;\n readonly observe: (\n subset: LoadSubsetOptions\n ) => Stream.Stream<RowsBatch<A> & { readonly revision: number }, unknown>;\n}\ninterface PersistedCollectionOptions<A extends object, K extends Key> {\n readonly id: string;\n readonly getKey: (value: A) => K;\n readonly primaryKey?: string;\n readonly load:\n | Effect.Effect<readonly { key: Key; value: A }[], unknown>\n | ((subset: LoadSubsetOptions) => Effect.Effect<readonly { key: Key; value: A }[], unknown>);\n readonly changes: Stream.Stream<void>;\n readonly observe?: (subset: LoadSubsetOptions) => Stream.Stream<\n {\n readonly reset: boolean;\n readonly rows: readonly { key: Key; value: A }[];\n readonly removed: readonly Key[];\n },\n unknown\n >;\n readonly persist?: (mutations: readonly Change<A>[]) => Effect.Effect<void, unknown>;\n readonly acquireDemand?:\n | Effect.Effect<void, unknown, Scope.Scope>\n | ((subset: LoadSubsetOptions) => Effect.Effect<void, unknown, Scope.Scope>);\n readonly describeSubset?: (subset: LoadSubsetOptions) => Omit<CollectionDemandDiagnostic, \"subscription\">;\n /** Compare the regions actually acquired by this source, after residual\n * filters/order have widened them. No inference from cached row contents.\n */\n readonly covers?: (requested: LoadSubsetOptions, held: LoadSubsetOptions) => boolean;\n readonly supportsOrderedWindow?: (subset: LoadSubsetOptions) => boolean;\n}\n/** Options creators are Effects: their callback fibers and subscriptions belong to the caller's scope. */\nexport const persistedCollectionOptions = <A extends object, K extends Key>(\n options: PersistedCollectionOptions<A, K>\n) => collectionOptionsImpl(options);\nconst collectionOptionsImpl = Effect.fnUntraced(function* <A extends object, K extends Key>(\n options: PersistedCollectionOptions<A, K>,\n native?: NativeObservations<A>\n) {\n const observing = options.observe !== undefined || native !== undefined;\n const scope = yield* Effect.scope;\n const context = yield* Effect.context<never>();\n let active = true;\n yield* Effect.addFinalizer(() =>\n Effect.sync(() => {\n active = false;\n })\n );\n const run = <B, E>(effect: Effect.Effect<B, E>, owner = scope) =>\n !active || owner.state._tag === \"Closed\"\n ? Promise.reject(new Error(\"Collection scope is closed.\"))\n : Effect.runPromiseWith(context)(\n Effect.flatMap(Effect.forkIn(effect, owner, { startImmediately: observing }), Fiber.join)\n );\n let refresh: (() => Promise<void>) | undefined;\n let queried = false;\n const persist: (args: {\n transaction: { mutations: readonly (Change<A> & { collection: unknown })[] };\n collection: unknown;\n }) => Promise<void> = options.persist\n ? async ({ transaction, collection }) => {\n await run(\n options.persist!(\n transaction.mutations.filter((mutation) => mutation.collection === collection)\n )\n );\n // In particular, optimistic:false callers must observe the confirmed write\n // as soon as the transaction settles.\n await refresh?.();\n }\n : () => Promise.reject(new Error(\"This collection is read-only. Use ontology actions to mutate it.\"));\n const config: CollectionConfig<A, K> = {\n id: options.id,\n getKey: options.getKey,\n defaultIndexType: BasicIndex,\n autoIndex: \"eager\",\n defaultStringCollation: { stringSort: \"lexical\" },\n syncMode: \"on-demand\",\n startSync: true,\n onInsert: persist,\n onUpdate: persist,\n onDelete: persist,\n sync: {\n rowUpdateMode: \"full\",\n supportsOrderedWindow: options.supportsOrderedWindow,\n sync: ({ begin, write, commit, markReady, fail, collection }) => {\n const runScope = Effect.runSync(Scope.fork(scope));\n let alive = true;\n let tail: Promise<void> | undefined;\n const releasing = new Set<Promise<void>>();\n interface Demand {\n scope: Scope.Closeable;\n ready: Promise<void>;\n available: Deferred.Deferred<void>;\n subset: LoadSubsetOptions;\n release: () => void;\n rows: Map<Key, A>;\n received: boolean;\n settled: boolean;\n observed: Deferred.Deferred<void, unknown>;\n keys?: readonly Key[];\n requiredRevision?: number;\n group?: Observation;\n }\n interface Observation {\n key: string;\n scope: Scope.Closeable;\n rows: Map<Key, A>;\n revision?: number;\n members: Set<Demand>;\n }\n const demands = new Map<LoadSubsetOptions, Demand>();\n const observations = new Map<string, Observation>();\n const releaseDiagnostics = options.describeSubset\n ? registerCollectionDemands(collection, () =>\n [...demands.values()].map(({ subset, received, settled }) => ({\n ...options.describeSubset!(subset),\n subscription: subset.subscription,\n received,\n ready: settled,\n }))\n )\n : undefined;\n const codec = Table.make<A>({ name: \"collection-value\" });\n // Diagnostic rows can include typed Error instances. Their display\n // values need no storage codec; conservatively rewrite such rows.\n const fingerprint = (value: A): string | undefined => {\n try {\n return codec.encode(value);\n } catch {\n return undefined;\n }\n };\n // Reload keeps the previous rows. Reconcile against those keys\n // rather than inserting them a second time in the new sync run.\n const installed = new Map<Key, string | undefined>(\n [...collection.entries()].map(([key, value]) => [key, fingerprint(value)])\n );\n const dirtyKeys = new Set<Key>();\n let reconcileInstalled = installed.size > 0;\n const stop = (error: unknown) => {\n if (!alive || !active) return;\n alive = false;\n fail(error);\n for (const demand of demands.values()) demand.release();\n const closing = Effect.runPromise(Scope.close(runScope, Exit.void));\n releasing.add(closing);\n void closing.finally(() => releasing.delete(closing)).catch(() => undefined);\n };\n const writeRows = async (rows: ReadonlyMap<Key, A>, changed?: ReadonlySet<Key>) => {\n if (!active || !alive) return;\n const stale = new Set<Key>();\n for (const key of changed ?? installed.keys())\n if (installed.has(key) && !rows.has(key)) stale.add(key);\n const candidates = changed\n ? [...changed].flatMap((key) =>\n rows.has(key) ? [[key, rows.get(key)!] as const] : []\n )\n : [...rows];\n const updates = candidates.filter(([key, value]) => {\n const encoded = fingerprint(value);\n return encoded === undefined || installed.get(key) !== encoded;\n });\n // A reload can receive its demanded subsets independently.\n // Keep the old rows until every active subset has a first batch.\n if (observing && [...demands.values()].some((demand) => !demand.received)) {\n if (stale.size) reconcileInstalled = true;\n stale.clear();\n } else if (reconcileInstalled) {\n for (const key of installed.keys()) if (!rows.has(key)) stale.add(key);\n reconcileInstalled = false;\n }\n if (!updates.length && !stale.size) return;\n begin();\n for (const [key, value] of updates)\n write({ type: installed.has(key) ? \"update\" : \"insert\", value });\n for (const key of stale) write({ type: \"delete\", key: key as K });\n const receipt = commit();\n await whenSyncAccepted(receipt);\n for (const key of stale) installed.delete(key);\n for (const [key, value] of updates) installed.set(key, fingerprint(value));\n };\n const load = () => {\n const work = async () => {\n if (!active || !alive) return;\n // Observation batches identify every key whose winning\n // demand can change. Take this work before awaiting a\n // commit so concurrent batches stay queued for next time.\n const changed = observing ? new Set(dirtyKeys) : undefined;\n dirtyKeys.clear();\n const rows = new Map<Key, A>();\n if (observing) {\n for (const demand of demands.values()) {\n if (!demand.received) continue;\n for (const [key, value] of demand.rows) rows.set(key, value);\n }\n } else {\n if (typeof options.load !== \"function\")\n for (const row of await run(options.load)) rows.set(row.key, row.value);\n for (const [key, demand] of demands) {\n if (typeof options.load !== \"function\") break;\n const loaded = await run(options.load(demand.subset));\n if (demands.get(key) !== demand) continue;\n for (const row of loaded) rows.set(row.key, row.value);\n }\n }\n await writeRows(rows, changed);\n };\n // Start an idle publisher in this turn. Its first sync commit\n // can install a native memory snapshot before a query reads it.\n // Reserve the queue slot first: commit can acquire more demand\n // reentrantly, which must still publish in FIFO order.\n let start!: () => void;\n const next = new Promise<void>((resolve, reject) => {\n start = () => {\n void work().then(resolve, reject);\n };\n });\n const previous = tail;\n tail = next;\n const finish = () => {\n if (tail === next) tail = undefined;\n };\n void next.then(finish, finish);\n if (previous) void previous.then(start, start);\n else if (observing) start();\n else void Promise.resolve().then(start);\n return next;\n };\n const close = (owner: Scope.Closeable) => {\n const closing = Effect.runPromise(Scope.close(owner, Exit.void));\n releasing.add(closing);\n void closing.then(\n () => releasing.delete(closing),\n (error) => {\n releasing.delete(closing);\n stop(error);\n }\n );\n };\n const publishObservation = async (\n group: Observation,\n batch?: RowsBatch<A> & { readonly revision: number }\n ) => {\n if (!alive || !active || observations.get(group.key) !== group) return;\n let changed = false;\n if (batch) {\n if (batch.reset) {\n for (const key of group.rows.keys()) dirtyKeys.add(key);\n changed = group.rows.size > 0;\n group.rows.clear();\n }\n for (const key of batch.removed) {\n if (!group.rows.delete(key)) continue;\n dirtyKeys.add(key);\n changed = true;\n }\n for (const row of batch.rows) {\n dirtyKeys.add(row.key);\n group.rows.set(row.key, row.value);\n changed = true;\n }\n // Admission must see this before load(): a DB commit can\n // acquire another identical include synchronously.\n group.revision = batch.revision;\n }\n let admitted = false;\n for (const member of group.members) {\n if (\n member.received ||\n group.revision === undefined ||\n group.revision < member.requiredRevision!\n )\n continue;\n member.received = true;\n admitted = true;\n // The new logical demand can change overlap precedence.\n for (const key of group.rows.keys()) dirtyKeys.add(key);\n }\n const published = [...group.members].filter((member) => member.received);\n if (changed || admitted || reconcileInstalled) await load();\n for (const member of published) {\n if (!alive || !active || !group.members.has(member)) continue;\n if (member.keys?.every((key) => group.rows.has(key)))\n Effect.runSync(Deferred.succeed(member.available, undefined));\n Effect.runSync(Deferred.succeed(member.observed, undefined));\n }\n };\n const observeNative = Effect.fnUntraced(function* (demand: Demand) {\n const revision = yield* native!.revision;\n const joined = yield* Effect.uninterruptible(\n Effect.gen(function* () {\n if (demands.get(demand.subset) !== demand) return;\n const key = native!.key(demand.subset);\n let group = observations.get(key);\n const created = !group;\n if (!group) {\n // Lookup, allocation and registration are one synchronous\n // operation, including under cooperative Effect scheduling.\n group = {\n key,\n scope: Scope.forkUnsafe(runScope),\n rows: new Map(),\n members: new Set(),\n };\n observations.set(key, group);\n }\n const current = group;\n demand.rows = current.rows;\n demand.requiredRevision = revision;\n demand.group = current;\n current.members.add(demand);\n if (created) {\n yield* Stream.runForEach(native!.observe(demand.subset), (batch) =>\n Effect.tryPromise({\n try: () => publishObservation(current, batch),\n catch: (cause) => cause,\n }).pipe(\n Effect.withSpan(\"Ontology.collection.publish\", {\n attributes: {\n collection: options.id,\n rows: batch.rows.length,\n removed: batch.removed.length,\n reset: batch.reset,\n },\n })\n )\n ).pipe(\n Effect.catch((error) =>\n Effect.sync(() => {\n if (observations.get(key) !== current) return;\n for (const member of current.members)\n Effect.runSync(Deferred.fail(member.observed, error));\n stop(error);\n })\n ),\n Effect.interruptible,\n Effect.forkIn(current.scope, { startImmediately: true })\n );\n }\n // Only registration is uninterruptible. The shared observer\n // belongs to its own scope before the first caller can leave.\n return { current, created };\n })\n );\n if (!joined) return;\n const { current, created } = joined;\n if (!created && current.revision !== undefined && current.revision >= revision) {\n yield* Effect.tryPromise({\n try: () => publishObservation(current),\n catch: (cause) => cause,\n });\n }\n yield* Deferred.await(demand.observed);\n });\n refresh = load;\n const watcher = run(\n Effect.forkIn(\n Stream.runForEach(observing ? Stream.empty : options.changes, () =>\n queried && (demands.size || typeof options.load !== \"function\")\n ? Effect.tryPromise({ try: load, catch: (cause) => cause })\n : Effect.void\n ).pipe(\n Effect.catch((error) =>\n Effect.sync(() => {\n stop(error);\n })\n )\n ),\n runScope,\n { startImmediately: true }\n ),\n runScope\n );\n markReady();\n return {\n loadSubset: (subset) => {\n if (subset.signal?.aborted) return Promise.resolve();\n queried = true;\n const keys = lookupKeys(subset, options.primaryKey);\n // A completed, still-held collection demand is a completeness\n // witness for every local filter/window, including empty results.\n const wholeCollection = [...demands.values()].some(\n (demand) =>\n demand.settled &&\n !demand.subset.where &&\n demand.subset.limit === undefined &&\n !demand.subset.offset &&\n !demand.subset.cursor\n );\n let cached =\n wholeCollection ||\n [...demands.values()].some(\n (demand) => demand.settled && options.covers?.(subset, demand.subset)\n ) ||\n (keys &&\n keys.every(\n (key) =>\n collection.has(key as K) &&\n [...demands.values()].some(\n (demand) => demand.settled && demand.rows.has(key)\n )\n ));\n // Each acquisition has its own immutable options, signal\n // and matching unload, even for equivalent queries.\n const key = subset;\n let demand = demands.get(key);\n if (!demand) {\n if (!demands.size) reconcileInstalled = true;\n const child = Effect.runSync(Scope.fork(runScope));\n const acquire = options.acquireDemand;\n demand = {\n scope: child,\n subset,\n rows: new Map(),\n received: false,\n settled: false,\n ready: Promise.resolve(),\n available: Effect.runSync(Deferred.make<void>()),\n observed: Effect.runSync(Deferred.make<void, unknown>()),\n keys,\n release: () => {\n subset.signal?.removeEventListener(\"abort\", demand!.release);\n if (!demand || demands.get(key) !== demand) return;\n if (demand.received)\n for (const rowKey of demand.rows.keys()) dirtyKeys.add(rowKey);\n demands.delete(key);\n const group = demand.group;\n group?.members.delete(demand);\n if (group && !group.members.size) {\n observations.delete(group.key);\n close(group.scope);\n }\n close(child);\n if (alive && active && demands.size) void load().catch(stop);\n },\n };\n demands.set(key, demand);\n subset.signal?.addEventListener(\"abort\", demand.release, { once: true });\n demand.ready = run(\n Scope.provide(\n Effect.gen(function* () {\n const acquisition =\n typeof acquire === \"function\" ? acquire(subset) : acquire;\n // Observe installed rows while readiness is pending. Cached\n // data is displayable; it does not mean remote demand is ready.\n const acquiring =\n observing && acquisition\n ? yield* Effect.forkIn(acquisition, child, {\n startImmediately: true,\n })\n : undefined;\n if (!observing && acquisition) yield* acquisition;\n if (native) {\n const observed = yield* Effect.forkIn(\n observeNative(demand!),\n child,\n {\n startImmediately: true,\n }\n );\n yield* Effect.all(\n [\n Fiber.join(observed),\n ...(acquiring ? [Fiber.join(acquiring)] : []),\n ],\n { concurrency: \"unbounded\", discard: true }\n );\n } else if (options.observe) {\n const ready = yield* Deferred.make<void, unknown>();\n yield* Stream.runForEach(options.observe(subset), (batch) =>\n Effect.tryPromise({\n try: async () => {\n if (!demand || demands.get(key) !== demand) return;\n const first = !demand.received;\n let changed = false;\n demand.received = true;\n if (batch.reset) {\n for (const rowKey of demand.rows.keys()) {\n dirtyKeys.add(rowKey);\n changed = true;\n }\n demand.rows.clear();\n }\n for (const removed of batch.removed) {\n // Native observers conservatively report keys\n // outside their filter. Only a key contributed\n // by this demand can change its winning row.\n if (!demand.rows.delete(removed)) continue;\n dirtyKeys.add(removed);\n changed = true;\n }\n for (const row of batch.rows) {\n dirtyKeys.add(row.key);\n demand.rows.set(row.key, row.value);\n changed = true;\n }\n if (first || changed || reconcileInstalled)\n await load();\n // An optimistic insert can arrive after a point read\n // starts. Its positive result is already known locally;\n // only absence needs completed upstream coverage.\n if (keys?.every((key) => demand!.rows.has(key)))\n Effect.runSync(\n Deferred.succeed(demand.available, undefined)\n );\n Effect.runSync(Deferred.succeed(ready, undefined));\n },\n catch: (cause) => cause,\n }).pipe(\n Effect.withSpan(\"Ontology.collection.publish\", {\n attributes: {\n collection: options.id,\n rows: batch.rows.length,\n removed: batch.removed.length,\n reset: batch.reset,\n },\n })\n )\n ).pipe(\n Effect.catch((error) =>\n Effect.gen(function* () {\n yield* Deferred.fail(ready, error);\n if (alive && active && demands.get(key) === demand)\n stop(error);\n })\n ),\n Effect.forkIn(child, { startImmediately: true })\n );\n yield* Effect.all(\n [\n Deferred.await(ready),\n ...(acquiring ? [Fiber.join(acquiring)] : []),\n ],\n { concurrency: \"unbounded\", discard: true }\n );\n }\n }),\n child\n ),\n child\n );\n void demand.ready.catch((error) => {\n if (\n (cached || demand!.settled) &&\n demands.get(key) === demand &&\n !subset.signal?.aborted\n )\n stop(error);\n demand!.release();\n });\n }\n const current = demand;\n // A synchronous first snapshot can answer a positive\n // point read immediately. Absence still waits for upstream\n // coverage, and the scoped acquisition reports late errors.\n cached ||= Boolean(\n keys?.every((key) => current.rows.has(key) && collection.has(key as K))\n );\n // Reusing rows or coverage never bypasses the new lease's\n // local revision fence, including a complete empty answer.\n if (native && !current.received) cached = false;\n const completed = Promise.race([\n current.ready,\n ...(keys ? [run(Deferred.await(current.available), current.scope)] : []),\n ]).then(async () => {\n await load();\n current.settled = true;\n });\n if (cached) {\n // Keep the scoped observer/lease and report later failures normally;\n // readiness needn't wait for another acquisition of a known row.\n void completed.catch((error) => {\n if (demands.get(key) === current && !subset.signal?.aborted) stop(error);\n });\n return true;\n }\n return completed;\n },\n unloadSubset: (subset) => {\n const demand = demands.get(subset);\n demand?.release();\n },\n cleanup: async () => {\n releaseDiagnostics?.();\n alive = false;\n refresh = undefined;\n await watcher.then(\n (fiber) => Effect.runPromise(Fiber.interrupt(fiber)),\n () => undefined\n );\n await Promise.all([\n ...releasing,\n ...[...demands.values()].map((demand) => {\n demand.subset.signal?.removeEventListener(\"abort\", demand.release);\n return Effect.runPromise(Scope.close(demand.scope, Exit.void));\n }),\n ]);\n demands.clear();\n observations.clear();\n dirtyKeys.clear();\n await Effect.runPromise(Scope.close(runScope, Exit.void));\n },\n };\n },\n },\n };\n return config;\n});\n// Local collection clients share the owning tables service, never another context's tables.\nconst localListeners = new WeakMap<TablesService, Set<() => void>>();\nconst localChanges = (tables: TablesService) => {\n let listeners = localListeners.get(tables);\n if (!listeners) localListeners.set(tables, (listeners = new Set()));\n const current = listeners;\n return {\n changes: Stream.callback<void>(\n (queue) =>\n Effect.acquireRelease(\n Effect.sync(() => {\n const listener = () => {\n Queue.offerUnsafe(queue, undefined);\n };\n current.add(listener);\n return listener;\n }),\n (listener) =>\n Effect.sync(() => {\n current.delete(listener);\n })\n ),\n { bufferSize: 1, strategy: \"sliding\" }\n ),\n notify: Effect.sync(() => {\n for (const listener of current) listener();\n }),\n };\n};\nexport const localCollectionOptions = Effect.fnUntraced(function* <A extends object, K extends Key>(options: {\n readonly name: string;\n readonly getKey: (value: A) => K;\n readonly schemaVersion?: number;\n}) {\n const runtime = yield* Runtime;\n const local = localChanges(runtime.tables);\n const table = Table.make<A>({\n name: JSON.stringify([\"local\", runtime.owner, runtime.namespace, options.name]),\n version: options.schemaVersion,\n });\n const config = yield* persistedCollectionOptions<A, K>({\n id: `party-stack:${runtime.owner}:${runtime.namespace}:${options.name}`,\n getKey: options.getKey,\n load: (subset) => runtime.tables.query(table, storageSubset(subset)),\n changes: local.changes,\n persist: (mutations) =>\n runtime.tables\n .transaction((tx) =>\n Effect.gen(function* () {\n for (const mutation of mutations) {\n if (mutation.type === \"delete\") yield* tx.delete(table, mutation.key);\n else yield* tx.put(table, mutation.key, mutation.modified);\n }\n })\n )\n .pipe(Effect.tap(() => local.notify)),\n });\n return config;\n});\nexport const replicatedCollectionOptions = Effect.fnUntraced(function* <A extends object>(options: {\n readonly replica: ReplicaService;\n readonly objectType: string;\n readonly getKey: (value: A) => Key;\n readonly id: string;\n /** Observe and retain local cache only; never acquire upstream demand. */\n readonly localOnly?: boolean;\n}) {\n const subsetCodec = Table.make({ name: \"native-observation-subset\" });\n const revision = readVisibleRevision(options.replica);\n const observe = (subset: LoadSubsetOptions) =>\n options.replica.observeSubset(ontologySubset(subset, options.replica.ir, options.objectType)).pipe(\n Stream.map((batch) => ({\n ...batch,\n rows: batch.rows.map((row) => ({ key: row.key, value: row.value as A })),\n }))\n );\n return yield* collectionOptionsImpl<A, Key>(\n {\n id: options.id,\n getKey: options.getKey,\n primaryKey: options.replica.ir.objectTypes.find((type) => type.name === options.objectType)\n ?.primaryKey,\n supportsOrderedWindow: (subset) =>\n analyzeOntologySubset(subset, options.replica.ir, options.objectType).orderedWindowExact,\n covers: (requested, held) =>\n coversSubset(\n {\n objectType: options.objectType,\n query: storageSubset(requested, options.replica.ir, options.objectType),\n },\n {\n objectType: options.objectType,\n query: storageSubset(held, options.replica.ir, options.objectType),\n }\n ),\n describeSubset: (subset) => ({\n objectType: options.objectType,\n ...analyzeStorageSubset(subset, options.replica.ir, options.objectType),\n requested: {\n where: subset.where,\n orderBy: subset.orderBy,\n limit: subset.limit,\n offset: subset.offset,\n cursor: subset.cursor,\n },\n }),\n load: (subset) =>\n Effect.map(\n options.replica.readSubset(\n ontologySubset(subset, options.replica.ir, options.objectType)\n ),\n (rows) =>\n rows.map((row) => ({\n key: row.key,\n value: row.value as A,\n }))\n ),\n changes: Stream.empty,\n observe,\n acquireDemand: (subset) =>\n options.localOnly\n ? options.replica.demand.acquire(\n ontologySubset(subset, options.replica.ir, options.objectType),\n { localOnly: true }\n )\n : options.replica.demand.acquire(\n ontologySubset(subset, options.replica.ir, options.objectType)\n ),\n },\n revision\n ? {\n key: (subset) =>\n subsetCodec.encode(ontologySubset(subset, options.replica.ir, options.objectType)),\n revision,\n observe,\n }\n : undefined\n );\n});\nexport const scopedCollection = <A extends object, K extends Key>(\n options: CollectionConfig<A, K>,\n client?: DbClient\n) =>\n client\n ? Effect.sync(() => client.collection(collectionOptions(options)))\n : Effect.acquireRelease(\n Effect.sync(() => createCollection(options)),\n (collection) =>\n Effect.promise(async () => {\n await collection.cleanup({ dependents: true });\n })\n );\nexport const makeLocalCollection = Effect.fn(\"Ontology.localCollection\")(function* <\n A extends object,\n K extends Key,\n>(options: Parameters<typeof localCollectionOptions<A, K>>[0]) {\n return yield* scopedCollection(yield* localCollectionOptions(options));\n});\nexport const makeReplicatedCollection = Effect.fn(\"Ontology.replicatedCollection\")(function* <\n A extends object,\n>(options: Parameters<typeof replicatedCollectionOptions<A>>[0], client?: DbClient) {\n return yield* scopedCollection(yield* replicatedCollectionOptions(options), client);\n});\n"],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { RuntimeService } from "@party-stack/runtime";
|
|
2
|
+
import { Scope } from "effect";
|
|
3
|
+
import { Collection } from "@tanstack/db";
|
|
4
|
+
//#region src/tanstack/createLocalCollection.d.ts
|
|
5
|
+
export declare function createLocalCollection<T extends object, TKey extends string | number>(options: {
|
|
6
|
+
name: string;
|
|
7
|
+
getKey: (value: T) => TKey;
|
|
8
|
+
runtime: RuntimeService;
|
|
9
|
+
schemaVersion?: number;
|
|
10
|
+
/** Optional owner for the collection's Effect resources. */
|
|
11
|
+
scope: Scope.Scope;
|
|
12
|
+
}): Collection<T, TKey>;
|
|
13
|
+
//#endregion
|
|
14
|
+
//# sourceMappingURL=createLocalCollection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createLocalCollection.d.ts","names":[],"sources":["../../src/tanstack/createLocalCollection.ts"],"mappings":";;;;wBAKgB,sBAAsB,kBAAkB,8BAA8B;EAClF;EACA,SAAS,OAAO,MAAM;EACtB,SAAS;EACT;;EAEA,OAAO,MAAM;IACb,WAAW,GAAG"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createEffectLocalCollection } from "./localCollection.js";
|
|
2
|
+
//#region src/tanstack/createLocalCollection.ts
|
|
3
|
+
function createLocalCollection(options) {
|
|
4
|
+
return createEffectLocalCollection(options);
|
|
5
|
+
}
|
|
6
|
+
//#endregion
|
|
7
|
+
export { createLocalCollection };
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=createLocalCollection.js.map
|