@crvouga/mockingbird-service-sqs 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/server.d.ts CHANGED
@@ -1,5 +1,124 @@
1
1
  import { Server } from 'node:http';
2
2
 
3
+ /** Bind values accepted by Mockingbird's SQLite port (matches sqlite-mem / better-sqlite3). */
4
+ type SqliteValue$2 = null | number | bigint | string | Uint8Array | boolean;
5
+ /** Mutation counters returned by {@link SqliteStatement.run}. */
6
+ type SqliteRunResult$2 = {
7
+ changes: number;
8
+ lastInsertRowid: number | bigint;
9
+ };
10
+ /**
11
+ * Prepared statement bound to a {@link SqliteClient}.
12
+ *
13
+ * Pass bind values as rest arguments on each call (no sticky `bind()`).
14
+ */
15
+ interface SqliteStatement$2 {
16
+ run(...params: SqliteValue$2[]): SqliteRunResult$2;
17
+ all<T = Record<string, unknown>>(...params: SqliteValue$2[]): T[];
18
+ get<T = Record<string, unknown>>(...params: SqliteValue$2[]): T | undefined;
19
+ }
20
+ /**
21
+ * Sync SQLite client port owned by Mockingbird.
22
+ *
23
+ * Duck-typed so `@crvouga/mockingbird-service-sqlite` `Database`, better-sqlite3, and wrapped
24
+ * `bun:sqlite` instances all work when they expose this surface.
25
+ */
26
+ interface SqliteClient$2 {
27
+ exec(sql: string): void;
28
+ prepare(sql: string): SqliteStatement$2;
29
+ transaction<T>(fn: () => T): T;
30
+ }
31
+
32
+ /** A stable identifier for a point in a {@link Timeline}. */
33
+ type CheckpointId$1 = string;
34
+ /** An immutable node in a timeline's checkpoint DAG. */
35
+ type Checkpoint$1<T> = Readonly<{
36
+ id: CheckpointId$1;
37
+ branch: string;
38
+ parent: CheckpointId$1 | null;
39
+ /** Logical time supplied by the timeline's injected clock. */
40
+ at: number;
41
+ value: T;
42
+ }>;
43
+ type TimelineOptions$1 = {
44
+ /** Logical clock used to stamp checkpoints. Defaults to a deterministic counter. */
45
+ now?: () => number;
46
+ /** Maximum retained checkpoints. Branch heads are never collected. Default 1,000. */
47
+ maxCheckpoints?: number;
48
+ /** Customize deterministic checkpoint IDs. */
49
+ id?: (sequence: number) => CheckpointId$1;
50
+ };
51
+ type CommitOptions$1 = {
52
+ branch?: string;
53
+ /** Parent checkpoint. Defaults to the selected branch's current head. */
54
+ parent?: CheckpointId$1 | null;
55
+ };
56
+ type ForkOptions$1 = {
57
+ /** Checkpoint to fork from. Defaults to the main branch's head. */
58
+ from?: CheckpointId$1;
59
+ };
60
+ /**
61
+ * Small, storage-agnostic checkpoint DAG shared by service runtimes. Its values may be immutable
62
+ * records, namespace images, or copy-on-write SQL engine snapshots.
63
+ *
64
+ * Values are retained by reference. Engines can therefore use persistent/COW snapshots while
65
+ * simpler services can use immutable values. IDs and GC order are deterministic, and all IO
66
+ * (the logical clock) is injected.
67
+ */
68
+ declare class Timeline$1<T> {
69
+ readonly maxCheckpoints: number;
70
+ private readonly now;
71
+ private readonly makeId;
72
+ private readonly nodes;
73
+ private readonly heads;
74
+ /** Unreferenced nodes in the exact order they became collectible. */
75
+ private readonly evictable;
76
+ /** Branch heads plus explicit retainers. Absent means zero. */
77
+ private readonly references;
78
+ private readonly explicitPins;
79
+ private sequence;
80
+ constructor(options?: TimelineOptions$1);
81
+ /** Capture a new immutable value and move `branch` to it. */
82
+ commit(value: T, options?: CommitOptions$1): Checkpoint$1<T>;
83
+ /** Create a branch pointer without copying its checkpoint value. */
84
+ fork(branch: string, options?: ForkOptions$1): Checkpoint$1<T> | undefined;
85
+ /** Move a branch pointer to an existing checkpoint. */
86
+ checkout(branch: string, id: CheckpointId$1): Checkpoint$1<T>;
87
+ get(id: CheckpointId$1): Checkpoint$1<T>;
88
+ head(branch?: string): Checkpoint$1<T> | undefined;
89
+ hasBranch(branch: string): boolean;
90
+ branches(): Readonly<Record<string, CheckpointId$1>>;
91
+ checkpoints(): readonly Checkpoint$1<T>[];
92
+ /** Number of retained checkpoints without allocating an array. */
93
+ get size(): number;
94
+ /** Pin a checkpoint independently of branch heads (used by compatibility snapshot handles). */
95
+ retain(id: CheckpointId$1): Checkpoint$1<T>;
96
+ /** Release one explicit pin. Branch heads remain pinned until moved or deleted. */
97
+ release(id: CheckpointId$1): boolean;
98
+ deleteBranch(branch: string): boolean;
99
+ /**
100
+ * Deterministically discard oldest unpinned checkpoints. Collection is O(number removed):
101
+ * commits never scan pinned nodes or the retained history. Parents are metadata rather than a
102
+ * storage dependency, so a retained node remains usable after pruning.
103
+ */
104
+ gc(max?: number): CheckpointId$1[];
105
+ private collect;
106
+ private moveHead;
107
+ private addReference;
108
+ private removeReference;
109
+ private assertBranch;
110
+ }
111
+
112
+ /**
113
+ * Anything that can answer a Fetch `Request` with a `Response`.
114
+ *
115
+ * Every Mockingbird service implements this, and every runtime adapter consumes it.
116
+ * It is the only contract shared across the whole graph.
117
+ */
118
+ interface FetchAPI$1 {
119
+ fetch(request: Request): Promise<Response>;
120
+ }
121
+
3
122
  /**
4
123
  * The single source of time for a service.
5
124
  *
@@ -30,35 +149,6 @@ type Clock$1 = {
30
149
  state(): ClockState$1;
31
150
  };
32
151
 
33
- /** Bind values accepted by Mockingbird's SQLite port (matches sqlite-mem / better-sqlite3). */
34
- type SqliteValue$2 = null | number | bigint | string | Uint8Array | boolean;
35
- /** Mutation counters returned by {@link SqliteStatement.run}. */
36
- type SqliteRunResult$2 = {
37
- changes: number;
38
- lastInsertRowid: number | bigint;
39
- };
40
- /**
41
- * Prepared statement bound to a {@link SqliteClient}.
42
- *
43
- * Pass bind values as rest arguments on each call (no sticky `bind()`).
44
- */
45
- interface SqliteStatement$2 {
46
- run(...params: SqliteValue$2[]): SqliteRunResult$2;
47
- all<T = Record<string, unknown>>(...params: SqliteValue$2[]): T[];
48
- get<T = Record<string, unknown>>(...params: SqliteValue$2[]): T | undefined;
49
- }
50
- /**
51
- * Sync SQLite client port owned by Mockingbird.
52
- *
53
- * Duck-typed so `@crvouga/mockingbird-service-sqlite` `Database`, better-sqlite3, and wrapped
54
- * `bun:sqlite` instances all work when they expose this surface.
55
- */
56
- interface SqliteClient$2 {
57
- exec(sql: string): void;
58
- prepare(sql: string): SqliteStatement$2;
59
- transaction<T>(fn: () => T): T;
60
- }
61
-
62
152
  /**
63
153
  * Seeded pseudo-random numbers, so anything a mock invents — ids, jitter, which
64
154
  * request a percentage fault hits — is reproducible from a seed.
@@ -186,96 +276,6 @@ type FaultRegistry$1 = {
186
276
  take(candidate: FaultCandidate$1): Promise<FaultHit$1[]>;
187
277
  };
188
278
 
189
- /** A stable identifier for a point in a {@link Timeline}. */
190
- type CheckpointId$1 = string;
191
- /** An immutable node in a timeline's checkpoint DAG. */
192
- type Checkpoint$1<T> = Readonly<{
193
- id: CheckpointId$1;
194
- branch: string;
195
- parent: CheckpointId$1 | null;
196
- /** Logical time supplied by the timeline's injected clock. */
197
- at: number;
198
- value: T;
199
- }>;
200
- type TimelineOptions$1 = {
201
- /** Logical clock used to stamp checkpoints. Defaults to a deterministic counter. */
202
- now?: () => number;
203
- /** Maximum retained checkpoints. Branch heads are never collected. Default 1,000. */
204
- maxCheckpoints?: number;
205
- /** Customize deterministic checkpoint IDs. */
206
- id?: (sequence: number) => CheckpointId$1;
207
- };
208
- type CommitOptions$1 = {
209
- branch?: string;
210
- /** Parent checkpoint. Defaults to the selected branch's current head. */
211
- parent?: CheckpointId$1 | null;
212
- };
213
- type ForkOptions$1 = {
214
- /** Checkpoint to fork from. Defaults to the main branch's head. */
215
- from?: CheckpointId$1;
216
- };
217
- /**
218
- * Small, storage-agnostic checkpoint DAG shared by service runtimes. Its values may be immutable
219
- * records, namespace images, or copy-on-write SQL engine snapshots.
220
- *
221
- * Values are retained by reference. Engines can therefore use persistent/COW snapshots while
222
- * simpler services can use immutable values. IDs and GC order are deterministic, and all IO
223
- * (the logical clock) is injected.
224
- */
225
- declare class Timeline$1<T> {
226
- readonly maxCheckpoints: number;
227
- private readonly now;
228
- private readonly makeId;
229
- private readonly nodes;
230
- private readonly heads;
231
- /** Unreferenced nodes in the exact order they became collectible. */
232
- private readonly evictable;
233
- /** Branch heads plus explicit retainers. Absent means zero. */
234
- private readonly references;
235
- private readonly explicitPins;
236
- private sequence;
237
- constructor(options?: TimelineOptions$1);
238
- /** Capture a new immutable value and move `branch` to it. */
239
- commit(value: T, options?: CommitOptions$1): Checkpoint$1<T>;
240
- /** Create a branch pointer without copying its checkpoint value. */
241
- fork(branch: string, options?: ForkOptions$1): Checkpoint$1<T> | undefined;
242
- /** Move a branch pointer to an existing checkpoint. */
243
- checkout(branch: string, id: CheckpointId$1): Checkpoint$1<T>;
244
- get(id: CheckpointId$1): Checkpoint$1<T>;
245
- head(branch?: string): Checkpoint$1<T> | undefined;
246
- hasBranch(branch: string): boolean;
247
- branches(): Readonly<Record<string, CheckpointId$1>>;
248
- checkpoints(): readonly Checkpoint$1<T>[];
249
- /** Number of retained checkpoints without allocating an array. */
250
- get size(): number;
251
- /** Pin a checkpoint independently of branch heads (used by compatibility snapshot handles). */
252
- retain(id: CheckpointId$1): Checkpoint$1<T>;
253
- /** Release one explicit pin. Branch heads remain pinned until moved or deleted. */
254
- release(id: CheckpointId$1): boolean;
255
- deleteBranch(branch: string): boolean;
256
- /**
257
- * Deterministically discard oldest unpinned checkpoints. Collection is O(number removed):
258
- * commits never scan pinned nodes or the retained history. Parents are metadata rather than a
259
- * storage dependency, so a retained node remains usable after pruning.
260
- */
261
- gc(max?: number): CheckpointId$1[];
262
- private collect;
263
- private moveHead;
264
- private addReference;
265
- private removeReference;
266
- private assertBranch;
267
- }
268
-
269
- /**
270
- * Anything that can answer a Fetch `Request` with a `Response`.
271
- *
272
- * Every Mockingbird service implements this, and every runtime adapter consumes it.
273
- * It is the only contract shared across the whole graph.
274
- */
275
- interface FetchAPI$1 {
276
- fetch(request: Request): Promise<Response>;
277
- }
278
-
279
279
  /**
280
280
  * One problem with a request body, at a dotted path (`patient.address.city`, `items.0.sku`).
281
281
  * `kind` is `media_type` when the body is present but its media type is not one the operation
@@ -317,6 +317,10 @@ type RequestLog$1 = {
317
317
  ids?: Record<string, string>;
318
318
  /** Set when the service created a resource the request referred to but that did not exist. */
319
319
  adopted?: boolean;
320
+ /** Explicit durable acceptance, independent of response delivery. */
321
+ accepted?: boolean;
322
+ /** Checkpoint captured at explicit acceptance. */
323
+ checkpoint?: string;
320
324
  /** Set on a rejection (status ≥ 400) the mock produced itself, never on a scripted fault. */
321
325
  request?: RejectedRequest$1;
322
326
  /** The validation issues behind a rejection, when the service found any. */
@@ -583,35 +587,221 @@ type Listening = {
583
587
  close(): Promise<void>;
584
588
  };
585
589
 
586
- type CliOption = {
587
- type: "string" | "boolean";
588
- description: string;
589
- /** Shown in help; the value placeholder, e.g. `<port>`. */
590
- value?: string;
591
- default?: string | boolean;
592
- };
593
- type CliValues = Record<string, string | boolean | undefined>;
594
- type CommonServeOptions = {
595
- adminPrefix?: string;
596
- adminKey: string | undefined;
597
- seed: string | undefined;
598
- onLog: ((entry: RequestLog$1) => void) | undefined;
599
- };
590
+ type CliOption = {
591
+ type: "string" | "boolean";
592
+ description: string;
593
+ /** Shown in help; the value placeholder, e.g. `<port>`. */
594
+ value?: string;
595
+ default?: string | boolean;
596
+ };
597
+ type CliValues = Record<string, string | boolean | undefined>;
598
+ type CommonServeOptions = {
599
+ adminPrefix?: string;
600
+ adminKey: string | undefined;
601
+ seed: string | undefined;
602
+ onLog: ((entry: RequestLog$1) => void) | undefined;
603
+ };
604
+ /**
605
+ * What a service contributes to `serve`: how to build its runtime from CLI flags,
606
+ * and what to say at startup. Every service's `./server` entry exports one as
607
+ * `serveTarget`, which is also how `serve --config` finds services by name.
608
+ */
609
+ type ServeTarget = {
610
+ name: string;
611
+ defaultPort: number;
612
+ /** Serve flags beyond the common ones. */
613
+ options?: Record<string, CliOption>;
614
+ create(values: CliValues, common: CommonServeOptions): Promise<ServiceRuntime$1<ServiceInstance$1>> | ServiceRuntime$1<ServiceInstance$1>;
615
+ /** Startup lines after the listen address, e.g. the loaded corpus version. */
616
+ banner?(runtime: ServiceRuntime$1<ServiceInstance$1>): string[];
617
+ /** After the HTTP server is bound. A service that speaks more than HTTP attaches it here. */
618
+ listening?(server: Listening): void;
619
+ };
620
+
621
+ /** Bind values accepted by Mockingbird's SQLite port (matches sqlite-mem / better-sqlite3). */
622
+ type SqliteValue$1 = null | number | bigint | string | Uint8Array | boolean;
623
+ /** Mutation counters returned by {@link SqliteStatement.run}. */
624
+ type SqliteRunResult$1 = {
625
+ changes: number;
626
+ lastInsertRowid: number | bigint;
627
+ };
628
+ /**
629
+ * Prepared statement bound to a {@link SqliteClient}.
630
+ *
631
+ * Pass bind values as rest arguments on each call (no sticky `bind()`).
632
+ */
633
+ interface SqliteStatement$1 {
634
+ run(...params: SqliteValue$1[]): SqliteRunResult$1;
635
+ all<T = Record<string, unknown>>(...params: SqliteValue$1[]): T[];
636
+ get<T = Record<string, unknown>>(...params: SqliteValue$1[]): T | undefined;
637
+ }
638
+ /**
639
+ * Sync SQLite client port owned by Mockingbird.
640
+ *
641
+ * Duck-typed so `@crvouga/mockingbird-service-sqlite` `Database`, better-sqlite3, and wrapped
642
+ * `bun:sqlite` instances all work when they expose this surface.
643
+ */
644
+ interface SqliteClient$1 {
645
+ exec(sql: string): void;
646
+ prepare(sql: string): SqliteStatement$1;
647
+ transaction<T>(fn: () => T): T;
648
+ }
649
+
650
+ /** Every stored record carries a monotonically increasing sequence for stable ordering. */
651
+ type Stored<T> = {
652
+ seq: number;
653
+ value: T;
654
+ };
655
+ type ListRecordsOptions<T> = {
656
+ /** Keep only records passing the predicate. */
657
+ where?: (value: T, seq: number) => boolean;
658
+ /** Sort order; default newest first. */
659
+ order?: "newest" | "oldest";
660
+ };
661
+ /**
662
+ * A SQLite-backed table of JSON records addressed by id. Ordering is by insertion
663
+ * sequence, never by id lexicographic order, so list semantics stay stable.
664
+ */
665
+ declare class Collection<T> {
666
+ private readonly sqlite;
667
+ /** Storage namespace. Admin introspection uses this to ignore another namespace's tables. */
668
+ readonly namespace: string;
669
+ /** Table name inside the namespace. Stable across resets of the rows themselves. */
670
+ readonly collectionName: string;
671
+ constructor(sqlite: SqliteClient$1,
672
+ /** Storage namespace. Admin introspection uses this to ignore another namespace's tables. */
673
+ namespace: string,
674
+ /** Table name inside the namespace. Stable across resets of the rows themselves. */
675
+ collectionName: string);
676
+ private bumpCollectionSeq;
677
+ nextSequence(): number;
678
+ get(id: string): T | undefined;
679
+ has(id: string): boolean;
680
+ /** Insert a new record, assigning it the next sequence number. */
681
+ insert(id: string, value: T): Stored<T>;
682
+ /** Replace an existing record's value, keeping its position. */
683
+ update(id: string, value: T): Stored<T> | undefined;
684
+ delete(id: string): boolean;
685
+ /** How many records the collection holds, without reading them. */
686
+ count(): number;
687
+ list(options?: ListRecordsOptions<T>): Array<Stored<T> & {
688
+ id: string;
689
+ }>;
690
+ }
691
+
692
+ /**
693
+ * Sequential id source persisted in SQLite. Ids are deterministic for a given
694
+ * sequence history (`cus_` + 14 opaque chars), so reproductions stay stable.
695
+ */
696
+ declare class IdSequence {
697
+ private readonly sqlite;
698
+ private readonly namespace;
699
+ private readonly salt;
700
+ constructor(sqlite: SqliteClient$1, namespace: string, salt?: string);
701
+ next(prefix: string, length?: number): string;
702
+ }
703
+
704
+ /** A stable identifier for a point in a {@link Timeline}. */
705
+ type CheckpointId = string;
706
+ /** An immutable node in a timeline's checkpoint DAG. */
707
+ type Checkpoint<T> = Readonly<{
708
+ id: CheckpointId;
709
+ branch: string;
710
+ parent: CheckpointId | null;
711
+ /** Logical time supplied by the timeline's injected clock. */
712
+ at: number;
713
+ value: T;
714
+ }>;
715
+ type TimelineOptions = {
716
+ /** Logical clock used to stamp checkpoints. Defaults to a deterministic counter. */
717
+ now?: () => number;
718
+ /** Maximum retained checkpoints. Branch heads are never collected. Default 1,000. */
719
+ maxCheckpoints?: number;
720
+ /** Customize deterministic checkpoint IDs. */
721
+ id?: (sequence: number) => CheckpointId;
722
+ };
723
+ type CommitOptions = {
724
+ branch?: string;
725
+ /** Parent checkpoint. Defaults to the selected branch's current head. */
726
+ parent?: CheckpointId | null;
727
+ };
728
+ type ForkOptions = {
729
+ /** Checkpoint to fork from. Defaults to the main branch's head. */
730
+ from?: CheckpointId;
731
+ };
732
+ /**
733
+ * Small, storage-agnostic checkpoint DAG shared by service runtimes. Its values may be immutable
734
+ * records, namespace images, or copy-on-write SQL engine snapshots.
735
+ *
736
+ * Values are retained by reference. Engines can therefore use persistent/COW snapshots while
737
+ * simpler services can use immutable values. IDs and GC order are deterministic, and all IO
738
+ * (the logical clock) is injected.
739
+ */
740
+ declare class Timeline<T> {
741
+ readonly maxCheckpoints: number;
742
+ private readonly now;
743
+ private readonly makeId;
744
+ private readonly nodes;
745
+ private readonly heads;
746
+ /** Unreferenced nodes in the exact order they became collectible. */
747
+ private readonly evictable;
748
+ /** Branch heads plus explicit retainers. Absent means zero. */
749
+ private readonly references;
750
+ private readonly explicitPins;
751
+ private sequence;
752
+ constructor(options?: TimelineOptions);
753
+ /** Capture a new immutable value and move `branch` to it. */
754
+ commit(value: T, options?: CommitOptions): Checkpoint<T>;
755
+ /** Create a branch pointer without copying its checkpoint value. */
756
+ fork(branch: string, options?: ForkOptions): Checkpoint<T> | undefined;
757
+ /** Move a branch pointer to an existing checkpoint. */
758
+ checkout(branch: string, id: CheckpointId): Checkpoint<T>;
759
+ get(id: CheckpointId): Checkpoint<T>;
760
+ head(branch?: string): Checkpoint<T> | undefined;
761
+ hasBranch(branch: string): boolean;
762
+ branches(): Readonly<Record<string, CheckpointId>>;
763
+ checkpoints(): readonly Checkpoint<T>[];
764
+ /** Number of retained checkpoints without allocating an array. */
765
+ get size(): number;
766
+ /** Pin a checkpoint independently of branch heads (used by compatibility snapshot handles). */
767
+ retain(id: CheckpointId): Checkpoint<T>;
768
+ /** Release one explicit pin. Branch heads remain pinned until moved or deleted. */
769
+ release(id: CheckpointId): boolean;
770
+ deleteBranch(branch: string): boolean;
771
+ /**
772
+ * Deterministically discard oldest unpinned checkpoints. Collection is O(number removed):
773
+ * commits never scan pinned nodes or the retained history. Parents are metadata rather than a
774
+ * storage dependency, so a retained node remains usable after pruning.
775
+ */
776
+ gc(max?: number): CheckpointId[];
777
+ private collect;
778
+ private moveHead;
779
+ private addReference;
780
+ private removeReference;
781
+ private assertBranch;
782
+ }
783
+
600
784
  /**
601
- * What a service contributes to `serve`: how to build its runtime from CLI flags,
602
- * and what to say at startup. Every service's `./server` entry exports one as
603
- * `serveTarget`, which is also how `serve --config` finds services by name.
785
+ * Anything that can answer a Fetch `Request` with a `Response`.
786
+ *
787
+ * Every Mockingbird service implements this, and every runtime adapter consumes it.
788
+ * It is the only contract shared across the whole graph.
604
789
  */
605
- type ServeTarget = {
606
- name: string;
607
- defaultPort: number;
608
- /** Serve flags beyond the common ones. */
609
- options?: Record<string, CliOption>;
610
- create(values: CliValues, common: CommonServeOptions): Promise<ServiceRuntime$1<ServiceInstance$1>> | ServiceRuntime$1<ServiceInstance$1>;
611
- /** Startup lines after the listen address, e.g. the loaded corpus version. */
612
- banner?(runtime: ServiceRuntime$1<ServiceInstance$1>): string[];
613
- /** After the HTTP server is bound. A service that speaks more than HTTP attaches it here. */
614
- listening?(server: Listening): void;
790
+ interface FetchAPI {
791
+ fetch(request: Request): Promise<Response>;
792
+ }
793
+
794
+ /** Options every provider constructor accepts. */
795
+ type APIOptions = {
796
+ /** Sync SQLite client. Defaults to `@crvouga/mockingbird-service-sqlite`. */
797
+ sqlite?: SqliteClient$1;
798
+ /** Clock used for `created`-style fields. Default `Date.now`. */
799
+ now?: () => number;
800
+ /**
801
+ * Storage namespace for this instance's records. Instances sharing one SQLite
802
+ * client stay isolated when their namespaces differ. Defaults to the service name.
803
+ */
804
+ namespace?: string;
615
805
  };
616
806
 
617
807
  /**
@@ -644,77 +834,6 @@ type Clock = {
644
834
  state(): ClockState;
645
835
  };
646
836
 
647
- /** Bind values accepted by Mockingbird's SQLite port (matches sqlite-mem / better-sqlite3). */
648
- type SqliteValue$1 = null | number | bigint | string | Uint8Array | boolean;
649
- /** Mutation counters returned by {@link SqliteStatement.run}. */
650
- type SqliteRunResult$1 = {
651
- changes: number;
652
- lastInsertRowid: number | bigint;
653
- };
654
- /**
655
- * Prepared statement bound to a {@link SqliteClient}.
656
- *
657
- * Pass bind values as rest arguments on each call (no sticky `bind()`).
658
- */
659
- interface SqliteStatement$1 {
660
- run(...params: SqliteValue$1[]): SqliteRunResult$1;
661
- all<T = Record<string, unknown>>(...params: SqliteValue$1[]): T[];
662
- get<T = Record<string, unknown>>(...params: SqliteValue$1[]): T | undefined;
663
- }
664
- /**
665
- * Sync SQLite client port owned by Mockingbird.
666
- *
667
- * Duck-typed so `@crvouga/mockingbird-service-sqlite` `Database`, better-sqlite3, and wrapped
668
- * `bun:sqlite` instances all work when they expose this surface.
669
- */
670
- interface SqliteClient$1 {
671
- exec(sql: string): void;
672
- prepare(sql: string): SqliteStatement$1;
673
- transaction<T>(fn: () => T): T;
674
- }
675
-
676
- /** Every stored record carries a monotonically increasing sequence for stable ordering. */
677
- type Stored<T> = {
678
- seq: number;
679
- value: T;
680
- };
681
- type ListRecordsOptions<T> = {
682
- /** Keep only records passing the predicate. */
683
- where?: (value: T, seq: number) => boolean;
684
- /** Sort order; default newest first. */
685
- order?: "newest" | "oldest";
686
- };
687
- /**
688
- * A SQLite-backed table of JSON records addressed by id. Ordering is by insertion
689
- * sequence, never by id lexicographic order, so list semantics stay stable.
690
- */
691
- declare class Collection<T> {
692
- private readonly sqlite;
693
- /** Storage namespace. Admin introspection uses this to ignore another namespace's tables. */
694
- readonly namespace: string;
695
- /** Table name inside the namespace. Stable across resets of the rows themselves. */
696
- readonly collectionName: string;
697
- constructor(sqlite: SqliteClient$1,
698
- /** Storage namespace. Admin introspection uses this to ignore another namespace's tables. */
699
- namespace: string,
700
- /** Table name inside the namespace. Stable across resets of the rows themselves. */
701
- collectionName: string);
702
- private bumpCollectionSeq;
703
- nextSequence(): number;
704
- get(id: string): T | undefined;
705
- has(id: string): boolean;
706
- /** Insert a new record, assigning it the next sequence number. */
707
- insert(id: string, value: T): Stored<T>;
708
- /** Replace an existing record's value, keeping its position. */
709
- update(id: string, value: T): Stored<T> | undefined;
710
- delete(id: string): boolean;
711
- /** How many records the collection holds, without reading them. */
712
- count(): number;
713
- list(options?: ListRecordsOptions<T>): Array<Stored<T> & {
714
- id: string;
715
- }>;
716
- }
717
-
718
837
  /**
719
838
  * Seeded pseudo-random numbers, so anything a mock invents — ids, jitter, which
720
839
  * request a percentage fault hits — is reproducible from a seed.
@@ -842,109 +961,6 @@ type FaultRegistry = {
842
961
  take(candidate: FaultCandidate): Promise<FaultHit[]>;
843
962
  };
844
963
 
845
- /** A stable identifier for a point in a {@link Timeline}. */
846
- type CheckpointId = string;
847
- /** An immutable node in a timeline's checkpoint DAG. */
848
- type Checkpoint<T> = Readonly<{
849
- id: CheckpointId;
850
- branch: string;
851
- parent: CheckpointId | null;
852
- /** Logical time supplied by the timeline's injected clock. */
853
- at: number;
854
- value: T;
855
- }>;
856
- type TimelineOptions = {
857
- /** Logical clock used to stamp checkpoints. Defaults to a deterministic counter. */
858
- now?: () => number;
859
- /** Maximum retained checkpoints. Branch heads are never collected. Default 1,000. */
860
- maxCheckpoints?: number;
861
- /** Customize deterministic checkpoint IDs. */
862
- id?: (sequence: number) => CheckpointId;
863
- };
864
- type CommitOptions = {
865
- branch?: string;
866
- /** Parent checkpoint. Defaults to the selected branch's current head. */
867
- parent?: CheckpointId | null;
868
- };
869
- type ForkOptions = {
870
- /** Checkpoint to fork from. Defaults to the main branch's head. */
871
- from?: CheckpointId;
872
- };
873
- /**
874
- * Small, storage-agnostic checkpoint DAG shared by service runtimes. Its values may be immutable
875
- * records, namespace images, or copy-on-write SQL engine snapshots.
876
- *
877
- * Values are retained by reference. Engines can therefore use persistent/COW snapshots while
878
- * simpler services can use immutable values. IDs and GC order are deterministic, and all IO
879
- * (the logical clock) is injected.
880
- */
881
- declare class Timeline<T> {
882
- readonly maxCheckpoints: number;
883
- private readonly now;
884
- private readonly makeId;
885
- private readonly nodes;
886
- private readonly heads;
887
- /** Unreferenced nodes in the exact order they became collectible. */
888
- private readonly evictable;
889
- /** Branch heads plus explicit retainers. Absent means zero. */
890
- private readonly references;
891
- private readonly explicitPins;
892
- private sequence;
893
- constructor(options?: TimelineOptions);
894
- /** Capture a new immutable value and move `branch` to it. */
895
- commit(value: T, options?: CommitOptions): Checkpoint<T>;
896
- /** Create a branch pointer without copying its checkpoint value. */
897
- fork(branch: string, options?: ForkOptions): Checkpoint<T> | undefined;
898
- /** Move a branch pointer to an existing checkpoint. */
899
- checkout(branch: string, id: CheckpointId): Checkpoint<T>;
900
- get(id: CheckpointId): Checkpoint<T>;
901
- head(branch?: string): Checkpoint<T> | undefined;
902
- hasBranch(branch: string): boolean;
903
- branches(): Readonly<Record<string, CheckpointId>>;
904
- checkpoints(): readonly Checkpoint<T>[];
905
- /** Number of retained checkpoints without allocating an array. */
906
- get size(): number;
907
- /** Pin a checkpoint independently of branch heads (used by compatibility snapshot handles). */
908
- retain(id: CheckpointId): Checkpoint<T>;
909
- /** Release one explicit pin. Branch heads remain pinned until moved or deleted. */
910
- release(id: CheckpointId): boolean;
911
- deleteBranch(branch: string): boolean;
912
- /**
913
- * Deterministically discard oldest unpinned checkpoints. Collection is O(number removed):
914
- * commits never scan pinned nodes or the retained history. Parents are metadata rather than a
915
- * storage dependency, so a retained node remains usable after pruning.
916
- */
917
- gc(max?: number): CheckpointId[];
918
- private collect;
919
- private moveHead;
920
- private addReference;
921
- private removeReference;
922
- private assertBranch;
923
- }
924
-
925
- /**
926
- * Anything that can answer a Fetch `Request` with a `Response`.
927
- *
928
- * Every Mockingbird service implements this, and every runtime adapter consumes it.
929
- * It is the only contract shared across the whole graph.
930
- */
931
- interface FetchAPI {
932
- fetch(request: Request): Promise<Response>;
933
- }
934
-
935
- /** Options every provider constructor accepts. */
936
- type APIOptions = {
937
- /** Sync SQLite client. Defaults to `@crvouga/mockingbird-service-sqlite`. */
938
- sqlite?: SqliteClient$1;
939
- /** Clock used for `created`-style fields. Default `Date.now`. */
940
- now?: () => number;
941
- /**
942
- * Storage namespace for this instance's records. Instances sharing one SQLite
943
- * client stay isolated when their namespaces differ. Defaults to the service name.
944
- */
945
- namespace?: string;
946
- };
947
-
948
964
  /**
949
965
  * One problem with a request body, at a dotted path (`patient.address.city`, `items.0.sku`).
950
966
  * `kind` is `media_type` when the body is present but its media type is not one the operation
@@ -986,6 +1002,10 @@ type RequestLog = {
986
1002
  ids?: Record<string, string>;
987
1003
  /** Set when the service created a resource the request referred to but that did not exist. */
988
1004
  adopted?: boolean;
1005
+ /** Explicit durable acceptance, independent of response delivery. */
1006
+ accepted?: boolean;
1007
+ /** Checkpoint captured at explicit acceptance. */
1008
+ checkpoint?: string;
989
1009
  /** Set on a rejection (status ≥ 400) the mock produced itself, never on a scripted fault. */
990
1010
  request?: RejectedRequest;
991
1011
  /** The validation issues behind a rejection, when the service found any. */
@@ -1049,18 +1069,6 @@ type CredentialRegistry = {
1049
1069
  }[];
1050
1070
  };
1051
1071
 
1052
- /**
1053
- * Sequential id source persisted in SQLite. Ids are deterministic for a given
1054
- * sequence history (`cus_` + 14 opaque chars), so reproductions stay stable.
1055
- */
1056
- declare class IdSequence {
1057
- private readonly sqlite;
1058
- private readonly namespace;
1059
- private readonly salt;
1060
- constructor(sqlite: SqliteClient$1, namespace: string, salt?: string);
1061
- next(prefix: string, length?: number): string;
1062
- }
1063
-
1064
1072
  /**
1065
1073
  * A point-in-time copy of everything a service namespace holds.
1066
1074
  *
@@ -1290,6 +1298,9 @@ type SqsQueue = {
1290
1298
  arn: string;
1291
1299
  attributes: Record<string, string>;
1292
1300
  createdAt: number;
1301
+ modifiedAt?: number;
1302
+ tags?: Record<string, string>;
1303
+ sequence?: number;
1293
1304
  lastPurgeAt?: number;
1294
1305
  };
1295
1306
  type SqsMessageAttribute = {
@@ -1317,6 +1328,8 @@ type SqsDeduplication = {
1317
1328
  id: string;
1318
1329
  messageId: string;
1319
1330
  expiresAt: number;
1331
+ md5?: string;
1332
+ sequenceNumber?: string;
1320
1333
  };
1321
1334
  declare class SqsState {
1322
1335
  readonly queues: Collection<SqsQueue>;
@@ -1354,11 +1367,13 @@ declare class SqsAPI {
1354
1367
  private queue;
1355
1368
  private attributes;
1356
1369
  enqueue(queue: SqsQueue, input: Input): Promise<{
1370
+ MD5OfMessageAttributes?: string;
1357
1371
  MessageId: string;
1358
1372
  MD5OfMessageBody: string;
1359
1373
  SequenceNumber: string | undefined;
1360
1374
  } | {
1361
1375
  SequenceNumber?: string;
1376
+ MD5OfMessageAttributes?: string;
1362
1377
  MessageId: string;
1363
1378
  MD5OfMessageBody: string;
1364
1379
  }>;
@@ -1366,6 +1381,13 @@ declare class SqsAPI {
1366
1381
  private receive;
1367
1382
  private byReceipt;
1368
1383
  fetch(request: Request): Promise<Response>;
1384
+ private receiptOperation;
1385
+ private expire;
1386
+ private validateAttributes;
1387
+ private validateBatch;
1388
+ private attributeSize;
1389
+ private attributeMd5;
1390
+ private selectedAttributes;
1369
1391
  }
1370
1392
 
1371
1393
  type SqsRuntimeOptions = {