@atolljs/core 0.1.4 → 0.1.6
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/contract/listSchema.d.ts +2 -2
- package/dist/contract/msgpackrCodec.d.ts +1 -1
- package/dist/contract/reef.d.ts +140 -80
- package/dist/contract/sharedMemory.d.ts +2 -2
- package/dist/contract/types.d.ts +1 -1
- package/dist/contract/zod.d.ts +114 -14
- package/dist/index.d.ts +31 -29
- package/dist/index.js +18 -17
- package/dist/index10.js +0 -2
- package/dist/index11.js +0 -2
- package/dist/index12.js +0 -2
- package/dist/index13.js +0 -2
- package/dist/index14.js +0 -2
- package/dist/index15.js +0 -2
- package/dist/index16.js +46 -38
- package/dist/index17.js +20 -21
- package/dist/index18.js +64 -37
- package/dist/index19.js +0 -2
- package/dist/index2.js +0 -2
- package/dist/index20.js +0 -2
- package/dist/index3.js +101 -43
- package/dist/index4.js +0 -2
- package/dist/index5.js +0 -2
- package/dist/index6.js +0 -2
- package/dist/index7.js +0 -2
- package/dist/index8.js +0 -2
- package/dist/index9.js +0 -2
- package/dist/observable.d.ts +2 -2
- package/dist/pool/memory.d.ts +1 -1
- package/dist/pool/workerClient.d.ts +6 -6
- package/dist/pool/workerPool.d.ts +2 -2
- package/dist/reactive.d.ts +1 -1
- package/dist/service.d.ts +1 -1
- package/dist/shared/sharedWorkerClient.d.ts +2 -2
- package/dist/task.d.ts +1 -1
- package/dist/testing/inProcessWorker.d.ts +27 -0
- package/dist/worker/defineWorker.d.ts +3 -4
- package/dist/worker/registry.d.ts +1 -1
- package/dist/worker/workerBootstrap.d.ts +9 -1
- package/package.json +6 -3
- package/src/contract/zod.ts +130 -14
- package/src/index.ts +2 -0
- package/src/reactive.ts +107 -42
- package/src/worker/defineWorker.ts +6 -2
- package/src/worker/workerBootstrap.ts +53 -37
package/dist/index3.js
CHANGED
|
@@ -93,16 +93,16 @@ var e = (e, t) => ({
|
|
|
93
93
|
inner(e) {
|
|
94
94
|
return typeof e == "bigint" ? e : _("bigint");
|
|
95
95
|
}
|
|
96
|
-
},
|
|
96
|
+
}, ee = class extends g {
|
|
97
97
|
inner(e) {
|
|
98
98
|
return e;
|
|
99
99
|
}
|
|
100
|
-
},
|
|
100
|
+
}, S = class extends g {
|
|
101
101
|
inner(e) {
|
|
102
102
|
let t = this._zod.def.cls;
|
|
103
103
|
return e instanceof t ? e : _(t.name ?? "instance");
|
|
104
104
|
}
|
|
105
|
-
},
|
|
105
|
+
}, C = class extends g {
|
|
106
106
|
get shape() {
|
|
107
107
|
return this._zod.def.shape;
|
|
108
108
|
}
|
|
@@ -112,55 +112,109 @@ var e = (e, t) => ({
|
|
|
112
112
|
for (let [n, r] of Object.entries(this.shape)) t[n] = r.parse(e[n]);
|
|
113
113
|
return t;
|
|
114
114
|
}
|
|
115
|
-
},
|
|
115
|
+
}, w = class extends g {
|
|
116
116
|
inner(e) {
|
|
117
117
|
if (!Array.isArray(e)) return _("array");
|
|
118
118
|
let t = this._zod.def.element;
|
|
119
119
|
return e.map((e) => t.parse(e));
|
|
120
120
|
}
|
|
121
|
-
},
|
|
121
|
+
}, T = class extends g {
|
|
122
|
+
inner(e) {
|
|
123
|
+
return e === void 0 ? void 0 : this._zod.def.element.parse(e);
|
|
124
|
+
}
|
|
125
|
+
}, E = class extends g {
|
|
126
|
+
inner(e) {
|
|
127
|
+
return e === null ? null : this._zod.def.element.parse(e);
|
|
128
|
+
}
|
|
129
|
+
}, D = class extends g {
|
|
130
|
+
inner(e) {
|
|
131
|
+
return e === this._zod.def.literal ? e : _(JSON.stringify(this._zod.def.literal));
|
|
132
|
+
}
|
|
133
|
+
}, O = class extends g {
|
|
134
|
+
inner(e) {
|
|
135
|
+
for (let t of this._zod.def.options) {
|
|
136
|
+
let n = t.safeParse(e);
|
|
137
|
+
if (n.success) return n.data;
|
|
138
|
+
}
|
|
139
|
+
return _("a union member");
|
|
140
|
+
}
|
|
141
|
+
}, k = class extends g {
|
|
142
|
+
inner(e) {
|
|
143
|
+
(typeof e != "object" || !e || Array.isArray(e)) && _("object");
|
|
144
|
+
let t = this._zod.def.element, n = {};
|
|
145
|
+
for (let [r, i] of Object.entries(e)) n[r] = t.parse(i);
|
|
146
|
+
return n;
|
|
147
|
+
}
|
|
148
|
+
}, A = class extends g {
|
|
149
|
+
inner(e) {
|
|
150
|
+
return typeof e == "function" ? e : _("function");
|
|
151
|
+
}
|
|
152
|
+
}, j = () => $(new v({ type: "number" })), M = () => $(new y({ type: "string" })), N = () => $(new b({ type: "boolean" })), P = () => $(new x({ type: "bigint" })), F = () => $(new ee({ type: "unknown" })), I = (e) => $(new S({
|
|
122
153
|
type: "instanceof",
|
|
123
154
|
cls: e
|
|
124
|
-
}),
|
|
155
|
+
})), L = (e) => $(new C({
|
|
125
156
|
type: "object",
|
|
126
157
|
shape: e
|
|
127
|
-
}),
|
|
158
|
+
})), R = (e) => $(new w({
|
|
128
159
|
type: "array",
|
|
129
160
|
element: e
|
|
130
|
-
}),
|
|
161
|
+
})), z = (e) => $(new T({
|
|
162
|
+
type: "optional",
|
|
163
|
+
element: e
|
|
164
|
+
})), B = (e) => $(new E({
|
|
165
|
+
type: "nullable",
|
|
166
|
+
element: e
|
|
167
|
+
})), V = (e) => $(new D({
|
|
168
|
+
type: "literal",
|
|
169
|
+
literal: e
|
|
170
|
+
})), H = (e) => $(new O({
|
|
171
|
+
type: "union",
|
|
172
|
+
options: e
|
|
173
|
+
})), U = (e) => $(new k({
|
|
174
|
+
type: "record",
|
|
175
|
+
element: e
|
|
176
|
+
})), W = () => $(new A({ type: "function" })), G = () => new v({
|
|
131
177
|
type: "number",
|
|
132
178
|
format: "int32"
|
|
133
|
-
}).check(d("int32", t, n)),
|
|
179
|
+
}).check(d("int32", t, n)), K = () => new v({
|
|
134
180
|
type: "number",
|
|
135
181
|
format: "uint32"
|
|
136
|
-
}).check(d("uint32", 0, 4294967295)),
|
|
182
|
+
}).check(d("uint32", 0, 4294967295)), q = () => new v({
|
|
137
183
|
type: "number",
|
|
138
184
|
format: "float32"
|
|
139
|
-
}),
|
|
185
|
+
}), J = () => new v({
|
|
140
186
|
type: "number",
|
|
141
187
|
format: "float64"
|
|
142
|
-
}),
|
|
188
|
+
}), Y = () => new x({
|
|
143
189
|
type: "bigint",
|
|
144
190
|
format: "int64"
|
|
145
|
-
}).check(f("int64", -(2n ** 63n), 2n ** 63n - 1n)),
|
|
191
|
+
}).check(f("int64", -(2n ** 63n), 2n ** 63n - 1n)), X = () => new x({
|
|
146
192
|
type: "bigint",
|
|
147
193
|
format: "uint64"
|
|
148
|
-
}).check(f("uint64", 0n, 2n ** 64n - 1n)),
|
|
194
|
+
}).check(f("uint64", 0n, 2n ** 64n - 1n)), Z = /* @__PURE__ */ new Set([
|
|
149
195
|
"string",
|
|
150
196
|
"array",
|
|
151
197
|
"set"
|
|
152
|
-
]),
|
|
153
|
-
let r =
|
|
198
|
+
]), Q = (e, t, n) => {
|
|
199
|
+
let r = Z.has(e._zod.def.type);
|
|
154
200
|
return t === "min" ? r ? u(n) : i(n) : r ? l(n) : a(n);
|
|
155
201
|
};
|
|
156
|
-
function
|
|
202
|
+
function $(e) {
|
|
157
203
|
let t = e.check.bind(e), n = e.register.bind(e), i = {
|
|
158
|
-
refine: (e, n) =>
|
|
159
|
-
meta: (t) => t === void 0 ? m.get(e) :
|
|
160
|
-
min: (n) =>
|
|
161
|
-
max: (n) =>
|
|
162
|
-
length: (e) =>
|
|
163
|
-
int: () =>
|
|
204
|
+
refine: (e, n) => $(t(s(e, n))),
|
|
205
|
+
meta: (t) => t === void 0 ? m.get(e) : $(n(m, t)),
|
|
206
|
+
min: (n) => $(t(Q(e, "min", n))),
|
|
207
|
+
max: (n) => $(t(Q(e, "max", n))),
|
|
208
|
+
length: (e) => $(t(c(e))),
|
|
209
|
+
int: () => $(t(r())),
|
|
210
|
+
optional: () => $(new T({
|
|
211
|
+
type: "optional",
|
|
212
|
+
element: e
|
|
213
|
+
})),
|
|
214
|
+
nullable: () => $(new E({
|
|
215
|
+
type: "nullable",
|
|
216
|
+
element: e
|
|
217
|
+
}))
|
|
164
218
|
};
|
|
165
219
|
for (let [t, n] of Object.entries(i)) Object.defineProperty(e, t, {
|
|
166
220
|
value: n,
|
|
@@ -169,21 +223,27 @@ function H(e) {
|
|
|
169
223
|
});
|
|
170
224
|
return e;
|
|
171
225
|
}
|
|
172
|
-
var
|
|
173
|
-
number:
|
|
174
|
-
string:
|
|
175
|
-
boolean:
|
|
176
|
-
bigint:
|
|
177
|
-
object:
|
|
178
|
-
array:
|
|
179
|
-
instanceof:
|
|
180
|
-
unknown:
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
226
|
+
var te = {
|
|
227
|
+
number: j,
|
|
228
|
+
string: M,
|
|
229
|
+
boolean: N,
|
|
230
|
+
bigint: P,
|
|
231
|
+
object: L,
|
|
232
|
+
array: R,
|
|
233
|
+
instanceof: I,
|
|
234
|
+
unknown: F,
|
|
235
|
+
optional: z,
|
|
236
|
+
nullable: B,
|
|
237
|
+
literal: V,
|
|
238
|
+
union: H,
|
|
239
|
+
record: U,
|
|
240
|
+
callback: W,
|
|
241
|
+
int32: G,
|
|
242
|
+
uint32: K,
|
|
243
|
+
float32: q,
|
|
244
|
+
float64: J,
|
|
245
|
+
int64: Y,
|
|
246
|
+
uint64: X,
|
|
187
247
|
int: r,
|
|
188
248
|
gte: i,
|
|
189
249
|
lte: a,
|
|
@@ -194,11 +254,9 @@ var U = {
|
|
|
194
254
|
minLength: u,
|
|
195
255
|
globalRegistry: m,
|
|
196
256
|
ZodType: g,
|
|
197
|
-
ZodObject:
|
|
198
|
-
ZodArray:
|
|
257
|
+
ZodObject: C,
|
|
258
|
+
ZodArray: w,
|
|
199
259
|
ZodString: y
|
|
200
260
|
};
|
|
201
261
|
//#endregion
|
|
202
|
-
export { h as SchemaError, g as ZodType,
|
|
203
|
-
|
|
204
|
-
//# sourceMappingURL=index3.js.map
|
|
262
|
+
export { h as SchemaError, g as ZodType, $ as fluent, m as globalRegistry, te as z };
|
package/dist/index4.js
CHANGED
package/dist/index5.js
CHANGED
|
@@ -36,5 +36,3 @@ function l(e) {
|
|
|
36
36
|
var u = (e) => e >= 1 << 20 ? `${(e / (1 << 20)).toFixed(1)}MB` : e >= 1024 ? `${(e / 1024).toFixed(1)}KB` : `${e}B`;
|
|
37
37
|
//#endregion
|
|
38
38
|
export { u as fmtBytes, o as getLogLevel, c as log, l as scoped, a as setLogLevel, s as setLogSink };
|
|
39
|
-
|
|
40
|
-
//# sourceMappingURL=index5.js.map
|
package/dist/index6.js
CHANGED
package/dist/index7.js
CHANGED
package/dist/index8.js
CHANGED
package/dist/index9.js
CHANGED
package/dist/observable.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Connector, PathConnector, SharedMemory, SharedSpec, SpecPath } from './contract/sharedMemory';
|
|
2
|
-
import { type SliceOptions } from './reactive';
|
|
1
|
+
import type { Connector, PathConnector, SharedMemory, SharedSpec, SpecPath } from './contract/sharedMemory.js';
|
|
2
|
+
import { type SliceOptions } from './reactive.js';
|
|
3
3
|
/**
|
|
4
4
|
* A minimal subscribable snapshot — `get()` plus `subscribe()`. This is the
|
|
5
5
|
* interface every framework binding adapts (useSyncExternalStore, refs,
|
package/dist/pool/memory.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { ServiceMethod, TaskRunner } from '../service';
|
|
2
|
-
import type { SharedAccess, SharedMemory, SharedSpec } from '../contract/sharedMemory';
|
|
3
|
-
import type { MemoryConfig, Prettify } from '../contract/types';
|
|
4
|
-
import { WorkerPool, type RunOptions } from './workerPool';
|
|
5
|
-
import type { WorkerDefinition, WorkerMethodMap } from '../worker/defineWorker';
|
|
1
|
+
import type { ServiceMethod, TaskRunner } from '../service.js';
|
|
2
|
+
import type { SharedAccess, SharedMemory, SharedSpec } from '../contract/sharedMemory.js';
|
|
3
|
+
import type { MemoryConfig, Prettify } from '../contract/types.js';
|
|
4
|
+
import { WorkerPool, type RunOptions } from './workerPool.js';
|
|
5
|
+
import type { WorkerDefinition, WorkerMethodMap } from '../worker/defineWorker.js';
|
|
6
6
|
/** Maps a worker method's declared type to its async client signature. */
|
|
7
7
|
type Sig<F> = F extends ServiceMethod<infer A extends any[], infer R> ? (...args: A) => Promise<R> : F extends {
|
|
8
8
|
run: (...args: infer A extends any[]) => infer R;
|
|
@@ -62,7 +62,7 @@ export type WorkerClient<W extends WorkerDefinition, S extends SharedSpec> = Wor
|
|
|
62
62
|
* One-line worker hookup for the main thread — the WorkerPool boilerplate
|
|
63
63
|
* (worker factory, shared memory, sizing) collapses into the client itself:
|
|
64
64
|
*
|
|
65
|
-
* import type { IncidentsWorker } from './worker/incidents.worker';
|
|
65
|
+
* import type { IncidentsWorker } from './worker/incidents.worker.js';
|
|
66
66
|
*
|
|
67
67
|
* export const incidents = connectWorker<IncidentsWorker>({
|
|
68
68
|
* sharedMemory: incidentsMemory,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { SharedAccess, SharedMemory, SharedSpec } from '../contract/sharedMemory';
|
|
2
|
-
import { MemoryPersistence, PoolTasks, TaskContract, TaskMap, WorkerPoolConfig } from '../contract/types';
|
|
1
|
+
import { SharedAccess, SharedMemory, SharedSpec } from '../contract/sharedMemory.js';
|
|
2
|
+
import { MemoryPersistence, PoolTasks, TaskContract, TaskMap, WorkerPoolConfig } from '../contract/types.js';
|
|
3
3
|
/** Per-call dispatch controls. */
|
|
4
4
|
export interface RunOptions {
|
|
5
5
|
/**
|
package/dist/reactive.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Connector } from './contract/sharedMemory';
|
|
1
|
+
import { Connector } from './contract/sharedMemory.js';
|
|
2
2
|
/** Emission control for slices — return `true` when `next` should be treated
|
|
3
3
|
* as unchanged (no emit). Defaults to `Object.is`. */
|
|
4
4
|
export type EqualityFn<T> = (prev: T, next: T) => boolean;
|
package/dist/service.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Schema, TaskContract, ViewType } from './contract/types';
|
|
1
|
+
import type { Schema, TaskContract, ViewType } from './contract/types.js';
|
|
2
2
|
/**
|
|
3
3
|
* One RPC method's declaration. Identical fields to {@link TaskContract}
|
|
4
4
|
* except `taskId` is optional — when omitted the wire id is derived as
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { SharedAccess, SharedMemory, SharedSpec } from '../contract/sharedMemory';
|
|
2
|
-
import { PoolTasks, TaskContract, TaskMap, SharedWorkerConfig } from '../contract/types';
|
|
1
|
+
import { SharedAccess, SharedMemory, SharedSpec } from '../contract/sharedMemory.js';
|
|
2
|
+
import { PoolTasks, TaskContract, TaskMap, SharedWorkerConfig } from '../contract/types.js';
|
|
3
3
|
declare class SharedWorkerClientImpl<S extends SharedSpec = SharedSpec> {
|
|
4
4
|
readonly clientIndex: number;
|
|
5
5
|
readonly sharedMemory: SharedMemory<S> & SharedAccess<S>;
|
package/dist/task.d.ts
CHANGED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export declare class InProcessWorker {
|
|
2
|
+
url: URL;
|
|
3
|
+
options?: any;
|
|
4
|
+
static created: InProcessWorker[];
|
|
5
|
+
static handlerModules: Array<() => Promise<unknown>>;
|
|
6
|
+
executed: any[];
|
|
7
|
+
terminated: boolean;
|
|
8
|
+
private listeners;
|
|
9
|
+
private ready;
|
|
10
|
+
/** Module-load failure — a crashed worker never executes another task. */
|
|
11
|
+
private dead;
|
|
12
|
+
constructor(url: URL, options?: any);
|
|
13
|
+
postMessage(data: any): void;
|
|
14
|
+
/** Imports the registered handler modules — what a real worker's entry does at boot. */
|
|
15
|
+
private boot;
|
|
16
|
+
/** Module-load failure = a real worker's 'error' event. */
|
|
17
|
+
private crashOnBoot;
|
|
18
|
+
private handle;
|
|
19
|
+
private emit;
|
|
20
|
+
/** Simulates a worker crash: fires 'error' listeners like a real worker's error event. */
|
|
21
|
+
crash(message?: string): void;
|
|
22
|
+
addEventListener(type: string, l: (event: any) => void): void;
|
|
23
|
+
removeEventListener(type: string, l: (event: any) => void): void;
|
|
24
|
+
terminate(): void;
|
|
25
|
+
}
|
|
26
|
+
/** Flushes microtasks + the waitAsync observer loop after a shared write. */
|
|
27
|
+
export declare const flushObservers: () => Promise<unknown>;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import '
|
|
2
|
-
import type {
|
|
3
|
-
import type { SharedMemory, SharedSpec } from '../contract/sharedMemory';
|
|
1
|
+
import type { ServiceMethod } from '../service.js';
|
|
2
|
+
import type { SharedMemory, SharedSpec } from '../contract/sharedMemory.js';
|
|
4
3
|
/**
|
|
5
4
|
* One worker-exposed method: a plain function (siblings reachable via `this`)
|
|
6
5
|
* or a {@link ServiceMethod} unit (`{ def, run }` — schemas enforced on the
|
|
@@ -38,7 +37,7 @@ export interface WorkerDefinition<S extends SharedSpec = SharedSpec, M extends W
|
|
|
38
37
|
export declare const RESERVED_CLIENT_KEYS: readonly ['start', 'terminate', 'pool', 'sharedMemory', 'then', 'with'];
|
|
39
38
|
/**
|
|
40
39
|
* The worker-side half of the tRPC-style pair: the worker script owns the
|
|
41
|
-
* runtime (
|
|
40
|
+
* runtime (calling this wires `self.onmessage` via workerBootstrap)
|
|
42
41
|
* and the method list — the main thread imports only `typeof` the returned
|
|
43
42
|
* definition and drives it through a {@link connectWorker} Proxy client.
|
|
44
43
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TaskContract } from '../contract/types';
|
|
1
|
+
import { TaskContract } from '../contract/types.js';
|
|
2
2
|
export type TaskHandler<Args extends any[] = any[], Result = any> = (...args: Args) => Result | Promise<Result>;
|
|
3
3
|
export declare class TaskRegistry {
|
|
4
4
|
private static tasks;
|
|
@@ -1 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Wire `self.onmessage` to the pool protocol (INIT / INIT_MEMORY /
|
|
3
|
+
* EXECUTE_TASK). Runs automatically on import for the public
|
|
4
|
+
* `import '@atolljs/core/worker/workerBootstrap'` entry, and is also called
|
|
5
|
+
* from `defineWorker()` — an explicit call survives bundler tree-shaking,
|
|
6
|
+
* unlike a bare side-effect import whose `sideEffects` glob can miss
|
|
7
|
+
* renamed dist chunks. Idempotent: safe on repeated defineWorker() calls.
|
|
8
|
+
*/
|
|
9
|
+
export declare function installWorkerListener(): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atolljs/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Typed shared-memory worker pools — defineWorker/connectWorker, SharedArrayBuffer contracts, cross-thread reactivity",
|
|
5
5
|
"homepage": "https://jwhenry3.github.io/atolljs/consumer/quickstart/",
|
|
6
6
|
"type": "module",
|
|
@@ -12,7 +12,10 @@
|
|
|
12
12
|
"import": "./dist/index.js"
|
|
13
13
|
},
|
|
14
14
|
"./package.json": "./package.json",
|
|
15
|
-
"./*":
|
|
15
|
+
"./*": {
|
|
16
|
+
"types": "./dist/*.d.ts",
|
|
17
|
+
"default": "./src/*"
|
|
18
|
+
}
|
|
16
19
|
},
|
|
17
20
|
"files": [
|
|
18
21
|
"dist",
|
|
@@ -29,7 +32,7 @@
|
|
|
29
32
|
"kill:all": "node scripts/kill-all.mjs",
|
|
30
33
|
"atoll": "node packages/cli/src/cli.ts",
|
|
31
34
|
"serve:all": "node scripts/serve-all.mjs",
|
|
32
|
-
"build": "tsc --noEmit && vite build",
|
|
35
|
+
"build": "tsc --noEmit && vite build && node scripts/core-dts.mjs",
|
|
33
36
|
"test": "vitest run",
|
|
34
37
|
"test:coverage": "vitest run --coverage",
|
|
35
38
|
"stats": "node scripts/bundle-stats.mjs",
|
package/src/contract/zod.ts
CHANGED
|
@@ -98,6 +98,10 @@ export interface SchemaDef {
|
|
|
98
98
|
format?: string;
|
|
99
99
|
shape?: Record<string, ZodLike>;
|
|
100
100
|
element?: ZodLike;
|
|
101
|
+
/** union members. */
|
|
102
|
+
options?: readonly ZodLike[];
|
|
103
|
+
/** literal value. */
|
|
104
|
+
literal?: unknown;
|
|
101
105
|
cls?: abstract new (...args: any[]) => unknown;
|
|
102
106
|
}
|
|
103
107
|
|
|
@@ -205,9 +209,24 @@ class ZodInstanceof<T> extends ZodType<T> {
|
|
|
205
209
|
}
|
|
206
210
|
}
|
|
207
211
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
212
|
+
/** Members whose output admits `undefined` become optional keys — mirroring
|
|
213
|
+
* zod's `z.optional()` object-member semantics (message-domain schemas like
|
|
214
|
+
* island prop contracts need this; reef's fixed-width members never produce
|
|
215
|
+
* it, so the split preserves their all-required output). */
|
|
216
|
+
type IsOptional<S, K extends keyof S> =
|
|
217
|
+
S[K] extends { _zod: { output: infer O } }
|
|
218
|
+
? undefined extends O
|
|
219
|
+
? true
|
|
220
|
+
: false
|
|
221
|
+
: false;
|
|
222
|
+
|
|
223
|
+
type Flatten<T> = { [K in keyof T]: T[K] };
|
|
224
|
+
|
|
225
|
+
type ShapeOutput<S extends Record<string, ZodLike>> = Flatten<
|
|
226
|
+
{ [K in keyof S as IsOptional<S, K> extends true ? never : K]: OutputOf<S[K]> } & {
|
|
227
|
+
[K in keyof S as IsOptional<S, K> extends true ? K : never]?: OutputOf<S[K]>;
|
|
228
|
+
}
|
|
229
|
+
>;
|
|
211
230
|
|
|
212
231
|
/** Strips unknown keys like zod's object parse — output is the shape only. */
|
|
213
232
|
class ZodObjectSchema<S extends Record<string, ZodLike>> extends ZodType<ShapeOutput<S>> {
|
|
@@ -242,21 +261,111 @@ class ZodArraySchema<E extends ZodLike> extends ZodType<OutputOf<E>[]> {
|
|
|
242
261
|
|
|
243
262
|
type OutputOf<S> = S extends { _zod: { output: infer O } } ? O : never;
|
|
244
263
|
|
|
245
|
-
/*
|
|
246
|
-
|
|
247
|
-
|
|
264
|
+
/* ── Message-domain kinds ────────────────────────────────────────────────
|
|
265
|
+
* Layout-free members for contracts that ride postMessage instead of the
|
|
266
|
+
* shared buffer — island prop/event schemas (defineIslandContract). The
|
|
267
|
+
* layout compiler doesn't understand these def.types and rejects them with
|
|
268
|
+
* "can't lay out" if they ever appear inside a fixed-width field — that
|
|
269
|
+
* loud failure is intended: they have no byte width.
|
|
270
|
+
*/
|
|
271
|
+
|
|
272
|
+
class ZodOptional<E extends ZodLike> extends ZodType<OutputOf<E> | undefined> {
|
|
273
|
+
declare readonly _zod: {
|
|
274
|
+
output: OutputOf<E> | undefined; input: OutputOf<E> | undefined;
|
|
275
|
+
def: SchemaDef & { type: 'optional'; element: E };
|
|
276
|
+
};
|
|
277
|
+
inner(v: unknown): OutputOf<E> | undefined {
|
|
278
|
+
// The intersected def narrows element to E; read it as the element's
|
|
279
|
+
// output type so the wrapper's output lines up.
|
|
280
|
+
return v === undefined
|
|
281
|
+
? undefined
|
|
282
|
+
: (this._zod.def.element as ZodLike<OutputOf<E>>).parse(v);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
class ZodNullable<E extends ZodLike> extends ZodType<OutputOf<E> | null> {
|
|
286
|
+
declare readonly _zod: {
|
|
287
|
+
output: OutputOf<E> | null; input: OutputOf<E> | null;
|
|
288
|
+
def: SchemaDef & { type: 'nullable'; element: E };
|
|
289
|
+
};
|
|
290
|
+
inner(v: unknown): OutputOf<E> | null {
|
|
291
|
+
return v === null
|
|
292
|
+
? null
|
|
293
|
+
: (this._zod.def.element as ZodLike<OutputOf<E>>).parse(v);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
class ZodLiteral<V extends string | number | boolean> extends ZodType<V> {
|
|
297
|
+
declare readonly _zod: { output: V; input: V; def: SchemaDef & { type: 'literal' } };
|
|
298
|
+
inner(v: unknown): V {
|
|
299
|
+
return v === this._zod.def.literal ? (v as V) : fail(JSON.stringify(this._zod.def.literal));
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
class ZodUnion<O extends readonly ZodLike[]> extends ZodType<OutputOf<O[number]>> {
|
|
303
|
+
declare readonly _zod: {
|
|
304
|
+
output: OutputOf<O[number]>; input: OutputOf<O[number]>;
|
|
305
|
+
def: SchemaDef & { type: 'union'; options: O };
|
|
306
|
+
};
|
|
307
|
+
inner(v: unknown): OutputOf<O[number]> {
|
|
308
|
+
for (const option of this._zod.def.options as readonly ZodLike<OutputOf<O[number]>>[]) {
|
|
309
|
+
const r = option.safeParse(v);
|
|
310
|
+
if (r.success) return r.data;
|
|
311
|
+
}
|
|
312
|
+
return fail('a union member');
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
class ZodRecord<E extends ZodLike> extends ZodType<Record<string, OutputOf<E>>> {
|
|
316
|
+
declare readonly _zod: {
|
|
317
|
+
output: Record<string, OutputOf<E>>; input: Record<string, OutputOf<E>>;
|
|
318
|
+
def: SchemaDef & { type: 'record'; element: E };
|
|
319
|
+
};
|
|
320
|
+
inner(v: unknown): Record<string, OutputOf<E>> {
|
|
321
|
+
if (typeof v !== 'object' || v === null || Array.isArray(v)) fail('object');
|
|
322
|
+
const el = this._zod.def.element;
|
|
323
|
+
const out: Record<string, unknown> = {};
|
|
324
|
+
for (const [k, value] of Object.entries(v as Record<string, unknown>)) {
|
|
325
|
+
out[k] = el.parse(value);
|
|
326
|
+
}
|
|
327
|
+
return out as Record<string, OutputOf<E>>;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Function-typed members — how a props schema declares a `callbackProp`
|
|
332
|
+
* slot: the wire carries a `{__cb:id}` handle that `unmarshalCallbackProps`
|
|
333
|
+
* restores to a callable BEFORE contract validation runs, so at parse time
|
|
334
|
+
* the member is a real function.
|
|
335
|
+
*/
|
|
336
|
+
class ZodCallback<F extends (...args: any[]) => any = (...args: unknown[]) => unknown>
|
|
337
|
+
extends ZodType<F> {
|
|
338
|
+
declare readonly _zod: { output: F; input: F; def: SchemaDef & { type: 'function' } };
|
|
339
|
+
inner(v: unknown): F {
|
|
340
|
+
return typeof v === 'function' ? (v as F) : fail('function');
|
|
341
|
+
}
|
|
342
|
+
}
|
|
248
343
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
const
|
|
252
|
-
const
|
|
253
|
-
const
|
|
344
|
+
// z factories return FLUENT schemas — `z.string().optional()` chains like
|
|
345
|
+
// classic zod; the mini spellings (`z.optional(z.string())`) stay valid.
|
|
346
|
+
const number = () => fluent(new ZodNumber({ type: 'number' }));
|
|
347
|
+
const string = () => fluent(new ZodString({ type: 'string' }));
|
|
348
|
+
const boolean_ = () => fluent(new ZodBoolean({ type: 'boolean' }));
|
|
349
|
+
const bigint_ = () => fluent(new ZodBigint({ type: 'bigint' }));
|
|
350
|
+
const unknown_ = () => fluent(new ZodUnknown({ type: 'unknown' }));
|
|
254
351
|
const instanceof_ = <T extends abstract new (...args: any[]) => any>(cls: T) =>
|
|
255
|
-
new ZodInstanceof<InstanceType<T>>({ type: 'instanceof', cls });
|
|
352
|
+
fluent(new ZodInstanceof<InstanceType<T>>({ type: 'instanceof', cls }));
|
|
256
353
|
const object_ = <S extends Record<string, ZodLike>>(shape: S) =>
|
|
257
|
-
new ZodObjectSchema<S>({ type: 'object', shape });
|
|
354
|
+
fluent(new ZodObjectSchema<S>({ type: 'object', shape }));
|
|
258
355
|
const array = <E extends ZodLike>(element: E) =>
|
|
259
|
-
new ZodArraySchema<E>({ type: 'array', element });
|
|
356
|
+
fluent(new ZodArraySchema<E>({ type: 'array', element }));
|
|
357
|
+
const optional = <E extends ZodLike>(element: E) =>
|
|
358
|
+
fluent(new ZodOptional<E>({ type: 'optional', element }));
|
|
359
|
+
const nullable = <E extends ZodLike>(element: E) =>
|
|
360
|
+
fluent(new ZodNullable<E>({ type: 'nullable', element }));
|
|
361
|
+
const literal = <V extends string | number | boolean>(value: V) =>
|
|
362
|
+
fluent(new ZodLiteral<V>({ type: 'literal', literal: value }));
|
|
363
|
+
const union = <O extends readonly [ZodLike, ...ZodLike[]]>(options: O) =>
|
|
364
|
+
fluent(new ZodUnion<O>({ type: 'union', options }));
|
|
365
|
+
const record = <E extends ZodLike>(element: E) =>
|
|
366
|
+
fluent(new ZodRecord<E>({ type: 'record', element }));
|
|
367
|
+
const callback = <F extends (...args: any[]) => any = (...args: unknown[]) => unknown>() =>
|
|
368
|
+
fluent(new ZodCallback<F>({ type: 'function' }));
|
|
260
369
|
|
|
261
370
|
const int32 = () => new ZodNumber({ type: 'number', format: 'int32' }).check(intRange('int32', int32min, int32max));
|
|
262
371
|
const uint32 = () => new ZodNumber({ type: 'number', format: 'uint32' }).check(intRange('uint32', 0, 4294967295));
|
|
@@ -288,6 +397,10 @@ export type Fluent<S extends ZodLike> = S & {
|
|
|
288
397
|
max(value: number | bigint): Fluent<S>;
|
|
289
398
|
length(n: number): Fluent<S>;
|
|
290
399
|
int(): Fluent<S>;
|
|
400
|
+
/** Wraps in an optional member — the `label?: string` spelling. */
|
|
401
|
+
optional(): Fluent<ZodOptional<S>>;
|
|
402
|
+
/** Wraps in a nullable member — `T | null`. */
|
|
403
|
+
nullable(): Fluent<ZodNullable<S>>;
|
|
291
404
|
};
|
|
292
405
|
|
|
293
406
|
/** Attaches the `Fluent` methods as non-enumerable own properties. */
|
|
@@ -302,6 +415,8 @@ export function fluent<S extends ZodType>(schema: S): Fluent<S> {
|
|
|
302
415
|
max: (v: number | bigint) => fluent(boundCheck_(boundCheck(schema, 'max', v))),
|
|
303
416
|
length: (n: number) => fluent(boundCheck_(length(n))),
|
|
304
417
|
int: () => fluent(boundCheck_(int())),
|
|
418
|
+
optional: () => fluent(new ZodOptional({ type: 'optional', element: schema })),
|
|
419
|
+
nullable: () => fluent(new ZodNullable({ type: 'nullable', element: schema })),
|
|
305
420
|
};
|
|
306
421
|
for (const [key, fn] of Object.entries(own)) {
|
|
307
422
|
Object.defineProperty(schema, key, { value: fn, enumerable: false, configurable: true });
|
|
@@ -316,6 +431,7 @@ export function fluent<S extends ZodType>(schema: S): Fluent<S> {
|
|
|
316
431
|
export const z = {
|
|
317
432
|
number, string, boolean: boolean_, bigint: bigint_, object: object_, array,
|
|
318
433
|
instanceof: instanceof_, unknown: unknown_,
|
|
434
|
+
optional, nullable, literal, union, record, callback,
|
|
319
435
|
int32, uint32, float32, float64, int64, uint64,
|
|
320
436
|
int, gte, lte, nonnegative, refine, length, maxLength, minLength,
|
|
321
437
|
globalRegistry,
|
package/src/index.ts
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
export { bindSharedMemories, defineSharedMemory, field, getDefinedSharedMemoryCount, jsonCodec, registerConnectorFactory } from './contract/sharedMemory';
|
|
4
4
|
export { reef } from './contract/reef';
|
|
5
|
+
export { z, SchemaError } from './contract/zod';
|
|
6
|
+
export type { ZodLike } from './contract/zod';
|
|
5
7
|
export type {
|
|
6
8
|
Codec,
|
|
7
9
|
Connector,
|