@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/CHANGELOG.md +5484 -0
- package/README.md +11 -0
- package/THIRD-PARTY-NOTICES.md +1511 -276
- package/dist/client.d.ts +5 -0
- package/dist/client.js +70 -58
- package/dist/crdt.js +1 -2
- package/dist/dialect.d.ts +20 -0
- package/dist/dialect.js +992 -694
- package/dist/factory.js +1 -2
- package/dist/fieldKeys.js +72 -0
- package/dist/fieldKeysSql.js +13 -0
- package/dist/fixtureRow.js +1 -2
- package/dist/formBindingHarness.js +1 -2
- package/dist/hotStoreSqlParity.js +135 -0
- package/dist/hydrateFixtureRows.js +1 -2
- package/dist/index.d.ts +119 -1
- package/dist/index.js +18 -16
- package/dist/invoke.js +77 -40
- package/dist/mockClock.js +1 -2
- package/dist/mockLLM.js +1 -2
- package/dist/mockWebhooks.js +1 -2
- package/dist/platform.js +1 -2
- package/dist/reachable.js +1 -2
- package/dist/serviceApiMock.js +1 -2
- package/dist/subject.js +1 -2
- package/dist/subscribeContext.js +1 -2
- package/dist/system.d.ts +99 -0
- package/dist/system.js +93 -0
- package/dist/testApps.js +1 -2
- package/dist/testContext.js +133 -113
- package/dist/testEventBus.js +1 -2
- package/dist/testRequest.js +56 -55
- package/dist/withConnections.js +25 -0
- package/dist/workflowRunner.js +1 -2
- package/package.json +17 -10
package/dist/client.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { FormBinding } from '@voltro/client';
|
|
|
6
6
|
import { FormStateSnapshot } from '@voltro/client';
|
|
7
7
|
import { ReactElement } from 'react';
|
|
8
8
|
import { ReactNode } from 'react';
|
|
9
|
+
import { RecoveryOptions } from '@voltro/client';
|
|
9
10
|
import { UseFormBindingOptions } from '@voltro/client';
|
|
10
11
|
|
|
11
12
|
/** The snapshot shape `useConnectionStatus` subscribes to. */
|
|
@@ -177,6 +178,10 @@ export declare interface VoltroTestClientConfig {
|
|
|
177
178
|
readonly mutations?: Readonly<Record<string, Handler>>;
|
|
178
179
|
/** Action handlers per tag. */
|
|
179
180
|
readonly actions?: Readonly<Record<string, Handler>>;
|
|
181
|
+
/** The client's recovery options, as an app passes them — `replayWindowMs` is how
|
|
182
|
+
* long an action waits for a disconnected transport before it is refused
|
|
183
|
+
* (default 10 s, at least 250 ms). */
|
|
184
|
+
readonly recovery?: RecoveryOptions;
|
|
180
185
|
}
|
|
181
186
|
|
|
182
187
|
export { }
|
package/dist/client.js
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
1
|
import { renderFormBinding as e } from "./formBindingHarness.js";
|
|
2
2
|
import { Effect as t } from "effect";
|
|
3
3
|
import { createElement as n } from "react";
|
|
4
|
-
import { FrameworkRuntimesContext as r, INITIAL_RECOVERY_SNAPSHOT as i, RpcErrorBus as a } from "@voltro/client";
|
|
5
|
-
|
|
6
|
-
var
|
|
4
|
+
import { FrameworkRuntimesContext as r, INITIAL_RECOVERY_SNAPSHOT as i, RpcErrorBus as a, resolveRecoveryOptions as o } from "@voltro/client";
|
|
5
|
+
// src/client.tsx
|
|
6
|
+
var s = {
|
|
7
7
|
runPromise: t.runPromise,
|
|
8
8
|
runPromiseExit: t.runPromiseExit,
|
|
9
9
|
runFork: t.runFork,
|
|
10
10
|
dispose: () => t.void
|
|
11
|
-
},
|
|
12
|
-
let
|
|
13
|
-
for (let [t, n] of Object.entries(e.subscriptions ?? {}))
|
|
11
|
+
}, c = (e = {}) => {
|
|
12
|
+
let c = e.apiName ?? "app", l = /* @__PURE__ */ new Map(), u = /* @__PURE__ */ new Map(), d = /* @__PURE__ */ new Map(), f = [];
|
|
13
|
+
for (let [t, n] of Object.entries(e.subscriptions ?? {})) l.set(t, {
|
|
14
14
|
data: n,
|
|
15
15
|
error: void 0,
|
|
16
16
|
revision: 0,
|
|
17
17
|
pendingPatches: 0,
|
|
18
18
|
emittedAt: void 0
|
|
19
19
|
});
|
|
20
|
-
let
|
|
20
|
+
let p = (e) => l.get(e) ?? {
|
|
21
21
|
data: void 0,
|
|
22
22
|
error: void 0,
|
|
23
23
|
revision: -1,
|
|
24
24
|
pendingPatches: 0,
|
|
25
25
|
emittedAt: void 0
|
|
26
|
-
},
|
|
27
|
-
|
|
28
|
-
for (let t of
|
|
29
|
-
},
|
|
26
|
+
}, m = (e) => {
|
|
27
|
+
d.delete(e);
|
|
28
|
+
for (let t of u.get(e) ?? []) t();
|
|
29
|
+
}, h = (e) => String(e[0] ?? ""), g = {
|
|
30
30
|
peek: (e) => {
|
|
31
|
-
let t =
|
|
31
|
+
let t = h(e), n = d.get(t);
|
|
32
32
|
if (n) return n;
|
|
33
|
-
let r =
|
|
33
|
+
let r = p(t), i = {
|
|
34
34
|
data: r.data,
|
|
35
35
|
revision: r.revision,
|
|
36
36
|
emittedAt: r.emittedAt,
|
|
37
37
|
error: r.error,
|
|
38
38
|
pendingPatches: r.pendingPatches
|
|
39
39
|
};
|
|
40
|
-
return
|
|
40
|
+
return d.set(t, i), i;
|
|
41
41
|
},
|
|
42
42
|
subscribe: (e, t, n, r) => {
|
|
43
|
-
let i =
|
|
44
|
-
return a.add(r),
|
|
43
|
+
let i = h(e), a = u.get(i) ?? /* @__PURE__ */ new Set();
|
|
44
|
+
return a.add(r), u.set(i, a), { unsubscribe: () => {
|
|
45
45
|
a.delete(r);
|
|
46
46
|
} };
|
|
47
47
|
},
|
|
@@ -54,9 +54,9 @@ var o = {
|
|
|
54
54
|
update: () => {},
|
|
55
55
|
forTag: () => ({ patchedCount: 0 }),
|
|
56
56
|
refreshAll: () => {
|
|
57
|
-
|
|
57
|
+
_ += 1;
|
|
58
58
|
}
|
|
59
|
-
},
|
|
59
|
+
}, _ = 0, v = {
|
|
60
60
|
rawTransport: "connected",
|
|
61
61
|
status: "connected",
|
|
62
62
|
failureCount: 0,
|
|
@@ -64,31 +64,44 @@ var o = {
|
|
|
64
64
|
failedSubscriptions: [],
|
|
65
65
|
pendingMutationReplays: 0,
|
|
66
66
|
mutationReplay: "unknown"
|
|
67
|
-
},
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
}, y = /* @__PURE__ */ new Set(), b = o(e.recovery), x = new a(), S = !0, C = {
|
|
68
|
+
options: b,
|
|
69
|
+
subscribe: (e) => (y.add(e), () => {
|
|
70
|
+
y.delete(e);
|
|
70
71
|
}),
|
|
71
|
-
getSnapshot: () =>
|
|
72
|
+
getSnapshot: () => v,
|
|
72
73
|
getServerSnapshot: () => i,
|
|
73
|
-
getPreloadSeedPermission: () =>
|
|
74
|
+
getPreloadSeedPermission: () => S,
|
|
74
75
|
invalidatePreloadSeeds: () => {
|
|
75
|
-
if (
|
|
76
|
-
|
|
77
|
-
for (let e of
|
|
76
|
+
if (S) {
|
|
77
|
+
S = !1;
|
|
78
|
+
for (let e of y) e();
|
|
78
79
|
}
|
|
79
80
|
},
|
|
80
|
-
onVisibleError: (e) =>
|
|
81
|
-
waitForProtocolReady:
|
|
81
|
+
onVisibleError: (e) => x.on(e),
|
|
82
|
+
waitForProtocolReady: (e, t) => {
|
|
83
|
+
if (t?.aborted) return Promise.resolve(!1);
|
|
84
|
+
if (v.rawTransport === "connected") return Promise.resolve(!0);
|
|
85
|
+
let n = b.replayWindowMs - (Date.now() - e);
|
|
86
|
+
return n <= 0 ? Promise.resolve(!1) : new Promise((e) => {
|
|
87
|
+
let r = (n) => {
|
|
88
|
+
y.delete(i), clearTimeout(o), t?.removeEventListener("abort", a), e(n);
|
|
89
|
+
}, i = () => {
|
|
90
|
+
v.rawTransport === "connected" && r(!0);
|
|
91
|
+
}, a = () => r(!1), o = setTimeout(() => r(!1), n);
|
|
92
|
+
y.add(i), t?.addEventListener("abort", a, { once: !0 }), t?.aborted && a();
|
|
93
|
+
});
|
|
94
|
+
},
|
|
82
95
|
reserveMutationReplay: () => void 0,
|
|
83
96
|
waitForMutationReplaySupport: async () => !1,
|
|
84
97
|
replayWindowRemaining: () => 0,
|
|
85
98
|
reportExternalSuccess: () => {},
|
|
86
99
|
subjectSignal: new AbortController().signal
|
|
87
|
-
},
|
|
88
|
-
let i = e.split("."), a =
|
|
100
|
+
}, w = {}, T = (e, n, r) => {
|
|
101
|
+
let i = e.split("."), a = w;
|
|
89
102
|
for (let e of i.slice(0, -1)) a[e] = a[e] ?? {}, a = a[e];
|
|
90
103
|
a[i[i.length - 1]] = (i) => t.tryPromise({
|
|
91
|
-
try: async () => (
|
|
104
|
+
try: async () => (f.push({
|
|
92
105
|
kind: n,
|
|
93
106
|
tag: e,
|
|
94
107
|
input: i
|
|
@@ -96,64 +109,63 @@ var o = {
|
|
|
96
109
|
catch: (e) => e
|
|
97
110
|
});
|
|
98
111
|
};
|
|
99
|
-
for (let [t, n] of Object.entries(e.mutations ?? {}))
|
|
100
|
-
for (let [t, n] of Object.entries(e.actions ?? {}))
|
|
101
|
-
let
|
|
102
|
-
runtime:
|
|
103
|
-
cache:
|
|
104
|
-
recovery:
|
|
105
|
-
client:
|
|
112
|
+
for (let [t, n] of Object.entries(e.mutations ?? {})) T(t, "mutation", n);
|
|
113
|
+
for (let [t, n] of Object.entries(e.actions ?? {})) T(t, "action", n);
|
|
114
|
+
let E = {
|
|
115
|
+
runtime: s,
|
|
116
|
+
cache: g,
|
|
117
|
+
recovery: C,
|
|
118
|
+
client: w,
|
|
106
119
|
descriptors: {},
|
|
107
120
|
inspectBaseUrl: "http://test.local",
|
|
108
|
-
errorBus:
|
|
109
|
-
},
|
|
121
|
+
errorBus: x
|
|
122
|
+
}, D = {
|
|
110
123
|
get: (e) => {
|
|
111
|
-
if (e !==
|
|
112
|
-
return
|
|
124
|
+
if (e !== c) throw Error(`makeVoltroTestClient: component asked for api '${e}' but the harness was built for '${c}'. Pass { apiName: '${e}' }.`);
|
|
125
|
+
return E;
|
|
113
126
|
},
|
|
114
|
-
names: [
|
|
127
|
+
names: [c]
|
|
115
128
|
};
|
|
116
129
|
return {
|
|
117
|
-
Provider: ({ children: e }) => n(r.Provider, { value:
|
|
130
|
+
Provider: ({ children: e }) => n(r.Provider, { value: D }, e),
|
|
118
131
|
setSubscription: (e, t, n) => {
|
|
119
|
-
let r =
|
|
120
|
-
|
|
132
|
+
let r = p(e);
|
|
133
|
+
l.set(e, {
|
|
121
134
|
data: t,
|
|
122
135
|
error: void 0,
|
|
123
136
|
revision: r.revision + 1,
|
|
124
137
|
pendingPatches: n?.pendingPatches ?? 0,
|
|
125
138
|
emittedAt: n?.emittedAt
|
|
126
|
-
}),
|
|
139
|
+
}), m(e);
|
|
127
140
|
},
|
|
128
141
|
failSubscription: (e, t) => {
|
|
129
|
-
|
|
142
|
+
l.set(e, {
|
|
130
143
|
data: void 0,
|
|
131
144
|
error: t,
|
|
132
145
|
revision: -1,
|
|
133
146
|
pendingPatches: 0,
|
|
134
147
|
emittedAt: void 0
|
|
135
|
-
}),
|
|
148
|
+
}), m(e);
|
|
136
149
|
},
|
|
137
150
|
resetSubscription: (e) => {
|
|
138
|
-
|
|
151
|
+
l.delete(e), m(e);
|
|
139
152
|
},
|
|
140
|
-
calls:
|
|
153
|
+
calls: f,
|
|
141
154
|
setConnectionStatus: (e, t) => {
|
|
142
|
-
|
|
143
|
-
...
|
|
155
|
+
v = {
|
|
156
|
+
...v,
|
|
144
157
|
...t,
|
|
145
158
|
status: e,
|
|
146
159
|
rawTransport: t?.rawTransport ?? (e === "connected" ? "connected" : "disconnected")
|
|
147
160
|
};
|
|
148
|
-
for (let e of
|
|
161
|
+
for (let e of y) e();
|
|
149
162
|
},
|
|
150
163
|
get refreshes() {
|
|
151
|
-
return
|
|
164
|
+
return _;
|
|
152
165
|
},
|
|
153
166
|
emitRpcError: (e) => {
|
|
154
|
-
|
|
167
|
+
E.errorBus.emit(e);
|
|
155
168
|
}
|
|
156
169
|
};
|
|
157
170
|
};
|
|
158
|
-
|
|
159
|
-
export { o as FAKE_RUNTIME, s as makeVoltroTestClient, e as renderFormBinding };
|
|
171
|
+
export { s as FAKE_RUNTIME, c as makeVoltroTestClient, e as renderFormBinding };
|
package/dist/crdt.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe as e, expect as t, it as n } from "vitest";
|
|
2
|
-
|
|
2
|
+
// src/crdtBackendConformance.ts
|
|
3
3
|
var r = (r, i) => {
|
|
4
4
|
let a = i.backend, o = (e) => a.createText(e).encodeState(), s = (e, t, n) => {
|
|
5
5
|
let r = a.createText();
|
|
@@ -73,5 +73,4 @@ var r = (r, i) => {
|
|
|
73
73
|
});
|
|
74
74
|
});
|
|
75
75
|
};
|
|
76
|
-
//#endregion
|
|
77
76
|
export { r as crdtBackendConformance };
|
package/dist/dialect.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { applySchema } from '@voltro/database/sql';
|
|
2
2
|
import { DataStore } from '@voltro/database';
|
|
3
|
+
import { DialectId } from '@voltro/database';
|
|
3
4
|
import { Effect } from 'effect';
|
|
4
5
|
import { SqlClient } from 'effect/sql';
|
|
5
6
|
import { SqlDialect } from '@voltro/database';
|
|
@@ -48,6 +49,22 @@ export declare interface DialectFixtureSession {
|
|
|
48
49
|
readonly dispose: () => Promise<void>;
|
|
49
50
|
}
|
|
50
51
|
|
|
52
|
+
export declare interface HotSqlFixture {
|
|
53
|
+
readonly dialect: DialectId;
|
|
54
|
+
readonly name: string;
|
|
55
|
+
readonly make: () => Promise<HotSqlFixtureSession>;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** A real SQL fixture owns a fresh physical namespace and every connection it opens. */
|
|
59
|
+
export declare interface HotSqlFixtureSession {
|
|
60
|
+
readonly store: DataStore;
|
|
61
|
+
/** Open another independent SQL connection/pool to the same owned tables. */
|
|
62
|
+
readonly connect: () => Promise<DataStore>;
|
|
63
|
+
/** Re-apply the declared tables; SQL fixtures must keep DDL idempotent. */
|
|
64
|
+
readonly migrate: () => Promise<void>;
|
|
65
|
+
readonly dispose: () => Promise<void>;
|
|
66
|
+
}
|
|
67
|
+
|
|
51
68
|
/**
|
|
52
69
|
* Register the dialect's parity suite with vitest. Calls
|
|
53
70
|
* `describe(...)` so the dialect's name appears in test output.
|
|
@@ -64,4 +81,7 @@ export declare interface DialectFixtureSession {
|
|
|
64
81
|
*/
|
|
65
82
|
export declare const runDialectParity: (fixture: DialectFixture) => void;
|
|
66
83
|
|
|
84
|
+
/** Identical HotStore assertions for every live SQL dialect; no fixture opt-outs. */
|
|
85
|
+
export declare const runHotStoreSqlParity: (fixture: HotSqlFixture) => void;
|
|
86
|
+
|
|
67
87
|
export { }
|