@sekiban/dcb-runtime 0.2.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.
Files changed (153) hide show
  1. package/LICENSE +86 -0
  2. package/README.md +13 -0
  3. package/dist/allocator/AllocatorDurableObject.d.ts +36 -0
  4. package/dist/allocator/AllocatorDurableObject.js +658 -0
  5. package/dist/allocator/IssuanceLedger.d.ts +188 -0
  6. package/dist/allocator/IssuanceLedger.js +608 -0
  7. package/dist/allocator/IssuanceReconciler.d.ts +41 -0
  8. package/dist/allocator/IssuanceReconciler.js +191 -0
  9. package/dist/allocator/OrderClock.d.ts +41 -0
  10. package/dist/allocator/OrderClock.js +92 -0
  11. package/dist/allocator/SortableUniqueId.d.ts +46 -0
  12. package/dist/allocator/SortableUniqueId.js +156 -0
  13. package/dist/allocator/types.d.ts +52 -0
  14. package/dist/allocator/types.js +1 -0
  15. package/dist/bootstrap/BootstrapCoordinatorDurableObject.d.ts +28 -0
  16. package/dist/bootstrap/BootstrapCoordinatorDurableObject.js +357 -0
  17. package/dist/bootstrap/BootstrapStoreAdapter.d.ts +51 -0
  18. package/dist/bootstrap/BootstrapStoreAdapter.js +162 -0
  19. package/dist/bootstrap/OperatorBootstrap.d.ts +20 -0
  20. package/dist/bootstrap/OperatorBootstrap.js +104 -0
  21. package/dist/bootstrap/manifest.d.ts +9 -0
  22. package/dist/bootstrap/manifest.js +115 -0
  23. package/dist/bootstrap/types.d.ts +75 -0
  24. package/dist/bootstrap/types.js +1 -0
  25. package/dist/cli/OperatorRepairCli.d.ts +11 -0
  26. package/dist/cli/OperatorRepairCli.js +108 -0
  27. package/dist/cloudflare.d.ts +164 -0
  28. package/dist/cloudflare.js +19487 -0
  29. package/dist/commit/CommitWorker.d.ts +101 -0
  30. package/dist/commit/CommitWorker.js +921 -0
  31. package/dist/commit/types.d.ts +25 -0
  32. package/dist/commit/types.js +13 -0
  33. package/dist/completeness/GlobalCompletenessReconciler.d.ts +77 -0
  34. package/dist/completeness/GlobalCompletenessReconciler.js +572 -0
  35. package/dist/completeness/types.d.ts +85 -0
  36. package/dist/completeness/types.js +6 -0
  37. package/dist/composition.d.ts +123 -0
  38. package/dist/composition.js +237 -0
  39. package/dist/cosmos.d.ts +11 -0
  40. package/dist/cosmos.js +1411 -0
  41. package/dist/d1-mv.d.ts +8 -0
  42. package/dist/d1-mv.js +2001 -0
  43. package/dist/d1.d.ts +16 -0
  44. package/dist/d1.js +3418 -0
  45. package/dist/diagnostics/G60DurableHop.d.ts +99 -0
  46. package/dist/diagnostics/G60DurableHop.js +248 -0
  47. package/dist/diagnostics/G65Admission.d.ts +23 -0
  48. package/dist/diagnostics/G65Admission.js +43 -0
  49. package/dist/diagnostics/G65DirectRing.d.ts +33 -0
  50. package/dist/diagnostics/G65DirectRing.js +85 -0
  51. package/dist/diagnostics/G69AdmissionAttempt.d.ts +43 -0
  52. package/dist/diagnostics/G69AdmissionAttempt.js +22 -0
  53. package/dist/downstream/DeliveryCore.d.ts +127 -0
  54. package/dist/downstream/DeliveryCore.js +304 -0
  55. package/dist/downstream/Doorbell.d.ts +43 -0
  56. package/dist/downstream/Doorbell.js +137 -0
  57. package/dist/downstream/DownstreamAdapter.d.ts +52 -0
  58. package/dist/downstream/DownstreamAdapter.js +299 -0
  59. package/dist/downstream/ExclusionLookup.d.ts +36 -0
  60. package/dist/downstream/ExclusionLookup.js +50 -0
  61. package/dist/downstream/InconsistencyDetector.d.ts +27 -0
  62. package/dist/downstream/InconsistencyDetector.js +82 -0
  63. package/dist/downstream/OutboxDrain.d.ts +35 -0
  64. package/dist/downstream/OutboxDrain.js +126 -0
  65. package/dist/downstream/types.d.ts +77 -0
  66. package/dist/downstream/types.js +64 -0
  67. package/dist/eventIdentity.d.ts +30 -0
  68. package/dist/eventIdentity.js +49 -0
  69. package/dist/eventRecord.d.ts +26 -0
  70. package/dist/eventRecord.js +53 -0
  71. package/dist/g42-probe.d.ts +9 -0
  72. package/dist/g42-probe.js +9 -0
  73. package/dist/http/SerializedQueryWorker.d.ts +58 -0
  74. package/dist/http/SerializedQueryWorker.js +497 -0
  75. package/dist/http/commitResponse.d.ts +46 -0
  76. package/dist/http/commitResponse.js +80 -0
  77. package/dist/http/testServiceId.d.ts +17 -0
  78. package/dist/http/testServiceId.js +14 -0
  79. package/dist/index.d.ts +112 -0
  80. package/dist/index.js +19926 -0
  81. package/dist/journal/JournalDurableObject.d.ts +30 -0
  82. package/dist/journal/JournalDurableObject.js +481 -0
  83. package/dist/journal/JournalFirstTouchProbe.d.ts +190 -0
  84. package/dist/journal/JournalFirstTouchProbe.js +375 -0
  85. package/dist/journal/types.d.ts +116 -0
  86. package/dist/journal/types.js +52 -0
  87. package/dist/mv/MaterializedViewCatchUp.d.ts +60 -0
  88. package/dist/mv/MaterializedViewCatchUp.js +353 -0
  89. package/dist/mv/MaterializedViewRuntime.d.ts +80 -0
  90. package/dist/mv/MaterializedViewRuntime.js +328 -0
  91. package/dist/mv/MaterializedViewStore.d.ts +257 -0
  92. package/dist/mv/MaterializedViewStore.js +875 -0
  93. package/dist/mv/UnsafeWindowMaterializedView.d.ts +112 -0
  94. package/dist/mv/UnsafeWindowMaterializedView.js +495 -0
  95. package/dist/mv/index.d.ts +8 -0
  96. package/dist/mv/index.js +2357 -0
  97. package/dist/projection/LiveProjectionWorker.d.ts +86 -0
  98. package/dist/projection/LiveProjectionWorker.js +240 -0
  99. package/dist/projection/ProjectionRuntime.d.ts +113 -0
  100. package/dist/projection/ProjectionRuntime.js +346 -0
  101. package/dist/projection/ProjectorRegistry.d.ts +51 -0
  102. package/dist/projection/ProjectorRegistry.js +116 -0
  103. package/dist/query/ProjectionQueryStore.d.ts +102 -0
  104. package/dist/query/ProjectionQueryStore.js +185 -0
  105. package/dist/query/QueryRegistry.d.ts +22 -0
  106. package/dist/query/QueryRegistry.js +36 -0
  107. package/dist/read/SerializedReadWorker.d.ts +36 -0
  108. package/dist/read/SerializedReadWorker.js +225 -0
  109. package/dist/repair/RepairWorker.d.ts +72 -0
  110. package/dist/repair/RepairWorker.js +461 -0
  111. package/dist/safeWindow.d.ts +20 -0
  112. package/dist/safeWindow.js +36 -0
  113. package/dist/scope/ControlRouteScope.d.ts +22 -0
  114. package/dist/scope/ControlRouteScope.js +36 -0
  115. package/dist/scope/ScopeName.d.ts +34 -0
  116. package/dist/scope/ScopeName.js +67 -0
  117. package/dist/service/ServiceIdentityProvider.d.ts +35 -0
  118. package/dist/service/ServiceIdentityProvider.js +56 -0
  119. package/dist/store/CosmosEventStore.d.ts +126 -0
  120. package/dist/store/CosmosEventStore.js +950 -0
  121. package/dist/store/D1EventStore.d.ts +111 -0
  122. package/dist/store/D1EventStore.js +1111 -0
  123. package/dist/store/PostgresEventStore.d.ts +35 -0
  124. package/dist/store/PostgresEventStore.js +811 -0
  125. package/dist/store/provider.d.ts +25 -0
  126. package/dist/store/provider.js +32 -0
  127. package/dist/store/types.d.ts +205 -0
  128. package/dist/store/types.js +18 -0
  129. package/dist/tag/EventDigest.d.ts +40 -0
  130. package/dist/tag/EventDigest.js +158 -0
  131. package/dist/tag/TagDurableObject.d.ts +286 -0
  132. package/dist/tag/TagDurableObject.js +4071 -0
  133. package/dist/tag/TagSqlMeasurement.d.ts +26 -0
  134. package/dist/tag/TagSqlMeasurement.js +44 -0
  135. package/dist/tag/TagSqlSchema.d.ts +29 -0
  136. package/dist/tag/TagSqlSchema.js +211 -0
  137. package/dist/tag/types.d.ts +173 -0
  138. package/dist/tag/types.js +3 -0
  139. package/dist/tagstate/TagStateDurableObject.d.ts +57 -0
  140. package/dist/tagstate/TagStateDurableObject.js +499 -0
  141. package/dist/trace/AttributionRatio.d.ts +12 -0
  142. package/dist/trace/AttributionRatio.js +68 -0
  143. package/dist/trace/CloudflareTracing.d.ts +7 -0
  144. package/dist/trace/CloudflareTracing.js +9 -0
  145. package/dist/trace/CommitTrace.d.ts +405 -0
  146. package/dist/trace/CommitTrace.js +1008 -0
  147. package/dist/trace/CommitTraceConsoleSink.d.ts +68 -0
  148. package/dist/trace/CommitTraceConsoleSink.js +114 -0
  149. package/dist/trace/CommitTraceVerifier.d.ts +22 -0
  150. package/dist/trace/CommitTraceVerifier.js +295 -0
  151. package/dist/trace/ObservationStream.d.ts +118 -0
  152. package/dist/trace/ObservationStream.js +148 -0
  153. package/package.json +71 -0
@@ -0,0 +1,123 @@
1
+ import type { DomainDefinition } from "@sekiban/dcb-core";
2
+ import { type CommitWorkerEnv, type CommitWorkerHooks } from "./commit/CommitWorker";
3
+ import type { DeliveryClass } from "./downstream/Doorbell";
4
+ import { ProjectorRegistry } from "./projection/ProjectorRegistry";
5
+ import { QueryRegistry, type QueryEndpoint } from "./query/QueryRegistry";
6
+ /** A query value accepted by the public runtime composition surface. */
7
+ export interface RuntimeQueryDefinition {
8
+ readonly queryType?: string;
9
+ readonly id?: string;
10
+ readonly name?: string;
11
+ readonly endpoint?: QueryEndpoint;
12
+ readonly tagGroup: string;
13
+ readonly tagProjector: string;
14
+ readonly materializedViewId?: string;
15
+ readonly enabled?: boolean;
16
+ }
17
+ /** Values which affect registration, never the serialized V1 wire format. */
18
+ export interface RuntimeWorkerConfig {
19
+ /** Domain layer of the two-layer direct-delivery opt-in. */
20
+ readonly deliveryClass?: DeliveryClass;
21
+ readonly queries?: readonly RuntimeQueryDefinition[];
22
+ readonly queryDefinitions?: readonly RuntimeQueryDefinition[];
23
+ readonly projectorPayloadNames?: Readonly<Record<string, string>>;
24
+ readonly tagPayloadNames?: Readonly<Record<string, string>>;
25
+ }
26
+ /** A command already normalized by the authoring-to-runtime bridge. */
27
+ export interface RuntimeCommandLike {
28
+ readonly id: string;
29
+ readonly name: string;
30
+ readonly parseInput: (value: unknown) => unknown;
31
+ readonly execute: (value: unknown, options?: unknown) => unknown | Promise<unknown>;
32
+ readonly handle: (value: unknown, options?: unknown) => unknown | Promise<unknown>;
33
+ }
34
+ /** Runtime command registry exposed by composition, without importing dcb-domain. */
35
+ export declare class RuntimeCommandRegistry {
36
+ private readonly byId;
37
+ constructor(values?: readonly unknown[]);
38
+ resolve(id: string): RuntimeCommandLike | undefined;
39
+ list(): readonly RuntimeCommandLike[];
40
+ execute(id: string, value: unknown, options?: unknown): unknown | Promise<unknown>;
41
+ }
42
+ export interface RuntimeComposition {
43
+ readonly projectors: ProjectorRegistry;
44
+ readonly queries: QueryRegistry;
45
+ readonly commands: RuntimeCommandRegistry;
46
+ }
47
+ /** Structural bridge returned by @sekiban/dcb-domain without a reverse package import. */
48
+ export interface RuntimeDomainLike {
49
+ readonly events?: readonly {
50
+ readonly eventPayloadName: string;
51
+ readonly parse?: (payload: unknown) => unknown;
52
+ }[];
53
+ readonly commands?: readonly unknown[];
54
+ readonly projectors?: readonly unknown[];
55
+ readonly queries?: readonly RuntimeQueryDefinition[];
56
+ }
57
+ /** Registered domain parsers are the exact-case admission authority. */
58
+ export declare function registeredEventParsers(domain: DomainDefinition | RuntimeDomainLike | undefined): Readonly<Record<string, (payload: unknown) => unknown>>;
59
+ export interface RuntimeCommitCandidateLike {
60
+ readonly kind: "candidate-envelope";
61
+ readonly now: string | number | bigint;
62
+ readonly events: readonly {
63
+ readonly eventType: string;
64
+ readonly eventName: string;
65
+ readonly payload: unknown;
66
+ readonly tags: readonly {
67
+ readonly id: string;
68
+ }[];
69
+ readonly ordinal: string;
70
+ }[];
71
+ readonly tags: readonly {
72
+ readonly id: string;
73
+ }[];
74
+ readonly readClaims: readonly {
75
+ readonly kind: "state" | "exists";
76
+ readonly projectorId?: string;
77
+ readonly tag: {
78
+ readonly id: string;
79
+ };
80
+ readonly head: string | null;
81
+ }[];
82
+ }
83
+ export interface RuntimeCommitAllocationLike {
84
+ readonly candidates: readonly {
85
+ readonly ordinal: string;
86
+ readonly suid: string;
87
+ }[];
88
+ readonly allocatorLineageId?: string;
89
+ readonly attemptId?: string;
90
+ }
91
+ export type RuntimeCommitPortResult = {
92
+ readonly kind: "accepted";
93
+ } | {
94
+ readonly kind: "consistency-conflict";
95
+ } | {
96
+ readonly kind: "unknown";
97
+ readonly error?: unknown;
98
+ readonly attemptId?: string;
99
+ } | {
100
+ readonly kind: "rejected";
101
+ readonly reason?: string;
102
+ readonly code?: string;
103
+ };
104
+ export interface RuntimeCommitPort {
105
+ readonly commit: (candidate: RuntimeCommitCandidateLike, allocation?: RuntimeCommitAllocationLike) => Promise<RuntimeCommitPortResult>;
106
+ }
107
+ export interface RuntimeCommitPortOptions {
108
+ readonly requestUrl?: string;
109
+ readonly hooks?: Omit<CommitWorkerHooks, "registeredEventParsers">;
110
+ readonly registeredEventParsers?: Readonly<Record<string, (payload: unknown) => unknown>>;
111
+ }
112
+ /**
113
+ * Adapt the composed command port to the existing serialized commit Worker.
114
+ * The Worker owns admission, tag reservation/acquire, allocation, append, and
115
+ * response mapping; this adapter is intentionally only a transport seam.
116
+ */
117
+ export declare function createRuntimeCommitPort(env: CommitWorkerEnv, options?: RuntimeCommitPortOptions): RuntimeCommitPort;
118
+ /**
119
+ * Build the two private registries used by the HTTP runtime. The registries
120
+ * intentionally never cross the package entrypoint; consumers provide only
121
+ * immutable dcb-core definition values and registration metadata.
122
+ */
123
+ export declare function composeRuntime(domain: DomainDefinition | RuntimeDomainLike | undefined, config?: RuntimeWorkerConfig): RuntimeComposition;
@@ -0,0 +1,237 @@
1
+ import { handleSerializedCommit } from "./commit/CommitWorker";
2
+ import { resolveDeliveryIdentity } from "./eventIdentity";
3
+ import { DEPLOYED_PROJECTOR_REGISTRY, ProjectorRegistry, } from "./projection/ProjectorRegistry";
4
+ import { DEPLOYED_QUERY_REGISTRY, QueryRegistry, } from "./query/QueryRegistry";
5
+ /** Runtime command registry exposed by composition, without importing dcb-domain. */
6
+ export class RuntimeCommandRegistry {
7
+ byId;
8
+ constructor(values = []) {
9
+ const entries = new Map();
10
+ for (const value of values) {
11
+ if (!isRuntimeCommandLike(value))
12
+ throw new Error("Runtime command definitions require id, parseInput, execute, and handle");
13
+ if (entries.has(value.id))
14
+ throw new Error(`Duplicate runtime command ${value.id}`);
15
+ entries.set(value.id, value);
16
+ }
17
+ this.byId = entries;
18
+ }
19
+ resolve(id) {
20
+ return this.byId.get(id);
21
+ }
22
+ list() {
23
+ return Object.freeze([...this.byId.values()]);
24
+ }
25
+ execute(id, value, options) {
26
+ const command = this.resolve(id);
27
+ if (command === undefined)
28
+ throw new Error(`Runtime command ${id} is not registered`);
29
+ return command.execute(value, options);
30
+ }
31
+ }
32
+ /** Registered domain parsers are the exact-case admission authority. */
33
+ export function registeredEventParsers(domain) {
34
+ const entries = [];
35
+ for (const event of domain?.events ?? []) {
36
+ if (typeof event.parse === "function")
37
+ entries.push([event.eventPayloadName, event.parse]);
38
+ }
39
+ return Object.freeze(Object.fromEntries(entries));
40
+ }
41
+ function decodeStoredJson(value) {
42
+ try {
43
+ return JSON.parse(value);
44
+ }
45
+ catch {
46
+ return value;
47
+ }
48
+ }
49
+ function jsonBytes(value) {
50
+ const bytes = new TextEncoder().encode(JSON.stringify(value));
51
+ let binary = "";
52
+ for (const byte of bytes)
53
+ binary += String.fromCharCode(byte);
54
+ return btoa(binary);
55
+ }
56
+ function isRuntimeBridgedProjector(definition) {
57
+ return "projectorId" in definition && "reduce" in definition;
58
+ }
59
+ function projectorFromDefinition(definition, config) {
60
+ const payloadNames = config.projectorPayloadNames ?? config.tagPayloadNames ?? {};
61
+ const payloadName = payloadNames[definition.id] ?? `${definition.id}State`;
62
+ const apply = (state, event) => {
63
+ const payload = decodeStoredJson(event.payload);
64
+ const identity = resolveDeliveryIdentity({ eventType: event.eventType, provenance: event.provenance }, "queue");
65
+ const eventName = identity.eventPayloadName;
66
+ const normalizedEventType = identity.key;
67
+ // Polling visits every registered projector for each discovered tag. A
68
+ // projector must therefore turn an event from another family into a
69
+ // state-preserving no-op before the authored bridge sees it.
70
+ if (!definition.subscribedEventTypes.includes(normalizedEventType))
71
+ return state;
72
+ if (isRuntimeBridgedProjector(definition)) {
73
+ return definition.apply(state, {
74
+ eventType: normalizedEventType,
75
+ eventPayloadName: eventName,
76
+ payload,
77
+ eventTags: event.eventTags,
78
+ provenance: event.provenance,
79
+ });
80
+ }
81
+ return definition.apply(state, {
82
+ eventName,
83
+ eventPayloadName: eventName,
84
+ // The legacy lane is only entered after provenance admission has
85
+ // proven a pre-G27 row. The authored projector still requires the
86
+ // canonical eventType field, so normalize that historical name to the
87
+ // immutable v1 registry identity before calling the real reducer.
88
+ eventType: normalizedEventType,
89
+ payload: payload,
90
+ });
91
+ };
92
+ return {
93
+ id: definition.id,
94
+ tagPayloadName: payloadName,
95
+ projectorVersion: String(definition.version),
96
+ initialState: () => definition.initialState,
97
+ apply,
98
+ serializeState: (state) => definition.serializeState(state),
99
+ deserializeState: (serialized) => definition.deserializeState(serialized),
100
+ payload: (state) => jsonBytes(state),
101
+ version: (state) => {
102
+ if (typeof state === "object" && state !== null && !Array.isArray(state)) {
103
+ const candidate = state.version;
104
+ if (typeof candidate === "number" && Number.isSafeInteger(candidate) && candidate >= 0)
105
+ return candidate;
106
+ }
107
+ return 0;
108
+ },
109
+ };
110
+ }
111
+ function queryFromDefinition(value) {
112
+ const queryType = value.queryType ?? value.id ?? value.name;
113
+ if (queryType === undefined || queryType.length === 0) {
114
+ throw new Error("Runtime query definitions require queryType or id");
115
+ }
116
+ return {
117
+ queryType,
118
+ endpoint: value.endpoint ?? "query",
119
+ tagGroup: value.tagGroup,
120
+ tagProjector: value.tagProjector,
121
+ materializedViewId: value.materializedViewId ?? value.tagProjector,
122
+ enabled: value.enabled ?? true,
123
+ };
124
+ }
125
+ function isRuntimeCommandLike(value) {
126
+ if (typeof value !== "object" || value === null)
127
+ return false;
128
+ const candidate = value;
129
+ return typeof candidate.id === "string" && candidate.id.length > 0 &&
130
+ typeof candidate.name === "string" && typeof candidate.parseInput === "function" &&
131
+ typeof candidate.execute === "function" && typeof candidate.handle === "function";
132
+ }
133
+ function encodeJsonPayload(value) {
134
+ const bytes = new TextEncoder().encode(JSON.stringify(value));
135
+ let binary = "";
136
+ for (const byte of bytes)
137
+ binary += String.fromCharCode(byte);
138
+ return btoa(binary);
139
+ }
140
+ function candidateToV1Envelope(candidate) {
141
+ const eventTags = new Set(candidate.events.flatMap((event) => event.tags.map((tag) => tag.id)));
142
+ const claims = new Map();
143
+ for (const claim of candidate.readClaims) {
144
+ // An observed empty head is the explicit V1 assert-empty sentinel. An
145
+ // unread/unknown claim remains null and is omitted from the wire.
146
+ if (eventTags.has(claim.tag.id) && claim.head !== null && !claims.has(claim.tag.id)) {
147
+ claims.set(claim.tag.id, claim.head);
148
+ }
149
+ }
150
+ return {
151
+ version: 1,
152
+ eventCandidates: candidate.events.map((event) => ({
153
+ payload: encodeJsonPayload(event.payload),
154
+ eventPayloadName: event.eventName,
155
+ tags: event.tags.map((tag) => tag.id),
156
+ })),
157
+ consistencyTags: [...claims].map(([tag, lastSortableUniqueId]) => ({ tag, lastSortableUniqueId })),
158
+ };
159
+ }
160
+ async function responseBody(response) {
161
+ try {
162
+ const value = await response.clone().json();
163
+ return typeof value === "object" && value !== null && !Array.isArray(value)
164
+ ? value
165
+ : undefined;
166
+ }
167
+ catch {
168
+ return undefined;
169
+ }
170
+ }
171
+ function attemptIdFromResponse(body) {
172
+ const writtenEvents = body?.writtenEvents;
173
+ if (!Array.isArray(writtenEvents))
174
+ return undefined;
175
+ const metadata = writtenEvents[0];
176
+ if (typeof metadata !== "object" || metadata === null || Array.isArray(metadata))
177
+ return undefined;
178
+ const eventMetadata = metadata.eventMetadata;
179
+ if (typeof eventMetadata !== "object" || eventMetadata === null || Array.isArray(eventMetadata))
180
+ return undefined;
181
+ const causationId = eventMetadata.causationId;
182
+ return typeof causationId === "string" && causationId.length > 0 ? causationId : undefined;
183
+ }
184
+ /**
185
+ * Adapt the composed command port to the existing serialized commit Worker.
186
+ * The Worker owns admission, tag reservation/acquire, allocation, append, and
187
+ * response mapping; this adapter is intentionally only a transport seam.
188
+ */
189
+ export function createRuntimeCommitPort(env, options = {}) {
190
+ return Object.freeze({
191
+ commit: async (candidate) => {
192
+ const request = new Request(options.requestUrl ?? "https://runtime.internal/api/sekiban/serialized/commit", {
193
+ method: "POST",
194
+ headers: { "content-type": "application/json" },
195
+ body: JSON.stringify(candidateToV1Envelope(candidate)),
196
+ });
197
+ const response = await handleSerializedCommit(request, env, {
198
+ ...(options.hooks ?? {}),
199
+ registeredEventParsers: options.registeredEventParsers,
200
+ });
201
+ const body = await responseBody(response);
202
+ if (response.ok)
203
+ return { kind: "accepted" };
204
+ const code = typeof body?.code === "string" ? body.code : undefined;
205
+ if (code === "consistency_conflict" || response.status === 409) {
206
+ return { kind: "consistency-conflict" };
207
+ }
208
+ if (response.status === 504 || response.status >= 500) {
209
+ return {
210
+ kind: "unknown",
211
+ ...(attemptIdFromResponse(body) === undefined ? {} : { attemptId: attemptIdFromResponse(body) }),
212
+ error: body,
213
+ };
214
+ }
215
+ return {
216
+ kind: "rejected",
217
+ ...(code === undefined ? {} : { code }),
218
+ ...(typeof body?.error === "string" ? { reason: body.error } : {}),
219
+ };
220
+ },
221
+ });
222
+ }
223
+ /**
224
+ * Build the two private registries used by the HTTP runtime. The registries
225
+ * intentionally never cross the package entrypoint; consumers provide only
226
+ * immutable dcb-core definition values and registration metadata.
227
+ */
228
+ export function composeRuntime(domain, config = {}) {
229
+ if (domain === undefined && config.queries === undefined && config.queryDefinitions === undefined) {
230
+ return { projectors: DEPLOYED_PROJECTOR_REGISTRY, queries: DEPLOYED_QUERY_REGISTRY, commands: new RuntimeCommandRegistry() };
231
+ }
232
+ const projectors = new ProjectorRegistry((domain?.projectors ?? []).map((value) => projectorFromDefinition(value, config)));
233
+ const configuredQueries = config.queryDefinitions ?? config.queries;
234
+ const domainQueries = (domain?.queries ?? []);
235
+ const queries = new QueryRegistry((configuredQueries ?? domainQueries).map(queryFromDefinition));
236
+ return { projectors, queries, commands: new RuntimeCommandRegistry(domain?.commands ?? []) };
237
+ }
@@ -0,0 +1,11 @@
1
+ import { CosmosEventStore, type CosmosDocumentClient, type CosmosStoreOptions } from "./store/CosmosEventStore";
2
+ import type { StoreProvider } from "./store/provider";
3
+ import { type BootstrapStoreAdapter } from "./bootstrap/BootstrapStoreAdapter";
4
+ export { CosmosClientError, CosmosEventStore, CosmosRestClient, DEFAULT_COSMOS_CONTAINERS, compareCosmosSuid, } from "./store/CosmosEventStore";
5
+ export type { CosmosContainerNames, CosmosDocumentClient, CosmosDocumentRecord, CosmosStoreOptions, CosmosWriteBoundary, } from "./store/CosmosEventStore";
6
+ export interface CosmosStoreProviderConfig extends Omit<CosmosStoreOptions, "client"> {
7
+ readonly client?: CosmosDocumentClient;
8
+ }
9
+ /** Explicit opt-in provider; the default runtime composition never reads Cosmos config. */
10
+ export declare function createCosmosStoreProvider(config: CosmosStoreProviderConfig): StoreProvider;
11
+ export declare function createCosmosBootstrapAdapter(store: CosmosEventStore): BootstrapStoreAdapter;