@crvouga/mockingbird-service-google-calendar 1.7.0 → 1.8.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 +21 -4
- package/dist/{chunk-PTK5HWQN.js → chunk-KZPEFGHP.js} +205 -28
- package/dist/chunk-KZPEFGHP.js.map +7 -0
- package/dist/chunk-N3EE72VA.js +831 -0
- package/dist/chunk-N3EE72VA.js.map +7 -0
- package/dist/cli.js +2 -2
- package/dist/index.d.ts +31 -2
- package/dist/index.js +1 -1
- package/dist/server.d.ts +62 -4
- package/dist/server.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-FJRK3DQ5.js +0 -364
- package/dist/chunk-FJRK3DQ5.js.map +0 -7
- package/dist/chunk-PTK5HWQN.js.map +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,14 +1,31 @@
|
|
|
1
1
|
# Changelog — @crvouga/mockingbird-service-google-calendar
|
|
2
2
|
|
|
3
|
-
## 1.
|
|
3
|
+
## 1.8.0 (2026-10-02)
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
6
|
|
|
7
|
-
-
|
|
7
|
+
- coordinate HTTP and protocol mocks ([3168653](https://github.com/crvouga/mockingbird/commit/31686534c55a9823fdaa92afc9cc456cf741b809))
|
|
8
|
+
|
|
9
|
+
### Fixes and improvements
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
- decouple smoke types from built packages ([a4b31c6](https://github.com/crvouga/mockingbird/commit/a4b31c6205d92aa0c6f7c9de3518d5ae44d38829))
|
|
12
|
+
- protect child admin endpoints ([5410b94](https://github.com/crvouga/mockingbird/commit/5410b948a30dcedc21e9a70e44fd415c1ea25394))
|
|
13
|
+
- harden protocol startup and state ([6f5b557](https://github.com/crvouga/mockingbird/commit/6f5b557e87b48b31985949e04f3b5ef58f51d295))
|
|
14
|
+
- preserve checkpoints and lifecycle ([50e8c32](https://github.com/crvouga/mockingbird/commit/50e8c322feded2f7f45afce9d8cdef43c37ab9ab))
|
|
15
|
+
- clean branch state on reset ([3b714d4](https://github.com/crvouga/mockingbird/commit/3b714d4a5df8e75fee0bb31e98d7c7566e164381))
|
|
16
|
+
- type signal listener cleanup ([5279852](https://github.com/crvouga/mockingbird/commit/5279852e56ea60262ccf17aa6e46b3c31091a34a))
|
|
17
|
+
|
|
18
|
+
## 1.7.1 (2026-10-01)
|
|
19
|
+
|
|
20
|
+
### Fixes and improvements
|
|
10
21
|
|
|
11
|
-
-
|
|
22
|
+
- freeze clock before setting time ([a054a1d](https://github.com/crvouga/mockingbird/commit/a054a1defad62539d719b1d31c15107afea623bd))
|
|
23
|
+
|
|
24
|
+
## 1.7.0 (2026-09-30)
|
|
25
|
+
|
|
26
|
+
### Features
|
|
27
|
+
|
|
28
|
+
- record SQL timelines and serve the admin explorer ([8ced17a](https://github.com/crvouga/mockingbird/commit/8ced17ac398e386ef4e9d7e01fc7744c34b95d07))
|
|
12
29
|
|
|
13
30
|
## 1.6.1 (2026-09-30)
|
|
14
31
|
|
|
@@ -183,29 +183,30 @@ var createControlPlane = (context) => {
|
|
|
183
183
|
return json(200, { status: "ok", reset: target === "*" ? context.namespaces() : [target] });
|
|
184
184
|
},
|
|
185
185
|
"GET /namespaces": () => json(200, { default: context.defaultNamespace, namespaces: context.namespaces() }),
|
|
186
|
-
"GET /clock": () => json(200, context.clock.state()),
|
|
187
|
-
"POST /clock": ({ body }) => {
|
|
186
|
+
"GET /clock": ({ namespace }) => json(200, (context.namespaceClock?.(namespace) ?? context.clock).state()),
|
|
187
|
+
"POST /clock": ({ body, namespace }) => {
|
|
188
|
+
const clock = context.namespaceClock?.(namespace) ?? context.clock;
|
|
188
189
|
if (!isRecord(body))
|
|
189
190
|
return adminError(400, "expected a JSON object");
|
|
190
191
|
if (body.reset === true)
|
|
191
|
-
|
|
192
|
+
clock.reset();
|
|
193
|
+
if (body.freeze === true)
|
|
194
|
+
clock.freeze();
|
|
192
195
|
if (body.set !== void 0) {
|
|
193
196
|
const instant = parseInstant(body.set);
|
|
194
197
|
if (instant === void 0)
|
|
195
198
|
return adminError(400, "set: expected epoch ms or ISO-8601");
|
|
196
|
-
|
|
199
|
+
clock.set(instant);
|
|
197
200
|
}
|
|
198
201
|
if (body.advance !== void 0) {
|
|
199
202
|
const delta = parseDuration(body.advance);
|
|
200
203
|
if (delta === void 0)
|
|
201
204
|
return adminError(400, 'advance: expected ms or "15m"-style');
|
|
202
|
-
|
|
205
|
+
clock.advance(delta);
|
|
203
206
|
}
|
|
204
|
-
if (body.freeze === true)
|
|
205
|
-
context.clock.freeze();
|
|
206
207
|
if (body.freeze === false)
|
|
207
|
-
|
|
208
|
-
return json(200,
|
|
208
|
+
clock.unfreeze();
|
|
209
|
+
return json(200, clock.state());
|
|
209
210
|
},
|
|
210
211
|
"GET /faults": () => json(200, { faults: context.faults.list() }),
|
|
211
212
|
"POST /faults": ({ body, namespace }) => {
|
|
@@ -492,7 +493,33 @@ var faultResponse = (rule) => {
|
|
|
492
493
|
};
|
|
493
494
|
var createFaultRegistry = (rng = createRng(0), sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))) => {
|
|
494
495
|
const entries = [];
|
|
496
|
+
let isolated = false;
|
|
497
|
+
const scopedRngs = /* @__PURE__ */ new Map();
|
|
498
|
+
const random = (namespace) => {
|
|
499
|
+
if (!isolated || namespace === "default")
|
|
500
|
+
return rng;
|
|
501
|
+
let scoped = scopedRngs.get(namespace);
|
|
502
|
+
if (!scoped) {
|
|
503
|
+
scoped = createRng(rng.seed);
|
|
504
|
+
scopedRngs.set(namespace, scoped);
|
|
505
|
+
}
|
|
506
|
+
return scoped;
|
|
507
|
+
};
|
|
495
508
|
return {
|
|
509
|
+
isolateNamespaces() {
|
|
510
|
+
isolated = true;
|
|
511
|
+
},
|
|
512
|
+
snapshot(namespace) {
|
|
513
|
+
return {
|
|
514
|
+
rules: structuredClone(entries.map((entry, position) => ({
|
|
515
|
+
...entry.rule,
|
|
516
|
+
remaining: entry.remaining,
|
|
517
|
+
hits: entry.hits,
|
|
518
|
+
position
|
|
519
|
+
})).filter((entry) => entry.namespace === namespace)),
|
|
520
|
+
rngState: random(namespace).state()
|
|
521
|
+
};
|
|
522
|
+
},
|
|
496
523
|
add(rule) {
|
|
497
524
|
const existing = entries.findIndex((e) => e.rule.id === rule.id);
|
|
498
525
|
const entry = { rule, remaining: rule.count ?? null, hits: 0 };
|
|
@@ -512,6 +539,16 @@ var createFaultRegistry = (rng = createRng(0), sleep = (ms) => new Promise((reso
|
|
|
512
539
|
},
|
|
513
540
|
clear() {
|
|
514
541
|
entries.length = 0;
|
|
542
|
+
rng.reset();
|
|
543
|
+
scopedRngs.clear();
|
|
544
|
+
},
|
|
545
|
+
restore(namespace, state) {
|
|
546
|
+
for (let i = entries.length - 1; i >= 0; i--)
|
|
547
|
+
if (entries[i]?.rule.namespace === namespace)
|
|
548
|
+
entries.splice(i, 1);
|
|
549
|
+
for (const { remaining, hits, position, ...rule } of state.rules)
|
|
550
|
+
entries.splice(Math.min(position, entries.length), 0, { rule, remaining, hits });
|
|
551
|
+
random(namespace).setState(state.rngState);
|
|
515
552
|
},
|
|
516
553
|
async take(candidate) {
|
|
517
554
|
const hits = [];
|
|
@@ -521,7 +558,7 @@ var createFaultRegistry = (rng = createRng(0), sleep = (ms) => new Promise((reso
|
|
|
521
558
|
if (!matches(entry.rule, candidate))
|
|
522
559
|
continue;
|
|
523
560
|
const rate = entry.rule.rate ?? 1;
|
|
524
|
-
if (
|
|
561
|
+
if (random(candidate.namespace).next() >= rate)
|
|
525
562
|
continue;
|
|
526
563
|
entry.hits++;
|
|
527
564
|
if (entry.remaining !== null)
|
|
@@ -1089,7 +1126,8 @@ var annotateResponse = (response, extra) => {
|
|
|
1089
1126
|
var responseNotes = (response) => notes.get(response);
|
|
1090
1127
|
|
|
1091
1128
|
// ../core/dist/metrics.js
|
|
1092
|
-
var createMetrics = () => {
|
|
1129
|
+
var createMetrics = (partition = true) => {
|
|
1130
|
+
const namespaces = /* @__PURE__ */ new Map();
|
|
1093
1131
|
let requests = 0;
|
|
1094
1132
|
let faults = 0;
|
|
1095
1133
|
let totalDurationMs = 0;
|
|
@@ -1097,6 +1135,14 @@ var createMetrics = () => {
|
|
|
1097
1135
|
const unmatched = /* @__PURE__ */ new Map();
|
|
1098
1136
|
return {
|
|
1099
1137
|
record(entry) {
|
|
1138
|
+
if (partition) {
|
|
1139
|
+
let scoped = namespaces.get(entry.namespace);
|
|
1140
|
+
if (!scoped) {
|
|
1141
|
+
scoped = createMetrics(false);
|
|
1142
|
+
namespaces.set(entry.namespace, scoped);
|
|
1143
|
+
}
|
|
1144
|
+
scoped.record(entry);
|
|
1145
|
+
}
|
|
1100
1146
|
requests++;
|
|
1101
1147
|
totalDurationMs += entry.durationMs;
|
|
1102
1148
|
if (entry.faultId !== void 0)
|
|
@@ -1108,7 +1154,7 @@ var createMetrics = () => {
|
|
|
1108
1154
|
unmatched.set(route, (unmatched.get(route) ?? 0) + 1);
|
|
1109
1155
|
}
|
|
1110
1156
|
},
|
|
1111
|
-
report: () => ({
|
|
1157
|
+
report: (namespace) => namespace !== void 0 ? (namespaces.get(namespace) ?? createMetrics(false)).report() : {
|
|
1112
1158
|
requests,
|
|
1113
1159
|
byOperation: Object.fromEntries([...byOperation].sort(([a], [b]) => a.localeCompare(b))),
|
|
1114
1160
|
unmatched: [...unmatched].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).map(([route, count]) => {
|
|
@@ -1117,8 +1163,13 @@ var createMetrics = () => {
|
|
|
1117
1163
|
}),
|
|
1118
1164
|
faults,
|
|
1119
1165
|
totalDurationMs
|
|
1120
|
-
}
|
|
1121
|
-
reset() {
|
|
1166
|
+
},
|
|
1167
|
+
reset(namespace) {
|
|
1168
|
+
if (namespace !== void 0) {
|
|
1169
|
+
namespaces.delete(namespace);
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1172
|
+
namespaces.clear();
|
|
1122
1173
|
requests = 0;
|
|
1123
1174
|
faults = 0;
|
|
1124
1175
|
totalDurationMs = 0;
|
|
@@ -4090,7 +4141,7 @@ var stateAdminRoutes = (routes) => {
|
|
|
4090
4141
|
};
|
|
4091
4142
|
|
|
4092
4143
|
// ../core/dist/version.js
|
|
4093
|
-
var PACKAGE_VERSION = true ? "1.
|
|
4144
|
+
var PACKAGE_VERSION = true ? "1.8.0" : UNRELEASED_VERSION;
|
|
4094
4145
|
|
|
4095
4146
|
// ../core/dist/signing.js
|
|
4096
4147
|
var encoder = new TextEncoder();
|
|
@@ -4183,7 +4234,9 @@ var createWebhookHub = (options) => {
|
|
|
4183
4234
|
const faults = /* @__PURE__ */ new Map();
|
|
4184
4235
|
const held = /* @__PURE__ */ new Map();
|
|
4185
4236
|
const inFlight = /* @__PURE__ */ new Set();
|
|
4237
|
+
const controllers = /* @__PURE__ */ new Map();
|
|
4186
4238
|
let immediate = Promise.resolve();
|
|
4239
|
+
const snapshots = /* @__PURE__ */ new WeakMap();
|
|
4187
4240
|
const track = (work) => {
|
|
4188
4241
|
inFlight.add(work);
|
|
4189
4242
|
void work.finally(() => inFlight.delete(work));
|
|
@@ -4204,6 +4257,7 @@ var createWebhookHub = (options) => {
|
|
|
4204
4257
|
responseBody: null
|
|
4205
4258
|
};
|
|
4206
4259
|
const controller = new AbortController();
|
|
4260
|
+
controllers.set(delivery.id, controller);
|
|
4207
4261
|
const timer = scheduleTimer(() => controller.abort(), timeoutMs);
|
|
4208
4262
|
try {
|
|
4209
4263
|
const signed = await options.signer({
|
|
@@ -4233,6 +4287,7 @@ var createWebhookHub = (options) => {
|
|
|
4233
4287
|
} catch (error) {
|
|
4234
4288
|
record.error = controller.signal.aborted ? `timed out after ${timeoutMs}ms` : error instanceof Error ? error.message : String(error);
|
|
4235
4289
|
} finally {
|
|
4290
|
+
controllers.delete(delivery.id);
|
|
4236
4291
|
cancel(timer);
|
|
4237
4292
|
record.durationMs = now() - started;
|
|
4238
4293
|
delivery.attempts.push(record);
|
|
@@ -4250,6 +4305,8 @@ var createWebhookHub = (options) => {
|
|
|
4250
4305
|
if (!payloads.has(delivery.id))
|
|
4251
4306
|
return;
|
|
4252
4307
|
await attempt(delivery).then((ok) => {
|
|
4308
|
+
if (!payloads.has(delivery.id))
|
|
4309
|
+
return;
|
|
4253
4310
|
if (ok)
|
|
4254
4311
|
delivery.state = "delivered";
|
|
4255
4312
|
else
|
|
@@ -4311,6 +4368,37 @@ var createWebhookHub = (options) => {
|
|
|
4311
4368
|
fanOut(message);
|
|
4312
4369
|
};
|
|
4313
4370
|
const hub = {
|
|
4371
|
+
pending(namespace) {
|
|
4372
|
+
return inFlight.size + (held.get(namespace)?.length ?? 0) + [...deliveries.values()].filter((d) => d.namespace === namespace && d.state === "pending").length;
|
|
4373
|
+
},
|
|
4374
|
+
snapshot(namespace) {
|
|
4375
|
+
if (hub.pending(namespace) > 0)
|
|
4376
|
+
throw new Error("webhooks are not quiescent");
|
|
4377
|
+
const handle = {};
|
|
4378
|
+
snapshots.set(handle, structuredClone({
|
|
4379
|
+
namespace,
|
|
4380
|
+
endpoints: own.get(namespace) ?? [],
|
|
4381
|
+
messages: messages.filter((m) => m.namespace === namespace),
|
|
4382
|
+
deliveries: [...deliveries].filter(([, d]) => d.namespace === namespace),
|
|
4383
|
+
payloads: [...payloads].filter(([, p]) => p.message.namespace === namespace),
|
|
4384
|
+
faults: faults.get(namespace) ?? []
|
|
4385
|
+
}));
|
|
4386
|
+
return handle;
|
|
4387
|
+
},
|
|
4388
|
+
restore(namespace, handle) {
|
|
4389
|
+
const point = typeof handle === "object" && handle !== null ? snapshots.get(handle) : void 0;
|
|
4390
|
+
if (!point || point.namespace !== namespace || hub.pending(namespace) > 0)
|
|
4391
|
+
throw new Error("invalid webhook restore");
|
|
4392
|
+
hub.clear(namespace);
|
|
4393
|
+
const copied = structuredClone(point);
|
|
4394
|
+
own.set(namespace, copied.endpoints);
|
|
4395
|
+
messages.push(...copied.messages);
|
|
4396
|
+
for (const [id2, delivery] of copied.deliveries)
|
|
4397
|
+
deliveries.set(id2, delivery);
|
|
4398
|
+
for (const [id2, payload] of copied.payloads)
|
|
4399
|
+
payloads.set(id2, payload);
|
|
4400
|
+
faults.set(namespace, copied.faults);
|
|
4401
|
+
},
|
|
4314
4402
|
publish(input) {
|
|
4315
4403
|
const contentType = input.contentType ?? (input.form ? "application/x-www-form-urlencoded" : "application/json");
|
|
4316
4404
|
const body = typeof input.body === "string" ? input.body : input.form ? new URLSearchParams(input.form).toString() : JSON.stringify(input.body);
|
|
@@ -4401,6 +4489,7 @@ var createWebhookHub = (options) => {
|
|
|
4401
4489
|
for (const [id2, delivery] of deliveries) {
|
|
4402
4490
|
if (namespace !== void 0 && delivery.namespace !== namespace)
|
|
4403
4491
|
continue;
|
|
4492
|
+
controllers.get(id2)?.abort();
|
|
4404
4493
|
const timer = pending.get(id2);
|
|
4405
4494
|
if (timer !== void 0)
|
|
4406
4495
|
cancel(timer);
|
|
@@ -4588,6 +4677,20 @@ var createRuntime = (options) => {
|
|
|
4588
4677
|
const instances = /* @__PURE__ */ new Map();
|
|
4589
4678
|
const publicNamespaces = /* @__PURE__ */ new Set();
|
|
4590
4679
|
const branchRngs = /* @__PURE__ */ new Map();
|
|
4680
|
+
const namespaceClocks = /* @__PURE__ */ new Map();
|
|
4681
|
+
const namespaceForStorage = /* @__PURE__ */ new Map();
|
|
4682
|
+
let isolatedNamespaces = false;
|
|
4683
|
+
const namespaceClock = (name = DEFAULT_NAMESPACE) => {
|
|
4684
|
+
if (!isolatedNamespaces || name === DEFAULT_NAMESPACE)
|
|
4685
|
+
return clock;
|
|
4686
|
+
let found = namespaceClocks.get(name);
|
|
4687
|
+
if (!found) {
|
|
4688
|
+
found = createClock();
|
|
4689
|
+
namespaceClocks.set(name, found);
|
|
4690
|
+
}
|
|
4691
|
+
return found;
|
|
4692
|
+
};
|
|
4693
|
+
const fleetPoints = /* @__PURE__ */ new WeakMap();
|
|
4591
4694
|
const timelines = /* @__PURE__ */ new Map();
|
|
4592
4695
|
const branchStorage = /* @__PURE__ */ new Map();
|
|
4593
4696
|
const captured = /* @__PURE__ */ new Map();
|
|
@@ -4601,17 +4704,21 @@ var createRuntime = (options) => {
|
|
|
4601
4704
|
if (!NAMESPACE_PATTERN.test(key) || !NAMESPACE_PATTERN.test(publicNamespace)) {
|
|
4602
4705
|
throw new RangeError(`namespace must match ${NAMESPACE_PATTERN}: ${JSON.stringify(publicNamespace)}`);
|
|
4603
4706
|
}
|
|
4707
|
+
const createdContextRng = isolatedRng ?? (isolatedNamespaces && key !== DEFAULT_NAMESPACE ? createRng(options.seed ?? 0) : rng);
|
|
4604
4708
|
const created = options.create({
|
|
4605
4709
|
namespace: storageNamespace(key),
|
|
4606
4710
|
publicNamespace,
|
|
4607
4711
|
sqlite,
|
|
4608
|
-
clock,
|
|
4609
|
-
rng:
|
|
4712
|
+
clock: namespaceClock(publicNamespace),
|
|
4713
|
+
rng: createdContextRng
|
|
4610
4714
|
});
|
|
4611
4715
|
instances.set(key, created);
|
|
4716
|
+
namespaceForStorage.set(key, publicNamespace);
|
|
4612
4717
|
publicNamespaces.add(publicNamespace);
|
|
4613
4718
|
if (isolatedRng)
|
|
4614
4719
|
branchRngs.set(key, isolatedRng);
|
|
4720
|
+
else if (isolatedNamespaces && key !== DEFAULT_NAMESPACE)
|
|
4721
|
+
branchRngs.set(key, createdContextRng);
|
|
4615
4722
|
return created;
|
|
4616
4723
|
};
|
|
4617
4724
|
const instance = (name = DEFAULT_NAMESPACE) => instanceFor(name);
|
|
@@ -4629,7 +4736,7 @@ var createRuntime = (options) => {
|
|
|
4629
4736
|
captured.set(storage, snapshot2);
|
|
4630
4737
|
return Object.freeze({
|
|
4631
4738
|
snapshot: snapshot2,
|
|
4632
|
-
clock: Object.freeze(
|
|
4739
|
+
clock: Object.freeze(namespaceClock(namespaceForStorage.get(storage) ?? storage).state()),
|
|
4633
4740
|
rngState: (branchRngs.get(storage) ?? rng).state()
|
|
4634
4741
|
});
|
|
4635
4742
|
};
|
|
@@ -4639,7 +4746,7 @@ var createRuntime = (options) => {
|
|
|
4639
4746
|
return found;
|
|
4640
4747
|
instance(name);
|
|
4641
4748
|
found = new Timeline({
|
|
4642
|
-
now:
|
|
4749
|
+
now: namespaceClock(name).now,
|
|
4643
4750
|
...options.maxCheckpoints !== void 0 ? { maxCheckpoints: options.maxCheckpoints } : {}
|
|
4644
4751
|
});
|
|
4645
4752
|
found.commit(capture(name));
|
|
@@ -4666,12 +4773,13 @@ var createRuntime = (options) => {
|
|
|
4666
4773
|
const point = history2.checkout("main", at);
|
|
4667
4774
|
restoreNamespace(sqlite, storageNamespace(namespace), point.value.snapshot);
|
|
4668
4775
|
captured.set(namespace, point.value.snapshot);
|
|
4669
|
-
rng.setState(point.value.rngState);
|
|
4670
|
-
|
|
4776
|
+
(branchRngs.get(namespace) ?? rng).setState(point.value.rngState);
|
|
4777
|
+
const selectedClock = namespaceClock(namespace);
|
|
4778
|
+
selectedClock.set(point.value.clock.now);
|
|
4671
4779
|
if (point.value.clock.frozen)
|
|
4672
|
-
|
|
4780
|
+
selectedClock.freeze();
|
|
4673
4781
|
else
|
|
4674
|
-
|
|
4782
|
+
selectedClock.unfreeze();
|
|
4675
4783
|
}
|
|
4676
4784
|
return namespace;
|
|
4677
4785
|
}
|
|
@@ -4729,11 +4837,12 @@ var createRuntime = (options) => {
|
|
|
4729
4837
|
const storage = ensureBranch(namespace, branchName);
|
|
4730
4838
|
restoreNamespace(sqlite, storageNamespace(storage), point.value.snapshot);
|
|
4731
4839
|
captured.set(storage, point.value.snapshot);
|
|
4732
|
-
|
|
4840
|
+
const selectedClock = namespaceClock(namespace);
|
|
4841
|
+
selectedClock.set(point.value.clock.now);
|
|
4733
4842
|
if (point.value.clock.frozen)
|
|
4734
|
-
|
|
4843
|
+
selectedClock.freeze();
|
|
4735
4844
|
else
|
|
4736
|
-
|
|
4845
|
+
selectedClock.unfreeze();
|
|
4737
4846
|
(branchRngs.get(storage) ?? rng).setState(point.value.rngState);
|
|
4738
4847
|
};
|
|
4739
4848
|
const reset = async (name = DEFAULT_NAMESPACE) => {
|
|
@@ -4741,10 +4850,21 @@ var createRuntime = (options) => {
|
|
|
4741
4850
|
options.webhooks?.clear();
|
|
4742
4851
|
for (const each of instances.values())
|
|
4743
4852
|
await each.reset();
|
|
4853
|
+
for (const each of branchRngs.values())
|
|
4854
|
+
each.reset();
|
|
4744
4855
|
timelines.clear();
|
|
4856
|
+
for (const storage of branchStorage.values()) {
|
|
4857
|
+
instances.delete(storage);
|
|
4858
|
+
branchRngs.delete(storage);
|
|
4859
|
+
namespaceForStorage.delete(storage);
|
|
4860
|
+
}
|
|
4745
4861
|
branchStorage.clear();
|
|
4746
|
-
branchRngs.clear();
|
|
4747
4862
|
captured.clear();
|
|
4863
|
+
faults.clear();
|
|
4864
|
+
clock.reset();
|
|
4865
|
+
rng.reset();
|
|
4866
|
+
for (const each of namespaceClocks.values())
|
|
4867
|
+
each.reset();
|
|
4748
4868
|
return;
|
|
4749
4869
|
}
|
|
4750
4870
|
options.webhooks?.clear(name);
|
|
@@ -4762,11 +4882,18 @@ var createRuntime = (options) => {
|
|
|
4762
4882
|
else
|
|
4763
4883
|
clearNamespace(sqlite, storageNamespace(storage));
|
|
4764
4884
|
branchStorage.delete(mapping);
|
|
4885
|
+
instances.delete(storage);
|
|
4886
|
+
namespaceForStorage.delete(storage);
|
|
4765
4887
|
branchRngs.delete(storage);
|
|
4766
4888
|
captured.delete(storage);
|
|
4767
4889
|
}
|
|
4768
4890
|
timelines.delete(name);
|
|
4769
4891
|
captured.delete(name);
|
|
4892
|
+
faults.restore(name, { rules: [], rngState: createRng(options.seed ?? 0).state() });
|
|
4893
|
+
namespaceClock(name).reset();
|
|
4894
|
+
(branchRngs.get(name) ?? rng).reset();
|
|
4895
|
+
journal.clear(name);
|
|
4896
|
+
metrics.reset(name);
|
|
4770
4897
|
};
|
|
4771
4898
|
const snapshot = (name = DEFAULT_NAMESPACE) => {
|
|
4772
4899
|
return checkpoint(name, "main").value.snapshot;
|
|
@@ -4804,6 +4931,53 @@ var createRuntime = (options) => {
|
|
|
4804
4931
|
rng,
|
|
4805
4932
|
credentials,
|
|
4806
4933
|
webhooks: options.webhooks,
|
|
4934
|
+
isolateNamespaces() {
|
|
4935
|
+
if (publicNamespaces.size > 1)
|
|
4936
|
+
throw new Error("enable namespace isolation before creating named namespaces");
|
|
4937
|
+
isolatedNamespaces = true;
|
|
4938
|
+
faults.isolateNamespaces();
|
|
4939
|
+
},
|
|
4940
|
+
namespaceClock,
|
|
4941
|
+
namespaceOf(request) {
|
|
4942
|
+
const url = new URL(request.url);
|
|
4943
|
+
const prefixed = PATH_PREFIX.exec(url.pathname);
|
|
4944
|
+
const selected = request.headers.get(NAMESPACE_HEADER) ?? (prefixed ? decodeURIComponent(prefixed[1]) : void 0);
|
|
4945
|
+
const path = prefixed ? prefixed[2] ?? "/" : url.pathname;
|
|
4946
|
+
if (path === "/__admin" || path.startsWith("/__admin/"))
|
|
4947
|
+
return url.searchParams.get("namespace") ?? selected ?? DEFAULT_NAMESPACE;
|
|
4948
|
+
if (selected !== void 0)
|
|
4949
|
+
return selected;
|
|
4950
|
+
const credential = options.credential?.(request);
|
|
4951
|
+
return (credential !== void 0 ? credentials.get(credential) : void 0) ?? DEFAULT_NAMESPACE;
|
|
4952
|
+
},
|
|
4953
|
+
fleetSnapshot(namespace) {
|
|
4954
|
+
instance(namespace);
|
|
4955
|
+
const handle = {};
|
|
4956
|
+
fleetPoints.set(handle, {
|
|
4957
|
+
namespace,
|
|
4958
|
+
state: capture(namespace),
|
|
4959
|
+
faults: faults.snapshot(namespace),
|
|
4960
|
+
webhooks: options.webhooks?.snapshot(namespace)
|
|
4961
|
+
});
|
|
4962
|
+
return handle;
|
|
4963
|
+
},
|
|
4964
|
+
fleetRestore(handle, namespace) {
|
|
4965
|
+
const point = typeof handle === "object" && handle !== null ? fleetPoints.get(handle) : void 0;
|
|
4966
|
+
if (!point || point.namespace !== namespace)
|
|
4967
|
+
throw new Error("invalid fleet checkpoint");
|
|
4968
|
+
restoreNamespace(sqlite, storageNamespace(namespace), point.state.snapshot);
|
|
4969
|
+
captured.set(namespace, point.state.snapshot);
|
|
4970
|
+
const selectedClock = namespaceClock(namespace);
|
|
4971
|
+
selectedClock.freeze();
|
|
4972
|
+
selectedClock.set(point.state.clock.now);
|
|
4973
|
+
if (!point.state.clock.frozen)
|
|
4974
|
+
selectedClock.unfreeze();
|
|
4975
|
+
(branchRngs.get(namespace) ?? rng).setState(point.state.rngState);
|
|
4976
|
+
faults.restore(namespace, point.faults);
|
|
4977
|
+
if (point.webhooks !== void 0)
|
|
4978
|
+
options.webhooks?.restore(namespace, point.webhooks);
|
|
4979
|
+
timelines.delete(namespace);
|
|
4980
|
+
},
|
|
4807
4981
|
applyPreset: (name, namespace = DEFAULT_NAMESPACE, overrides = {}) => {
|
|
4808
4982
|
const preset = options.presets?.[name];
|
|
4809
4983
|
if (!preset)
|
|
@@ -4979,6 +5153,7 @@ var createRuntime = (options) => {
|
|
|
4979
5153
|
startedAt: wallNow(),
|
|
4980
5154
|
wallNow,
|
|
4981
5155
|
clock,
|
|
5156
|
+
namespaceClock,
|
|
4982
5157
|
faults,
|
|
4983
5158
|
metrics,
|
|
4984
5159
|
journal,
|
|
@@ -6160,6 +6335,8 @@ var GoogleCalendarAPI = class {
|
|
|
6160
6335
|
};
|
|
6161
6336
|
|
|
6162
6337
|
export {
|
|
6338
|
+
createClock,
|
|
6339
|
+
parseDuration,
|
|
6163
6340
|
document2 as document,
|
|
6164
6341
|
operationIds,
|
|
6165
6342
|
supportedOperationIds,
|
|
@@ -6175,4 +6352,4 @@ export {
|
|
|
6175
6352
|
emailFromCode,
|
|
6176
6353
|
GoogleCalendarAPI
|
|
6177
6354
|
};
|
|
6178
|
-
//# sourceMappingURL=chunk-
|
|
6355
|
+
//# sourceMappingURL=chunk-KZPEFGHP.js.map
|