@crvouga/mockingbird-service-junction 0.4.0 → 0.6.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 +16 -0
- package/README.md +1 -1
- package/dist/{chunk-ICINEQ7D.js → chunk-MS774AJA.js} +526 -46
- package/dist/chunk-MS774AJA.js.map +7 -0
- package/dist/{chunk-CR35KYXY.js → chunk-TG2EOH3J.js} +2 -2
- package/dist/cli.js +2 -2
- package/dist/index.d.ts +136 -22
- package/dist/index.js +1 -1
- package/dist/server.d.ts +267 -44
- package/dist/server.js +2 -2
- package/package.json +6 -3
- package/dist/chunk-ICINEQ7D.js.map +0 -7
- /package/dist/{chunk-CR35KYXY.js.map → chunk-TG2EOH3J.js.map} +0 -0
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
IDENTITY_MODES,
|
|
3
3
|
createRuntime,
|
|
4
4
|
pullCorpus
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-MS774AJA.js";
|
|
6
6
|
import {
|
|
7
7
|
defaultCorpus
|
|
8
8
|
} from "./chunk-C2UGIPPM.js";
|
|
@@ -513,4 +513,4 @@ export {
|
|
|
513
513
|
createServer2 as createServer,
|
|
514
514
|
serveTarget
|
|
515
515
|
};
|
|
516
|
-
//# sourceMappingURL=chunk-
|
|
516
|
+
//# sourceMappingURL=chunk-TG2EOH3J.js.map
|
package/dist/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
runCli,
|
|
5
5
|
serveCommand,
|
|
6
6
|
serveTarget
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-TG2EOH3J.js";
|
|
8
8
|
import {
|
|
9
9
|
DEFAULT_JUNCTION_BASE_URL,
|
|
10
10
|
createRuntime,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
isSandboxKey,
|
|
13
13
|
pullCorpus,
|
|
14
14
|
verifyAgainstReal
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-MS774AJA.js";
|
|
16
16
|
import {
|
|
17
17
|
defaultCorpus
|
|
18
18
|
} from "./chunk-C2UGIPPM.js";
|
package/dist/index.d.ts
CHANGED
|
@@ -73,6 +73,10 @@ type Rng = {
|
|
|
73
73
|
int(min: number, max: number): number;
|
|
74
74
|
/** Restart the stream from its seed. */
|
|
75
75
|
reset(): void;
|
|
76
|
+
/** Serializable engine state used by deterministic checkpoints. */
|
|
77
|
+
state(): number;
|
|
78
|
+
/** Restore a state previously returned by {@link state}. */
|
|
79
|
+
setState(state: number): void;
|
|
76
80
|
seed: number;
|
|
77
81
|
};
|
|
78
82
|
|
|
@@ -229,28 +233,6 @@ type Journal = {
|
|
|
229
233
|
clear(namespace?: string): void;
|
|
230
234
|
};
|
|
231
235
|
|
|
232
|
-
/**
|
|
233
|
-
* A point-in-time copy of everything a service namespace holds.
|
|
234
|
-
*
|
|
235
|
-
* All service state lives in the two core tables keyed by namespace, so a snapshot
|
|
236
|
-
* is generic: any service gets per-test rollback without knowing its own schema.
|
|
237
|
-
* Restoring is much cheaper than rebuilding a namespace from a corpus.
|
|
238
|
-
*/
|
|
239
|
-
type NamespaceSnapshot = {
|
|
240
|
-
namespace: string;
|
|
241
|
-
records: {
|
|
242
|
-
collection: string;
|
|
243
|
-
id: string;
|
|
244
|
-
seq: number;
|
|
245
|
-
value: string;
|
|
246
|
-
}[];
|
|
247
|
-
sequences: {
|
|
248
|
-
name: string;
|
|
249
|
-
kind: string;
|
|
250
|
-
value: number;
|
|
251
|
-
}[];
|
|
252
|
-
};
|
|
253
|
-
|
|
254
236
|
/** Credential → namespace mapping behind `PUT /__admin/credentials`. */
|
|
255
237
|
type CredentialRegistry = {
|
|
256
238
|
set(credential: string, namespace: string): void;
|
|
@@ -263,6 +245,86 @@ type CredentialRegistry = {
|
|
|
263
245
|
}[];
|
|
264
246
|
};
|
|
265
247
|
|
|
248
|
+
/** A stable identifier for a point in a {@link Timeline}. */
|
|
249
|
+
type CheckpointId = string;
|
|
250
|
+
/** An immutable node in a timeline's checkpoint DAG. */
|
|
251
|
+
type Checkpoint<T> = Readonly<{
|
|
252
|
+
id: CheckpointId;
|
|
253
|
+
branch: string;
|
|
254
|
+
parent: CheckpointId | null;
|
|
255
|
+
/** Logical time supplied by the timeline's injected clock. */
|
|
256
|
+
at: number;
|
|
257
|
+
value: T;
|
|
258
|
+
}>;
|
|
259
|
+
type TimelineOptions = {
|
|
260
|
+
/** Logical clock used to stamp checkpoints. Defaults to a deterministic counter. */
|
|
261
|
+
now?: () => number;
|
|
262
|
+
/** Maximum retained checkpoints. Branch heads are never collected. Default 1,000. */
|
|
263
|
+
maxCheckpoints?: number;
|
|
264
|
+
/** Customize deterministic checkpoint IDs. */
|
|
265
|
+
id?: (sequence: number) => CheckpointId;
|
|
266
|
+
};
|
|
267
|
+
type CommitOptions = {
|
|
268
|
+
branch?: string;
|
|
269
|
+
/** Parent checkpoint. Defaults to the selected branch's current head. */
|
|
270
|
+
parent?: CheckpointId | null;
|
|
271
|
+
};
|
|
272
|
+
type ForkOptions = {
|
|
273
|
+
/** Checkpoint to fork from. Defaults to the main branch's head. */
|
|
274
|
+
from?: CheckpointId;
|
|
275
|
+
};
|
|
276
|
+
/**
|
|
277
|
+
* Small, storage-agnostic checkpoint DAG shared by service runtimes. Its values may be immutable
|
|
278
|
+
* records, namespace images, or copy-on-write SQL engine snapshots.
|
|
279
|
+
*
|
|
280
|
+
* Values are retained by reference. Engines can therefore use persistent/COW snapshots while
|
|
281
|
+
* simpler services can use immutable values. IDs and GC order are deterministic, and all IO
|
|
282
|
+
* (the logical clock) is injected.
|
|
283
|
+
*/
|
|
284
|
+
declare class Timeline<T> {
|
|
285
|
+
readonly maxCheckpoints: number;
|
|
286
|
+
private readonly now;
|
|
287
|
+
private readonly makeId;
|
|
288
|
+
private readonly nodes;
|
|
289
|
+
private readonly heads;
|
|
290
|
+
/** Unreferenced nodes in the exact order they became collectible. */
|
|
291
|
+
private readonly evictable;
|
|
292
|
+
/** Branch heads plus explicit retainers. Absent means zero. */
|
|
293
|
+
private readonly references;
|
|
294
|
+
private readonly explicitPins;
|
|
295
|
+
private sequence;
|
|
296
|
+
constructor(options?: TimelineOptions);
|
|
297
|
+
/** Capture a new immutable value and move `branch` to it. */
|
|
298
|
+
commit(value: T, options?: CommitOptions): Checkpoint<T>;
|
|
299
|
+
/** Create a branch pointer without copying its checkpoint value. */
|
|
300
|
+
fork(branch: string, options?: ForkOptions): Checkpoint<T> | undefined;
|
|
301
|
+
/** Move a branch pointer to an existing checkpoint. */
|
|
302
|
+
checkout(branch: string, id: CheckpointId): Checkpoint<T>;
|
|
303
|
+
get(id: CheckpointId): Checkpoint<T>;
|
|
304
|
+
head(branch?: string): Checkpoint<T> | undefined;
|
|
305
|
+
hasBranch(branch: string): boolean;
|
|
306
|
+
branches(): Readonly<Record<string, CheckpointId>>;
|
|
307
|
+
checkpoints(): readonly Checkpoint<T>[];
|
|
308
|
+
/** Number of retained checkpoints without allocating an array. */
|
|
309
|
+
get size(): number;
|
|
310
|
+
/** Pin a checkpoint independently of branch heads (used by compatibility snapshot handles). */
|
|
311
|
+
retain(id: CheckpointId): Checkpoint<T>;
|
|
312
|
+
/** Release one explicit pin. Branch heads remain pinned until moved or deleted. */
|
|
313
|
+
release(id: CheckpointId): boolean;
|
|
314
|
+
deleteBranch(branch: string): boolean;
|
|
315
|
+
/**
|
|
316
|
+
* Deterministically discard oldest unpinned checkpoints. Collection is O(number removed):
|
|
317
|
+
* commits never scan pinned nodes or the retained history. Parents are metadata rather than a
|
|
318
|
+
* storage dependency, so a retained node remains usable after pruning.
|
|
319
|
+
*/
|
|
320
|
+
gc(max?: number): CheckpointId[];
|
|
321
|
+
private collect;
|
|
322
|
+
private moveHead;
|
|
323
|
+
private addReference;
|
|
324
|
+
private removeReference;
|
|
325
|
+
private assertBranch;
|
|
326
|
+
}
|
|
327
|
+
|
|
266
328
|
/**
|
|
267
329
|
* Anything that can answer a Fetch `Request` with a `Response`.
|
|
268
330
|
*
|
|
@@ -273,6 +335,28 @@ interface FetchAPI$1 {
|
|
|
273
335
|
fetch(request: Request): Promise<Response>;
|
|
274
336
|
}
|
|
275
337
|
|
|
338
|
+
/**
|
|
339
|
+
* A point-in-time copy of everything a service namespace holds.
|
|
340
|
+
*
|
|
341
|
+
* All service state lives in the two core tables keyed by namespace, so a snapshot
|
|
342
|
+
* is generic: any service gets per-test rollback without knowing its own schema.
|
|
343
|
+
* Restoring is much cheaper than rebuilding a namespace from a corpus.
|
|
344
|
+
*/
|
|
345
|
+
type NamespaceSnapshot = {
|
|
346
|
+
namespace: string;
|
|
347
|
+
records: {
|
|
348
|
+
collection: string;
|
|
349
|
+
id: string;
|
|
350
|
+
seq: number;
|
|
351
|
+
value: string;
|
|
352
|
+
}[];
|
|
353
|
+
sequences: {
|
|
354
|
+
name: string;
|
|
355
|
+
kind: string;
|
|
356
|
+
value: number;
|
|
357
|
+
}[];
|
|
358
|
+
};
|
|
359
|
+
|
|
276
360
|
type WebhookEndpoint$1 = {
|
|
277
361
|
/** Stable id; generated when omitted. */
|
|
278
362
|
id?: string;
|
|
@@ -293,6 +377,7 @@ type WebhookMessage = {
|
|
|
293
377
|
body: string;
|
|
294
378
|
contentType: string;
|
|
295
379
|
tags: Record<string, string>;
|
|
380
|
+
headers?: Record<string, string>;
|
|
296
381
|
/** Wall-clock ISO-8601 time of publication. */
|
|
297
382
|
publishedAt: string;
|
|
298
383
|
};
|
|
@@ -302,6 +387,8 @@ type WebhookAttempt$1 = {
|
|
|
302
387
|
status: number | null;
|
|
303
388
|
error: string | null;
|
|
304
389
|
durationMs: number;
|
|
390
|
+
/** Exact receiver response body, when one was returned. */
|
|
391
|
+
responseBody?: string | null;
|
|
305
392
|
};
|
|
306
393
|
type WebhookDelivery$1 = {
|
|
307
394
|
id: string;
|
|
@@ -329,6 +416,8 @@ type PublishInput = {
|
|
|
329
416
|
/** Form parameters, when the vendor posts `application/x-www-form-urlencoded`. */
|
|
330
417
|
form?: Record<string, string>;
|
|
331
418
|
tags?: Record<string, string>;
|
|
419
|
+
/** Message-specific delivery headers, captured as part of durable message state. */
|
|
420
|
+
headers?: Record<string, string>;
|
|
332
421
|
/** Message id; generated when omitted. */
|
|
333
422
|
id?: string;
|
|
334
423
|
};
|
|
@@ -353,6 +442,12 @@ type WebhookHub = {
|
|
|
353
442
|
type ServiceInstance = FetchAPI$1 & {
|
|
354
443
|
reset(): Promise<void>;
|
|
355
444
|
};
|
|
445
|
+
type ServiceTimelineState = Readonly<{
|
|
446
|
+
snapshot: NamespaceSnapshot;
|
|
447
|
+
clock: Readonly<ReturnType<Clock["state"]>>;
|
|
448
|
+
rngState: number;
|
|
449
|
+
}>;
|
|
450
|
+
type ServiceCheckpoint = Checkpoint<ServiceTimelineState>;
|
|
356
451
|
type ServiceRuntime<T extends ServiceInstance> = FetchAPI$1 & {
|
|
357
452
|
readonly name: string;
|
|
358
453
|
readonly sqlite: SqliteClient$1;
|
|
@@ -374,6 +469,20 @@ type ServiceRuntime<T extends ServiceInstance> = FetchAPI$1 & {
|
|
|
374
469
|
reset(namespace?: string): Promise<void>;
|
|
375
470
|
snapshot(namespace?: string): NamespaceSnapshot;
|
|
376
471
|
restore(snapshot: NamespaceSnapshot, namespace?: string): void;
|
|
472
|
+
/** Capture the current branch. Mutating HTTP calls do this automatically. */
|
|
473
|
+
checkpoint(namespace?: string, branch?: string): ServiceCheckpoint;
|
|
474
|
+
/** Create an isolated branch, optionally from a historical checkpoint. */
|
|
475
|
+
branch(name: string, options?: {
|
|
476
|
+
namespace?: string;
|
|
477
|
+
at?: string;
|
|
478
|
+
}): ServiceCheckpoint;
|
|
479
|
+
/** Restore a branch, clock, and PRNG to a checkpoint. */
|
|
480
|
+
checkout(checkpoint: string, options?: {
|
|
481
|
+
namespace?: string;
|
|
482
|
+
branch?: string;
|
|
483
|
+
}): void;
|
|
484
|
+
/** Inspect the retained history for a namespace. */
|
|
485
|
+
timeline(namespace?: string): Timeline<ServiceTimelineState>;
|
|
377
486
|
};
|
|
378
487
|
|
|
379
488
|
/** Options every provider constructor accepts. */
|
|
@@ -882,6 +991,11 @@ type WebhookEndpoint = {
|
|
|
882
991
|
/** Added to every delivery, e.g. a routing scope for a shared receiver. */
|
|
883
992
|
headers?: Record<string, string>;
|
|
884
993
|
fetch?: (request: Request) => Promise<Response>;
|
|
994
|
+
/** Injectable wall clock for signatures and delivery records. */
|
|
995
|
+
now?: () => number;
|
|
996
|
+
/** Injectable scheduler for timeouts and retry delays. */
|
|
997
|
+
schedule?: (callback: () => void, delayMs: number) => unknown;
|
|
998
|
+
cancel?: (handle: unknown) => void;
|
|
885
999
|
};
|
|
886
1000
|
type WebhookAttempt = {
|
|
887
1001
|
attempt: number;
|
package/dist/index.js
CHANGED
package/dist/server.d.ts
CHANGED
|
@@ -74,6 +74,10 @@ type Rng$1 = {
|
|
|
74
74
|
int(min: number, max: number): number;
|
|
75
75
|
/** Restart the stream from its seed. */
|
|
76
76
|
reset(): void;
|
|
77
|
+
/** Serializable engine state used by deterministic checkpoints. */
|
|
78
|
+
state(): number;
|
|
79
|
+
/** Restore a state previously returned by {@link state}. */
|
|
80
|
+
setState(state: number): void;
|
|
77
81
|
seed: number;
|
|
78
82
|
};
|
|
79
83
|
|
|
@@ -230,28 +234,6 @@ type Journal$1 = {
|
|
|
230
234
|
clear(namespace?: string): void;
|
|
231
235
|
};
|
|
232
236
|
|
|
233
|
-
/**
|
|
234
|
-
* A point-in-time copy of everything a service namespace holds.
|
|
235
|
-
*
|
|
236
|
-
* All service state lives in the two core tables keyed by namespace, so a snapshot
|
|
237
|
-
* is generic: any service gets per-test rollback without knowing its own schema.
|
|
238
|
-
* Restoring is much cheaper than rebuilding a namespace from a corpus.
|
|
239
|
-
*/
|
|
240
|
-
type NamespaceSnapshot$1 = {
|
|
241
|
-
namespace: string;
|
|
242
|
-
records: {
|
|
243
|
-
collection: string;
|
|
244
|
-
id: string;
|
|
245
|
-
seq: number;
|
|
246
|
-
value: string;
|
|
247
|
-
}[];
|
|
248
|
-
sequences: {
|
|
249
|
-
name: string;
|
|
250
|
-
kind: string;
|
|
251
|
-
value: number;
|
|
252
|
-
}[];
|
|
253
|
-
};
|
|
254
|
-
|
|
255
237
|
/** Credential → namespace mapping behind `PUT /__admin/credentials`. */
|
|
256
238
|
type CredentialRegistry$1 = {
|
|
257
239
|
set(credential: string, namespace: string): void;
|
|
@@ -264,6 +246,86 @@ type CredentialRegistry$1 = {
|
|
|
264
246
|
}[];
|
|
265
247
|
};
|
|
266
248
|
|
|
249
|
+
/** A stable identifier for a point in a {@link Timeline}. */
|
|
250
|
+
type CheckpointId$1 = string;
|
|
251
|
+
/** An immutable node in a timeline's checkpoint DAG. */
|
|
252
|
+
type Checkpoint$1<T> = Readonly<{
|
|
253
|
+
id: CheckpointId$1;
|
|
254
|
+
branch: string;
|
|
255
|
+
parent: CheckpointId$1 | null;
|
|
256
|
+
/** Logical time supplied by the timeline's injected clock. */
|
|
257
|
+
at: number;
|
|
258
|
+
value: T;
|
|
259
|
+
}>;
|
|
260
|
+
type TimelineOptions$1 = {
|
|
261
|
+
/** Logical clock used to stamp checkpoints. Defaults to a deterministic counter. */
|
|
262
|
+
now?: () => number;
|
|
263
|
+
/** Maximum retained checkpoints. Branch heads are never collected. Default 1,000. */
|
|
264
|
+
maxCheckpoints?: number;
|
|
265
|
+
/** Customize deterministic checkpoint IDs. */
|
|
266
|
+
id?: (sequence: number) => CheckpointId$1;
|
|
267
|
+
};
|
|
268
|
+
type CommitOptions$1 = {
|
|
269
|
+
branch?: string;
|
|
270
|
+
/** Parent checkpoint. Defaults to the selected branch's current head. */
|
|
271
|
+
parent?: CheckpointId$1 | null;
|
|
272
|
+
};
|
|
273
|
+
type ForkOptions$1 = {
|
|
274
|
+
/** Checkpoint to fork from. Defaults to the main branch's head. */
|
|
275
|
+
from?: CheckpointId$1;
|
|
276
|
+
};
|
|
277
|
+
/**
|
|
278
|
+
* Small, storage-agnostic checkpoint DAG shared by service runtimes. Its values may be immutable
|
|
279
|
+
* records, namespace images, or copy-on-write SQL engine snapshots.
|
|
280
|
+
*
|
|
281
|
+
* Values are retained by reference. Engines can therefore use persistent/COW snapshots while
|
|
282
|
+
* simpler services can use immutable values. IDs and GC order are deterministic, and all IO
|
|
283
|
+
* (the logical clock) is injected.
|
|
284
|
+
*/
|
|
285
|
+
declare class Timeline$1<T> {
|
|
286
|
+
readonly maxCheckpoints: number;
|
|
287
|
+
private readonly now;
|
|
288
|
+
private readonly makeId;
|
|
289
|
+
private readonly nodes;
|
|
290
|
+
private readonly heads;
|
|
291
|
+
/** Unreferenced nodes in the exact order they became collectible. */
|
|
292
|
+
private readonly evictable;
|
|
293
|
+
/** Branch heads plus explicit retainers. Absent means zero. */
|
|
294
|
+
private readonly references;
|
|
295
|
+
private readonly explicitPins;
|
|
296
|
+
private sequence;
|
|
297
|
+
constructor(options?: TimelineOptions$1);
|
|
298
|
+
/** Capture a new immutable value and move `branch` to it. */
|
|
299
|
+
commit(value: T, options?: CommitOptions$1): Checkpoint$1<T>;
|
|
300
|
+
/** Create a branch pointer without copying its checkpoint value. */
|
|
301
|
+
fork(branch: string, options?: ForkOptions$1): Checkpoint$1<T> | undefined;
|
|
302
|
+
/** Move a branch pointer to an existing checkpoint. */
|
|
303
|
+
checkout(branch: string, id: CheckpointId$1): Checkpoint$1<T>;
|
|
304
|
+
get(id: CheckpointId$1): Checkpoint$1<T>;
|
|
305
|
+
head(branch?: string): Checkpoint$1<T> | undefined;
|
|
306
|
+
hasBranch(branch: string): boolean;
|
|
307
|
+
branches(): Readonly<Record<string, CheckpointId$1>>;
|
|
308
|
+
checkpoints(): readonly Checkpoint$1<T>[];
|
|
309
|
+
/** Number of retained checkpoints without allocating an array. */
|
|
310
|
+
get size(): number;
|
|
311
|
+
/** Pin a checkpoint independently of branch heads (used by compatibility snapshot handles). */
|
|
312
|
+
retain(id: CheckpointId$1): Checkpoint$1<T>;
|
|
313
|
+
/** Release one explicit pin. Branch heads remain pinned until moved or deleted. */
|
|
314
|
+
release(id: CheckpointId$1): boolean;
|
|
315
|
+
deleteBranch(branch: string): boolean;
|
|
316
|
+
/**
|
|
317
|
+
* Deterministically discard oldest unpinned checkpoints. Collection is O(number removed):
|
|
318
|
+
* commits never scan pinned nodes or the retained history. Parents are metadata rather than a
|
|
319
|
+
* storage dependency, so a retained node remains usable after pruning.
|
|
320
|
+
*/
|
|
321
|
+
gc(max?: number): CheckpointId$1[];
|
|
322
|
+
private collect;
|
|
323
|
+
private moveHead;
|
|
324
|
+
private addReference;
|
|
325
|
+
private removeReference;
|
|
326
|
+
private assertBranch;
|
|
327
|
+
}
|
|
328
|
+
|
|
267
329
|
/**
|
|
268
330
|
* Anything that can answer a Fetch `Request` with a `Response`.
|
|
269
331
|
*
|
|
@@ -274,6 +336,28 @@ interface FetchAPI$2 {
|
|
|
274
336
|
fetch(request: Request): Promise<Response>;
|
|
275
337
|
}
|
|
276
338
|
|
|
339
|
+
/**
|
|
340
|
+
* A point-in-time copy of everything a service namespace holds.
|
|
341
|
+
*
|
|
342
|
+
* All service state lives in the two core tables keyed by namespace, so a snapshot
|
|
343
|
+
* is generic: any service gets per-test rollback without knowing its own schema.
|
|
344
|
+
* Restoring is much cheaper than rebuilding a namespace from a corpus.
|
|
345
|
+
*/
|
|
346
|
+
type NamespaceSnapshot$1 = {
|
|
347
|
+
namespace: string;
|
|
348
|
+
records: {
|
|
349
|
+
collection: string;
|
|
350
|
+
id: string;
|
|
351
|
+
seq: number;
|
|
352
|
+
value: string;
|
|
353
|
+
}[];
|
|
354
|
+
sequences: {
|
|
355
|
+
name: string;
|
|
356
|
+
kind: string;
|
|
357
|
+
value: number;
|
|
358
|
+
}[];
|
|
359
|
+
};
|
|
360
|
+
|
|
277
361
|
type WebhookEndpoint$2 = {
|
|
278
362
|
/** Stable id; generated when omitted. */
|
|
279
363
|
id?: string;
|
|
@@ -294,6 +378,7 @@ type WebhookMessage$1 = {
|
|
|
294
378
|
body: string;
|
|
295
379
|
contentType: string;
|
|
296
380
|
tags: Record<string, string>;
|
|
381
|
+
headers?: Record<string, string>;
|
|
297
382
|
/** Wall-clock ISO-8601 time of publication. */
|
|
298
383
|
publishedAt: string;
|
|
299
384
|
};
|
|
@@ -303,6 +388,8 @@ type WebhookAttempt$2 = {
|
|
|
303
388
|
status: number | null;
|
|
304
389
|
error: string | null;
|
|
305
390
|
durationMs: number;
|
|
391
|
+
/** Exact receiver response body, when one was returned. */
|
|
392
|
+
responseBody?: string | null;
|
|
306
393
|
};
|
|
307
394
|
type WebhookDelivery$2 = {
|
|
308
395
|
id: string;
|
|
@@ -330,6 +417,8 @@ type PublishInput$1 = {
|
|
|
330
417
|
/** Form parameters, when the vendor posts `application/x-www-form-urlencoded`. */
|
|
331
418
|
form?: Record<string, string>;
|
|
332
419
|
tags?: Record<string, string>;
|
|
420
|
+
/** Message-specific delivery headers, captured as part of durable message state. */
|
|
421
|
+
headers?: Record<string, string>;
|
|
333
422
|
/** Message id; generated when omitted. */
|
|
334
423
|
id?: string;
|
|
335
424
|
};
|
|
@@ -354,6 +443,12 @@ type WebhookHub$1 = {
|
|
|
354
443
|
type ServiceInstance$1 = FetchAPI$2 & {
|
|
355
444
|
reset(): Promise<void>;
|
|
356
445
|
};
|
|
446
|
+
type ServiceTimelineState$1 = Readonly<{
|
|
447
|
+
snapshot: NamespaceSnapshot$1;
|
|
448
|
+
clock: Readonly<ReturnType<Clock$1["state"]>>;
|
|
449
|
+
rngState: number;
|
|
450
|
+
}>;
|
|
451
|
+
type ServiceCheckpoint$1 = Checkpoint$1<ServiceTimelineState$1>;
|
|
357
452
|
type ServiceRuntime$1<T extends ServiceInstance$1> = FetchAPI$2 & {
|
|
358
453
|
readonly name: string;
|
|
359
454
|
readonly sqlite: SqliteClient$2;
|
|
@@ -375,6 +470,20 @@ type ServiceRuntime$1<T extends ServiceInstance$1> = FetchAPI$2 & {
|
|
|
375
470
|
reset(namespace?: string): Promise<void>;
|
|
376
471
|
snapshot(namespace?: string): NamespaceSnapshot$1;
|
|
377
472
|
restore(snapshot: NamespaceSnapshot$1, namespace?: string): void;
|
|
473
|
+
/** Capture the current branch. Mutating HTTP calls do this automatically. */
|
|
474
|
+
checkpoint(namespace?: string, branch?: string): ServiceCheckpoint$1;
|
|
475
|
+
/** Create an isolated branch, optionally from a historical checkpoint. */
|
|
476
|
+
branch(name: string, options?: {
|
|
477
|
+
namespace?: string;
|
|
478
|
+
at?: string;
|
|
479
|
+
}): ServiceCheckpoint$1;
|
|
480
|
+
/** Restore a branch, clock, and PRNG to a checkpoint. */
|
|
481
|
+
checkout(checkpoint: string, options?: {
|
|
482
|
+
namespace?: string;
|
|
483
|
+
branch?: string;
|
|
484
|
+
}): void;
|
|
485
|
+
/** Inspect the retained history for a namespace. */
|
|
486
|
+
timeline(namespace?: string): Timeline$1<ServiceTimelineState$1>;
|
|
378
487
|
};
|
|
379
488
|
|
|
380
489
|
type CliOption = {
|
|
@@ -487,6 +596,10 @@ type Rng = {
|
|
|
487
596
|
int(min: number, max: number): number;
|
|
488
597
|
/** Restart the stream from its seed. */
|
|
489
598
|
reset(): void;
|
|
599
|
+
/** Serializable engine state used by deterministic checkpoints. */
|
|
600
|
+
state(): number;
|
|
601
|
+
/** Restore a state previously returned by {@link state}. */
|
|
602
|
+
setState(state: number): void;
|
|
490
603
|
seed: number;
|
|
491
604
|
};
|
|
492
605
|
|
|
@@ -643,28 +756,6 @@ type Journal = {
|
|
|
643
756
|
clear(namespace?: string): void;
|
|
644
757
|
};
|
|
645
758
|
|
|
646
|
-
/**
|
|
647
|
-
* A point-in-time copy of everything a service namespace holds.
|
|
648
|
-
*
|
|
649
|
-
* All service state lives in the two core tables keyed by namespace, so a snapshot
|
|
650
|
-
* is generic: any service gets per-test rollback without knowing its own schema.
|
|
651
|
-
* Restoring is much cheaper than rebuilding a namespace from a corpus.
|
|
652
|
-
*/
|
|
653
|
-
type NamespaceSnapshot = {
|
|
654
|
-
namespace: string;
|
|
655
|
-
records: {
|
|
656
|
-
collection: string;
|
|
657
|
-
id: string;
|
|
658
|
-
seq: number;
|
|
659
|
-
value: string;
|
|
660
|
-
}[];
|
|
661
|
-
sequences: {
|
|
662
|
-
name: string;
|
|
663
|
-
kind: string;
|
|
664
|
-
value: number;
|
|
665
|
-
}[];
|
|
666
|
-
};
|
|
667
|
-
|
|
668
759
|
/** Credential → namespace mapping behind `PUT /__admin/credentials`. */
|
|
669
760
|
type CredentialRegistry = {
|
|
670
761
|
set(credential: string, namespace: string): void;
|
|
@@ -677,6 +768,86 @@ type CredentialRegistry = {
|
|
|
677
768
|
}[];
|
|
678
769
|
};
|
|
679
770
|
|
|
771
|
+
/** A stable identifier for a point in a {@link Timeline}. */
|
|
772
|
+
type CheckpointId = string;
|
|
773
|
+
/** An immutable node in a timeline's checkpoint DAG. */
|
|
774
|
+
type Checkpoint<T> = Readonly<{
|
|
775
|
+
id: CheckpointId;
|
|
776
|
+
branch: string;
|
|
777
|
+
parent: CheckpointId | null;
|
|
778
|
+
/** Logical time supplied by the timeline's injected clock. */
|
|
779
|
+
at: number;
|
|
780
|
+
value: T;
|
|
781
|
+
}>;
|
|
782
|
+
type TimelineOptions = {
|
|
783
|
+
/** Logical clock used to stamp checkpoints. Defaults to a deterministic counter. */
|
|
784
|
+
now?: () => number;
|
|
785
|
+
/** Maximum retained checkpoints. Branch heads are never collected. Default 1,000. */
|
|
786
|
+
maxCheckpoints?: number;
|
|
787
|
+
/** Customize deterministic checkpoint IDs. */
|
|
788
|
+
id?: (sequence: number) => CheckpointId;
|
|
789
|
+
};
|
|
790
|
+
type CommitOptions = {
|
|
791
|
+
branch?: string;
|
|
792
|
+
/** Parent checkpoint. Defaults to the selected branch's current head. */
|
|
793
|
+
parent?: CheckpointId | null;
|
|
794
|
+
};
|
|
795
|
+
type ForkOptions = {
|
|
796
|
+
/** Checkpoint to fork from. Defaults to the main branch's head. */
|
|
797
|
+
from?: CheckpointId;
|
|
798
|
+
};
|
|
799
|
+
/**
|
|
800
|
+
* Small, storage-agnostic checkpoint DAG shared by service runtimes. Its values may be immutable
|
|
801
|
+
* records, namespace images, or copy-on-write SQL engine snapshots.
|
|
802
|
+
*
|
|
803
|
+
* Values are retained by reference. Engines can therefore use persistent/COW snapshots while
|
|
804
|
+
* simpler services can use immutable values. IDs and GC order are deterministic, and all IO
|
|
805
|
+
* (the logical clock) is injected.
|
|
806
|
+
*/
|
|
807
|
+
declare class Timeline<T> {
|
|
808
|
+
readonly maxCheckpoints: number;
|
|
809
|
+
private readonly now;
|
|
810
|
+
private readonly makeId;
|
|
811
|
+
private readonly nodes;
|
|
812
|
+
private readonly heads;
|
|
813
|
+
/** Unreferenced nodes in the exact order they became collectible. */
|
|
814
|
+
private readonly evictable;
|
|
815
|
+
/** Branch heads plus explicit retainers. Absent means zero. */
|
|
816
|
+
private readonly references;
|
|
817
|
+
private readonly explicitPins;
|
|
818
|
+
private sequence;
|
|
819
|
+
constructor(options?: TimelineOptions);
|
|
820
|
+
/** Capture a new immutable value and move `branch` to it. */
|
|
821
|
+
commit(value: T, options?: CommitOptions): Checkpoint<T>;
|
|
822
|
+
/** Create a branch pointer without copying its checkpoint value. */
|
|
823
|
+
fork(branch: string, options?: ForkOptions): Checkpoint<T> | undefined;
|
|
824
|
+
/** Move a branch pointer to an existing checkpoint. */
|
|
825
|
+
checkout(branch: string, id: CheckpointId): Checkpoint<T>;
|
|
826
|
+
get(id: CheckpointId): Checkpoint<T>;
|
|
827
|
+
head(branch?: string): Checkpoint<T> | undefined;
|
|
828
|
+
hasBranch(branch: string): boolean;
|
|
829
|
+
branches(): Readonly<Record<string, CheckpointId>>;
|
|
830
|
+
checkpoints(): readonly Checkpoint<T>[];
|
|
831
|
+
/** Number of retained checkpoints without allocating an array. */
|
|
832
|
+
get size(): number;
|
|
833
|
+
/** Pin a checkpoint independently of branch heads (used by compatibility snapshot handles). */
|
|
834
|
+
retain(id: CheckpointId): Checkpoint<T>;
|
|
835
|
+
/** Release one explicit pin. Branch heads remain pinned until moved or deleted. */
|
|
836
|
+
release(id: CheckpointId): boolean;
|
|
837
|
+
deleteBranch(branch: string): boolean;
|
|
838
|
+
/**
|
|
839
|
+
* Deterministically discard oldest unpinned checkpoints. Collection is O(number removed):
|
|
840
|
+
* commits never scan pinned nodes or the retained history. Parents are metadata rather than a
|
|
841
|
+
* storage dependency, so a retained node remains usable after pruning.
|
|
842
|
+
*/
|
|
843
|
+
gc(max?: number): CheckpointId[];
|
|
844
|
+
private collect;
|
|
845
|
+
private moveHead;
|
|
846
|
+
private addReference;
|
|
847
|
+
private removeReference;
|
|
848
|
+
private assertBranch;
|
|
849
|
+
}
|
|
850
|
+
|
|
680
851
|
/**
|
|
681
852
|
* Anything that can answer a Fetch `Request` with a `Response`.
|
|
682
853
|
*
|
|
@@ -687,6 +858,28 @@ interface FetchAPI$1 {
|
|
|
687
858
|
fetch(request: Request): Promise<Response>;
|
|
688
859
|
}
|
|
689
860
|
|
|
861
|
+
/**
|
|
862
|
+
* A point-in-time copy of everything a service namespace holds.
|
|
863
|
+
*
|
|
864
|
+
* All service state lives in the two core tables keyed by namespace, so a snapshot
|
|
865
|
+
* is generic: any service gets per-test rollback without knowing its own schema.
|
|
866
|
+
* Restoring is much cheaper than rebuilding a namespace from a corpus.
|
|
867
|
+
*/
|
|
868
|
+
type NamespaceSnapshot = {
|
|
869
|
+
namespace: string;
|
|
870
|
+
records: {
|
|
871
|
+
collection: string;
|
|
872
|
+
id: string;
|
|
873
|
+
seq: number;
|
|
874
|
+
value: string;
|
|
875
|
+
}[];
|
|
876
|
+
sequences: {
|
|
877
|
+
name: string;
|
|
878
|
+
kind: string;
|
|
879
|
+
value: number;
|
|
880
|
+
}[];
|
|
881
|
+
};
|
|
882
|
+
|
|
690
883
|
type WebhookEndpoint$1 = {
|
|
691
884
|
/** Stable id; generated when omitted. */
|
|
692
885
|
id?: string;
|
|
@@ -707,6 +900,7 @@ type WebhookMessage = {
|
|
|
707
900
|
body: string;
|
|
708
901
|
contentType: string;
|
|
709
902
|
tags: Record<string, string>;
|
|
903
|
+
headers?: Record<string, string>;
|
|
710
904
|
/** Wall-clock ISO-8601 time of publication. */
|
|
711
905
|
publishedAt: string;
|
|
712
906
|
};
|
|
@@ -716,6 +910,8 @@ type WebhookAttempt$1 = {
|
|
|
716
910
|
status: number | null;
|
|
717
911
|
error: string | null;
|
|
718
912
|
durationMs: number;
|
|
913
|
+
/** Exact receiver response body, when one was returned. */
|
|
914
|
+
responseBody?: string | null;
|
|
719
915
|
};
|
|
720
916
|
type WebhookDelivery$1 = {
|
|
721
917
|
id: string;
|
|
@@ -743,6 +939,8 @@ type PublishInput = {
|
|
|
743
939
|
/** Form parameters, when the vendor posts `application/x-www-form-urlencoded`. */
|
|
744
940
|
form?: Record<string, string>;
|
|
745
941
|
tags?: Record<string, string>;
|
|
942
|
+
/** Message-specific delivery headers, captured as part of durable message state. */
|
|
943
|
+
headers?: Record<string, string>;
|
|
746
944
|
/** Message id; generated when omitted. */
|
|
747
945
|
id?: string;
|
|
748
946
|
};
|
|
@@ -767,6 +965,12 @@ type WebhookHub = {
|
|
|
767
965
|
type ServiceInstance = FetchAPI$1 & {
|
|
768
966
|
reset(): Promise<void>;
|
|
769
967
|
};
|
|
968
|
+
type ServiceTimelineState = Readonly<{
|
|
969
|
+
snapshot: NamespaceSnapshot;
|
|
970
|
+
clock: Readonly<ReturnType<Clock["state"]>>;
|
|
971
|
+
rngState: number;
|
|
972
|
+
}>;
|
|
973
|
+
type ServiceCheckpoint = Checkpoint<ServiceTimelineState>;
|
|
770
974
|
type ServiceRuntime<T extends ServiceInstance> = FetchAPI$1 & {
|
|
771
975
|
readonly name: string;
|
|
772
976
|
readonly sqlite: SqliteClient$1;
|
|
@@ -788,6 +992,20 @@ type ServiceRuntime<T extends ServiceInstance> = FetchAPI$1 & {
|
|
|
788
992
|
reset(namespace?: string): Promise<void>;
|
|
789
993
|
snapshot(namespace?: string): NamespaceSnapshot;
|
|
790
994
|
restore(snapshot: NamespaceSnapshot, namespace?: string): void;
|
|
995
|
+
/** Capture the current branch. Mutating HTTP calls do this automatically. */
|
|
996
|
+
checkpoint(namespace?: string, branch?: string): ServiceCheckpoint;
|
|
997
|
+
/** Create an isolated branch, optionally from a historical checkpoint. */
|
|
998
|
+
branch(name: string, options?: {
|
|
999
|
+
namespace?: string;
|
|
1000
|
+
at?: string;
|
|
1001
|
+
}): ServiceCheckpoint;
|
|
1002
|
+
/** Restore a branch, clock, and PRNG to a checkpoint. */
|
|
1003
|
+
checkout(checkpoint: string, options?: {
|
|
1004
|
+
namespace?: string;
|
|
1005
|
+
branch?: string;
|
|
1006
|
+
}): void;
|
|
1007
|
+
/** Inspect the retained history for a namespace. */
|
|
1008
|
+
timeline(namespace?: string): Timeline<ServiceTimelineState>;
|
|
791
1009
|
};
|
|
792
1010
|
|
|
793
1011
|
/** Options every provider constructor accepts. */
|
|
@@ -1229,6 +1447,11 @@ type WebhookEndpoint = {
|
|
|
1229
1447
|
/** Added to every delivery, e.g. a routing scope for a shared receiver. */
|
|
1230
1448
|
headers?: Record<string, string>;
|
|
1231
1449
|
fetch?: (request: Request) => Promise<Response>;
|
|
1450
|
+
/** Injectable wall clock for signatures and delivery records. */
|
|
1451
|
+
now?: () => number;
|
|
1452
|
+
/** Injectable scheduler for timeouts and retry delays. */
|
|
1453
|
+
schedule?: (callback: () => void, delayMs: number) => unknown;
|
|
1454
|
+
cancel?: (handle: unknown) => void;
|
|
1232
1455
|
};
|
|
1233
1456
|
type WebhookAttempt = {
|
|
1234
1457
|
attempt: number;
|