@party-stack/ontology 0.20.0 → 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 +29 -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 +3 -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 -30
- 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 +53 -18
- 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 -18
- 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 -223
- 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 -413
- 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 -104
- 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 -24
- 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 -69
- 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 -50
- 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
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
import { runOutboxLeader } from "./leaderExecutor.js";
|
|
2
|
-
import { OUTBOX_COORDINATION_SERVICE } from "./service.js";
|
|
3
|
-
import { serveOntologyOutbox } from "./outboxService.js";
|
|
4
|
-
import { OntologyOutboxRepository } from "./repository.js";
|
|
5
|
-
import { OutboxProjectionManager } from "./projectionManager.js";
|
|
6
|
-
import { CoordinationError, createLocalCollection, isCoordinationHost } from "@party-stack/runtime";
|
|
7
|
-
import { cloneValue } from "@party-stack/coordination";
|
|
8
|
-
import { useConnectivityChanges } from "@party-stack/runtime/effection";
|
|
9
|
-
import { createSignal, each, resource, run, spawn, suspend, until, useAbortSignal } from "effection";
|
|
10
|
-
//#region src/live/outbox/createOntologyOutbox.ts
|
|
11
|
-
const DEFAULT_MAX_RETRIES = 3;
|
|
12
|
-
const DEFAULT_RETRY_DELAY_MS = 1e3;
|
|
13
|
-
function nonNegativeInteger(value, fallback, name) {
|
|
14
|
-
const resolved = value ?? fallback;
|
|
15
|
-
if (!Number.isSafeInteger(resolved) || resolved < 0) throw new RangeError(`${name} must be a non-negative safe integer.`);
|
|
16
|
-
return resolved;
|
|
17
|
-
}
|
|
18
|
-
function deferred() {
|
|
19
|
-
let resolvePromise;
|
|
20
|
-
let rejectPromise;
|
|
21
|
-
const value = {
|
|
22
|
-
promise: void 0,
|
|
23
|
-
settled: false,
|
|
24
|
-
resolve(result) {
|
|
25
|
-
if (value.settled) return;
|
|
26
|
-
value.settled = true;
|
|
27
|
-
resolvePromise(result);
|
|
28
|
-
},
|
|
29
|
-
reject(error) {
|
|
30
|
-
if (value.settled) return;
|
|
31
|
-
value.settled = true;
|
|
32
|
-
rejectPromise(error);
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
value.promise = new Promise((resolve, reject) => {
|
|
36
|
-
resolvePromise = resolve;
|
|
37
|
-
rejectPromise = reject;
|
|
38
|
-
});
|
|
39
|
-
return value;
|
|
40
|
-
}
|
|
41
|
-
function normalizeError(error) {
|
|
42
|
-
return error instanceof Error ? error : new Error(String(error));
|
|
43
|
-
}
|
|
44
|
-
function eventError(event) {
|
|
45
|
-
const error = new Error(event.error.message);
|
|
46
|
-
error.name = event.error.name;
|
|
47
|
-
return error;
|
|
48
|
-
}
|
|
49
|
-
function createOutboxCollection(options) {
|
|
50
|
-
return createLocalCollection({
|
|
51
|
-
name: "ontology-outbox",
|
|
52
|
-
getKey: (entry) => entry.id,
|
|
53
|
-
runtime: options.runtime,
|
|
54
|
-
schemaVersion: 1
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
function useOntologyOutbox(options, collection = createOutboxCollection(options)) {
|
|
58
|
-
return resource(function* (provide) {
|
|
59
|
-
const repository = new OntologyOutboxRepository(collection);
|
|
60
|
-
const failureStrategy = options.failureStrategy ?? "discard-all";
|
|
61
|
-
const service = options.runtime.coordination.service(OUTBOX_COORDINATION_SERVICE);
|
|
62
|
-
const wake = createSignal();
|
|
63
|
-
const projections = new OutboxProjectionManager(options.project ? async (entry) => options.project?.(entry) : void 0);
|
|
64
|
-
const completions = /* @__PURE__ */ new Map();
|
|
65
|
-
const lifetime = {};
|
|
66
|
-
let disposing = false;
|
|
67
|
-
let reconciliationVersion = 0;
|
|
68
|
-
const deliverResult = async (event) => {
|
|
69
|
-
const completion = completions.get(event.id);
|
|
70
|
-
if (event.type === "completed") {
|
|
71
|
-
await projections.discard(event.id);
|
|
72
|
-
if (completion) {
|
|
73
|
-
completions.delete(event.id);
|
|
74
|
-
completion.resolve(event.result);
|
|
75
|
-
}
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
const error = eventError(event);
|
|
79
|
-
await projections.discard(event.id, error);
|
|
80
|
-
if (completion) {
|
|
81
|
-
completions.delete(event.id);
|
|
82
|
-
completion.reject(error);
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
try {
|
|
86
|
-
lifetime.unsubscribeResults = service.events.subscribe("result", (event) => {
|
|
87
|
-
deliverResult(event);
|
|
88
|
-
});
|
|
89
|
-
yield* until(repository.preload());
|
|
90
|
-
if (isCoordinationHost(options.runtime.coordination)) lifetime.server = serveOntologyOutbox(options.runtime.coordination, repository);
|
|
91
|
-
const reconcileProjections = async () => {
|
|
92
|
-
const version = ++reconciliationVersion;
|
|
93
|
-
const entries = await repository.entries();
|
|
94
|
-
if (disposing || version !== reconciliationVersion) return;
|
|
95
|
-
await projections.reconcile(entries);
|
|
96
|
-
};
|
|
97
|
-
lifetime.unsubscribeCollection = collection.subscribeChanges(() => {
|
|
98
|
-
wake.send();
|
|
99
|
-
reconcileProjections();
|
|
100
|
-
});
|
|
101
|
-
lifetime.unsubscribeConnection = options.connection ? { unsubscribe: options.connection.subscribe(() => {
|
|
102
|
-
wake.send();
|
|
103
|
-
}) } : void 0;
|
|
104
|
-
const existing = yield* until(repository.entries());
|
|
105
|
-
yield* until(projections.restore(existing));
|
|
106
|
-
const connectivityChanges = yield* useConnectivityChanges(options.runtime);
|
|
107
|
-
lifetime.connectivityTask = yield* spawn(function* () {
|
|
108
|
-
for (const isConnected of yield* each(connectivityChanges)) {
|
|
109
|
-
wake.send();
|
|
110
|
-
yield* each.next();
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
if (isCoordinationHost(options.runtime.coordination)) {
|
|
114
|
-
const host = options.runtime.coordination;
|
|
115
|
-
const leaderOptions = {
|
|
116
|
-
runtime: options.runtime,
|
|
117
|
-
service,
|
|
118
|
-
wake,
|
|
119
|
-
failureStrategy,
|
|
120
|
-
maxRetries: nonNegativeInteger(options.maxRetries, DEFAULT_MAX_RETRIES, "Outbox maxRetries"),
|
|
121
|
-
retryDelayMs: DEFAULT_RETRY_DELAY_MS,
|
|
122
|
-
execute: (entry) => options.execute(entry),
|
|
123
|
-
connection: options.connection
|
|
124
|
-
};
|
|
125
|
-
lifetime.leaderTask = yield* spawn(function* () {
|
|
126
|
-
const lifetimeSignal = yield* useAbortSignal();
|
|
127
|
-
while (!lifetimeSignal.aborted) try {
|
|
128
|
-
const leaderRun = host.runAsLeader(({ signal }) => runOutboxLeader(signal, leaderOptions), { signal: lifetimeSignal });
|
|
129
|
-
lifetime.leaderRun = leaderRun;
|
|
130
|
-
yield* until(leaderRun);
|
|
131
|
-
return;
|
|
132
|
-
} catch (error) {
|
|
133
|
-
if (lifetimeSignal.aborted) return;
|
|
134
|
-
if (!host.isLeader && !(error instanceof CoordinationError)) continue;
|
|
135
|
-
throw error;
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
yield* provide({
|
|
140
|
-
collection,
|
|
141
|
-
ready: Promise.resolve(),
|
|
142
|
-
async enqueue(request, enqueueOptions) {
|
|
143
|
-
const timestamp = Date.now();
|
|
144
|
-
const proposed = {
|
|
145
|
-
id: crypto.randomUUID(),
|
|
146
|
-
sequence: 0,
|
|
147
|
-
request: {
|
|
148
|
-
...request,
|
|
149
|
-
idempotencyKey: request.idempotencyKey ?? crypto.randomUUID()
|
|
150
|
-
},
|
|
151
|
-
visibility: enqueueOptions?.visibility ?? "confirmed",
|
|
152
|
-
status: "queued",
|
|
153
|
-
createdAt: timestamp,
|
|
154
|
-
updatedAt: timestamp,
|
|
155
|
-
attempts: 0,
|
|
156
|
-
retryable: true,
|
|
157
|
-
nextAttemptAt: timestamp
|
|
158
|
-
};
|
|
159
|
-
const completion = deferred();
|
|
160
|
-
completion.promise.catch(() => void 0);
|
|
161
|
-
completions.set(proposed.id, completion);
|
|
162
|
-
let entry;
|
|
163
|
-
try {
|
|
164
|
-
entry = await service.methods.enqueue({ entry: proposed });
|
|
165
|
-
} catch (error) {
|
|
166
|
-
completions.delete(proposed.id);
|
|
167
|
-
completion.reject(normalizeError(error));
|
|
168
|
-
throw error;
|
|
169
|
-
}
|
|
170
|
-
await projections.ensure(entry);
|
|
171
|
-
return {
|
|
172
|
-
entry,
|
|
173
|
-
completed: completion.promise
|
|
174
|
-
};
|
|
175
|
-
},
|
|
176
|
-
async edit(id, update) {
|
|
177
|
-
const current = repository.get(id);
|
|
178
|
-
if (!current) throw new Error(`Outbox entry "${id}" was not found in this context.`);
|
|
179
|
-
const request = cloneValue(current.request);
|
|
180
|
-
update(request);
|
|
181
|
-
const entry = await service.methods.edit({
|
|
182
|
-
id,
|
|
183
|
-
request
|
|
184
|
-
});
|
|
185
|
-
await projections.ensure(entry);
|
|
186
|
-
return entry;
|
|
187
|
-
},
|
|
188
|
-
async remove(id) {
|
|
189
|
-
await service.methods.remove({ id });
|
|
190
|
-
},
|
|
191
|
-
async retry(id) {
|
|
192
|
-
await service.methods.retry({ id });
|
|
193
|
-
wake.send();
|
|
194
|
-
},
|
|
195
|
-
cleanup() {
|
|
196
|
-
return Promise.resolve();
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
} finally {
|
|
200
|
-
disposing = true;
|
|
201
|
-
reconciliationVersion += 1;
|
|
202
|
-
const cleanupErrors = [];
|
|
203
|
-
const capture = (error) => {
|
|
204
|
-
cleanupErrors.push(normalizeError(error));
|
|
205
|
-
};
|
|
206
|
-
lifetime.unsubscribeResults?.();
|
|
207
|
-
lifetime.unsubscribeCollection?.unsubscribe();
|
|
208
|
-
lifetime.unsubscribeConnection?.unsubscribe();
|
|
209
|
-
if (lifetime.server) try {
|
|
210
|
-
yield* until(lifetime.server.close());
|
|
211
|
-
} catch (error) {
|
|
212
|
-
capture(error);
|
|
213
|
-
}
|
|
214
|
-
if (lifetime.leaderTask !== void 0) try {
|
|
215
|
-
yield* lifetime.leaderTask.halt();
|
|
216
|
-
} catch (error) {
|
|
217
|
-
capture(error);
|
|
218
|
-
}
|
|
219
|
-
if (lifetime.leaderRun) yield* until(Promise.allSettled([lifetime.leaderRun]));
|
|
220
|
-
if (lifetime.connectivityTask !== void 0) try {
|
|
221
|
-
yield* lifetime.connectivityTask.halt();
|
|
222
|
-
} catch (error) {
|
|
223
|
-
capture(error);
|
|
224
|
-
}
|
|
225
|
-
try {
|
|
226
|
-
yield* until(projections.close());
|
|
227
|
-
} catch (error) {
|
|
228
|
-
capture(error);
|
|
229
|
-
}
|
|
230
|
-
const disposed = /* @__PURE__ */ new Error("Outbox disposed.");
|
|
231
|
-
for (const completion of completions.values()) completion.reject(disposed);
|
|
232
|
-
completions.clear();
|
|
233
|
-
try {
|
|
234
|
-
yield* until(collection.cleanup());
|
|
235
|
-
} catch (error) {
|
|
236
|
-
capture(error);
|
|
237
|
-
}
|
|
238
|
-
if (cleanupErrors[0]) yield* until(Promise.reject(cleanupErrors[0]));
|
|
239
|
-
}
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
function createOntologyOutbox(options) {
|
|
243
|
-
const collection = createOutboxCollection(options);
|
|
244
|
-
let outbox;
|
|
245
|
-
const ready = deferred();
|
|
246
|
-
ready.promise.catch(() => void 0);
|
|
247
|
-
let cleanupPromise;
|
|
248
|
-
const task = run(function* () {
|
|
249
|
-
try {
|
|
250
|
-
outbox = yield* useOntologyOutbox(options, collection);
|
|
251
|
-
ready.resolve();
|
|
252
|
-
yield* suspend();
|
|
253
|
-
} catch (error) {
|
|
254
|
-
ready.reject(normalizeError(error));
|
|
255
|
-
throw error;
|
|
256
|
-
}
|
|
257
|
-
});
|
|
258
|
-
task.catch(() => void 0);
|
|
259
|
-
return {
|
|
260
|
-
collection,
|
|
261
|
-
ready: ready.promise,
|
|
262
|
-
task,
|
|
263
|
-
async enqueue(request, enqueueOptions) {
|
|
264
|
-
await ready.promise;
|
|
265
|
-
return outbox.enqueue(request, enqueueOptions);
|
|
266
|
-
},
|
|
267
|
-
async edit(id, update) {
|
|
268
|
-
await ready.promise;
|
|
269
|
-
return outbox.edit(id, update);
|
|
270
|
-
},
|
|
271
|
-
async remove(id) {
|
|
272
|
-
await ready.promise;
|
|
273
|
-
return outbox.remove(id);
|
|
274
|
-
},
|
|
275
|
-
async retry(id) {
|
|
276
|
-
await ready.promise;
|
|
277
|
-
return outbox.retry(id);
|
|
278
|
-
},
|
|
279
|
-
async cleanup() {
|
|
280
|
-
cleanupPromise ??= (async () => {
|
|
281
|
-
await Promise.allSettled([ready.promise, collection.preload()]);
|
|
282
|
-
await task.halt().catch(() => void 0);
|
|
283
|
-
if (collection.status !== "cleaned-up") await collection.cleanup().catch(() => void 0);
|
|
284
|
-
})();
|
|
285
|
-
return cleanupPromise;
|
|
286
|
-
}
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
//#endregion
|
|
290
|
-
export { createOntologyOutbox, useOntologyOutbox };
|
|
291
|
-
|
|
292
|
-
//# sourceMappingURL=createOntologyOutbox.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createOntologyOutbox.js","names":[],"sources":["../../../src/live/outbox/createOntologyOutbox.ts"],"sourcesContent":["import { cloneValue } from \"@party-stack/coordination\";\nimport {\n createLocalCollection,\n isCoordinationHost,\n CoordinationError,\n type CoordinationServiceServer,\n type RuntimeAdapter,\n} from \"@party-stack/runtime\";\nimport { useConnectivityChanges } from \"@party-stack/runtime/effection\";\nimport {\n createSignal,\n each,\n resource,\n run,\n spawn,\n suspend,\n until,\n useAbortSignal,\n type Operation,\n type Task,\n} from \"effection\";\nimport { runOutboxLeader, type OutboxLeaderOptions } from \"./leaderExecutor.js\";\nimport { serveOntologyOutbox } from \"./outboxService.js\";\nimport { OutboxProjectionManager, type OutboxProjection } from \"./projectionManager.js\";\nimport { OntologyOutboxRepository } from \"./repository.js\";\nimport {\n OUTBOX_COORDINATION_SERVICE,\n type OutboxCoordinationService,\n type OutboxResultEvent,\n} from \"./service.js\";\nimport type {\n EnqueuedOntologyAction,\n OntologyActionRequest,\n OntologyOutbox,\n OntologyOutboxEntry,\n} from \"./types.js\";\nimport type { ConnectionMonitor } from \"@party-stack/connections\";\nimport type { Collection } from \"@tanstack/db\";\n\nexport type { OutboxProjection } from \"./projectionManager.js\";\n\nconst DEFAULT_MAX_RETRIES = 3;\nconst DEFAULT_RETRY_DELAY_MS = 1_000;\n\nexport interface CreateOntologyOutboxOptions {\n runtime: RuntimeAdapter;\n execute(entry: OntologyOutboxEntry): Promise<unknown>;\n project?(entry: OntologyOutboxEntry): Promise<OutboxProjection | undefined>;\n failureStrategy?: \"pause\" | \"discard-all\";\n maxRetries?: number;\n connection?: ConnectionMonitor;\n}\n\nfunction nonNegativeInteger(value: number | undefined, fallback: number, name: string): number {\n const resolved = value ?? fallback;\n if (!Number.isSafeInteger(resolved) || resolved < 0) {\n throw new RangeError(`${name} must be a non-negative safe integer.`);\n }\n return resolved;\n}\n\ninterface Deferred<T> {\n promise: Promise<T>;\n settled: boolean;\n resolve(value: T): void;\n reject(error: Error): void;\n}\n\nfunction deferred<T>(): Deferred<T> {\n let resolvePromise!: (value: T) => void;\n let rejectPromise!: (error: Error) => void;\n const value: Deferred<T> = {\n promise: undefined as unknown as Promise<T>,\n settled: false,\n resolve(result) {\n if (value.settled) return;\n value.settled = true;\n resolvePromise(result);\n },\n reject(error) {\n if (value.settled) return;\n value.settled = true;\n rejectPromise(error);\n },\n };\n value.promise = new Promise<T>((resolve, reject) => {\n resolvePromise = resolve;\n rejectPromise = reject;\n });\n return value;\n}\n\nfunction normalizeError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\nfunction eventError(event: Extract<OutboxResultEvent, { type: \"rejected\" }>): Error {\n const error = new Error(event.error.message);\n error.name = event.error.name;\n return error;\n}\n\nfunction createOutboxCollection(\n options: CreateOntologyOutboxOptions\n): Collection<OntologyOutboxEntry, string> {\n return createLocalCollection<OntologyOutboxEntry, string>({\n name: \"ontology-outbox\",\n getKey: (entry) => entry.id,\n runtime: options.runtime,\n schemaVersion: 1,\n });\n}\n\nexport function useOntologyOutbox(\n options: CreateOntologyOutboxOptions,\n collection: Collection<OntologyOutboxEntry, string> = createOutboxCollection(options)\n): Operation<OntologyOutbox> {\n return resource(function* (provide) {\n const repository = new OntologyOutboxRepository(collection);\n const failureStrategy = options.failureStrategy ?? \"discard-all\";\n const service =\n options.runtime.coordination.service<OutboxCoordinationService>(OUTBOX_COORDINATION_SERVICE);\n const wake = createSignal<void>();\n const projections = new OutboxProjectionManager(\n options.project ? async (entry) => options.project?.(entry) : undefined\n );\n const completions = new Map<string, Deferred<unknown>>();\n const lifetime: {\n server?: CoordinationServiceServer<OutboxCoordinationService>;\n unsubscribeResults?: () => void;\n unsubscribeCollection?: {\n unsubscribe(): void;\n };\n connectivityTask?: Task<void>;\n unsubscribeConnection?: {\n unsubscribe(): void;\n };\n leaderTask?: Task<void>;\n leaderRun?: Promise<unknown>;\n } = {};\n let disposing = false;\n let reconciliationVersion = 0;\n\n const deliverResult = async (event: OutboxResultEvent) => {\n const completion = completions.get(event.id);\n if (event.type === \"completed\") {\n await projections.discard(event.id);\n if (completion) {\n completions.delete(event.id);\n completion.resolve(event.result);\n }\n return;\n }\n\n const error = eventError(event);\n await projections.discard(event.id, error);\n if (completion) {\n completions.delete(event.id);\n completion.reject(error);\n }\n };\n try {\n lifetime.unsubscribeResults = service.events.subscribe(\"result\", (event) => {\n void deliverResult(event);\n });\n\n yield* until(repository.preload());\n if (isCoordinationHost(options.runtime.coordination)) {\n lifetime.server = serveOntologyOutbox(options.runtime.coordination, repository);\n }\n\n const reconcileProjections = async (): Promise<void> => {\n const version = ++reconciliationVersion;\n const entries = await repository.entries();\n if (disposing || version !== reconciliationVersion) {\n return;\n }\n await projections.reconcile(entries);\n };\n lifetime.unsubscribeCollection = collection.subscribeChanges(() => {\n wake.send();\n void reconcileProjections();\n });\n lifetime.unsubscribeConnection = options.connection\n ? {\n unsubscribe: options.connection.subscribe(() => {\n wake.send();\n }),\n }\n : undefined;\n\n const existing = yield* until(repository.entries());\n yield* until(projections.restore(existing));\n\n const connectivityChanges = yield* useConnectivityChanges(options.runtime);\n lifetime.connectivityTask = yield* spawn(function* () {\n for (const isConnected of yield* each(connectivityChanges)) {\n void isConnected;\n wake.send();\n yield* each.next();\n }\n });\n\n if (isCoordinationHost(options.runtime.coordination)) {\n const host = options.runtime.coordination;\n const leaderOptions: OutboxLeaderOptions = {\n runtime: options.runtime,\n service,\n wake,\n failureStrategy: failureStrategy,\n maxRetries: nonNegativeInteger(\n options.maxRetries,\n DEFAULT_MAX_RETRIES,\n \"Outbox maxRetries\"\n ),\n retryDelayMs: DEFAULT_RETRY_DELAY_MS,\n execute: (entry) => options.execute(entry),\n connection: options.connection,\n };\n lifetime.leaderTask = yield* spawn(function* () {\n const lifetimeSignal = yield* useAbortSignal();\n while (!lifetimeSignal.aborted) {\n try {\n const leaderRun = host.runAsLeader(\n ({ signal }) => runOutboxLeader(signal, leaderOptions),\n {\n signal: lifetimeSignal,\n }\n );\n lifetime.leaderRun = leaderRun;\n yield* until(leaderRun);\n return;\n } catch (error) {\n if (lifetimeSignal.aborted) {\n return;\n }\n if (!host.isLeader && !(error instanceof CoordinationError)) {\n continue;\n }\n throw error;\n }\n }\n });\n }\n\n const outbox: OntologyOutbox = {\n collection,\n ready: Promise.resolve(),\n async enqueue<Result>(\n request: Omit<OntologyActionRequest, \"idempotencyKey\"> & {\n idempotencyKey?: string;\n },\n enqueueOptions?: {\n visibility?: \"confirmed\" | \"optimistic\";\n }\n ) {\n const timestamp = Date.now();\n const proposed: OntologyOutboxEntry = {\n id: crypto.randomUUID(),\n sequence: 0,\n request: {\n ...request,\n idempotencyKey: request.idempotencyKey ?? crypto.randomUUID(),\n },\n visibility: enqueueOptions?.visibility ?? \"confirmed\",\n status: \"queued\",\n createdAt: timestamp,\n updatedAt: timestamp,\n attempts: 0,\n retryable: true,\n nextAttemptAt: timestamp,\n };\n const completion = deferred<Result>();\n void completion.promise.catch(() => undefined);\n completions.set(proposed.id, completion);\n\n let entry: OntologyOutboxEntry;\n try {\n entry = await service.methods.enqueue({\n entry: proposed,\n });\n } catch (error) {\n completions.delete(proposed.id);\n completion.reject(normalizeError(error));\n throw error;\n }\n\n await projections.ensure(entry);\n\n return {\n entry,\n completed: completion.promise,\n } as EnqueuedOntologyAction<Result>;\n },\n async edit(id, update) {\n const current = repository.get(id);\n if (!current) {\n throw new Error(`Outbox entry \"${id}\" was not found in this context.`);\n }\n const request = cloneValue(current.request);\n update(request);\n const entry = await service.methods.edit({\n id,\n request,\n });\n await projections.ensure(entry);\n return entry;\n },\n async remove(id) {\n await service.methods.remove({ id });\n },\n async retry(id) {\n await service.methods.retry({ id });\n wake.send();\n },\n cleanup() {\n return Promise.resolve();\n },\n };\n\n yield* provide(outbox);\n } finally {\n disposing = true;\n reconciliationVersion += 1;\n const cleanupErrors: Error[] = [];\n const capture = (error: unknown) => {\n cleanupErrors.push(normalizeError(error));\n };\n\n lifetime.unsubscribeResults?.();\n lifetime.unsubscribeCollection?.unsubscribe();\n lifetime.unsubscribeConnection?.unsubscribe();\n if (lifetime.server) {\n try {\n yield* until(lifetime.server.close());\n } catch (error) {\n capture(error);\n }\n }\n if (lifetime.leaderTask !== undefined) {\n try {\n yield* lifetime.leaderTask.halt();\n } catch (error) {\n capture(error);\n }\n }\n if (lifetime.leaderRun) {\n yield* until(Promise.allSettled([lifetime.leaderRun]));\n }\n if (lifetime.connectivityTask !== undefined) {\n try {\n yield* lifetime.connectivityTask.halt();\n } catch (error) {\n capture(error);\n }\n }\n try {\n yield* until(projections.close());\n } catch (error) {\n capture(error);\n }\n const disposed = new Error(\"Outbox disposed.\");\n for (const completion of completions.values()) {\n completion.reject(disposed);\n }\n completions.clear();\n try {\n yield* until(collection.cleanup());\n } catch (error) {\n capture(error);\n }\n\n if (cleanupErrors[0]) {\n yield* until(Promise.reject(cleanupErrors[0]));\n }\n }\n });\n}\n\nexport interface StartedOntologyOutbox extends OntologyOutbox {\n readonly task: Task<void>;\n}\n\nexport function createOntologyOutbox(options: CreateOntologyOutboxOptions): StartedOntologyOutbox {\n const collection = createOutboxCollection(options);\n let outbox: OntologyOutbox | undefined;\n const ready = deferred<void>();\n // Prevent unhandled rejection when cleanup races startup.\n void ready.promise.catch(() => undefined);\n let cleanupPromise: Promise<void> | undefined;\n const task = run(function* () {\n try {\n const value = yield* useOntologyOutbox(options, collection);\n outbox = value;\n ready.resolve();\n yield* suspend();\n } catch (error) {\n ready.reject(normalizeError(error));\n throw error;\n }\n });\n void task.catch(() => undefined);\n\n return {\n collection,\n ready: ready.promise,\n task,\n async enqueue(request, enqueueOptions) {\n await ready.promise;\n return outbox!.enqueue(request, enqueueOptions);\n },\n async edit(id, update) {\n await ready.promise;\n return outbox!.edit(id, update);\n },\n async remove(id) {\n await ready.promise;\n return outbox!.remove(id);\n },\n async retry(id) {\n await ready.promise;\n return outbox!.retry(id);\n },\n async cleanup() {\n cleanupPromise ??= (async () => {\n // Let persistence startup settle before tearing down so\n // loopback markReady cannot race cleaned-up status.\n await Promise.allSettled([ready.promise, collection.preload()]);\n await task.halt().catch(() => undefined);\n if (collection.status !== \"cleaned-up\") {\n await collection.cleanup().catch(() => undefined);\n }\n })();\n return cleanupPromise;\n },\n };\n}\n"],"mappings":";;;;;;;;;;AAyCA,MAAM,sBAAsB;AAC5B,MAAM,yBAAyB;AAW/B,SAAS,mBAAmB,OAA2B,UAAkB,MAAsB;CAC3F,MAAM,WAAW,SAAS;CAC1B,IAAI,CAAC,OAAO,cAAc,QAAQ,KAAK,WAAW,GAC9C,MAAM,IAAI,WAAW,GAAG,KAAK,sCAAsC;CAEvE,OAAO;AACX;AASA,SAAS,WAA2B;CAChC,IAAI;CACJ,IAAI;CACJ,MAAM,QAAqB;EACvB,SAAS,KAAA;EACT,SAAS;EACT,QAAQ,QAAQ;GACZ,IAAI,MAAM,SAAS;GACnB,MAAM,UAAU;GAChB,eAAe,MAAM;EACzB;EACA,OAAO,OAAO;GACV,IAAI,MAAM,SAAS;GACnB,MAAM,UAAU;GAChB,cAAc,KAAK;EACvB;CACJ;CACA,MAAM,UAAU,IAAI,SAAY,SAAS,WAAW;EAChD,iBAAiB;EACjB,gBAAgB;CACpB,CAAC;CACD,OAAO;AACX;AAEA,SAAS,eAAe,OAAuB;CAC3C,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACnE;AAEA,SAAS,WAAW,OAAgE;CAChF,MAAM,QAAQ,IAAI,MAAM,MAAM,MAAM,OAAO;CAC3C,MAAM,OAAO,MAAM,MAAM;CACzB,OAAO;AACX;AAEA,SAAS,uBACL,SACuC;CACvC,OAAO,sBAAmD;EACtD,MAAM;EACN,SAAS,UAAU,MAAM;EACzB,SAAS,QAAQ;EACjB,eAAe;CACnB,CAAC;AACL;AAEA,SAAgB,kBACZ,SACA,aAAsD,uBAAuB,OAAO,GAC3D;CACzB,OAAO,SAAS,WAAW,SAAS;EAChC,MAAM,aAAa,IAAI,yBAAyB,UAAU;EAC1D,MAAM,kBAAkB,QAAQ,mBAAmB;EACnD,MAAM,UACF,QAAQ,QAAQ,aAAa,QAAmC,2BAA2B;EAC/F,MAAM,OAAO,aAAmB;EAChC,MAAM,cAAc,IAAI,wBACpB,QAAQ,UAAU,OAAO,UAAU,QAAQ,UAAU,KAAK,IAAI,KAAA,CAClE;EACA,MAAM,8BAAc,IAAI,IAA+B;EACvD,MAAM,WAYF,CAAC;EACL,IAAI,YAAY;EAChB,IAAI,wBAAwB;EAE5B,MAAM,gBAAgB,OAAO,UAA6B;GACtD,MAAM,aAAa,YAAY,IAAI,MAAM,EAAE;GAC3C,IAAI,MAAM,SAAS,aAAa;IAC5B,MAAM,YAAY,QAAQ,MAAM,EAAE;IAClC,IAAI,YAAY;KACZ,YAAY,OAAO,MAAM,EAAE;KAC3B,WAAW,QAAQ,MAAM,MAAM;IACnC;IACA;GACJ;GAEA,MAAM,QAAQ,WAAW,KAAK;GAC9B,MAAM,YAAY,QAAQ,MAAM,IAAI,KAAK;GACzC,IAAI,YAAY;IACZ,YAAY,OAAO,MAAM,EAAE;IAC3B,WAAW,OAAO,KAAK;GAC3B;EACJ;EACA,IAAI;GACA,SAAS,qBAAqB,QAAQ,OAAO,UAAU,WAAW,UAAU;IACxE,cAAmB,KAAK;GAC5B,CAAC;GAED,OAAO,MAAM,WAAW,QAAQ,CAAC;GACjC,IAAI,mBAAmB,QAAQ,QAAQ,YAAY,GAC/C,SAAS,SAAS,oBAAoB,QAAQ,QAAQ,cAAc,UAAU;GAGlF,MAAM,uBAAuB,YAA2B;IACpD,MAAM,UAAU,EAAE;IAClB,MAAM,UAAU,MAAM,WAAW,QAAQ;IACzC,IAAI,aAAa,YAAY,uBACzB;IAEJ,MAAM,YAAY,UAAU,OAAO;GACvC;GACA,SAAS,wBAAwB,WAAW,uBAAuB;IAC/D,KAAK,KAAK;IACV,qBAA0B;GAC9B,CAAC;GACD,SAAS,wBAAwB,QAAQ,aACnC,EACI,aAAa,QAAQ,WAAW,gBAAgB;IAC5C,KAAK,KAAK;GACd,CAAC,EACL,IACA,KAAA;GAEN,MAAM,WAAW,OAAO,MAAM,WAAW,QAAQ,CAAC;GAClD,OAAO,MAAM,YAAY,QAAQ,QAAQ,CAAC;GAE1C,MAAM,sBAAsB,OAAO,uBAAuB,QAAQ,OAAO;GACzE,SAAS,mBAAmB,OAAO,MAAM,aAAa;IAClD,KAAK,MAAM,eAAe,OAAO,KAAK,mBAAmB,GAAG;KAExD,KAAK,KAAK;KACV,OAAO,KAAK,KAAK;IACrB;GACJ,CAAC;GAED,IAAI,mBAAmB,QAAQ,QAAQ,YAAY,GAAG;IAClD,MAAM,OAAO,QAAQ,QAAQ;IAC7B,MAAM,gBAAqC;KACvC,SAAS,QAAQ;KACjB;KACA;KACiB;KACjB,YAAY,mBACR,QAAQ,YACR,qBACA,mBACJ;KACA,cAAc;KACd,UAAU,UAAU,QAAQ,QAAQ,KAAK;KACzC,YAAY,QAAQ;IACxB;IACA,SAAS,aAAa,OAAO,MAAM,aAAa;KAC5C,MAAM,iBAAiB,OAAO,eAAe;KAC7C,OAAO,CAAC,eAAe,SACnB,IAAI;MACA,MAAM,YAAY,KAAK,aAClB,EAAE,aAAa,gBAAgB,QAAQ,aAAa,GACrD,EACI,QAAQ,eACZ,CACJ;MACA,SAAS,YAAY;MACrB,OAAO,MAAM,SAAS;MACtB;KACJ,SAAS,OAAO;MACZ,IAAI,eAAe,SACf;MAEJ,IAAI,CAAC,KAAK,YAAY,EAAE,iBAAiB,oBACrC;MAEJ,MAAM;KACV;IAER,CAAC;GACL;GA6EA,OAAO,QAAQ;IA1EX;IACA,OAAO,QAAQ,QAAQ;IACvB,MAAM,QACF,SAGA,gBAGF;KACE,MAAM,YAAY,KAAK,IAAI;KAC3B,MAAM,WAAgC;MAClC,IAAI,OAAO,WAAW;MACtB,UAAU;MACV,SAAS;OACL,GAAG;OACH,gBAAgB,QAAQ,kBAAkB,OAAO,WAAW;MAChE;MACA,YAAY,gBAAgB,cAAc;MAC1C,QAAQ;MACR,WAAW;MACX,WAAW;MACX,UAAU;MACV,WAAW;MACX,eAAe;KACnB;KACA,MAAM,aAAa,SAAiB;KACpC,WAAgB,QAAQ,YAAY,KAAA,CAAS;KAC7C,YAAY,IAAI,SAAS,IAAI,UAAU;KAEvC,IAAI;KACJ,IAAI;MACA,QAAQ,MAAM,QAAQ,QAAQ,QAAQ,EAClC,OAAO,SACX,CAAC;KACL,SAAS,OAAO;MACZ,YAAY,OAAO,SAAS,EAAE;MAC9B,WAAW,OAAO,eAAe,KAAK,CAAC;MACvC,MAAM;KACV;KAEA,MAAM,YAAY,OAAO,KAAK;KAE9B,OAAO;MACH;MACA,WAAW,WAAW;KAC1B;IACJ;IACA,MAAM,KAAK,IAAI,QAAQ;KACnB,MAAM,UAAU,WAAW,IAAI,EAAE;KACjC,IAAI,CAAC,SACD,MAAM,IAAI,MAAM,iBAAiB,GAAG,iCAAiC;KAEzE,MAAM,UAAU,WAAW,QAAQ,OAAO;KAC1C,OAAO,OAAO;KACd,MAAM,QAAQ,MAAM,QAAQ,QAAQ,KAAK;MACrC;MACA;KACJ,CAAC;KACD,MAAM,YAAY,OAAO,KAAK;KAC9B,OAAO;IACX;IACA,MAAM,OAAO,IAAI;KACb,MAAM,QAAQ,QAAQ,OAAO,EAAE,GAAG,CAAC;IACvC;IACA,MAAM,MAAM,IAAI;KACZ,MAAM,QAAQ,QAAQ,MAAM,EAAE,GAAG,CAAC;KAClC,KAAK,KAAK;IACd;IACA,UAAU;KACN,OAAO,QAAQ,QAAQ;IAC3B;GAGgB,CAAC;EACzB,UAAU;GACN,YAAY;GACZ,yBAAyB;GACzB,MAAM,gBAAyB,CAAC;GAChC,MAAM,WAAW,UAAmB;IAChC,cAAc,KAAK,eAAe,KAAK,CAAC;GAC5C;GAEA,SAAS,qBAAqB;GAC9B,SAAS,uBAAuB,YAAY;GAC5C,SAAS,uBAAuB,YAAY;GAC5C,IAAI,SAAS,QACT,IAAI;IACA,OAAO,MAAM,SAAS,OAAO,MAAM,CAAC;GACxC,SAAS,OAAO;IACZ,QAAQ,KAAK;GACjB;GAEJ,IAAI,SAAS,eAAe,KAAA,GACxB,IAAI;IACA,OAAO,SAAS,WAAW,KAAK;GACpC,SAAS,OAAO;IACZ,QAAQ,KAAK;GACjB;GAEJ,IAAI,SAAS,WACT,OAAO,MAAM,QAAQ,WAAW,CAAC,SAAS,SAAS,CAAC,CAAC;GAEzD,IAAI,SAAS,qBAAqB,KAAA,GAC9B,IAAI;IACA,OAAO,SAAS,iBAAiB,KAAK;GAC1C,SAAS,OAAO;IACZ,QAAQ,KAAK;GACjB;GAEJ,IAAI;IACA,OAAO,MAAM,YAAY,MAAM,CAAC;GACpC,SAAS,OAAO;IACZ,QAAQ,KAAK;GACjB;GACA,MAAM,2BAAW,IAAI,MAAM,kBAAkB;GAC7C,KAAK,MAAM,cAAc,YAAY,OAAO,GACxC,WAAW,OAAO,QAAQ;GAE9B,YAAY,MAAM;GAClB,IAAI;IACA,OAAO,MAAM,WAAW,QAAQ,CAAC;GACrC,SAAS,OAAO;IACZ,QAAQ,KAAK;GACjB;GAEA,IAAI,cAAc,IACd,OAAO,MAAM,QAAQ,OAAO,cAAc,EAAE,CAAC;EAErD;CACJ,CAAC;AACL;AAMA,SAAgB,qBAAqB,SAA6D;CAC9F,MAAM,aAAa,uBAAuB,OAAO;CACjD,IAAI;CACJ,MAAM,QAAQ,SAAe;CAE7B,MAAW,QAAQ,YAAY,KAAA,CAAS;CACxC,IAAI;CACJ,MAAM,OAAO,IAAI,aAAa;EAC1B,IAAI;GAEA,SAAS,OADY,kBAAkB,SAAS,UAAU;GAE1D,MAAM,QAAQ;GACd,OAAO,QAAQ;EACnB,SAAS,OAAO;GACZ,MAAM,OAAO,eAAe,KAAK,CAAC;GAClC,MAAM;EACV;CACJ,CAAC;CACD,KAAU,YAAY,KAAA,CAAS;CAE/B,OAAO;EACH;EACA,OAAO,MAAM;EACb;EACA,MAAM,QAAQ,SAAS,gBAAgB;GACnC,MAAM,MAAM;GACZ,OAAO,OAAQ,QAAQ,SAAS,cAAc;EAClD;EACA,MAAM,KAAK,IAAI,QAAQ;GACnB,MAAM,MAAM;GACZ,OAAO,OAAQ,KAAK,IAAI,MAAM;EAClC;EACA,MAAM,OAAO,IAAI;GACb,MAAM,MAAM;GACZ,OAAO,OAAQ,OAAO,EAAE;EAC5B;EACA,MAAM,MAAM,IAAI;GACZ,MAAM,MAAM;GACZ,OAAO,OAAQ,MAAM,EAAE;EAC3B;EACA,MAAM,UAAU;GACZ,oBAAoB,YAAY;IAG5B,MAAM,QAAQ,WAAW,CAAC,MAAM,SAAS,WAAW,QAAQ,CAAC,CAAC;IAC9D,MAAM,KAAK,KAAK,CAAC,CAAC,YAAY,KAAA,CAAS;IACvC,IAAI,WAAW,WAAW,cACtB,MAAM,WAAW,QAAQ,CAAC,CAAC,YAAY,KAAA,CAAS;GAExD,EAAA,CAAG;GACH,OAAO;EACX;CACJ;AACJ"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { OntologyOutboxEntry } from "./types.js";
|
|
2
|
-
import { OutboxCoordinationService } from "./service.js";
|
|
3
|
-
import { CoordinationServiceClient, RuntimeAdapter } from "@party-stack/runtime";
|
|
4
|
-
import { Operation, Stream } from "effection";
|
|
5
|
-
import { ConnectionMonitor } from "@party-stack/connections";
|
|
6
|
-
//#region src/live/outbox/leaderExecutor.d.ts
|
|
7
|
-
export interface OutboxLeaderOptions {
|
|
8
|
-
runtime: RuntimeAdapter;
|
|
9
|
-
service: CoordinationServiceClient<OutboxCoordinationService>;
|
|
10
|
-
wake: Stream<void, never>;
|
|
11
|
-
failureStrategy: "pause" | "discard-all";
|
|
12
|
-
maxRetries: number;
|
|
13
|
-
retryDelayMs: number;
|
|
14
|
-
execute(entry: OntologyOutboxEntry): Promise<unknown>;
|
|
15
|
-
connection?: ConnectionMonitor;
|
|
16
|
-
}
|
|
17
|
-
export declare function useOutboxLeader(options: OutboxLeaderOptions): Operation<void>;
|
|
18
|
-
export declare function runOutboxLeader(signal: AbortSignal, options: OutboxLeaderOptions): Promise<void>;
|
|
19
|
-
//#endregion
|
|
20
|
-
//# sourceMappingURL=leaderExecutor.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"leaderExecutor.d.ts","names":[],"sources":["../../../src/live/outbox/leaderExecutor.ts"],"mappings":";;;;;;iBAWiB;EACb,SAAS;EACT,SAAS,0BAA0B;EACnC,MAAM;EACN;EACA;EACA;EACA,QAAQ,OAAO,sBAAsB;EACrC,aAAa;;wBA2BD,gBAAgB,SAAS,sBAAsB;wBA8HzC,gBAAgB,QAAQ,aAAa,SAAS,sBAAsB"}
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import { NonRetryableError } from "./types.js";
|
|
2
|
-
import { CoordinationTaskRejectedError } from "@party-stack/runtime";
|
|
3
|
-
import { race, run, sleep, until, useAbortSignal } from "effection";
|
|
4
|
-
import { isUnauthenticatedError } from "@party-stack/errors";
|
|
5
|
-
//#region src/live/outbox/leaderExecutor.ts
|
|
6
|
-
function normalizeError(error) {
|
|
7
|
-
return error instanceof Error ? error : new Error(String(error));
|
|
8
|
-
}
|
|
9
|
-
function isStaleExecution(error) {
|
|
10
|
-
return error instanceof CoordinationTaskRejectedError && error.code === "STALE_EXECUTION";
|
|
11
|
-
}
|
|
12
|
-
function retryDelay(baseDelayMs, retryIndex) {
|
|
13
|
-
return Math.min(Number.MAX_SAFE_INTEGER, baseDelayMs * 2 ** Math.min(retryIndex, 16));
|
|
14
|
-
}
|
|
15
|
-
function isConnected(runtime) {
|
|
16
|
-
return runtime.connectivity?.isConnected !== false;
|
|
17
|
-
}
|
|
18
|
-
function isConnectionReady(connection) {
|
|
19
|
-
return !connection || connection.state.status === "active";
|
|
20
|
-
}
|
|
21
|
-
function canExecute(options) {
|
|
22
|
-
return isConnected(options.runtime) && isConnectionReady(options.connection);
|
|
23
|
-
}
|
|
24
|
-
function useOutboxLeader(options) {
|
|
25
|
-
return (function* () {
|
|
26
|
-
const signal = yield* useAbortSignal();
|
|
27
|
-
yield* until(options.service.methods.recover({
|
|
28
|
-
failureStrategy: options.failureStrategy,
|
|
29
|
-
maxRetries: options.maxRetries
|
|
30
|
-
}));
|
|
31
|
-
const wakes = yield* options.wake;
|
|
32
|
-
while (true) {
|
|
33
|
-
if (canExecute(options)) while (true) {
|
|
34
|
-
if (!canExecute(options)) break;
|
|
35
|
-
const entry = yield* until(options.service.methods.claim({}));
|
|
36
|
-
if (!entry) {
|
|
37
|
-
const retryAt = yield* until(options.service.methods.nextRetryAt({}));
|
|
38
|
-
if (retryAt === void 0) break;
|
|
39
|
-
const delay = Math.max(0, retryAt - Date.now());
|
|
40
|
-
if (delay > 0) yield* race([sleep(delay), wakes.next()]);
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
const executionId = entry.executionId;
|
|
44
|
-
let result;
|
|
45
|
-
try {
|
|
46
|
-
result = yield* until(options.execute(entry));
|
|
47
|
-
} catch (error) {
|
|
48
|
-
if (signal.aborted) throw error;
|
|
49
|
-
const normalized = normalizeError(error);
|
|
50
|
-
if (isUnauthenticatedError(error) && options.connection) {
|
|
51
|
-
yield* until(options.service.methods.fail({
|
|
52
|
-
id: entry.id,
|
|
53
|
-
executionId,
|
|
54
|
-
retryable: true,
|
|
55
|
-
retryAt: Date.now(),
|
|
56
|
-
error: {
|
|
57
|
-
name: normalized.name,
|
|
58
|
-
message: normalized.message
|
|
59
|
-
}
|
|
60
|
-
}));
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
const retryable = !(normalized instanceof NonRetryableError);
|
|
64
|
-
const retryScheduled = retryable && entry.attempts < options.maxRetries;
|
|
65
|
-
try {
|
|
66
|
-
const errorDetails = {
|
|
67
|
-
name: normalized.name,
|
|
68
|
-
message: normalized.message
|
|
69
|
-
};
|
|
70
|
-
if (retryScheduled) yield* until(options.service.methods.fail({
|
|
71
|
-
id: entry.id,
|
|
72
|
-
executionId,
|
|
73
|
-
retryable: true,
|
|
74
|
-
retryAt: Date.now() + retryDelay(options.retryDelayMs, entry.attempts),
|
|
75
|
-
error: errorDetails
|
|
76
|
-
}));
|
|
77
|
-
else if (options.failureStrategy === "discard-all") yield* until(options.service.methods.discardAll({
|
|
78
|
-
id: entry.id,
|
|
79
|
-
executionId,
|
|
80
|
-
error: errorDetails
|
|
81
|
-
}));
|
|
82
|
-
else yield* until(options.service.methods.fail({
|
|
83
|
-
id: entry.id,
|
|
84
|
-
executionId,
|
|
85
|
-
retryable,
|
|
86
|
-
error: errorDetails
|
|
87
|
-
}));
|
|
88
|
-
} catch (claimError) {
|
|
89
|
-
if (isStaleExecution(claimError)) break;
|
|
90
|
-
throw claimError;
|
|
91
|
-
}
|
|
92
|
-
if (retryScheduled) continue;
|
|
93
|
-
break;
|
|
94
|
-
}
|
|
95
|
-
if (signal.aborted) throw signal.reason;
|
|
96
|
-
try {
|
|
97
|
-
yield* until(options.service.methods.complete({
|
|
98
|
-
id: entry.id,
|
|
99
|
-
executionId,
|
|
100
|
-
result
|
|
101
|
-
}));
|
|
102
|
-
} catch (error) {
|
|
103
|
-
if (isStaleExecution(error)) break;
|
|
104
|
-
throw error;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
yield* wakes.next();
|
|
108
|
-
}
|
|
109
|
-
})();
|
|
110
|
-
}
|
|
111
|
-
async function runOutboxLeader(signal, options) {
|
|
112
|
-
const task = run(() => useOutboxLeader(options));
|
|
113
|
-
let halt;
|
|
114
|
-
const haltTask = () => {
|
|
115
|
-
halt ??= Promise.resolve(task.halt()).then(() => void 0);
|
|
116
|
-
};
|
|
117
|
-
signal.addEventListener("abort", haltTask, { once: true });
|
|
118
|
-
if (signal.aborted) haltTask();
|
|
119
|
-
try {
|
|
120
|
-
await task;
|
|
121
|
-
} finally {
|
|
122
|
-
signal.removeEventListener("abort", haltTask);
|
|
123
|
-
haltTask();
|
|
124
|
-
await halt;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
//#endregion
|
|
128
|
-
export { runOutboxLeader, useOutboxLeader };
|
|
129
|
-
|
|
130
|
-
//# sourceMappingURL=leaderExecutor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"leaderExecutor.js","names":[],"sources":["../../../src/live/outbox/leaderExecutor.ts"],"sourcesContent":["import { type ConnectionMonitor } from \"@party-stack/connections\";\nimport { isUnauthenticatedError } from \"@party-stack/errors\";\nimport {\n CoordinationTaskRejectedError,\n type CoordinationServiceClient,\n type RuntimeAdapter,\n} from \"@party-stack/runtime\";\nimport { race, run, sleep, until, useAbortSignal, type Operation, type Stream, type Task } from \"effection\";\nimport { NonRetryableError, type OntologyOutboxEntry } from \"./types.js\";\nimport type { OutboxCoordinationService } from \"./service.js\";\n\nexport interface OutboxLeaderOptions {\n runtime: RuntimeAdapter;\n service: CoordinationServiceClient<OutboxCoordinationService>;\n wake: Stream<void, never>;\n failureStrategy: \"pause\" | \"discard-all\";\n maxRetries: number;\n retryDelayMs: number;\n execute(entry: OntologyOutboxEntry): Promise<unknown>;\n connection?: ConnectionMonitor;\n}\n\nfunction normalizeError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\nfunction isStaleExecution(error: unknown): boolean {\n return error instanceof CoordinationTaskRejectedError && error.code === \"STALE_EXECUTION\";\n}\n\nfunction retryDelay(baseDelayMs: number, retryIndex: number): number {\n return Math.min(Number.MAX_SAFE_INTEGER, baseDelayMs * 2 ** Math.min(retryIndex, 16));\n}\n\nfunction isConnected(runtime: RuntimeAdapter): boolean {\n return runtime.connectivity?.isConnected !== false;\n}\n\nfunction isConnectionReady(connection: OutboxLeaderOptions[\"connection\"]): boolean {\n return !connection || connection.state.status === \"active\";\n}\n\nfunction canExecute(options: OutboxLeaderOptions): boolean {\n return isConnected(options.runtime) && isConnectionReady(options.connection);\n}\n\nexport function useOutboxLeader(options: OutboxLeaderOptions): Operation<void> {\n return (function* () {\n const signal = yield* useAbortSignal();\n yield* until(\n options.service.methods.recover({\n failureStrategy: options.failureStrategy,\n maxRetries: options.maxRetries,\n })\n );\n const wakes = yield* options.wake;\n\n while (true) {\n if (canExecute(options)) {\n while (true) {\n if (!canExecute(options)) {\n break;\n }\n const entry = yield* until(options.service.methods.claim({}));\n if (!entry) {\n const retryAt = yield* until(options.service.methods.nextRetryAt({}));\n if (retryAt === undefined) {\n break;\n }\n const delay = Math.max(0, retryAt - Date.now());\n if (delay > 0) {\n yield* race([sleep(delay), wakes.next()]);\n }\n continue;\n }\n const executionId = entry.executionId!;\n\n let result: unknown;\n try {\n result = yield* until(options.execute(entry));\n } catch (error) {\n if (signal.aborted) throw error;\n const normalized = normalizeError(error);\n if (isUnauthenticatedError(error) && options.connection) {\n // Connection egress currently reports authentication\n // failures. A future LiveOntology backend supervisor\n // should own reporting for every adapter operation.\n yield* until(\n options.service.methods.fail({\n id: entry.id,\n executionId,\n retryable: true,\n retryAt: Date.now(),\n error: {\n name: normalized.name,\n message: normalized.message,\n },\n })\n );\n break;\n }\n const retryable = !(normalized instanceof NonRetryableError);\n const retryScheduled = retryable && entry.attempts < options.maxRetries;\n try {\n const errorDetails = {\n name: normalized.name,\n message: normalized.message,\n };\n if (retryScheduled) {\n yield* until(\n options.service.methods.fail({\n id: entry.id,\n executionId,\n retryable: true,\n retryAt:\n Date.now() + retryDelay(options.retryDelayMs, entry.attempts),\n error: errorDetails,\n })\n );\n } else if (options.failureStrategy === \"discard-all\") {\n yield* until(\n options.service.methods.discardAll({\n id: entry.id,\n executionId,\n error: errorDetails,\n })\n );\n } else {\n yield* until(\n options.service.methods.fail({\n id: entry.id,\n executionId,\n retryable,\n error: errorDetails,\n })\n );\n }\n } catch (claimError) {\n if (isStaleExecution(claimError)) {\n break;\n }\n throw claimError;\n }\n if (retryScheduled) {\n continue;\n }\n break;\n }\n\n if (signal.aborted) {\n throw signal.reason;\n }\n try {\n yield* until(\n options.service.methods.complete({\n id: entry.id,\n executionId,\n result,\n })\n );\n } catch (error) {\n if (isStaleExecution(error)) break;\n throw error;\n }\n }\n }\n\n yield* wakes.next();\n }\n })();\n}\n\nexport async function runOutboxLeader(signal: AbortSignal, options: OutboxLeaderOptions): Promise<void> {\n const task: Task<void> = run(() => useOutboxLeader(options));\n let halt: Promise<void> | undefined;\n const haltTask = () => {\n halt ??= Promise.resolve(task.halt()).then(() => undefined);\n };\n signal.addEventListener(\"abort\", haltTask, {\n once: true,\n });\n if (signal.aborted) haltTask();\n\n try {\n await task;\n } finally {\n signal.removeEventListener(\"abort\", haltTask);\n haltTask();\n await halt;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { OutboxCoordinationService } from "./service.js";
|
|
2
|
-
import { OntologyOutboxRepository } from "./repository.js";
|
|
3
|
-
import { CoordinationHost, CoordinationServiceServer } from "@party-stack/runtime";
|
|
4
|
-
//#region src/live/outbox/outboxService.d.ts
|
|
5
|
-
export declare function serveOntologyOutbox(host: CoordinationHost, repository: OntologyOutboxRepository): CoordinationServiceServer<OutboxCoordinationService>;
|
|
6
|
-
//#endregion
|
|
7
|
-
//# sourceMappingURL=outboxService.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"outboxService.d.ts","names":[],"sources":["../../../src/live/outbox/outboxService.ts"],"mappings":";;;;wBAYgB,oBACZ,MAAM,kBACN,YAAY,2BACb,0BAA0B"}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { OUTBOX_COORDINATION_SERVICE } from "./service.js";
|
|
2
|
-
//#region src/live/outbox/outboxService.ts
|
|
3
|
-
function serveOntologyOutbox(host, repository) {
|
|
4
|
-
let publishResult = () => void 0;
|
|
5
|
-
const server = host.serve(OUTBOX_COORDINATION_SERVICE, {
|
|
6
|
-
enqueue: ({ entry }) => repository.enqueue(entry),
|
|
7
|
-
edit: ({ id, request }) => repository.edit(id, request),
|
|
8
|
-
remove: async ({ id }) => {
|
|
9
|
-
await repository.remove(id);
|
|
10
|
-
publishResult({
|
|
11
|
-
type: "rejected",
|
|
12
|
-
id,
|
|
13
|
-
error: {
|
|
14
|
-
name: "OutboxEntryRemoved",
|
|
15
|
-
message: "Outbox entry removed."
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
},
|
|
19
|
-
retry: ({ id }) => repository.retry(id),
|
|
20
|
-
recover: async ({ failureStrategy, maxRetries }) => {
|
|
21
|
-
const discarded = await repository.recover(failureStrategy, maxRetries);
|
|
22
|
-
for (const entry of discarded) publishResult({
|
|
23
|
-
type: "rejected",
|
|
24
|
-
id: entry.id,
|
|
25
|
-
error: {
|
|
26
|
-
name: "InterruptedExecutionDiscarded",
|
|
27
|
-
message: "Discarded because execution was interrupted before its result was recorded."
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
},
|
|
31
|
-
claim: () => repository.claim(),
|
|
32
|
-
nextRetryAt: () => repository.nextRetryAt(),
|
|
33
|
-
complete: async ({ id, executionId, result }) => {
|
|
34
|
-
await repository.complete(id, executionId);
|
|
35
|
-
publishResult({
|
|
36
|
-
type: "completed",
|
|
37
|
-
id,
|
|
38
|
-
result
|
|
39
|
-
});
|
|
40
|
-
},
|
|
41
|
-
fail: async ({ id, executionId, retryable, retryAt, error }) => {
|
|
42
|
-
const entry = await repository.fail(id, executionId, retryable, error, retryAt);
|
|
43
|
-
if (!retryable) publishResult({
|
|
44
|
-
type: "rejected",
|
|
45
|
-
id,
|
|
46
|
-
error
|
|
47
|
-
});
|
|
48
|
-
return entry;
|
|
49
|
-
},
|
|
50
|
-
discardAll: async ({ id, executionId, error }) => {
|
|
51
|
-
const discarded = await repository.discardAll(id, executionId);
|
|
52
|
-
for (const entry of discarded) publishResult({
|
|
53
|
-
type: "rejected",
|
|
54
|
-
id: entry.id,
|
|
55
|
-
error: entry.id === id ? error : {
|
|
56
|
-
name: "OutboxDiscardedAfterNonRetryableError",
|
|
57
|
-
message: `Discarded because outbox entry "${id}" failed permanently: ${error.message}`
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
publishResult = (event) => server.events.publish("result", event);
|
|
63
|
-
return server;
|
|
64
|
-
}
|
|
65
|
-
//#endregion
|
|
66
|
-
export { serveOntologyOutbox };
|
|
67
|
-
|
|
68
|
-
//# sourceMappingURL=outboxService.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"outboxService.js","names":[],"sources":["../../../src/live/outbox/outboxService.ts"],"sourcesContent":["import { OntologyOutboxRepository } from \"./repository.js\";\nimport {\n OUTBOX_COORDINATION_SERVICE,\n type OutboxCoordinationService,\n type OutboxResultEvent,\n} from \"./service.js\";\nimport type {\n CoordinationHost,\n CoordinationServiceHandlers,\n CoordinationServiceServer,\n} from \"@party-stack/runtime\";\n\nexport function serveOntologyOutbox(\n host: CoordinationHost,\n repository: OntologyOutboxRepository\n): CoordinationServiceServer<OutboxCoordinationService> {\n let publishResult: (event: OutboxResultEvent) => void = () => undefined;\n const handlers: CoordinationServiceHandlers<OutboxCoordinationService> = {\n enqueue: ({ entry }) => repository.enqueue(entry),\n edit: ({ id, request }) => repository.edit(id, request),\n remove: async ({ id }) => {\n await repository.remove(id);\n publishResult({\n type: \"rejected\",\n id,\n error: {\n name: \"OutboxEntryRemoved\",\n message: \"Outbox entry removed.\",\n },\n });\n },\n retry: ({ id }) => repository.retry(id),\n recover: async ({ failureStrategy, maxRetries }) => {\n const discarded = await repository.recover(failureStrategy, maxRetries);\n for (const entry of discarded) {\n publishResult({\n type: \"rejected\",\n id: entry.id,\n error: {\n name: \"InterruptedExecutionDiscarded\",\n message:\n \"Discarded because execution was interrupted before its result was recorded.\",\n },\n });\n }\n },\n claim: () => repository.claim(),\n nextRetryAt: () => repository.nextRetryAt(),\n complete: async ({ id, executionId, result }) => {\n await repository.complete(id, executionId);\n publishResult({\n type: \"completed\",\n id,\n result,\n });\n },\n fail: async ({ id, executionId, retryable, retryAt, error }) => {\n const entry = await repository.fail(id, executionId, retryable, error, retryAt);\n if (!retryable) {\n publishResult({\n type: \"rejected\",\n id,\n error,\n });\n }\n return entry;\n },\n discardAll: async ({ id, executionId, error }) => {\n const discarded = await repository.discardAll(id, executionId);\n for (const entry of discarded) {\n publishResult({\n type: \"rejected\",\n id: entry.id,\n error:\n entry.id === id\n ? error\n : {\n name: \"OutboxDiscardedAfterNonRetryableError\",\n message: `Discarded because outbox entry \"${id}\" failed permanently: ${error.message}`,\n },\n });\n }\n },\n };\n\n const server = host.serve<OutboxCoordinationService>(OUTBOX_COORDINATION_SERVICE, handlers);\n publishResult = (event) => server.events.publish(\"result\", event);\n return server;\n}\n"],"mappings":";;AAYA,SAAgB,oBACZ,MACA,YACoD;CACpD,IAAI,sBAA0D,KAAA;CAqE9D,MAAM,SAAS,KAAK,MAAiC,6BAA6B;EAnE9E,UAAU,EAAE,YAAY,WAAW,QAAQ,KAAK;EAChD,OAAO,EAAE,IAAI,cAAc,WAAW,KAAK,IAAI,OAAO;EACtD,QAAQ,OAAO,EAAE,SAAS;GACtB,MAAM,WAAW,OAAO,EAAE;GAC1B,cAAc;IACV,MAAM;IACN;IACA,OAAO;KACH,MAAM;KACN,SAAS;IACb;GACJ,CAAC;EACL;EACA,QAAQ,EAAE,SAAS,WAAW,MAAM,EAAE;EACtC,SAAS,OAAO,EAAE,iBAAiB,iBAAiB;GAChD,MAAM,YAAY,MAAM,WAAW,QAAQ,iBAAiB,UAAU;GACtE,KAAK,MAAM,SAAS,WAChB,cAAc;IACV,MAAM;IACN,IAAI,MAAM;IACV,OAAO;KACH,MAAM;KACN,SACI;IACR;GACJ,CAAC;EAET;EACA,aAAa,WAAW,MAAM;EAC9B,mBAAmB,WAAW,YAAY;EAC1C,UAAU,OAAO,EAAE,IAAI,aAAa,aAAa;GAC7C,MAAM,WAAW,SAAS,IAAI,WAAW;GACzC,cAAc;IACV,MAAM;IACN;IACA;GACJ,CAAC;EACL;EACA,MAAM,OAAO,EAAE,IAAI,aAAa,WAAW,SAAS,YAAY;GAC5D,MAAM,QAAQ,MAAM,WAAW,KAAK,IAAI,aAAa,WAAW,OAAO,OAAO;GAC9E,IAAI,CAAC,WACD,cAAc;IACV,MAAM;IACN;IACA;GACJ,CAAC;GAEL,OAAO;EACX;EACA,YAAY,OAAO,EAAE,IAAI,aAAa,YAAY;GAC9C,MAAM,YAAY,MAAM,WAAW,WAAW,IAAI,WAAW;GAC7D,KAAK,MAAM,SAAS,WAChB,cAAc;IACV,MAAM;IACN,IAAI,MAAM;IACV,OACI,MAAM,OAAO,KACP,QACA;KACI,MAAM;KACN,SAAS,mCAAmC,GAAG,wBAAwB,MAAM;IACjF;GACd,CAAC;EAET;CAGqF,CAAC;CAC1F,iBAAiB,UAAU,OAAO,OAAO,QAAQ,UAAU,KAAK;CAChE,OAAO;AACX"}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { OntologyOutboxEntry } from "./types.js";
|
|
2
|
-
//#region src/live/outbox/projectionManager.d.ts
|
|
3
|
-
export interface OutboxProjection {
|
|
4
|
-
settle(error?: Error): void | Promise<void>;
|
|
5
|
-
}
|
|
6
|
-
export declare class OutboxProjectionManager {
|
|
7
|
-
private readonly project;
|
|
8
|
-
private desired;
|
|
9
|
-
private readonly projections;
|
|
10
|
-
private readonly installedFingerprints;
|
|
11
|
-
private readonly versions;
|
|
12
|
-
private tail;
|
|
13
|
-
private closed;
|
|
14
|
-
private disabledError;
|
|
15
|
-
constructor(project: ((entry: OntologyOutboxEntry) => Promise<OutboxProjection | undefined>) | undefined);
|
|
16
|
-
get error(): Error | undefined;
|
|
17
|
-
restore(entries: readonly OntologyOutboxEntry[]): Promise<void>;
|
|
18
|
-
reconcile(entries: readonly OntologyOutboxEntry[]): Promise<void>;
|
|
19
|
-
ensure(entry: OntologyOutboxEntry): Promise<void>;
|
|
20
|
-
discard(id: string, error?: Error): Promise<void>;
|
|
21
|
-
close(): Promise<void>;
|
|
22
|
-
private schedule;
|
|
23
|
-
private applyDesired;
|
|
24
|
-
private disable;
|
|
25
|
-
private firstDivergence;
|
|
26
|
-
private install;
|
|
27
|
-
private invalidate;
|
|
28
|
-
private settle;
|
|
29
|
-
}
|
|
30
|
-
//#endregion
|
|
31
|
-
//# sourceMappingURL=projectionManager.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"projectionManager.d.ts","names":[],"sources":["../../../src/live/outbox/projectionManager.ts"],"mappings":";;iBAGiB;EACb,OAAO,QAAQ,eAAe;;qBAsBrB;mBAUY;UATb;mBACS;mBACA;mBACA;UACT;UACA;UACA;EAER,YACqB,WACT,OAAO,wBAAwB,QAAQ;MAI/C,SAAS;EAIb,QAAQ,kBAAkB,wBAAwB;EAIlD,UAAU,kBAAkB,wBAAwB;EAIpD,OAAO,OAAO,sBAAsB;EAUpC,QAAQ,YAAY,QAAQ,QAAQ;EAUpC,SAAS;UASD;UAWM;UAsCA;UAQN;UAkBM;UAsBA;UAOA"}
|