@crvouga/mockingbird-service-plane 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/CHANGELOG.md +33 -4
- package/README.md +18 -1
- package/SUPPORT.md +8 -3
- package/dist/chunk-7ZEMJWNY.js +4139 -0
- package/dist/chunk-7ZEMJWNY.js.map +7 -0
- package/dist/{chunk-4RCG3YYZ.js → chunk-IBJ4UB3V.js} +2 -2
- package/dist/cli.js +2 -2
- package/dist/index.d.ts +203 -139
- package/dist/index.js +1 -1
- package/dist/server.d.ts +389 -321
- package/dist/server.js +2 -2
- package/openapi.yaml +445 -1
- package/package.json +2 -2
- package/dist/chunk-NSDJM2TL.js +0 -3781
- package/dist/chunk-NSDJM2TL.js.map +0 -7
- /package/dist/{chunk-4RCG3YYZ.js.map → chunk-IBJ4UB3V.js.map} +0 -0
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,209 @@ 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
|
+
/** A stable identifier for a point in a {@link Timeline}. */
|
|
694
|
+
type CheckpointId = string;
|
|
695
|
+
/** An immutable node in a timeline's checkpoint DAG. */
|
|
696
|
+
type Checkpoint<T> = Readonly<{
|
|
697
|
+
id: CheckpointId;
|
|
698
|
+
branch: string;
|
|
699
|
+
parent: CheckpointId | null;
|
|
700
|
+
/** Logical time supplied by the timeline's injected clock. */
|
|
701
|
+
at: number;
|
|
702
|
+
value: T;
|
|
703
|
+
}>;
|
|
704
|
+
type TimelineOptions = {
|
|
705
|
+
/** Logical clock used to stamp checkpoints. Defaults to a deterministic counter. */
|
|
706
|
+
now?: () => number;
|
|
707
|
+
/** Maximum retained checkpoints. Branch heads are never collected. Default 1,000. */
|
|
708
|
+
maxCheckpoints?: number;
|
|
709
|
+
/** Customize deterministic checkpoint IDs. */
|
|
710
|
+
id?: (sequence: number) => CheckpointId;
|
|
711
|
+
};
|
|
712
|
+
type CommitOptions = {
|
|
713
|
+
branch?: string;
|
|
714
|
+
/** Parent checkpoint. Defaults to the selected branch's current head. */
|
|
715
|
+
parent?: CheckpointId | null;
|
|
716
|
+
};
|
|
717
|
+
type ForkOptions = {
|
|
718
|
+
/** Checkpoint to fork from. Defaults to the main branch's head. */
|
|
719
|
+
from?: CheckpointId;
|
|
720
|
+
};
|
|
721
|
+
/**
|
|
722
|
+
* Small, storage-agnostic checkpoint DAG shared by service runtimes. Its values may be immutable
|
|
723
|
+
* records, namespace images, or copy-on-write SQL engine snapshots.
|
|
724
|
+
*
|
|
725
|
+
* Values are retained by reference. Engines can therefore use persistent/COW snapshots while
|
|
726
|
+
* simpler services can use immutable values. IDs and GC order are deterministic, and all IO
|
|
727
|
+
* (the logical clock) is injected.
|
|
728
|
+
*/
|
|
729
|
+
declare class Timeline<T> {
|
|
730
|
+
readonly maxCheckpoints: number;
|
|
731
|
+
private readonly now;
|
|
732
|
+
private readonly makeId;
|
|
733
|
+
private readonly nodes;
|
|
734
|
+
private readonly heads;
|
|
735
|
+
/** Unreferenced nodes in the exact order they became collectible. */
|
|
736
|
+
private readonly evictable;
|
|
737
|
+
/** Branch heads plus explicit retainers. Absent means zero. */
|
|
738
|
+
private readonly references;
|
|
739
|
+
private readonly explicitPins;
|
|
740
|
+
private sequence;
|
|
741
|
+
constructor(options?: TimelineOptions);
|
|
742
|
+
/** Capture a new immutable value and move `branch` to it. */
|
|
743
|
+
commit(value: T, options?: CommitOptions): Checkpoint<T>;
|
|
744
|
+
/** Create a branch pointer without copying its checkpoint value. */
|
|
745
|
+
fork(branch: string, options?: ForkOptions): Checkpoint<T> | undefined;
|
|
746
|
+
/** Move a branch pointer to an existing checkpoint. */
|
|
747
|
+
checkout(branch: string, id: CheckpointId): Checkpoint<T>;
|
|
748
|
+
get(id: CheckpointId): Checkpoint<T>;
|
|
749
|
+
head(branch?: string): Checkpoint<T> | undefined;
|
|
750
|
+
hasBranch(branch: string): boolean;
|
|
751
|
+
branches(): Readonly<Record<string, CheckpointId>>;
|
|
752
|
+
checkpoints(): readonly Checkpoint<T>[];
|
|
753
|
+
/** Number of retained checkpoints without allocating an array. */
|
|
754
|
+
get size(): number;
|
|
755
|
+
/** Pin a checkpoint independently of branch heads (used by compatibility snapshot handles). */
|
|
756
|
+
retain(id: CheckpointId): Checkpoint<T>;
|
|
757
|
+
/** Release one explicit pin. Branch heads remain pinned until moved or deleted. */
|
|
758
|
+
release(id: CheckpointId): boolean;
|
|
759
|
+
deleteBranch(branch: string): boolean;
|
|
760
|
+
/**
|
|
761
|
+
* Deterministically discard oldest unpinned checkpoints. Collection is O(number removed):
|
|
762
|
+
* commits never scan pinned nodes or the retained history. Parents are metadata rather than a
|
|
763
|
+
* storage dependency, so a retained node remains usable after pruning.
|
|
764
|
+
*/
|
|
765
|
+
gc(max?: number): CheckpointId[];
|
|
766
|
+
private collect;
|
|
767
|
+
private moveHead;
|
|
768
|
+
private addReference;
|
|
769
|
+
private removeReference;
|
|
770
|
+
private assertBranch;
|
|
771
|
+
}
|
|
772
|
+
|
|
601
773
|
/**
|
|
602
|
-
*
|
|
603
|
-
*
|
|
604
|
-
*
|
|
774
|
+
* Anything that can answer a Fetch `Request` with a `Response`.
|
|
775
|
+
*
|
|
776
|
+
* Every Mockingbird service implements this, and every runtime adapter consumes it.
|
|
777
|
+
* It is the only contract shared across the whole graph.
|
|
605
778
|
*/
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
/**
|
|
613
|
-
|
|
614
|
-
/**
|
|
615
|
-
|
|
779
|
+
interface FetchAPI$1 {
|
|
780
|
+
fetch(request: Request): Promise<Response>;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
/** Options every provider constructor accepts. */
|
|
784
|
+
type APIOptions = {
|
|
785
|
+
/** Sync SQLite client. Defaults to `@crvouga/mockingbird-service-sqlite`. */
|
|
786
|
+
sqlite?: SqliteClient$1;
|
|
787
|
+
/** Clock used for `created`-style fields. Default `Date.now`. */
|
|
788
|
+
now?: () => number;
|
|
789
|
+
/**
|
|
790
|
+
* Storage namespace for this instance's records. Instances sharing one SQLite
|
|
791
|
+
* client stay isolated when their namespaces differ. Defaults to the service name.
|
|
792
|
+
*/
|
|
793
|
+
namespace?: string;
|
|
616
794
|
};
|
|
617
795
|
|
|
618
796
|
/**
|
|
@@ -645,77 +823,6 @@ type Clock = {
|
|
|
645
823
|
state(): ClockState;
|
|
646
824
|
};
|
|
647
825
|
|
|
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
826
|
/**
|
|
720
827
|
* Seeded pseudo-random numbers, so anything a mock invents — ids, jitter, which
|
|
721
828
|
* request a percentage fault hits — is reproducible from a seed.
|
|
@@ -843,109 +950,6 @@ type FaultRegistry = {
|
|
|
843
950
|
take(candidate: FaultCandidate): Promise<FaultHit[]>;
|
|
844
951
|
};
|
|
845
952
|
|
|
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
953
|
/**
|
|
950
954
|
* One problem with a request body, at a dotted path (`patient.address.city`, `items.0.sku`).
|
|
951
955
|
* `kind` is `media_type` when the body is present but its media type is not one the operation
|
|
@@ -987,6 +991,10 @@ type RequestLog = {
|
|
|
987
991
|
ids?: Record<string, string>;
|
|
988
992
|
/** Set when the service created a resource the request referred to but that did not exist. */
|
|
989
993
|
adopted?: boolean;
|
|
994
|
+
/** Explicit durable acceptance, independent of response delivery. */
|
|
995
|
+
accepted?: boolean;
|
|
996
|
+
/** Checkpoint captured at explicit acceptance. */
|
|
997
|
+
checkpoint?: string;
|
|
990
998
|
/** Set on a rejection (status ≥ 400) the mock produced itself, never on a scripted fault. */
|
|
991
999
|
request?: RejectedRequest;
|
|
992
1000
|
/** The validation issues behind a rejection, when the service found any. */
|
|
@@ -1317,6 +1325,8 @@ type PlaneWorkItemRecord = {
|
|
|
1317
1325
|
description_stripped: string | null;
|
|
1318
1326
|
priority: "urgent" | "high" | "medium" | "low" | "none";
|
|
1319
1327
|
state: string;
|
|
1328
|
+
type_id: string | null;
|
|
1329
|
+
type: string | null;
|
|
1320
1330
|
labels: string[];
|
|
1321
1331
|
assignees: string[];
|
|
1322
1332
|
parent: string | null;
|
|
@@ -1356,6 +1366,52 @@ type PlaneLinkRecord = {
|
|
|
1356
1366
|
created_at: string;
|
|
1357
1367
|
updated_at: string;
|
|
1358
1368
|
};
|
|
1369
|
+
type PlaneCycleRecord = {
|
|
1370
|
+
id: string;
|
|
1371
|
+
name: string;
|
|
1372
|
+
description: string;
|
|
1373
|
+
start_date: string | null;
|
|
1374
|
+
end_date: string | null;
|
|
1375
|
+
owned_by: string | null;
|
|
1376
|
+
timezone: string;
|
|
1377
|
+
external_source: string | null;
|
|
1378
|
+
external_id: string | null;
|
|
1379
|
+
project: string;
|
|
1380
|
+
workspace: string;
|
|
1381
|
+
created_at: string;
|
|
1382
|
+
updated_at: string;
|
|
1383
|
+
archived_at: string | null;
|
|
1384
|
+
deleted_at: string | null;
|
|
1385
|
+
};
|
|
1386
|
+
type PlaneCycleMembership = {
|
|
1387
|
+
id: string;
|
|
1388
|
+
cycle: string;
|
|
1389
|
+
issue: string;
|
|
1390
|
+
project: string;
|
|
1391
|
+
workspace: string;
|
|
1392
|
+
created_at: string;
|
|
1393
|
+
updated_at: string;
|
|
1394
|
+
deleted_at: string | null;
|
|
1395
|
+
};
|
|
1396
|
+
type PlaneWorkItemType = {
|
|
1397
|
+
id: string;
|
|
1398
|
+
name: string;
|
|
1399
|
+
description: string;
|
|
1400
|
+
project_ids: string[];
|
|
1401
|
+
logo_props: Record<string, unknown>;
|
|
1402
|
+
is_epic: boolean;
|
|
1403
|
+
is_default: boolean;
|
|
1404
|
+
is_active: boolean;
|
|
1405
|
+
level: number;
|
|
1406
|
+
created_at: string;
|
|
1407
|
+
updated_at: string;
|
|
1408
|
+
deleted_at: string | null;
|
|
1409
|
+
};
|
|
1410
|
+
type WorkItemTypeSeed = {
|
|
1411
|
+
name: string;
|
|
1412
|
+
description?: string;
|
|
1413
|
+
is_default?: boolean;
|
|
1414
|
+
};
|
|
1359
1415
|
/** One project: its workspace slug and the per-project work-item sequence. */
|
|
1360
1416
|
type ProjectRecord = {
|
|
1361
1417
|
id: string;
|
|
@@ -1380,6 +1436,9 @@ declare class PlaneState {
|
|
|
1380
1436
|
readonly items: Collection<PlaneWorkItemRecord>;
|
|
1381
1437
|
readonly comments: Collection<PlaneCommentRecord>;
|
|
1382
1438
|
readonly links: Collection<PlaneLinkRecord>;
|
|
1439
|
+
readonly cycles: Collection<PlaneCycleRecord>;
|
|
1440
|
+
readonly memberships: Collection<PlaneCycleMembership>;
|
|
1441
|
+
readonly types: Collection<PlaneWorkItemType>;
|
|
1383
1442
|
readonly settings: Collection<Settings>;
|
|
1384
1443
|
readonly rateLimits: Collection<number>;
|
|
1385
1444
|
private readonly ids;
|
|
@@ -1416,11 +1475,20 @@ declare class PlaneAPI implements FetchAPI {
|
|
|
1416
1475
|
private item;
|
|
1417
1476
|
statesOf(projectId: string): PlaneStateRecord[];
|
|
1418
1477
|
labelsOf(projectId: string): PlaneLabelRecord[];
|
|
1478
|
+
typesOf(projectId: string): PlaneWorkItemType[];
|
|
1479
|
+
/** Idempotent fixture provisioning; type IDs remain stable when metadata is reseeded. */
|
|
1480
|
+
seedWorkItemTypes(workspace: string, projectId: string, types: WorkItemTypeSeed[]): PlaneWorkItemType[] | undefined;
|
|
1419
1481
|
/** Plane's cursor paginator: `cursor=<per_page>:<page>:<is_prev>`, offset = page × per_page. */
|
|
1420
1482
|
private paginate;
|
|
1421
1483
|
private listWorkItems;
|
|
1484
|
+
private cycle;
|
|
1485
|
+
private cycleView;
|
|
1486
|
+
private listCycles;
|
|
1487
|
+
private createCycle;
|
|
1488
|
+
private listCycleWorkItems;
|
|
1489
|
+
private addCycleWorkItems;
|
|
1422
1490
|
private body;
|
|
1423
|
-
/** Validate
|
|
1491
|
+
/** Validate workflow references before any part of a write is persisted, DRF-style. */
|
|
1424
1492
|
private references;
|
|
1425
1493
|
private createWorkItem;
|
|
1426
1494
|
private updateWorkItem;
|