@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,104 @@
1
+ import { parseBootstrapDump } from "./manifest";
2
+ import { createBootstrapStoreAdapter } from "./BootstrapStoreAdapter";
3
+ import { scopeIdFor } from "../scope/ScopeName";
4
+ function json(body, status = 200) { return new Response(JSON.stringify(body), { status, headers: { "content-type": "application/json; charset=utf-8" } }); }
5
+ function object(value) { return typeof value === "object" && value !== null && !Array.isArray(value); }
6
+ function bearer(request, token) {
7
+ const supplied = request.headers.get("authorization");
8
+ // Keep absence indistinguishable from an undiscovered management surface.
9
+ if (supplied === null)
10
+ return json({ code: "not_found", error: "not found" }, 404);
11
+ if (supplied !== `Bearer ${token}`)
12
+ return json({ code: "operator_auth_required", error: "valid bearer required" }, 403);
13
+ return undefined;
14
+ }
15
+ /** Bearer-only operator lane. Incoming headers are never forwarded to a DO. */
16
+ export async function handleOperatorBootstrap(request, env, storeProvider, hooks = {}) {
17
+ const denied = bearer(request, env.REPAIR_OPERATOR_TOKEN);
18
+ if (denied !== undefined)
19
+ return denied;
20
+ const url = new URL(request.url);
21
+ const match = url.pathname.match(/^\/operator\/bootstrap\/([^/]+)\/(plan|import|status|abort|export)$/);
22
+ if (match === null)
23
+ return json({ code: "not_found", error: "not found" }, 404);
24
+ let serviceId;
25
+ try {
26
+ serviceId = decodeURIComponent(match[1]);
27
+ }
28
+ catch {
29
+ return json({ code: "bootstrap_service_invalid", error: "Bootstrap serviceId must be URI encoded" }, 400);
30
+ }
31
+ if (serviceId.length === 0)
32
+ return json({ code: "bootstrap_service_invalid", error: "Bootstrap serviceId is required" }, 400);
33
+ const operation = match[2];
34
+ const coordinator = env.BOOTSTRAP.get(scopeIdFor(env.BOOTSTRAP, { serviceId, doClass: "bootstrap", identity: "coordinator" }));
35
+ let body = {};
36
+ if (operation !== "status")
37
+ try {
38
+ body = await request.json();
39
+ }
40
+ catch {
41
+ return json({ code: "bootstrap_body_invalid", error: "JSON body required" }, 400);
42
+ }
43
+ const invoke = (path, value, method = "POST") => {
44
+ const internal = new URL(`https://bootstrap.internal${path}`);
45
+ internal.searchParams.set("__serviceId", serviceId);
46
+ return coordinator.fetch(new Request(internal, method === "GET" ? { method } : { method, headers: { "content-type": "application/json" }, body: JSON.stringify(value) }));
47
+ };
48
+ if (operation === "status")
49
+ return invoke("/state", undefined, "GET");
50
+ if (operation === "abort")
51
+ return invoke("/abort", body);
52
+ if (operation === "export") {
53
+ if (!object(body) || typeof body.targetServiceId !== "string" || body.targetServiceId.length === 0 || "allocatorLineageId" in body)
54
+ return json({ code: "bootstrap_export_invalid", error: "targetServiceId is required and allocator lineage is server-derived" }, 400);
55
+ // A caller must not nominate a synthetic lineage. Initializing the target
56
+ // service allocator first gives bootstrap and future commits one durable,
57
+ // authoritative lineage source.
58
+ const allocator = env.ALLOCATOR.get(scopeIdFor(env.ALLOCATOR, { serviceId: body.targetServiceId, doClass: "allocator", identity: "allocator" }));
59
+ const allocatorState = await allocator.fetch(new Request("https://bootstrap.internal/state"));
60
+ if (!allocatorState.ok)
61
+ return json({ code: "bootstrap_allocator_unavailable", error: "target allocator state is unavailable" }, 503);
62
+ const allocatorBody = await allocatorState.json();
63
+ if (typeof allocatorBody.allocatorLineageId !== "string" || allocatorBody.allocatorLineageId.length === 0)
64
+ return json({ code: "bootstrap_allocator_invalid", error: "target allocator lineage is invalid" }, 500);
65
+ const sourceAllocator = env.ALLOCATOR.get(scopeIdFor(env.ALLOCATOR, { serviceId, doClass: "allocator", identity: "allocator" }));
66
+ const sourceAllocatorState = await sourceAllocator.fetch(new Request("https://bootstrap.internal/state"));
67
+ if (!sourceAllocatorState.ok)
68
+ return json({ code: "bootstrap_allocator_unavailable", error: "source allocator state is unavailable" }, 503);
69
+ const sourceAllocatorBody = await sourceAllocatorState.json();
70
+ if (typeof sourceAllocatorBody.allocatorLineageId !== "string" || sourceAllocatorBody.allocatorLineageId.length === 0)
71
+ return json({ code: "bootstrap_allocator_invalid", error: "source allocator lineage is invalid" }, 500);
72
+ const adapter = storeProvider.createBootstrapAdapter?.(env) ?? createBootstrapStoreAdapter(storeProvider.name, storeProvider.create(env));
73
+ return json(await adapter.exportPage({ sourceServiceId: serviceId, sourceAllocatorLineageId: sourceAllocatorBody.allocatorLineageId, targetServiceId: body.targetServiceId, allocatorLineageId: allocatorBody.allocatorLineageId, pageSize: typeof body.pageSize === "number" ? body.pageSize : 128 }));
74
+ }
75
+ if (operation === "plan")
76
+ return invoke("/plan", body);
77
+ if (!object(body) || !object(body.dump))
78
+ return json({ code: "bootstrap_dump_invalid", error: "import requires dump" }, 400);
79
+ let dump;
80
+ try {
81
+ dump = parseBootstrapDump(body.dump);
82
+ }
83
+ catch {
84
+ return json({ code: "bootstrap_dump_invalid", error: "invalid canonical dump" }, 400);
85
+ }
86
+ if (typeof body.importId !== "string" || typeof body.leaseEpoch !== "number")
87
+ return json({ code: "bootstrap_epoch_rejected", error: "importId and leaseEpoch required" }, 409);
88
+ const adapter = storeProvider.createBootstrapAdapter?.(env) ?? createBootstrapStoreAdapter(storeProvider.name, storeProvider.create(env));
89
+ await adapter.admitBootstrap({ importId: body.importId, leaseEpoch: body.leaseEpoch, manifest: dump.manifest, events: dump.events });
90
+ const imported = await invoke("/import", body);
91
+ if (!imported.ok)
92
+ return imported;
93
+ const verified = await invoke("/verify", body);
94
+ if (!verified.ok)
95
+ return verified;
96
+ await adapter.verifyBootstrap({ importId: body.importId, manifest: dump.manifest });
97
+ try {
98
+ await hooks.afterVerifyBeforeReady?.({ serviceId, importId: body.importId, leaseEpoch: body.leaseEpoch, manifest: dump.manifest });
99
+ }
100
+ catch {
101
+ return json({ code: "bootstrap_read_model_rebuild_failed", error: "target read-model rebuild failed before READY" }, 503);
102
+ }
103
+ return invoke("/ready", body);
104
+ }
@@ -0,0 +1,9 @@
1
+ import type { BootstrapDump } from "./types";
2
+ export declare class BootstrapManifestError extends Error {
3
+ readonly code: string;
4
+ constructor(code: string, message: string);
5
+ }
6
+ /** A small deterministic digest for portable validation. It is deliberately not a security primitive. */
7
+ export declare function bootstrapDigest(value: unknown): string;
8
+ /** Parses and validates the complete dump before a coordinator can mutate a target. */
9
+ export declare function parseBootstrapDump(value: unknown): BootstrapDump;
@@ -0,0 +1,115 @@
1
+ import { assertCanonicalEventType } from "../eventIdentity";
2
+ import { assertSortableUniqueId } from "../allocator/SortableUniqueId";
3
+ import { CANONICAL_UTC_TIMESTAMP_PATTERN, isRfc4122Uuid, serializedEventMetadata } from "../eventRecord";
4
+ export class BootstrapManifestError extends Error {
5
+ code;
6
+ constructor(code, message) {
7
+ super(message);
8
+ this.code = code;
9
+ }
10
+ }
11
+ const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
12
+ const nonEmpty = (value) => typeof value === "string" && value.length > 0;
13
+ const exactKeys = (value, keys, name) => {
14
+ const actual = Object.keys(value).sort();
15
+ const expected = [...keys].sort();
16
+ if (actual.length !== expected.length || actual.some((key, index) => key !== expected[index]))
17
+ throw new BootstrapManifestError("unknown_or_missing_field", `${name} has unknown or missing fields`);
18
+ };
19
+ const canonical = (value) => {
20
+ if (Array.isArray(value))
21
+ return `[${value.map(canonical).join(",")}]`;
22
+ if (isObject(value))
23
+ return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`).join(",")}}`;
24
+ return JSON.stringify(value);
25
+ };
26
+ /** A small deterministic digest for portable validation. It is deliberately not a security primitive. */
27
+ export function bootstrapDigest(value) {
28
+ let hash = 2166136261;
29
+ for (const char of canonical(value)) {
30
+ hash ^= char.charCodeAt(0);
31
+ hash = Math.imul(hash, 16777619);
32
+ }
33
+ return `fnv1a32:${(hash >>> 0).toString(16).padStart(8, "0")}`;
34
+ }
35
+ function parseManifest(value) {
36
+ if (!isObject(value))
37
+ throw new BootstrapManifestError("manifest_invalid", "manifest must be an object");
38
+ exactKeys(value, ["canonicalization", "contentDigest", "eventCount", "format", "highWatermark", "source", "tagCounts", "target", "version"], "manifest");
39
+ if (value.format !== "sekiban-dcb-bootstrap" || value.version !== 1 || value.canonicalization !== "utf8-json-sorted-keys-v1" || !nonEmpty(value.contentDigest) || !isObject(value.source) || !isObject(value.target) || !isObject(value.tagCounts))
40
+ throw new BootstrapManifestError("manifest_invalid", "manifest has an invalid format or version");
41
+ exactKeys(value.source, ["lineageId", "serviceId"], "manifest.source");
42
+ exactKeys(value.target, ["allocatorLineageId", "serviceId"], "manifest.target");
43
+ const eventCount = value.eventCount;
44
+ const tagCounts = value.tagCounts;
45
+ if (!nonEmpty(value.source.serviceId) || !nonEmpty(value.source.lineageId) || !nonEmpty(value.target.serviceId) || !nonEmpty(value.target.allocatorLineageId) || (typeof value.highWatermark !== "string" && value.highWatermark !== null) || typeof eventCount !== "number" || !Number.isSafeInteger(eventCount) || eventCount < 0 || !Object.entries(tagCounts).every(([tag, count]) => nonEmpty(tag) && typeof count === "number" && Number.isSafeInteger(count) && count >= 0))
46
+ throw new BootstrapManifestError("manifest_invalid", "manifest field is invalid");
47
+ return value;
48
+ }
49
+ function parseEvent(value) {
50
+ if (!isObject(value))
51
+ throw new BootstrapManifestError("record_invalid", "event record must be an object");
52
+ const allowed = ["causationId", "correlationId", "eventId", "eventTags", "eventType", "executedUser", "payload", "provenance", "suid", "timestamp"];
53
+ if (Object.keys(value).some((key) => !allowed.includes(key)) || !nonEmpty(value.eventId) || !nonEmpty(value.suid) ||
54
+ typeof value.payload !== "string" || !Array.isArray(value.eventTags) || !value.eventTags.every(nonEmpty) ||
55
+ new Set(value.eventTags).size !== value.eventTags.length || !nonEmpty(value.eventType) ||
56
+ !isObject(value.provenance) || value.provenance.origin !== "g32" || !nonEmpty(value.timestamp) ||
57
+ ![value.causationId, value.correlationId, value.executedUser].every((metadata) => metadata === null || nonEmpty(metadata))) {
58
+ throw new BootstrapManifestError("record_invalid", "event record is invalid");
59
+ }
60
+ try {
61
+ assertSortableUniqueId(value.suid);
62
+ // A C# import is permitted to contain any RFC 4122 Id. New commit
63
+ // admission remains UUID v7; this parser is the migration boundary.
64
+ if (!isRfc4122Uuid(value.eventId))
65
+ throw new Error("event id");
66
+ assertCanonicalEventType(value.eventType);
67
+ JSON.parse(value.payload);
68
+ }
69
+ catch {
70
+ throw new BootstrapManifestError("record_invalid", "G32 record identity or payload is invalid");
71
+ }
72
+ if (!CANONICAL_UTC_TIMESTAMP_PATTERN.test(value.timestamp)) {
73
+ throw new BootstrapManifestError("record_invalid", "record timestamp is not UTC");
74
+ }
75
+ const metadata = serializedEventMetadata(value.eventId);
76
+ const nullableMetadata = value.causationId === null && value.correlationId === null && value.executedUser === null;
77
+ const serializedMetadata = value.causationId === metadata.causationId && value.correlationId === metadata.correlationId && value.executedUser === metadata.executedUser;
78
+ if (!nullableMetadata && !serializedMetadata) {
79
+ throw new BootstrapManifestError("record_invalid", "record metadata must be all null or use the serialized C# constants");
80
+ }
81
+ return {
82
+ eventId: value.eventId,
83
+ suid: value.suid,
84
+ payload: value.payload,
85
+ // C# Tags preserve emission order; do not sort the durable record.
86
+ eventTags: [...value.eventTags],
87
+ eventType: value.eventType,
88
+ provenance: { origin: "g32" },
89
+ timestamp: value.timestamp,
90
+ causationId: value.causationId,
91
+ correlationId: value.correlationId,
92
+ executedUser: value.executedUser,
93
+ };
94
+ }
95
+ /** Parses and validates the complete dump before a coordinator can mutate a target. */
96
+ export function parseBootstrapDump(value) {
97
+ if (!isObject(value))
98
+ throw new BootstrapManifestError("dump_invalid", "dump must be an object");
99
+ exactKeys(value, ["events", "manifest"], "dump");
100
+ if (!Array.isArray(value.events))
101
+ throw new BootstrapManifestError("dump_invalid", "events must be an array");
102
+ const manifest = parseManifest(value.manifest);
103
+ const events = value.events.map(parseEvent);
104
+ if (events.length !== manifest.eventCount || new Set(events.map((event) => event.eventId)).size !== events.length || events.some((event, index) => index > 0 && events[index - 1].suid >= event.suid))
105
+ throw new BootstrapManifestError("record_order_or_duplicate", "event records must be unique and strictly SUID-ascending");
106
+ const counts = {};
107
+ for (const event of events)
108
+ for (const tag of event.eventTags)
109
+ counts[tag] = (counts[tag] ?? 0) + 1;
110
+ if (canonical(counts) !== canonical(manifest.tagCounts) || (events.at(-1)?.suid ?? null) !== manifest.highWatermark)
111
+ throw new BootstrapManifestError("manifest_mismatch", "manifest counts or high watermark do not match records");
112
+ if (bootstrapDigest({ manifest: { ...manifest, contentDigest: "" }, events }) !== manifest.contentDigest)
113
+ throw new BootstrapManifestError("digest_mismatch", "dump content digest does not match");
114
+ return { manifest, events };
115
+ }
@@ -0,0 +1,75 @@
1
+ /** Provider-neutral, immutable G32 dump wire. */
2
+ export interface BootstrapManifest {
3
+ readonly format: "sekiban-dcb-bootstrap";
4
+ readonly version: 1;
5
+ readonly source: {
6
+ readonly serviceId: string;
7
+ readonly lineageId: string;
8
+ };
9
+ readonly target: {
10
+ readonly serviceId: string;
11
+ readonly allocatorLineageId: string;
12
+ };
13
+ readonly highWatermark: string | null;
14
+ readonly eventCount: number;
15
+ readonly tagCounts: Readonly<Record<string, number>>;
16
+ readonly contentDigest: string;
17
+ readonly canonicalization: "utf8-json-sorted-keys-v1";
18
+ }
19
+ export interface BootstrapEventRecord {
20
+ readonly eventId: string;
21
+ readonly suid: string;
22
+ readonly payload: string;
23
+ readonly eventTags: readonly string[];
24
+ readonly eventType: string;
25
+ readonly provenance: Readonly<{
26
+ readonly origin: "g32";
27
+ }>;
28
+ readonly timestamp: string;
29
+ readonly causationId: string | null;
30
+ readonly correlationId: string | null;
31
+ readonly executedUser: string | null;
32
+ }
33
+ export interface BootstrapDump {
34
+ readonly manifest: BootstrapManifest;
35
+ readonly events: readonly BootstrapEventRecord[];
36
+ }
37
+ export type BootstrapStatus = "EMPTY" | "PLANNED" | "IMPORTING" | "VERIFYING" | "READY" | "FAILED";
38
+ export interface BootstrapControlRecord {
39
+ readonly schemaVersion: 1;
40
+ readonly status: BootstrapStatus;
41
+ readonly importId: string | null;
42
+ readonly targetServiceId: string;
43
+ readonly allocatorLineageId: string | null;
44
+ readonly source: BootstrapManifest["source"] | null;
45
+ readonly digest: string | null;
46
+ readonly manifest: BootstrapManifest | null;
47
+ readonly progress: Readonly<Record<string, string | null>>;
48
+ readonly leaseEpoch: number;
49
+ readonly leaseUntil: number | null;
50
+ readonly failure: string | null;
51
+ readonly readyAt: string | null;
52
+ readonly normalInFlight: number;
53
+ /** Commands admitted before a bootstrap plan. The epoch is carried to every
54
+ * final durable write, rather than treating admission as a one-time check. */
55
+ readonly normalCommands?: Readonly<Record<string, number>>;
56
+ /** Recently released entry admissions, retained only for their final epoch check. */
57
+ readonly releasedCommands?: Readonly<Record<string, number>>;
58
+ /** READY is a post-verification state, never merely an import completion. */
59
+ readonly verifiedImportId?: string | null;
60
+ readonly verifiedLeaseEpoch?: number | null;
61
+ readonly storeCompletion?: "prepopulated-manifest" | null;
62
+ }
63
+ /** G22 supplies provider implementations. Bootstrap core deliberately has no adapter. */
64
+ export interface BootstrapStoreAdmissionPort {
65
+ admitBootstrap(input: {
66
+ readonly importId: string;
67
+ readonly leaseEpoch: number;
68
+ readonly manifest: BootstrapManifest;
69
+ readonly events: readonly BootstrapEventRecord[];
70
+ }): Promise<void>;
71
+ verifyBootstrap(input: {
72
+ readonly importId: string;
73
+ readonly manifest: BootstrapManifest;
74
+ }): Promise<void>;
75
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ import { type NativeTracing } from "../trace/CommitTrace";
2
+ import { type ServiceIdentityProvider } from "../service/ServiceIdentityProvider";
3
+ export interface OperatorRepairEnv {
4
+ JOURNAL: DurableObjectNamespace;
5
+ TAG: DurableObjectNamespace;
6
+ REPAIR_OPERATOR_TOKEN: string;
7
+ REPAIR_EXCLUSION_LOOKUP?: Fetcher;
8
+ SDT_SERVICE_ID?: string;
9
+ }
10
+ /** Authenticated, bounded control-plane command; it is not a V1 public wire endpoint. */
11
+ export declare function handleOperatorRepair(request: Request, env: OperatorRepairEnv, nativeTracing?: NativeTracing, serviceIdentityProvider?: ServiceIdentityProvider): Promise<Response>;
@@ -0,0 +1,108 @@
1
+ import { BindingExclusionLookupClient } from "../downstream/ExclusionLookup";
2
+ import { RepairWorker, RepairWorkerFailure } from "../repair/RepairWorker";
3
+ import { noOpNativeTracing } from "../trace/CommitTrace";
4
+ import { envServiceIdentity, requireServiceIdentity } from "../service/ServiceIdentityProvider";
5
+ function json(body, status = 200) {
6
+ return new Response(JSON.stringify(body), {
7
+ status,
8
+ headers: { "content-type": "application/json; charset=utf-8" },
9
+ });
10
+ }
11
+ function error(status, code, message) {
12
+ return json({ error: message, code }, status);
13
+ }
14
+ function isObject(value) {
15
+ return typeof value === "object" && value !== null && !Array.isArray(value);
16
+ }
17
+ function isNonEmptyString(value) {
18
+ return typeof value === "string" && value.length > 0;
19
+ }
20
+ function uniqueStrings(value, name) {
21
+ if (!Array.isArray(value) || value.length === 0 || !value.every(isNonEmptyString)) {
22
+ return { error: `${name} must be a non-empty array of non-empty strings` };
23
+ }
24
+ if (new Set(value).size !== value.length) {
25
+ return { error: `${name} values must be unique` };
26
+ }
27
+ return { value: [...value] };
28
+ }
29
+ function executionFrom(value, testFault) {
30
+ if (!isObject(value) || !isNonEmptyString(value.actor)) {
31
+ return { error: "actor is required" };
32
+ }
33
+ const attemptIds = uniqueStrings(value.attemptIds, "attemptIds");
34
+ const tags = uniqueStrings(value.tags, "tags");
35
+ if (attemptIds.value === undefined || tags.value === undefined) {
36
+ return { error: attemptIds.error ?? tags.error };
37
+ }
38
+ const mode = value.mode === undefined ? "dry-run" : value.mode;
39
+ if (mode !== "dry-run" && mode !== "execute") {
40
+ return { error: "mode must be dry-run or execute" };
41
+ }
42
+ const maxItems = value.maxItems === undefined ? 100 : value.maxItems;
43
+ if (typeof maxItems !== "number" || !Number.isSafeInteger(maxItems) || maxItems <= 0 || maxItems > 1_000) {
44
+ return { error: "maxItems must be a positive safe integer no greater than 1000" };
45
+ }
46
+ if (value.checkpoint !== undefined && !isNonEmptyString(value.checkpoint)) {
47
+ return { error: "checkpoint must be a non-empty string when present" };
48
+ }
49
+ return {
50
+ value: {
51
+ attemptIds: attemptIds.value,
52
+ tags: tags.value,
53
+ actor: value.actor,
54
+ // Store an auditable operator identity, never the bearer secret itself.
55
+ owner: `operator:${value.actor}`,
56
+ mode,
57
+ maxItems,
58
+ ...(value.checkpoint === undefined ? {} : { checkpoint: value.checkpoint }),
59
+ ...(testFault === undefined ? {} : { fault: testFault }),
60
+ },
61
+ };
62
+ }
63
+ function testFaultFromRequest(request) {
64
+ if (new URL(request.url).hostname !== "repair.test") {
65
+ return undefined;
66
+ }
67
+ const value = request.headers.get("x-sdt-g6-test-fault");
68
+ return value === "after-lease-before-prepare" ||
69
+ value === "after-prepare-before-apply" ||
70
+ value === "after-apply-before-observation" ||
71
+ value === "after-verify-before-audit" ||
72
+ value === "after-audit-before-clear" ||
73
+ value === "after-clear-before-final-observation"
74
+ ? value
75
+ : undefined;
76
+ }
77
+ /** Authenticated, bounded control-plane command; it is not a V1 public wire endpoint. */
78
+ export async function handleOperatorRepair(request, env, nativeTracing = noOpNativeTracing, serviceIdentityProvider) {
79
+ if (request.method !== "POST") {
80
+ return error(404, "operator_repair_route_not_found", "Operator repair requires POST");
81
+ }
82
+ const token = env.REPAIR_OPERATOR_TOKEN;
83
+ if (!isNonEmptyString(token) || request.headers.get("authorization") !== `Bearer ${token}`) {
84
+ return error(401, "operator_auth_required", "A valid operator repair bearer token is required");
85
+ }
86
+ let body;
87
+ try {
88
+ body = await request.json();
89
+ }
90
+ catch {
91
+ return error(400, "invalid_operator_repair_request", "Operator repair request must be JSON");
92
+ }
93
+ const parsed = executionFrom(body, testFaultFromRequest(request));
94
+ if (parsed.value === undefined) {
95
+ return error(400, "invalid_operator_repair_request", parsed.error ?? "Invalid operator repair request");
96
+ }
97
+ try {
98
+ const worker = new RepairWorker(env, new BindingExclusionLookupClient(env.REPAIR_EXCLUSION_LOOKUP), requireServiceIdentity(serviceIdentityProvider ?? envServiceIdentity(env)), { nativeTracing });
99
+ const result = await worker.execute(parsed.value);
100
+ return json(result, result.interrupted === undefined ? 200 : 202);
101
+ }
102
+ catch (failure) {
103
+ const message = failure instanceof RepairWorkerFailure
104
+ ? failure.message
105
+ : "Operator repair could not determine a durable repair result";
106
+ return error(500, "operator_repair_failed", message);
107
+ }
108
+ }
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Cloudflare-only runtime composition.
3
+ *
4
+ * This entrypoint is deliberately separate from the default runtime entrypoint:
5
+ * it imports the D1 provider directly and never imports the Postgres/Cosmos
6
+ * provider graph. A Worker using this surface therefore has an auditable
7
+ * zero-external-database bundle while the ordinary entrypoint remains the
8
+ * unchanged Postgres composition.
9
+ */
10
+ import type { DomainDefinition } from "@sekiban/dcb-core";
11
+ import { AllocatorDurableObject as RuntimeAllocatorDurableObject } from "./allocator/AllocatorDurableObject";
12
+ import { BootstrapCoordinatorDurableObject as RuntimeBootstrapCoordinatorDurableObject } from "./bootstrap/BootstrapCoordinatorDurableObject";
13
+ import type { DeliveryCoreResult, DeliveryViewHandler } from "./downstream/DeliveryCore";
14
+ import type { DownstreamDoorbellBinding } from "./downstream/Doorbell";
15
+ import type { DownstreamOutboxMessage } from "./downstream/types";
16
+ import { JournalDurableObject as RuntimeJournalDurableObject } from "./journal/JournalDurableObject";
17
+ import { type RuntimeDomainLike, type RuntimeWorkerConfig } from "./composition";
18
+ import { type LiveProjectionPollObserver } from "./projection/LiveProjectionWorker";
19
+ import { TagDurableObject as RuntimeTagDurableObject } from "./tag/TagDurableObject";
20
+ import { TagStateDurableObject as RuntimeTagStateDurableObject } from "./tagstate/TagStateDurableObject";
21
+ import type { GlobalCompletenessScanResult } from "./completeness/types";
22
+ import type { StoredEvent } from "./store/types";
23
+ import { type ServiceIdentityProvider } from "./service/ServiceIdentityProvider";
24
+ export { createG60DurableHopObserver, observeG60UnsafeWriter, recordDurableHop, recordDurableHopSubstep, recordDurableUnsafeWriterBoundary, recordFirstUnsafeVisibleRead, } from "./diagnostics/G60DurableHop";
25
+ export { G60_POST_ADMISSION_STAGES, G60_UNSAFE_WRITER_PATHS, } from "./diagnostics/G60DurableHop";
26
+ export { G65_DIRECT_RING_BUDGET_MS, G65_DIRECT_RING_CLOCK_ORIGIN, recordG65DirectRing, readG65DirectRing, markG65DirectApplyStarted, markG65DirectApplyFinished, } from "./diagnostics/G65DirectRing";
27
+ export type { G65DirectApplyOutcome, G65DirectRingOutcome, G65DirectRingRecord, } from "./diagnostics/G65DirectRing";
28
+ export type { G60DurableUnsafeWriterObservation, G60DurablePostAdmissionObservation, G60DurableHopObservation, G60DurableHopObserver, G60PostAdmissionBoundary, G60PostAdmissionStage, G60UnsafeWriterBoundary, G60UnsafeWriterPath, G60UnsafeWriterTransport, G60HopStage, G60HopTransport, } from "./diagnostics/G60DurableHop";
29
+ export { buildScopeName, DURABLE_OBJECT_SCOPE_CLASSES, isScopeServiceId, parseScopeName, scopeIdFor, ScopeNameError, tagStateScopeIdentity, } from "./scope/ScopeName";
30
+ export type { DurableObjectScope, DurableObjectScopeClass, ScopeNameNamespace } from "./scope/ScopeName";
31
+ export { envServiceIdentity, G11_SERVICE_ID_HEADER, injectableServiceIdentity, requestServiceIdentity, requireServiceIdentity, ServiceIdentityMissingError, TEST_SERVICE_ID_HEADER, } from "./service/ServiceIdentityProvider";
32
+ export type { ServiceIdentityBehavior, ServiceIdentityEnvironment, ServiceIdentityProvider, ServiceIdentityRequestOptions, ServiceIdentityResolution, } from "./service/ServiceIdentityProvider";
33
+ export interface CloudflareOnlyEnv {
34
+ ALLOCATOR: DurableObjectNamespace;
35
+ BOOTSTRAP: DurableObjectNamespace;
36
+ JOURNAL: DurableObjectNamespace;
37
+ TAG: DurableObjectNamespace;
38
+ TAG_STATE: DurableObjectNamespace;
39
+ DOWNSTREAM_QUEUE: Queue<DownstreamOutboxMessage>;
40
+ DOWNSTREAM_DOORBELL?: DownstreamDoorbellBinding;
41
+ D1: D1Database;
42
+ D1_MV: D1Database;
43
+ AUTO_DRAIN_OUTBOX?: string;
44
+ REPAIR_OPERATOR_TOKEN: string;
45
+ REPAIR_EXCLUSION_LOOKUP?: Fetcher;
46
+ G11_VERIFICATION_ENABLED?: string;
47
+ SDT_SERVICE_ID?: string;
48
+ DOMAIN_DELIVERY_CLASS?: string;
49
+ DIRECT_DOORBELL?: string;
50
+ DIRECT_DOORBELL_ALLOWED_VIEWS?: string;
51
+ DIRECT_DOORBELL_MAX_INVOCATIONS?: string;
52
+ DIRECT_DOORBELL_DEGRADATION?: string;
53
+ DIRECT_DOORBELL_RECEIVER_MODE?: string;
54
+ DIRECT_DOORBELL_SELF_BINDING_PROOF?: string;
55
+ G26_VIEW_COUNT?: string;
56
+ /** Bound from Cloudflare Worker Version metadata; observation-only. */
57
+ WORKER_VERSION?: Readonly<{
58
+ id?: unknown;
59
+ }>;
60
+ }
61
+ export interface CloudflareOnlyWorkerOptions {
62
+ readonly domain?: DomainDefinition | RuntimeDomainLike;
63
+ readonly config?: RuntimeWorkerConfig;
64
+ /** Host seam; deployed composition defaults to envServiceIdentity. */
65
+ readonly serviceIdentityProvider?: ServiceIdentityProvider;
66
+ /** Optional deployment read-model rebuild that must finish before READY. */
67
+ readonly afterBootstrapVerify?: (input: {
68
+ readonly serviceId: string;
69
+ readonly env: CloudflareOnlyEnv;
70
+ }) => Promise<void>;
71
+ /**
72
+ * Runs after the fresh G44 reconciliation and before the scheduled
73
+ * live-projection poll. A sample can use the resulting persisted coverage
74
+ * for its SafeWindow-fenced materialized-view pass in this same tick.
75
+ */
76
+ readonly beforeLiveProjectionPoll?: (input: {
77
+ readonly env: CloudflareOnlyEnv;
78
+ readonly serviceId: string;
79
+ readonly scan: GlobalCompletenessScanResult;
80
+ readonly ctx: ExecutionContext;
81
+ }) => Promise<BeforeLiveProjectionPollResult | void>;
82
+ /** Persists the observation-only lifecycle of each scheduled live poll. */
83
+ readonly liveProjectionPollObserver?: LiveProjectionPollObserver;
84
+ /** Factories are evaluated per invocation; Queue and receiver can select views independently. */
85
+ readonly deliveryViews?: (input: {
86
+ readonly env: CloudflareOnlyEnv;
87
+ readonly ctx: ExecutionContext;
88
+ }) => readonly DeliveryViewHandler[];
89
+ /** Runs after all selected views have completed and before the drain trigger returns. */
90
+ readonly afterStoredDownstreamDelivery?: (input: {
91
+ readonly message: DownstreamOutboxMessage;
92
+ readonly event: StoredEvent;
93
+ readonly arrivedAt: number;
94
+ readonly env: CloudflareOnlyEnv;
95
+ readonly ctx: ExecutionContext;
96
+ readonly source?: "queue" | "fast" | "import";
97
+ readonly result?: DeliveryCoreResult;
98
+ }) => Promise<void>;
99
+ /**
100
+ * Runs after a Queue message has durably recorded its event, including when
101
+ * G44 keeps ordinary views fail-closed. The callback must only register
102
+ * non-blocking work with the active ExecutionContext and return.
103
+ */
104
+ readonly afterStoredQueueDelivery?: (input: {
105
+ readonly message: DownstreamOutboxMessage;
106
+ readonly result: DeliveryCoreResult;
107
+ readonly env: CloudflareOnlyEnv;
108
+ readonly ctx: ExecutionContext;
109
+ }) => void;
110
+ }
111
+ /**
112
+ * Result returned by the sample's retained-frontier safe-lane hook. The
113
+ * scanner result itself intentionally has no mutable frontier: on BLOCK the
114
+ * hook reads the last proven FULL cursor from the persisted health authority.
115
+ */
116
+ export interface BeforeLiveProjectionPollResult {
117
+ readonly frontierSuid?: string | null;
118
+ }
119
+ /**
120
+ * Translate a scheduled scanner outcome and the hook's retained frontier into
121
+ * the live-poll fence. A FULL scan keeps the established unbounded behavior;
122
+ * every other outcome invokes the poll but is bounded by the last proven
123
+ * frontier (or by `null` when none exists).
124
+ */
125
+ export declare function scheduledLiveProjectionMaximumSuid(scan: Pick<GlobalCompletenessScanResult, "kind">, retainedFrontierSuid: string | null | undefined): string | null | undefined;
126
+ /**
127
+ * Keep the portable runtime free of a `cloudflare:workers` runtime import.
128
+ * These entrypoint-owned wrappers inject the active Cloudflare custom-span
129
+ * API into every Durable Object constructor used by the deployed Worker.
130
+ */
131
+ export declare class AllocatorDurableObject extends RuntimeAllocatorDurableObject {
132
+ constructor(ctx: DurableObjectState, env: CloudflareOnlyEnv);
133
+ }
134
+ export declare class BootstrapCoordinatorDurableObject extends RuntimeBootstrapCoordinatorDurableObject {
135
+ constructor(ctx: DurableObjectState, env: CloudflareOnlyEnv);
136
+ }
137
+ export declare class JournalDurableObject extends RuntimeJournalDurableObject {
138
+ constructor(ctx: DurableObjectState, env: CloudflareOnlyEnv);
139
+ }
140
+ export declare class TagDurableObject extends RuntimeTagDurableObject {
141
+ constructor(ctx: DurableObjectState, env: CloudflareOnlyEnv);
142
+ }
143
+ /** The dedicated (service, tag, projector) cache/replay Durable Object. */
144
+ export declare class TagStateDurableObject extends RuntimeTagStateDurableObject {
145
+ }
146
+ /** Compose the named two-D1 Cloudflare-only Worker. */
147
+ export declare function createCloudflareOnlyRuntimeWorker(options?: CloudflareOnlyWorkerOptions): ExportedHandler<CloudflareOnlyEnv>;
148
+ export { processDownstreamDoorbell } from "./downstream/DownstreamAdapter";
149
+ export { LIVE_PROJECTION_POLL_OUTCOMES, pollLiveProjections, } from "./projection/LiveProjectionWorker";
150
+ export type { LiveProjectionEnv, LiveProjectionPollObservation, LiveProjectionPollObserver, LiveProjectionPollOutcome, ProjectionPollOptions, } from "./projection/LiveProjectionWorker";
151
+ export type { ClosedPrefixCertificate } from "./allocator/types";
152
+ export type { SafeViewCoverageContext } from "./projection/ProjectionRuntime";
153
+ export { downstreamEnvelopeBytes, classifyDirectDoorbellFailure, preflightDirectDoorbell, readDomainDeliveryClass, readDirectDoorbellConfig, selectDirectDoorbellViews, MAX_SERVICE_BINDING_INVOCATIONS_PER_REQUEST, } from "./downstream/Doorbell";
154
+ export { deliveryCorrelationId } from "./downstream/DeliveryCore";
155
+ export { GlobalCompletenessReconciler } from "./completeness/GlobalCompletenessReconciler";
156
+ export { G44_HEALTH_STALE_AFTER_MS, G44_SCANNER_VERSION, GLOBAL_COMPLETENESS_INTERIM_DISPOSITION, } from "./completeness/types";
157
+ export type { GlobalCompletenessHealth, GlobalCompletenessCoverage, GlobalCompletenessHealthRecord, GlobalCompletenessScanResult, SourceObligationFact, SourceObligationPage, SourcePartitionSnapshot, } from "./completeness/types";
158
+ export { observeFaultBarrier } from "./trace/ObservationStream";
159
+ export { G42_JOURNAL_PROBE_ALARM_KEY, G42_JOURNAL_PROBE_IDENTITY_PREFIX, G42_JOURNAL_PROBE_INDEX_KEY, G42_JOURNAL_PROBE_INTERNAL_PREFIX, G42_JOURNAL_PROBE_LOGICAL_KEY_PREFIX, G42_JOURNAL_PROBE_PATH, G42_JOURNAL_PROBE_SCHEMA, G42_JOURNAL_PROBE_STORAGE_PREFIX, cleanupG42JournalProbeTrial, g42ProbeStorageKey, inventoryG42JournalProbeTrial, isG42ProbeIdentity, isG42ProbeLogicalKey, parseG42JournalProbeRequest, prepareG42JournalProbeTrial, measureG42JournalProbeTrial, runG42JournalProbeTrial, } from "./journal/JournalFirstTouchProbe";
160
+ export type { G42JournalProbeCleanup, G42JournalProbeCleanupReceipt, G42JournalProbeInventory, G42JournalProbeInventoryReceipt, G42JournalProbeMeasurement, G42JournalProbeMeasurementReceipt, G42JournalProbePreparation, G42JournalProbePreparationReceipt, G42JournalProbeRequest, G42JournalProbeTrial, G42JournalProbeTrialReceipt, G42ProbeActivationFact, G42ProbeAlarmMode, G42ProbeCell, G42ProbeMediator, G42ProbeOperationResult, } from "./journal/JournalFirstTouchProbe";
161
+ export type { DeliveryClass, DownstreamDoorbellBinding, DirectDoorbellDegradation, DirectDoorbellDeploymentConfig, DirectDoorbellPreflightResult, DirectDoorbellReceiverMode, DirectDoorbellFailureKind, } from "./downstream/Doorbell";
162
+ export type { DeliveryCoreEnvironment, DeliveryCoreFailure, DeliveryCoreOptions, DeliveryCoreResult, DeliverySource, DeliveryViewApplyResult, DeliveryViewFailureClass, DeliveryViewHandler, DeliveryViewInput, DeliveryViewResult, } from "./downstream/DeliveryCore";
163
+ declare const cloudflareOnlyRuntime: ExportedHandler<CloudflareOnlyEnv, unknown, unknown, unknown>;
164
+ export default cloudflareOnlyRuntime;