@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,77 @@
1
+ /** A queue payload is intentionally an internal envelope, never part of V1. */
2
+ /**
3
+ * `import` is a direct, operator-owned C# record import. It never traverses
4
+ * Queue or doorbell, where a newly authored event must always be UUID v7.
5
+ */
6
+ export type DeliverySource = "queue" | "fast" | "import";
7
+ /** G32 has no legacy delivery lane. Every durable envelope is explicitly g32. */
8
+ export type DeliveryProvenance = "g32";
9
+ /** One tag-local committed-membership fact carried by a G43 obligation. */
10
+ export interface OutboxCommittedMembership {
11
+ readonly serviceId: string;
12
+ readonly eventId: string;
13
+ readonly tag: string;
14
+ }
15
+ /**
16
+ * Source-authoritative facts required to turn a transport handoff into a
17
+ * global-array receipt. `canonicalBytesBase64` is the exact G43 digest
18
+ * preimage, not a projection-derived reconstruction.
19
+ */
20
+ export interface OutboxCompletenessFacts {
21
+ readonly canonicalBytesBase64: string;
22
+ readonly eventDigest: string;
23
+ readonly declaredTagSet: readonly string[];
24
+ readonly localCommittedMembership: readonly OutboxCommittedMembership[];
25
+ /** Local to the source Tag DO; never treated as a global sequence. */
26
+ readonly obligationSequence: number;
27
+ }
28
+ export interface DownstreamOutboxMessage {
29
+ version: 1;
30
+ serviceId: string;
31
+ /** Stable identity of the allocator DO lineage that issued this delivery. */
32
+ allocatorLineageId: string;
33
+ tag: string;
34
+ attemptId: string;
35
+ eventId: string;
36
+ suid: string;
37
+ payload: string;
38
+ /** UTC write-time timestamp carried with the exact event payload. */
39
+ timestamp: string;
40
+ /** Nullable only on the fenced C# import lane; normal delivery is exact constants. */
41
+ causationId: string | null;
42
+ correlationId: string | null;
43
+ executedUser: string | null;
44
+ /** The complete set of tag-side copies expected for this event. */
45
+ eventTags: string[];
46
+ /** Durable C# EventType = eventPayloadName. */
47
+ eventType: string;
48
+ provenance: DeliveryProvenance;
49
+ /** Durable outbox clock fact, set before the first queue send attempt. */
50
+ enqueuedAt: number;
51
+ /** G43 source facts; required before the global array can acknowledge. */
52
+ completeness: OutboxCompletenessFacts;
53
+ }
54
+ export interface OutboxDeliveryIdentity {
55
+ attemptId: string;
56
+ eventId: string;
57
+ suid: string;
58
+ allocatorLineageId: string;
59
+ payload: string;
60
+ eventType: string;
61
+ provenance: DeliveryProvenance;
62
+ timestamp: string;
63
+ causationId: string | null;
64
+ correlationId: string | null;
65
+ executedUser: string | null;
66
+ completeness: Pick<OutboxCompletenessFacts, "eventDigest" | "obligationSequence">;
67
+ }
68
+ export interface OutboxDelivery extends OutboxDeliveryIdentity {
69
+ enqueuedAt: number;
70
+ deliveredAt: number | null;
71
+ }
72
+ export interface PipelineClock {
73
+ now(): number;
74
+ }
75
+ export declare const systemPipelineClock: PipelineClock;
76
+ export declare function outboxIdentity(message: OutboxDeliveryIdentity): string;
77
+ export declare function isDownstreamOutboxMessage(value: unknown): value is DownstreamOutboxMessage;
@@ -0,0 +1,64 @@
1
+ import { parseCanonicalEventKey } from "@sekiban/dcb-core";
2
+ import { isSortableUniqueId } from "../allocator/SortableUniqueId";
3
+ import { CANONICAL_UTC_TIMESTAMP_PATTERN, isUuidV7, serializedEventMetadata } from "../eventRecord";
4
+ export const systemPipelineClock = {
5
+ now: () => Date.now(),
6
+ };
7
+ export function outboxIdentity(message) {
8
+ return [message.attemptId, message.eventId, message.suid, message.allocatorLineageId, message.payload, message.eventType, message.provenance, message.timestamp ?? "", message.causationId ?? "", message.correlationId ?? "", message.executedUser ?? "", message.completeness.eventDigest, String(message.completeness.obligationSequence)].join("\u0000");
9
+ }
10
+ function isCommittedMembership(value, candidate) {
11
+ if (typeof value !== "object" || value === null || Array.isArray(value))
12
+ return false;
13
+ const membership = value;
14
+ return membership.serviceId === candidate.serviceId &&
15
+ membership.eventId === candidate.eventId &&
16
+ typeof membership.tag === "string" && membership.tag.length > 0;
17
+ }
18
+ function isCompletenessFacts(value, candidate) {
19
+ if (typeof value !== "object" || value === null || Array.isArray(value))
20
+ return false;
21
+ const facts = value;
22
+ return typeof facts.canonicalBytesBase64 === "string" && facts.canonicalBytesBase64.length > 0 &&
23
+ typeof facts.eventDigest === "string" && /^[0-9a-f]{64}$/.test(facts.eventDigest) &&
24
+ Array.isArray(facts.declaredTagSet) && facts.declaredTagSet.length > 0 &&
25
+ facts.declaredTagSet.every((tag) => typeof tag === "string" && tag.length > 0) &&
26
+ new Set(facts.declaredTagSet).size === facts.declaredTagSet.length &&
27
+ Array.isArray(facts.localCommittedMembership) && facts.localCommittedMembership.length === 1 &&
28
+ facts.localCommittedMembership.every((membership) => isCommittedMembership(membership, candidate)) &&
29
+ facts.localCommittedMembership[0] !== undefined &&
30
+ facts.localCommittedMembership[0].tag === candidate.tag &&
31
+ Number.isSafeInteger(facts.obligationSequence) && facts.obligationSequence > 0;
32
+ }
33
+ export function isDownstreamOutboxMessage(value) {
34
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
35
+ return false;
36
+ }
37
+ const candidate = value;
38
+ if (typeof candidate.eventType !== "string" || candidate.eventType.length === 0 || candidate.provenance !== "g32")
39
+ return false;
40
+ try {
41
+ parseCanonicalEventKey(candidate.eventType);
42
+ }
43
+ catch {
44
+ return false;
45
+ }
46
+ const metadata = typeof candidate.eventId === "string" ? serializedEventMetadata(candidate.eventId) : undefined;
47
+ return candidate.version === 1 &&
48
+ typeof candidate.serviceId === "string" && candidate.serviceId.length > 0 &&
49
+ typeof candidate.allocatorLineageId === "string" && candidate.allocatorLineageId.length > 0 &&
50
+ typeof candidate.tag === "string" && candidate.tag.length > 0 &&
51
+ typeof candidate.attemptId === "string" && candidate.attemptId.length > 0 &&
52
+ isUuidV7(candidate.eventId) &&
53
+ isSortableUniqueId(candidate.suid) &&
54
+ typeof candidate.payload === "string" &&
55
+ Array.isArray(candidate.eventTags) && candidate.eventTags.every((tag) => typeof tag === "string" && tag.length > 0) &&
56
+ new Set(candidate.eventTags).size === candidate.eventTags.length && candidate.eventTags.includes(candidate.tag) &&
57
+ typeof candidate.timestamp === "string" && CANONICAL_UTC_TIMESTAMP_PATTERN.test(candidate.timestamp) &&
58
+ candidate.causationId === metadata?.causationId &&
59
+ candidate.correlationId === metadata?.correlationId &&
60
+ candidate.executedUser === metadata?.executedUser &&
61
+ typeof candidate.enqueuedAt === "number" && Number.isSafeInteger(candidate.enqueuedAt) &&
62
+ candidate.provenance === "g32" &&
63
+ isCompletenessFacts(candidate.completeness, candidate);
64
+ }
@@ -0,0 +1,30 @@
1
+ import { type CanonicalEventIdentity } from "@sekiban/dcb-core";
2
+ import type { DeliverySource } from "./downstream/types";
3
+ /** G32 has one durable delivery format; legacy lanes are deliberately gone. */
4
+ export type EventProvenance = "g32";
5
+ export type DeliveryProvenance = "g32";
6
+ export declare class DeliveryIdentityError extends Error {
7
+ readonly code: string;
8
+ readonly retryable = false;
9
+ constructor(message: string);
10
+ }
11
+ export declare class MissingCanonicalEventIdentityError extends DeliveryIdentityError {
12
+ readonly code: "MISSING_CANONICAL_EVENT_IDENTITY";
13
+ constructor(source: DeliverySource);
14
+ }
15
+ export interface ResolvedDeliveryIdentity extends CanonicalEventIdentity {
16
+ readonly provenance: "g32";
17
+ /** Compatibility shape only; it is always false for an admitted G32 row. */
18
+ readonly legacy: false;
19
+ }
20
+ export declare function canonicalEventType(eventPayloadName: string): string;
21
+ /**
22
+ * Resolve identity at the delivery admission boundary. A G32 delivery has a
23
+ * durable EventType equal to eventPayloadName; no payload discriminator or
24
+ * historical compatibility lane is permitted.
25
+ */
26
+ export declare function resolveDeliveryIdentity(message: {
27
+ readonly eventType?: string;
28
+ readonly provenance?: DeliveryProvenance | EventProvenance;
29
+ }, source: DeliverySource): ResolvedDeliveryIdentity;
30
+ export declare function assertCanonicalEventType(value: string): CanonicalEventIdentity;
@@ -0,0 +1,49 @@
1
+ import { canonicalEventKey, parseCanonicalEventKey } from "@sekiban/dcb-core";
2
+ export class DeliveryIdentityError extends Error {
3
+ code = "DELIVERY_IDENTITY_INVALID";
4
+ retryable = false;
5
+ constructor(message) {
6
+ super(message);
7
+ this.name = "DeliveryIdentityError";
8
+ }
9
+ }
10
+ export class MissingCanonicalEventIdentityError extends DeliveryIdentityError {
11
+ code = "MISSING_CANONICAL_EVENT_IDENTITY";
12
+ constructor(source) {
13
+ super(`G32 ${source} delivery is missing canonical event identity`);
14
+ this.name = "MissingCanonicalEventIdentityError";
15
+ }
16
+ }
17
+ export function canonicalEventType(eventPayloadName) {
18
+ return canonicalEventKey(eventPayloadName);
19
+ }
20
+ function provenanceFrom(value) {
21
+ if (value === undefined)
22
+ return undefined;
23
+ if (value === "g32")
24
+ return value;
25
+ throw new DeliveryIdentityError("Unknown event identity provenance");
26
+ }
27
+ /**
28
+ * Resolve identity at the delivery admission boundary. A G32 delivery has a
29
+ * durable EventType equal to eventPayloadName; no payload discriminator or
30
+ * historical compatibility lane is permitted.
31
+ */
32
+ export function resolveDeliveryIdentity(message, source) {
33
+ const provenance = provenanceFrom(message.provenance);
34
+ if (message.eventType === undefined) {
35
+ throw new MissingCanonicalEventIdentityError(source);
36
+ }
37
+ const identity = parseCanonicalEventKey(message.eventType);
38
+ if (provenance !== "g32") {
39
+ throw new DeliveryIdentityError("G32 delivery provenance is required");
40
+ }
41
+ return {
42
+ ...identity,
43
+ provenance: "g32",
44
+ legacy: false,
45
+ };
46
+ }
47
+ export function assertCanonicalEventType(value) {
48
+ return parseCanonicalEventKey(value);
49
+ }
@@ -0,0 +1,26 @@
1
+ /** C# serialized-path constants used by every G32 logical event record. */
2
+ export declare const SERIALIZED_COMMIT_CORRELATION_ID: "SerializedCommit";
3
+ export declare const SERIALIZED_SEKIBAN_EXECUTOR: "SerializedSekibanExecutor";
4
+ /**
5
+ * UTC text accepted by the C# provider models. DateTime has seven tick
6
+ * digits, but its JSON serializer legitimately elides trailing zeroes; the
7
+ * durable interchange therefore permits one through seven fractional digits.
8
+ * TS-authored writes continue to use the millisecond spelling from
9
+ * writeTimestampUtc.
10
+ */
11
+ export declare const CANONICAL_UTC_TIMESTAMP_PATTERN: RegExp;
12
+ export interface SerializedEventMetadata {
13
+ readonly causationId: string;
14
+ readonly correlationId: typeof SERIALIZED_COMMIT_CORRELATION_ID;
15
+ readonly executedUser: typeof SERIALIZED_SEKIBAN_EXECUTOR;
16
+ }
17
+ export declare function serializedEventMetadata(eventId: string): SerializedEventMetadata;
18
+ /**
19
+ * UUID version 7 following the RFC 9562 layout used by Guid.CreateVersion7:
20
+ * 48 bits Unix milliseconds, version 7, RFC4122 variant, then crypto bits.
21
+ */
22
+ export declare function createUuidV7(nowMs?: number): string;
23
+ export declare function isRfc4122Uuid(value: unknown): value is string;
24
+ export declare function isUuidV7(value: unknown): value is string;
25
+ /** ISO-8601 UTC spelling required by D1's logical C# record. */
26
+ export declare function writeTimestampUtc(nowMs?: number): string;
@@ -0,0 +1,53 @@
1
+ /** C# serialized-path constants used by every G32 logical event record. */
2
+ export const SERIALIZED_COMMIT_CORRELATION_ID = "SerializedCommit";
3
+ export const SERIALIZED_SEKIBAN_EXECUTOR = "SerializedSekibanExecutor";
4
+ /**
5
+ * UTC text accepted by the C# provider models. DateTime has seven tick
6
+ * digits, but its JSON serializer legitimately elides trailing zeroes; the
7
+ * durable interchange therefore permits one through seven fractional digits.
8
+ * TS-authored writes continue to use the millisecond spelling from
9
+ * writeTimestampUtc.
10
+ */
11
+ export const CANONICAL_UTC_TIMESTAMP_PATTERN = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{1,7}Z$/;
12
+ export function serializedEventMetadata(eventId) {
13
+ return Object.freeze({
14
+ causationId: eventId,
15
+ correlationId: SERIALIZED_COMMIT_CORRELATION_ID,
16
+ executedUser: SERIALIZED_SEKIBAN_EXECUTOR,
17
+ });
18
+ }
19
+ /**
20
+ * UUID version 7 following the RFC 9562 layout used by Guid.CreateVersion7:
21
+ * 48 bits Unix milliseconds, version 7, RFC4122 variant, then crypto bits.
22
+ */
23
+ export function createUuidV7(nowMs = Date.now()) {
24
+ if (!Number.isSafeInteger(nowMs) || nowMs < 0 || nowMs > 0xffff_ffff_ffff) {
25
+ throw new Error("UUIDv7 time must be a non-negative 48-bit safe integer");
26
+ }
27
+ if (typeof globalThis.crypto?.getRandomValues !== "function") {
28
+ throw new Error("crypto.getRandomValues is required for UUIDv7");
29
+ }
30
+ const bytes = new Uint8Array(16);
31
+ globalThis.crypto.getRandomValues(bytes);
32
+ let time = BigInt(nowMs);
33
+ for (let index = 5; index >= 0; index -= 1) {
34
+ bytes[index] = Number(time & 0xffn);
35
+ time >>= 8n;
36
+ }
37
+ bytes[6] = (bytes[6] & 0x0f) | 0x70;
38
+ bytes[8] = (bytes[8] & 0x3f) | 0x80;
39
+ const hex = [...bytes].map((value) => value.toString(16).padStart(2, "0")).join("");
40
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
41
+ }
42
+ export function isRfc4122Uuid(value) {
43
+ return typeof value === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
44
+ }
45
+ export function isUuidV7(value) {
46
+ return typeof value === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(value);
47
+ }
48
+ /** ISO-8601 UTC spelling required by D1's logical C# record. */
49
+ export function writeTimestampUtc(nowMs = Date.now()) {
50
+ if (!Number.isSafeInteger(nowMs) || nowMs < 0)
51
+ throw new Error("Write timestamp requires a non-negative safe Unix millisecond value");
52
+ return new Date(nowMs).toISOString();
53
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Node-safe contract entrypoint for SDT-G42's external probe runner.
3
+ *
4
+ * The primary Worker imports the same source through `cloudflare.ts`; this
5
+ * narrow entrypoint intentionally does not compose the Cloudflare runtime, so
6
+ * the pre-run runner and checker can execute under ordinary Node without
7
+ * resolving `cloudflare:workers`.
8
+ */
9
+ export { G42_JOURNAL_PROBE_PATH, G42_JOURNAL_PROBE_SCHEMA, } from "./journal/JournalFirstTouchProbe";
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Node-safe contract entrypoint for SDT-G42's external probe runner.
3
+ *
4
+ * The primary Worker imports the same source through `cloudflare.ts`; this
5
+ * narrow entrypoint intentionally does not compose the Cloudflare runtime, so
6
+ * the pre-run runner and checker can execute under ordinary Node without
7
+ * resolving `cloudflare:workers`.
8
+ */
9
+ export { G42_JOURNAL_PROBE_PATH, G42_JOURNAL_PROBE_SCHEMA, } from "./journal/JournalFirstTouchProbe";
@@ -0,0 +1,58 @@
1
+ import { type ProjectorRegistry } from "../projection/ProjectorRegistry";
2
+ import { type ProjectedQueryEntry, type QueryBacking, type MaterializedViewQueryPort, type QueryProjectionStore } from "../query/ProjectionQueryStore";
3
+ import { type QueryRegistry } from "../query/QueryRegistry";
4
+ import type { StoreProvider } from "../store/provider";
5
+ import { type ServiceIdentityProvider } from "../service/ServiceIdentityProvider";
6
+ export interface QueryWorkerEnv {
7
+ POSTGRES_URL?: string;
8
+ HYPERDRIVE?: Hyperdrive;
9
+ /** Optional explicit D1 provider binding; Postgres remains the default. */
10
+ D1?: D1Database;
11
+ /** Set only by an authenticated deployment-verification lane. */
12
+ G11_VERIFICATION_ENABLED?: string;
13
+ /** Non-secret service identity configured per deployment. */
14
+ SDT_SERVICE_ID?: string;
15
+ /** Separate D1 binding for row-backed materialized-view queries. */
16
+ D1_MV?: D1Database;
17
+ }
18
+ export interface QueryExecutionOptions {
19
+ /** A read-only fake store keeps wait and paging tests deterministic. */
20
+ store?: QueryProjectionStore;
21
+ storeProvider?: StoreProvider;
22
+ registry?: QueryRegistry;
23
+ projectors?: ProjectorRegistry;
24
+ /** Deploy-time query backing; request data can never select this value. */
25
+ queryBacking?: QueryBacking;
26
+ /** Optional injected port for tests or an explicitly composed runtime. */
27
+ materializedViewQueryPort?: MaterializedViewQueryPort;
28
+ now?: () => number;
29
+ sleep?: (milliseconds: number) => Promise<void>;
30
+ pollIntervalMs?: number;
31
+ /** Internal observation only; invoked without awaiting or changing the V1 response. */
32
+ afterUnsafeRead?: (input: {
33
+ readonly serviceId: string;
34
+ readonly viewId: string;
35
+ readonly entries: readonly ProjectedQueryEntry[];
36
+ readonly observedAt: number;
37
+ }) => void;
38
+ /** Host/deployment identity seam; defaults to envServiceIdentity. */
39
+ serviceIdentityProvider?: ServiceIdentityProvider;
40
+ }
41
+ /**
42
+ * G31 reserves a final loop slot so a healthy pending 120s waiter does not
43
+ * stop polling before its absolute deadline: 126 loop slots / at most 126
44
+ * source+MV probes plus one final confirmation. Backoff is 25, 50, 100, 200,
45
+ * 400, 800, then 1000ms. A normal pending waiter therefore makes 26 paired
46
+ * probes at the 20s floor and 126 at the 120s ceiling; a mandatory
47
+ * final-success recheck raises the global maximum to 127 paired probes / 254
48
+ * point-read statements. The cap
49
+ * also makes a stalled test clock deterministic instead of issuing unbounded
50
+ * reads.
51
+ */
52
+ export declare const D1_WAIT_MAX_ITERATIONS = 126;
53
+ export declare const D1_WAIT_MAX_POINT_READS = 254;
54
+ /**
55
+ * V1 §5.4/§5.5 HTTP surface. It never starts a projection catch-up or writes
56
+ * a source/checkpoint row: the query sees only the durable read-side snapshot.
57
+ */
58
+ export declare function handleSerializedQuery(request: Request, env: QueryWorkerEnv, options?: QueryExecutionOptions): Promise<Response>;