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