@voltro/testing 0.86.0 → 0.88.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mockClock.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Effect as e } from "effect";
2
- //#region src/mockClock.ts
2
+ // src/mockClock.ts
3
3
  var t = Symbol.for("voltro/testing/mockClock.installed"), n = () => globalThis, r = (e, t) => new Proxy(e, {
4
4
  construct: (e, n, r) => Reflect.construct(e, n.length === 0 ? [t()] : n, r),
5
5
  apply: () => new e(t()).toString(),
@@ -74,5 +74,4 @@ var t = Symbol.for("voltro/testing/mockClock.installed"), n = () => globalThis,
74
74
  default: throw Error(`mockClock: unknown unit '${r}'`);
75
75
  }
76
76
  };
77
- //#endregion
78
77
  export { a as MockClock, c as frozenTime, s as withFrozenTime };
package/dist/mockLLM.js CHANGED
@@ -1,4 +1,4 @@
1
- //#region src/mockLLM.ts
1
+ // src/mockLLM.ts
2
2
  var e = class {
3
3
  queue;
4
4
  calls = [];
@@ -15,5 +15,4 @@ var e = class {
15
15
  return this.queue.length;
16
16
  }
17
17
  };
18
- //#endregion
19
18
  export { e as MockLLM };
@@ -1,4 +1,4 @@
1
- //#region src/mockWebhooks.ts
1
+ // src/mockWebhooks.ts
2
2
  var e = class {
3
3
  emitted = [];
4
4
  async emit(e, t) {
@@ -22,5 +22,4 @@ var e = class {
22
22
  this.emitted.length = 0;
23
23
  }
24
24
  };
25
- //#endregion
26
25
  export { e as MockWebhooks };
package/dist/platform.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { describe as e, expect as t, it as n } from "vitest";
2
- //#region src/platformConformance.ts
2
+ // src/platformConformance.ts
3
3
  var r = (r, i) => {
4
4
  let a = i.scratchKey ?? "voltro:conformance", o = async () => i.adapter();
5
5
  e(`platform adapter conformance — ${r}`, () => {
@@ -38,5 +38,4 @@ var r = (r, i) => {
38
38
  });
39
39
  });
40
40
  };
41
- //#endregion
42
41
  export { r as platformAdapterConformance };
package/dist/reachable.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import e from "node:net";
2
2
  import { describe as t } from "vitest";
3
- //#region src/reachable.ts
3
+ // src/reachable.ts
4
4
  var n = (t) => new Promise((n) => {
5
5
  let r = new e.Socket(), i = (e) => {
6
6
  clearTimeout(a), r.destroy(), n(e);
@@ -23,5 +23,4 @@ var n = (t) => new Promise((n) => {
23
23
  n !== void 0 && n !== "" && console.log(`[engine] ${e}: ${n}`);
24
24
  } catch {}
25
25
  };
26
- //#endregion
27
26
  export { r as describeIfAvailable, i as describeIfReachable, n as isTcpReachable, a as reportEngineVersion };
@@ -1,6 +1,6 @@
1
1
  import { Effect as e, Schema as t } from "effect";
2
2
  import { ApiUnavailable as n } from "@voltro/protocol";
3
- //#region src/serviceApiMock.ts
3
+ // src/serviceApiMock.ts
4
4
  var r = (r, i, a = {}) => {
5
5
  let o = a.name ?? "mock", s = [], c = /* @__PURE__ */ new Map(), l = (e, t) => `${e}\u0000${JSON.stringify(t)}`, u = async (e, a, c) => {
6
6
  let l = r[e];
@@ -49,5 +49,4 @@ var r = (r, i, a = {}) => {
49
49
  }
50
50
  };
51
51
  };
52
- //#endregion
53
52
  export { r as makeServiceApiMock };
package/dist/subject.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { anonymousSubject as e, systemSubject as t } from "@voltro/protocol";
2
- //#region src/subject.ts
2
+ // src/subject.ts
3
3
  var n = "test-tenant", r = (e, t, n) => ({
4
4
  type: e,
5
5
  id: t,
@@ -7,5 +7,4 @@ var n = "test-tenant", r = (e, t, n) => ({
7
7
  scopes: n.scopes ?? [],
8
8
  ...n.metadata === void 0 ? {} : { metadata: n.metadata }
9
9
  }), i = (e, t = {}) => r("user", e, t), a = (e, t = {}) => r("apiKey", e, t), o = (e, t = {}) => r("serviceAccount", e, t), s = (t = null) => e(t), c = (e = "job:test", n) => n === void 0 ? t(e) : t(e, n);
10
- //#endregion
11
10
  export { n as TEST_TENANT_ID, s as anonymous, a as apiKey, o as serviceAccount, c as system, i as user };
@@ -1,6 +1,6 @@
1
1
  import { changeDelete as e, changeInsert as t, changeSoftDelete as n, changeUpdate as r } from "@voltro/database";
2
2
  import { createLogger as i } from "@voltro/logger";
3
- //#region src/subscribeContext.ts
3
+ // src/subscribeContext.ts
4
4
  var a = (e = {}) => {
5
5
  let t = e.id ?? "test", n = e.store ?? new Proxy({}, { get: (e, t) => {
6
6
  throw Error(`makeSubscribeContext: this subscriber reached ctx.store.${String(t)} and the test passed no store. Pass \`{ store: makeTestContext().store }\` so the subscriber and the code under test share one — an empty stand-in would let a read of the wrong table pass.`);
@@ -12,5 +12,4 @@ var a = (e = {}) => {
12
12
  ...e.publish === void 0 ? {} : { publish: e.publish }
13
13
  };
14
14
  };
15
- //#endregion
16
15
  export { e as changeDelete, t as changeInsert, n as changeSoftDelete, r as changeUpdate, a as makeSubscribeContext };
@@ -0,0 +1,99 @@
1
+ import { AnyEventDescriptor } from '@voltro/protocol';
2
+ import { Context } from 'effect';
3
+ import { Effect } from 'effect';
4
+ import { Layer } from 'effect';
5
+ import { PluginInspectRequest } from '@voltro/protocol';
6
+ import { PluginInspectResponse } from '@voltro/protocol';
7
+ import { PluginPrivacyRequest } from '@voltro/protocol';
8
+ import { PluginPrivacyTarget } from '@voltro/protocol';
9
+ import { VoltroPlugin } from '@voltro/protocol';
10
+
11
+ /**
12
+ * Register the system contract against real exports and descriptor surfaces.
13
+ * Refuses incomplete inventories before registering any tests. This suite does
14
+ * not establish SQL parity, ordinary boot, four dashboard layers or capacity.
15
+ */
16
+ export declare const systemContractConformance: (plugin: VoltroPlugin, options: SystemContractConformanceOptions) => void;
17
+
18
+ export declare interface SystemContractConformanceOptions {
19
+ readonly manifest: SystemContractManifest;
20
+ /** Actual module namespace imports, never copies of the system exports. */
21
+ readonly strategies: Readonly<Record<string, unknown>>;
22
+ readonly ports: Readonly<Record<string, unknown>>;
23
+ readonly testing: Readonly<Record<string, unknown>>;
24
+ /** Actual descriptors used by discovery/codegen. Hidden events are not inferred. */
25
+ readonly eventCatalog: ReadonlyArray<AnyEventDescriptor>;
26
+ readonly eventFixtures: Readonly<Record<string, SystemEventFixture>>;
27
+ readonly stages: Readonly<Record<'take' | 'configure' | 'hook' | 'override' | 'extendOrReplace', SystemContractProbe>>;
28
+ readonly privacy: Readonly<Record<string, (kind: PluginPrivacyTarget['kind']) => Effect.Effect<SystemPrivacyFixture, unknown>>>;
29
+ /** Exactly one case per contributed endpoint, keyed as "GET path". */
30
+ readonly inspect: Readonly<Record<string, SystemInspectFixture>>;
31
+ }
32
+
33
+ /** Export this inventory beside the system's public strategies and ports. */
34
+ export declare interface SystemContractManifest {
35
+ readonly slots: Readonly<Record<string, {
36
+ readonly defaultExport: string;
37
+ readonly fixtureExport: string;
38
+ }>>;
39
+ readonly ports: Readonly<Record<string, {
40
+ readonly tagExport: string;
41
+ readonly fakeLayerExport: string;
42
+ readonly fixtureExport: string;
43
+ }>>;
44
+ readonly events: ReadonlyArray<string>;
45
+ }
46
+
47
+ /** A measured observation. Use inputs that distinguish defaults from overrides. */
48
+ export declare interface SystemContractProbe {
49
+ readonly run: () => Effect.Effect<unknown, unknown>;
50
+ readonly expected: unknown;
51
+ }
52
+
53
+ export declare interface SystemEventFixture {
54
+ readonly descriptor: AnyEventDescriptor;
55
+ readonly key: unknown;
56
+ readonly payload: unknown;
57
+ }
58
+
59
+ export declare interface SystemInspectFixture {
60
+ readonly request: PluginInspectRequest;
61
+ readonly expected: PluginInspectResponse;
62
+ }
63
+
64
+ export declare interface SystemPortFixture {
65
+ readonly kind: 'port';
66
+ readonly tag: unknown;
67
+ readonly fakeLayer: unknown;
68
+ readonly probe: SystemContractProbe;
69
+ }
70
+
71
+ /** Preserve concrete Tag/Layer types; the suite owns scope acquisition and cleanup. */
72
+ export declare const systemPortFixture: <Identifier, Service>(options: {
73
+ readonly tag: Context.Service<Identifier, Service>;
74
+ readonly fakeLayer: Layer.Layer<Identifier>;
75
+ readonly read: Effect.Effect<unknown, unknown, Identifier>;
76
+ readonly expected: unknown;
77
+ }) => SystemPortFixture;
78
+
79
+ /** A fresh, seeded fixture; read() must include peer/tenant rows that must survive. */
80
+ export declare interface SystemPrivacyFixture {
81
+ /** Explicitly reviewed tenant-wide table without subject facts; erase retains every row. */
82
+ readonly subjectData?: 'none';
83
+ readonly request: PluginPrivacyRequest;
84
+ readonly read: () => Effect.Effect<ReadonlyArray<unknown>, unknown>;
85
+ readonly before: ReadonlyArray<unknown>;
86
+ readonly after: ReadonlyArray<unknown>;
87
+ readonly exported: unknown;
88
+ readonly close: Effect.Effect<void>;
89
+ }
90
+
91
+ /** A ./testing export that exercises the imported default and configured override. */
92
+ export declare interface SystemSlotFixture {
93
+ readonly kind: 'slot';
94
+ readonly defaultImplementation: unknown;
95
+ readonly defaultProbe: SystemContractProbe;
96
+ readonly overrideProbe: SystemContractProbe;
97
+ }
98
+
99
+ export { }
package/dist/system.js ADDED
@@ -0,0 +1,93 @@
1
+ import { testEventBus as e } from "./testEventBus.js";
2
+ import { Context as t, Effect as n, Layer as r } from "effect";
3
+ import { createPluginPrivacyRegistry as i } from "@voltro/protocol";
4
+ import { describe as a, expect as o, it as s } from "vitest";
5
+ // src/systemContractConformance.ts
6
+ var c = (e) => ({
7
+ kind: "port",
8
+ tag: e.tag,
9
+ fakeLayer: e.fakeLayer,
10
+ probe: {
11
+ run: () => n.scoped(e.read.pipe(n.provide(e.fakeLayer))),
12
+ expected: e.expected
13
+ }
14
+ }), l = (e, t) => {
15
+ if (e.some((e) => !e.trim()) || new Set(e).size !== e.length) throw Error(`Invalid system ${t} inventory`);
16
+ }, u = (e, t, n) => {
17
+ if (l(e, n), l(t, n), JSON.stringify([...e].sort()) !== JSON.stringify([...t].sort())) throw Error(`Incomplete system ${n} fixtures`);
18
+ }, d = (e) => typeof e == "object" && !!e, f = (e) => d(e) && typeof e.run == "function" && e.expected !== void 0, p = (e) => d(e) && e.kind === "slot" && typeof e.defaultImplementation == "function" && f(e.defaultProbe) && f(e.overrideProbe), m = (e) => d(e) && e.kind === "port" && t.isKey(e.tag) && r.isLayer(e.fakeLayer) && f(e.probe), h = (e, t) => `${e} ${t.replace(/^\//, "")}`, g = (t, r) => {
19
+ let { manifest: c } = r, g = t.services !== void 0 || (t.routes?.length ?? 0) > 0 || (t.extendSchema?.tables?.length ?? 0) > 0 || (t.inspectEndpoints?.length ?? 0) > 0 || t.onActivate !== void 0 || t.interceptMutation !== void 0;
20
+ if (!t.name.trim() || !g || Object.keys(c.slots).length === 0) throw Error("System conformance requires an implemented system with strategy slots");
21
+ let _ = (t.extendSchema?.tables ?? []).map((e) => {
22
+ if (!d(e) || typeof e.tableName != "string") throw Error("System conformance requires named table descriptors");
23
+ return e.tableName;
24
+ });
25
+ u(Object.keys(r.stages), [
26
+ "take",
27
+ "configure",
28
+ "hook",
29
+ "override",
30
+ "extendOrReplace"
31
+ ], "stages");
32
+ for (let e of Object.values(r.stages)) if (!f(e)) throw Error("System stages require measured probes");
33
+ u(Object.keys(r.privacy), _, "privacy"), u(r.eventCatalog.map((e) => e.name), c.events, "events"), u(Object.keys(r.eventFixtures), c.events, "events");
34
+ let v = t.inspectEndpoints ?? [];
35
+ u(Object.keys(r.inspect), v.map((e) => h(e.method, e.path)), "inspect");
36
+ let y = Object.entries(c.slots).map(([e, t]) => {
37
+ l([e], "slots");
38
+ let n = r.strategies[t.defaultExport], i = r.testing[t.fixtureExport];
39
+ if (typeof n != "function" || !p(i) || i.defaultImplementation !== n) throw Error(`System slot requires its actual default export and fixture: ${e}`);
40
+ return {
41
+ name: e,
42
+ fixture: i
43
+ };
44
+ }), b = Object.entries(c.ports).map(([e, t]) => {
45
+ l([e], "ports");
46
+ let n = r.testing[t.fixtureExport];
47
+ if (!m(n) || n.tag !== r.ports[t.tagExport] || n.fakeLayer !== r.testing[t.fakeLayerExport]) throw Error(`System port requires its actual Tag, fake Layer and fixture: ${e}`);
48
+ return {
49
+ name: e,
50
+ fixture: n
51
+ };
52
+ });
53
+ for (let e of r.eventCatalog) if (e.kind !== "event" || r.eventFixtures[e.name]?.descriptor !== e) throw Error(`System event requires its actual catalog descriptor: ${e.name}`);
54
+ for (let e of v) {
55
+ let t = r.inspect[h(e.method, e.path)];
56
+ if (t.request.method !== e.method || t.expected.kind !== "json" || (t.expected.status ?? 200) !== 200 || t.expected.data === void 0) throw Error("System inspect fixture must observe successful JSON");
57
+ }
58
+ let x = i([t]);
59
+ if (_.length > 0 && (!t.subjectPrivacy || x.coverage("user").missing.length > 0 || x.coverage("guest").missing.length > 0 || !t.subjectPrivacy.kinds.includes("user") || !t.subjectPrivacy.kinds.includes("guest"))) throw Error("System tables require user and guest erase/export coverage");
60
+ let S = async (e) => {
61
+ o(await n.runPromise(n.suspend(e.run))).toEqual(e.expected);
62
+ };
63
+ a(`system contract — ${t.name}`, () => {
64
+ for (let [e, t] of Object.entries(r.stages)) s(`stage ${e}`, () => S(t));
65
+ for (let { name: e, fixture: t } of y) s(`slot ${e}: exported default and configured override`, async () => {
66
+ o(t.overrideProbe.expected).not.toEqual(t.defaultProbe.expected), await S(t.defaultProbe), await S(t.overrideProbe);
67
+ });
68
+ for (let { name: e, fixture: t } of b) s(`port ${e}: scoped fake Layer`, () => S(t.probe));
69
+ for (let t of r.eventCatalog) s(`event ${t.name}: real validation and delivery`, async () => {
70
+ let n = r.eventFixtures[t.name], i = e(), a = i.subscribe(t, n.key);
71
+ try {
72
+ await i.publish(t, n.key, n.payload), o(a.received).toEqual([n.payload]), o(a.missedCount).toBe(0);
73
+ } finally {
74
+ a.stop(), i.reset();
75
+ }
76
+ });
77
+ for (let e of _) for (let i of ["user", "guest"]) s(`table ${e}: ${i} export, erase, peers and idempotent retry`, () => n.runPromise(n.acquireUseRelease(r.privacy[e](i), (e) => n.gen(function* () {
78
+ o(e.request.target.kind).toBe(i), o(e.before.length).toBeGreaterThan(0), e.subjectData === "none" ? o(e.before).toEqual(e.after) : o(e.before).not.toEqual(e.after), o(yield* e.read()).toEqual(e.before);
79
+ let n = yield* x.exportSubject(e.request);
80
+ o(n.plugins).toEqual([{
81
+ name: t.name,
82
+ data: e.exported
83
+ }]);
84
+ let r = yield* x.eraseSubject(e.request);
85
+ o(r.completed).toEqual([t.name]), o(yield* e.read()).toEqual(e.after), yield* x.eraseSubject(e.request), o(yield* e.read()).toEqual(e.after);
86
+ }), (e) => e.close)));
87
+ for (let e of v) s(`inspect ${h(e.method, e.path)}: actual handler`, async () => {
88
+ let t = r.inspect[h(e.method, e.path)];
89
+ o(await n.runPromise(n.suspend(() => e.handler(t.request)))).toEqual(t.expected);
90
+ });
91
+ });
92
+ };
93
+ export { g as systemContractConformance, c as systemPortFixture };
package/dist/testApps.js CHANGED
@@ -4,7 +4,7 @@ import { randomBytes as a } from "node:crypto";
4
4
  import { spawn as o } from "node:child_process";
5
5
  import { createRequire as s } from "node:module";
6
6
  import { dirname as c, join as l } from "node:path";
7
- //#region src/testApps.ts
7
+ // src/testApps.ts
8
8
  var u = () => new Promise((e, t) => {
9
9
  let n = i.createServer();
10
10
  n.once("error", t), n.listen(0, "127.0.0.1", () => {
@@ -107,5 +107,4 @@ var u = () => new Promise((e, t) => {
107
107
  stop: C
108
108
  };
109
109
  };
110
- //#endregion
111
110
  export { h as startTestApps };
@@ -1,48 +1,50 @@
1
1
  import { MockClock as e } from "./mockClock.js";
2
- import { MockWebhooks as t } from "./mockWebhooks.js";
3
- import { testEventBus as n } from "./testEventBus.js";
4
- import { MockLLM as r } from "./mockLLM.js";
5
- import { allRegisteredTables as i, clearRelationsRegistry as a, registerRelations as o } from "@voltro/database";
6
- import { Layer as s } from "effect";
7
- import { anonymousSubject as c, composeRpcInterceptors as l, tenantScopedSubject as u } from "@voltro/protocol";
8
- import { InMemoryDataStore as d, NO_ROW_FILTER as f, appValidation as p, applyRowFilterToDescriptor as m, clearSystemStoreHandle as h, getRowFilter as g, getSystemStoreHandle as _, makeAppAccess as v, makeConnectionState as y, makeDataLoader as b, makeEventPublisher as ee, makeFieldCipher as x, makeOutboxFacade as S, makeSchemaRegistry as C, resolveRowFilterScopeFor as w, resolveTransactionSubject as T, runProvidedEffect as E, setFieldCipher as te, setSystemStoreHandle as D, wrapStoreWithMixinBehaviour as O } from "@voltro/runtime";
9
- import { installEnvSnapshot as k } from "@voltro/env";
10
- //#region src/testContext.ts
11
- var A = (e) => e, j = "00000000000000000000000000000000", M = /* @__PURE__ */ new WeakMap(), N = /* @__PURE__ */ new WeakMap(), P = (e, t) => {
12
- let n = N.get(e);
2
+ import { recordTestRawStore as t, registerTestFieldKeys as n } from "./fieldKeys.js";
3
+ import { MockWebhooks as r } from "./mockWebhooks.js";
4
+ import { testEventBus as i } from "./testEventBus.js";
5
+ import { MockLLM as a } from "./mockLLM.js";
6
+ import { allRegisteredTables as o, clearRelationsRegistry as s, registerRelations as c } from "@voltro/database";
7
+ import { Effect as l, Layer as u } from "effect";
8
+ import { anonymousSubject as d, composeRpcInterceptors as f, tenantScopedSubject as p } from "@voltro/protocol";
9
+ import { InMemoryDataStore as m, NO_ROW_FILTER as h, appValidation as g, applyRowFilterToDescriptor as _, clearSystemStoreHandle as v, getRowFilter as y, getSystemStoreHandle as b, installComputedQueryCacheCapture as x, makeAppAccess as S, makeConnectionState as ee, makeDataLoader as te, makeEventPublisher as ne, makeFieldCipher as C, makeOutboxFacade as w, makeSchemaRegistry as T, queryCachePolicy as E, recordingStore as D, resolveRowFilterScopeFor as O, resolveTransactionSubject as k, runProvidedEffect as A, setFieldCipher as j, setSystemStoreHandle as M, wrapStoreWithMixinBehaviour as N } from "@voltro/runtime";
10
+ import { installEnvSnapshot as re } from "@voltro/env";
11
+ import { Cache as ie, layerMemory as ae } from "@voltro/cache";
12
+ // src/testContext.ts
13
+ var P = (e) => e, F = "00000000000000000000000000000000", I = /* @__PURE__ */ new WeakMap(), L = /* @__PURE__ */ new WeakMap(), R = (e, t) => {
14
+ let n = L.get(e);
13
15
  if (n === void 0) throw Error("withRpcConnection requires a context created by makeTestContext");
14
16
  return n(t);
15
- }, F = /* @__PURE__ */ new WeakMap(), I = /* @__PURE__ */ new WeakMap(), L = /* @__PURE__ */ new WeakMap(), R = (e) => L.get(e) ?? [], z = /* @__PURE__ */ new WeakMap(), B = (e, t, n) => {
16
- z.set(e, {
17
+ }, z = /* @__PURE__ */ new WeakMap(), B = /* @__PURE__ */ new WeakMap(), V = /* @__PURE__ */ new WeakMap(), H = (e) => V.get(e) ?? [], U = /* @__PURE__ */ new WeakMap(), W = /* @__PURE__ */ new WeakMap(), G = (e) => W.get(e), K = (e, t, n) => {
18
+ U.set(e, {
17
19
  publicApi: t,
18
20
  ...n === void 0 ? {} : { remoteAddr: n }
19
21
  });
20
- }, V = (e) => z.get(e), H = /* @__PURE__ */ new WeakMap(), U = (e, t) => {
21
- let n = L.get(e) ?? [], r = t === "mutation" ? "interceptMutation" : t === "query" ? "interceptQuery" : "interceptAction", i = [];
22
+ }, q = (e) => U.get(e), J = /* @__PURE__ */ new WeakMap(), oe = (e, t) => {
23
+ let n = V.get(e) ?? [], r = t === "mutation" ? "interceptMutation" : t === "query" ? "interceptQuery" : "interceptAction", i = [];
22
24
  for (let e of n) {
23
25
  let t = e[r];
24
26
  typeof t == "function" && i.push(t);
25
27
  }
26
- return l(i);
27
- }, W = (e) => {
28
- let t = (L.get(e) ?? []).map((e) => e.services).filter((e) => e !== void 0), n = H.get(e) ?? [], r = [...t, ...n];
29
- if (r.length !== 0) return s.mergeAll(...r);
30
- }, G = (e) => {
31
- let t = F.get(e);
28
+ return f(i);
29
+ }, se = (e) => {
30
+ let t = (V.get(e) ?? []).map((e) => e.services).filter((e) => e !== void 0), n = J.get(e) ?? [], r = [...t, ...n];
31
+ if (r.length !== 0) return u.mergeAll(...r);
32
+ }, ce = (e) => {
33
+ let t = z.get(e);
32
34
  t !== void 0 && (t.length = 0);
33
- }, K = async (e) => {
34
- let t = F.get(e);
35
+ }, Y = async (e) => {
36
+ let t = z.get(e);
35
37
  if (t === void 0 || t.length === 0) return;
36
38
  let n = [...t];
37
39
  t.length = 0;
38
40
  for (let e of n) await e();
39
- }, q = (e) => I.get(e) ?? [], J = async (e, t) => {
40
- let n = M.get(e);
41
+ }, X = (e) => B.get(e) ?? [], Z = async (e, t) => {
42
+ let n = I.get(e);
41
43
  return n === void 0 ? e.store.transactional(async (n) => t({
42
44
  ...e,
43
45
  store: n
44
46
  })) : n(t);
45
- }, Y = (e) => {
47
+ }, le = (e) => {
46
48
  let t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), r = (n) => {
47
49
  let r = t.get(n);
48
50
  return r === void 0 ? !1 : r.expiresAt !== null && r.expiresAt <= e() ? (t.delete(n), !1) : !0;
@@ -81,7 +83,7 @@ var A = (e) => e, j = "00000000000000000000000000000000", M = /* @__PURE__ */ ne
81
83
  return i(e, o, n.ttlMs, n.tags), o;
82
84
  }
83
85
  };
84
- }, X = (e) => {
86
+ }, ue = (e) => {
85
87
  let t = /* @__PURE__ */ new Map(), n = (n) => {
86
88
  let r = t.get(n);
87
89
  return r === void 0 ? !1 : r.expiresAt !== null && r.expiresAt <= e() ? (t.delete(n), !1) : !0;
@@ -109,140 +111,158 @@ var A = (e) => e, j = "00000000000000000000000000000000", M = /* @__PURE__ */ ne
109
111
  t.clear();
110
112
  }
111
113
  };
112
- }, Z = async (e, t) => {
113
- let n = _();
114
- D(e);
114
+ }, de = async (e, t) => {
115
+ let n = b();
116
+ M(e);
115
117
  try {
116
118
  return await t();
117
119
  } finally {
118
- n === void 0 ? h() : D(n);
120
+ n === void 0 ? v() : M(n);
119
121
  }
120
- }, Q = /* @__PURE__ */ new Set(), ne = (e) => {
122
+ }, Q = /* @__PURE__ */ new Set(), fe = (e) => {
121
123
  Q.has(e) || (Q.add(e), console.warn(e));
122
- }, re = (e, t, n) => {
123
- let r = ie, i;
124
+ }, pe = (e, t, n) => {
125
+ let r = me, i;
124
126
  return () => {
125
- let a = t ?? g();
126
- return t !== void 0 && g() !== void 0 && t !== g() && ne("[voltro:testing] this test passes `rowFilter:` while a DIFFERENT filter is registered via `setRowFilter`. The option wins, so this test does not exercise your app's registration. Drop `rowFilter:` to run the real process-global one."), (i === void 0 || a !== r) && (r = a, i = Z(n, () => E(w(a, e, (e) => {
127
+ let a = t ?? y();
128
+ return t !== void 0 && y() !== void 0 && t !== y() && fe("[voltro:testing] this test passes `rowFilter:` while a DIFFERENT filter is registered via `setRowFilter`. The option wins, so this test does not exercise your app's registration. Drop `rowFilter:` to run the real process-global one."), (i === void 0 || a !== r) && (r = a, i = de(n, () => A(O(a, e, (e) => {
127
129
  console.error("[voltro:testing] row filter failed to load — reads refused for this subject", e);
128
130
  })))), i;
129
131
  };
130
- }, ie = Symbol("unresolved"), $ = (e, t) => new Proxy(e, { get: (e, n) => {
131
- if (n === "query") return async (n) => e.query(m(await t(), n));
132
+ }, me = Symbol("unresolved"), $ = (e, t) => new Proxy(e, { get: (e, n) => {
133
+ if (n === "query") return async (n) => e.query(_(await t(), n));
132
134
  let r = Reflect.get(e, n, e);
133
135
  return typeof r == "function" ? r.bind(e) : r;
134
- } }), ae = (s = {}) => {
135
- if (k({
136
+ } }), he = (u = {}) => {
137
+ if (re({
136
138
  ...process.env,
137
- ...s.env ?? {}
138
- }), s.fieldEncryptionKey !== void 0 && te(x(s.fieldEncryptionKey)), s.relations !== void 0) {
139
- a();
140
- for (let e of s.relations) o(e);
139
+ ...u.env ?? {}
140
+ }), u.fieldEncryptionKey !== void 0 && u.fieldKeys !== void 0) throw Error("makeTestContext: pass `fieldEncryptionKey` or `fieldKeys`, not both — one is a keyring of one key");
141
+ if (u.fieldEncryptionKey !== void 0 && j(C(u.fieldEncryptionKey)), u.fieldKeys !== void 0 && n(u.fieldKeys), u.relations !== void 0) {
142
+ s();
143
+ for (let e of u.relations) c(e);
141
144
  }
142
- let l = s.tables ?? i(), m = C(l), h = new d(s.store ?? {});
143
- for (let e of s.plugins ?? []) e.bindDataStore?.(h);
144
- let g = {
145
- dataStore: h,
146
- schemaRegistry: m
145
+ let f = u.tables ?? o(), _ = T(f), v = new m(u.store ?? {});
146
+ for (let e of u.plugins ?? []) e.bindDataStore?.(v);
147
+ let y = {
148
+ dataStore: v,
149
+ schemaRegistry: _
147
150
  };
148
- D(g);
149
- let _ = new e(s.clockStart), w = new t(), E = n(), A = new r(s.llmResponses ?? []), P = Y(() => _.now()), R = X(() => _.now()), z = (e, t, n = h, r, i = !1) => {
150
- let a = {
151
+ M(y);
152
+ let b = new e(u.clockStart);
153
+ x();
154
+ let O = l.runSync(ie.make.pipe(l.provide(ae({ now: () => b.now() }))));
155
+ v.onChange((e) => {
156
+ l.runSync(O.invalidateTag(e.table).pipe(l.ignore));
157
+ });
158
+ let A = [], P = {
159
+ wrapDynamic: (e, t, n, r) => O.wrapDynamic(e, t, n, r),
160
+ policyFor: E,
161
+ codeIdentity: "test",
162
+ maxEntryBytes: 1048576,
163
+ notice: (e, t, n) => {
164
+ A.push(n);
165
+ }
166
+ }, R = new r(), H = i(), U = new a(u.llmResponses ?? []), G = le(() => b.now()), K = ue(() => b.now()), q = (e, n, r = v, i, a = !1) => {
167
+ let o = {
151
168
  subject: e,
152
- traceId: j,
153
- ...t === void 0 ? {} : { connection: t }
154
- }, o = r?.queued ?? [], c = r?.nudges ?? [], l = ee({
155
- bus: E.bus,
169
+ traceId: F,
170
+ ...n === void 0 ? {} : { connection: n }
171
+ }, s = i?.queued ?? [], c = i?.nudges ?? [], l = ne({
172
+ bus: H.bus,
156
173
  tenantId: e.tenantId ?? null,
157
- ...n === h ? {} : { deferToCommit: (e) => {
158
- o.push(async () => {
174
+ ...r === v ? {} : { deferToCommit: (e) => {
175
+ s.push(async () => {
159
176
  e();
160
177
  });
161
178
  } }
162
- }), d = b({ store: n }), x = i ? async () => f : re(e, s.rowFilter, g), C = {
163
- apis: s.apis ?? Object.freeze({}),
164
- transaction: async (r, a) => {
165
- let o = T(e, a?.tenantId, n !== h);
166
- if (o !== e) return z(o, t, h, void 0, !0).transaction(r);
167
- if (n !== h) return r(C);
168
- let s, l = await n.transactional(async (n) => {
169
- let a = z(e, t, n, {
179
+ }), d = te({ store: r }), f = a ? async () => h : pe(e, u.rowFilter, y), m = {
180
+ apis: u.apis ?? Object.freeze({}),
181
+ transaction: async (t, i) => {
182
+ let o = k(e, i?.tenantId, r !== v);
183
+ if (o !== e) return q(o, n, v, void 0, !0).transaction(t);
184
+ if (r !== v) return t(m);
185
+ let s, l = await r.transactional(async (r) => {
186
+ let i = q(e, n, r, {
170
187
  queued: [],
171
188
  nudges: []
172
- }, i), o = await r(a);
173
- return s = a, o;
189
+ }, a), o = await t(i);
190
+ return s = i, o;
174
191
  });
175
- return s !== void 0 && (await K(s), c.push(...q(s))), l;
192
+ return s !== void 0 && (await Y(s), c.push(...X(s))), l;
176
193
  },
177
- clock: _,
178
- webhooks: w,
194
+ clock: b,
195
+ webhooks: R,
179
196
  events: l,
180
- eventBus: E,
181
- llm: A,
182
- ...s.ai === void 0 ? {} : { ai: s.ai },
183
- request: a,
184
- ...t === void 0 ? {} : { connectionState: y(t, n === h ? void 0 : (e) => {
185
- o.push(e);
197
+ eventBus: H,
198
+ llm: U,
199
+ ...u.ai === void 0 ? {} : { ai: u.ai },
200
+ request: o,
201
+ ...n === void 0 ? {} : { connectionState: ee(n, r === v ? void 0 : (e) => {
202
+ s.push(e);
186
203
  }) },
187
- validation: p,
188
- access: v(e),
189
- cache: P,
190
- kv: R,
191
- store: O($(n, x), {
204
+ validation: g,
205
+ access: S(e),
206
+ cache: G,
207
+ kv: K,
208
+ store: N(D($(r, f)), {
192
209
  subject: e,
193
- schemaRegistry: m,
194
- rowFilter: f
210
+ schemaRegistry: _,
211
+ rowFilter: h
195
212
  }),
196
- storeForTenant: (t) => O($(n, x), {
197
- subject: u(e, t),
198
- schemaRegistry: m,
199
- rowFilter: f
213
+ storeForTenant: (t) => N($(r, f), {
214
+ subject: p(e, t),
215
+ schemaRegistry: _,
216
+ rowFilter: h
200
217
  }),
201
- outbox: S({
202
- store: n,
218
+ outbox: w({
219
+ store: r,
203
220
  subject: e,
204
- traceId: j,
221
+ traceId: F,
205
222
  nudge: () => {
206
- c.push(j);
223
+ c.push(F);
207
224
  },
208
225
  afterCommit: (e) => {
209
- o.push(e);
226
+ s.push(e);
210
227
  }
211
228
  }),
212
229
  load: d.load,
213
230
  loadMany: d.loadMany,
214
- withSubject: (e, r) => Promise.resolve(r(z(e, t, n, {
215
- queued: o,
231
+ withSubject: (e, t) => Promise.resolve(t(q(e, n, r, {
232
+ queued: s,
216
233
  nudges: c
217
234
  }))),
218
- withTenant: (r, i) => Promise.resolve(i(z({
235
+ withTenant: (t, i) => Promise.resolve(i(q({
219
236
  ...e,
220
- tenantId: r
221
- }, t, n, {
222
- queued: o,
237
+ tenantId: t
238
+ }, n, r, {
239
+ queued: s,
223
240
  nudges: c
224
241
  }))),
225
- asSubject: (e) => z(e, t, n, {
226
- queued: o,
242
+ asSubject: (e) => q(e, n, r, {
243
+ queued: s,
227
244
  nudges: c
228
245
  }),
229
- asTenant: (r) => z({
246
+ asTenant: (t) => q({
230
247
  ...e,
231
- tenantId: r
232
- }, t, n, {
233
- queued: o,
248
+ tenantId: t
249
+ }, n, r, {
250
+ queued: s,
234
251
  nudges: c
235
252
  })
236
253
  };
237
- return F.set(C, o), N.set(C, (t) => z(e, t, n, {
238
- queued: o,
254
+ return z.set(m, s), L.set(m, (t) => q(e, t, r, {
255
+ queued: s,
239
256
  nudges: c
240
- })), I.set(C, c), L.set(C, s.plugins ?? []), H.set(C, s.layers ?? []), M.set(C, (r) => n.transactional((n) => r(z(e, t, n, {
241
- queued: o,
257
+ })), B.set(m, c), V.set(m, u.plugins ?? []), J.set(m, u.layers ?? []), W.set(m, {
258
+ deps: P,
259
+ rowFilter: async () => u.rowFilter === void 0 ? void 0 : f(),
260
+ notices: A
261
+ }), I.set(m, (t) => r.transactional((r) => t(q(e, n, r, {
262
+ queued: s,
242
263
  nudges: c
243
- })))), C;
264
+ })))), t(m, v), m;
244
265
  };
245
- return z(s.subject ?? c(null), s.connection);
266
+ return q(u.subject ?? d(null), u.connection);
246
267
  };
247
- //#endregion
248
- export { ae as makeTestContext, B as markRestInvocation, A as mockStore, q as outboxNudgesOf, R as pluginsOf, G as resetAfterCommit, V as restInvocationOf, U as rpcInterceptorFor, K as runAfterCommit, J as runInStoreTransaction, W as serviceLayerFor, P as withRpcConnection };
268
+ export { he as makeTestContext, K as markRestInvocation, P as mockStore, X as outboxNudgesOf, H as pluginsOf, G as queryCacheOf, ce as resetAfterCommit, q as restInvocationOf, oe as rpcInterceptorFor, Y as runAfterCommit, Z as runInStoreTransaction, se as serviceLayerFor, R as withRpcConnection };