@atolljs/core 0.1.5 → 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/reef.d.ts +88 -28
- package/dist/contract/zod.d.ts +114 -14
- package/dist/index.d.ts +2 -0
- package/dist/index.js +18 -17
- package/dist/index18.js +64 -35
- package/dist/index3.js +101 -41
- package/package.json +1 -1
- package/src/contract/zod.ts +130 -14
- package/src/index.ts +2 -0
- package/src/reactive.ts +107 -42
package/dist/contract/reef.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ import { z } from './zod.js';
|
|
|
24
24
|
* `_zod.def`, so `reef.object({ id: z.uint32() })` mixes freely.
|
|
25
25
|
*/
|
|
26
26
|
export declare const reef: {
|
|
27
|
-
i8: () => import("./zod.js").Fluent<{
|
|
27
|
+
i8: () => import("./zod.js").Fluent<import("./zod.js").Fluent<{
|
|
28
28
|
readonly _zod: {
|
|
29
29
|
output: number;
|
|
30
30
|
input: number;
|
|
@@ -43,8 +43,8 @@ export declare const reef: {
|
|
|
43
43
|
};
|
|
44
44
|
check(...checks: import("./zod.js").Check[]): /*elided*/ any;
|
|
45
45
|
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): /*elided*/ any;
|
|
46
|
-
}
|
|
47
|
-
u8: () => import("./zod.js").Fluent<{
|
|
46
|
+
}>>;
|
|
47
|
+
u8: () => import("./zod.js").Fluent<import("./zod.js").Fluent<{
|
|
48
48
|
readonly _zod: {
|
|
49
49
|
output: number;
|
|
50
50
|
input: number;
|
|
@@ -63,8 +63,8 @@ export declare const reef: {
|
|
|
63
63
|
};
|
|
64
64
|
check(...checks: import("./zod.js").Check[]): any;
|
|
65
65
|
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): any;
|
|
66
|
-
}
|
|
67
|
-
i16: () => import("./zod.js").Fluent<{
|
|
66
|
+
}>>;
|
|
67
|
+
i16: () => import("./zod.js").Fluent<import("./zod.js").Fluent<{
|
|
68
68
|
readonly _zod: {
|
|
69
69
|
output: number;
|
|
70
70
|
input: number;
|
|
@@ -83,8 +83,8 @@ export declare const reef: {
|
|
|
83
83
|
};
|
|
84
84
|
check(...checks: import("./zod.js").Check[]): any;
|
|
85
85
|
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): any;
|
|
86
|
-
}
|
|
87
|
-
u16: () => import("./zod.js").Fluent<{
|
|
86
|
+
}>>;
|
|
87
|
+
u16: () => import("./zod.js").Fluent<import("./zod.js").Fluent<{
|
|
88
88
|
readonly _zod: {
|
|
89
89
|
output: number;
|
|
90
90
|
input: number;
|
|
@@ -103,7 +103,7 @@ export declare const reef: {
|
|
|
103
103
|
};
|
|
104
104
|
check(...checks: import("./zod.js").Check[]): any;
|
|
105
105
|
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): any;
|
|
106
|
-
}
|
|
106
|
+
}>>;
|
|
107
107
|
i32: () => import("./zod.js").Fluent<{
|
|
108
108
|
readonly _zod: {
|
|
109
109
|
output: number;
|
|
@@ -225,7 +225,7 @@ export declare const reef: {
|
|
|
225
225
|
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): any;
|
|
226
226
|
}>;
|
|
227
227
|
/** Bounded int — compiles to the narrowest covering kind (0..3 → u8). */
|
|
228
|
-
int: (min: number, max: number) => import("./zod.js").Fluent<{
|
|
228
|
+
int: (min: number, max: number) => import("./zod.js").Fluent<import("./zod.js").Fluent<{
|
|
229
229
|
readonly _zod: {
|
|
230
230
|
output: number;
|
|
231
231
|
input: number;
|
|
@@ -244,9 +244,9 @@ export declare const reef: {
|
|
|
244
244
|
};
|
|
245
245
|
check(...checks: import("./zod.js").Check[]): /*elided*/ any;
|
|
246
246
|
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): /*elided*/ any;
|
|
247
|
-
}
|
|
247
|
+
}>>;
|
|
248
248
|
/** A flag byte — reads and writes as boolean. */
|
|
249
|
-
boolean: () => import("./zod.js").Fluent<{
|
|
249
|
+
boolean: () => import("./zod.js").Fluent<import("./zod.js").Fluent<{
|
|
250
250
|
readonly _zod: {
|
|
251
251
|
output: boolean;
|
|
252
252
|
input: boolean;
|
|
@@ -265,11 +265,11 @@ export declare const reef: {
|
|
|
265
265
|
};
|
|
266
266
|
check(...checks: import("./zod.js").Check[]): /*elided*/ any;
|
|
267
267
|
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): /*elided*/ any;
|
|
268
|
-
}
|
|
268
|
+
}>>;
|
|
269
269
|
/** Fixed-capacity inline UTF-8 string — `bytes` is the byte budget. The
|
|
270
270
|
* schema itself refuses over-budget values, so `.parse` and connector
|
|
271
271
|
* writes enforce the same limit. */
|
|
272
|
-
string: (bytes: number) => import("./zod.js").Fluent<{
|
|
272
|
+
string: (bytes: number) => import("./zod.js").Fluent<import("./zod.js").Fluent<{
|
|
273
273
|
readonly _zod: {
|
|
274
274
|
output: string;
|
|
275
275
|
input: string;
|
|
@@ -288,52 +288,112 @@ export declare const reef: {
|
|
|
288
288
|
};
|
|
289
289
|
check(...checks: import("./zod.js").Check[]): /*elided*/ any;
|
|
290
290
|
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): /*elided*/ any;
|
|
291
|
-
}
|
|
291
|
+
}>>;
|
|
292
292
|
/** A fixed-layout record shape — every member must be a fixed-width schema. */
|
|
293
|
-
object: <S extends z.ZodRawShape>(shape: S) => import("./zod.js").Fluent<{
|
|
293
|
+
object: <S extends z.ZodRawShape>(shape: S) => import("./zod.js").Fluent<import("./zod.js").Fluent<{
|
|
294
294
|
readonly _zod: {
|
|
295
|
-
output: { [K in keyof S
|
|
295
|
+
output: { [K in keyof S as (S[K] extends {
|
|
296
|
+
_zod: {
|
|
297
|
+
output: infer O;
|
|
298
|
+
};
|
|
299
|
+
} ? undefined extends O ? true : false : false) extends true ? never : K]: S[K] extends infer T_1 ? T_1 extends S[K] ? T_1 extends {
|
|
300
|
+
_zod: {
|
|
301
|
+
output: infer O_1;
|
|
302
|
+
};
|
|
303
|
+
} ? O_1 : never : never : never; } & { [K in keyof S as (S[K] extends {
|
|
296
304
|
_zod: {
|
|
297
305
|
output: infer O;
|
|
298
306
|
};
|
|
299
|
-
} ? O : never
|
|
300
|
-
|
|
307
|
+
} ? undefined extends O ? true : false : false) extends true ? K : never]?: (S[K] extends infer T_1 ? T_1 extends S[K] ? T_1 extends {
|
|
308
|
+
_zod: {
|
|
309
|
+
output: infer O_1;
|
|
310
|
+
};
|
|
311
|
+
} ? O : never : never : never) | undefined; } extends infer T ? { [K in keyof T]: T[K]; } : never;
|
|
312
|
+
input: { [K in keyof S as (S[K] extends {
|
|
301
313
|
_zod: {
|
|
302
314
|
output: infer O;
|
|
303
315
|
};
|
|
304
|
-
} ? O : never
|
|
316
|
+
} ? undefined extends O ? true : false : false) extends true ? never : K]: S[K] extends infer T_1 ? T_1 extends S[K] ? T_1 extends {
|
|
317
|
+
_zod: {
|
|
318
|
+
output: infer O_1;
|
|
319
|
+
};
|
|
320
|
+
} ? O_1 : never : never : never; } & { [K in keyof S as (S[K] extends {
|
|
321
|
+
_zod: {
|
|
322
|
+
output: infer O;
|
|
323
|
+
};
|
|
324
|
+
} ? undefined extends O ? true : false : false) extends true ? K : never]?: (S[K] extends infer T_1 ? T_1 extends S[K] ? T_1 extends {
|
|
325
|
+
_zod: {
|
|
326
|
+
output: infer O_1;
|
|
327
|
+
};
|
|
328
|
+
} ? O : never : never : never) | undefined; } extends infer T ? { [K in keyof T]: T[K]; } : never;
|
|
305
329
|
def: import("./zod.js").SchemaDef & {
|
|
306
330
|
type: 'object';
|
|
307
331
|
shape: S;
|
|
308
332
|
};
|
|
309
333
|
};
|
|
310
334
|
get shape(): S;
|
|
311
|
-
inner(v: unknown): { [K in keyof S
|
|
335
|
+
inner(v: unknown): { [K in keyof S as (S[K] extends {
|
|
336
|
+
_zod: {
|
|
337
|
+
output: infer O;
|
|
338
|
+
};
|
|
339
|
+
} ? undefined extends O ? true : false : false) extends true ? never : K]: S[K] extends infer T_1 ? T_1 extends S[K] ? T_1 extends {
|
|
340
|
+
_zod: {
|
|
341
|
+
output: infer O_1;
|
|
342
|
+
};
|
|
343
|
+
} ? O_1 : never : never : never; } & { [K in keyof S as (S[K] extends {
|
|
312
344
|
_zod: {
|
|
313
345
|
output: infer O;
|
|
314
346
|
};
|
|
315
|
-
} ? O : never
|
|
316
|
-
|
|
347
|
+
} ? undefined extends O ? true : false : false) extends true ? K : never]?: (S[K] extends infer T_1 ? T_1 extends S[K] ? T_1 extends {
|
|
348
|
+
_zod: {
|
|
349
|
+
output: infer O_1;
|
|
350
|
+
};
|
|
351
|
+
} ? O : never : never : never) | undefined; } extends infer T ? { [K in keyof T]: T[K]; } : never;
|
|
352
|
+
parse(value: unknown): { [K in keyof S as (S[K] extends {
|
|
353
|
+
_zod: {
|
|
354
|
+
output: infer O;
|
|
355
|
+
};
|
|
356
|
+
} ? undefined extends O ? true : false : false) extends true ? never : K]: S[K] extends infer T_1 ? T_1 extends S[K] ? T_1 extends {
|
|
357
|
+
_zod: {
|
|
358
|
+
output: infer O_1;
|
|
359
|
+
};
|
|
360
|
+
} ? O_1 : never : never : never; } & { [K in keyof S as (S[K] extends {
|
|
317
361
|
_zod: {
|
|
318
362
|
output: infer O;
|
|
319
363
|
};
|
|
320
|
-
} ? O : never
|
|
364
|
+
} ? undefined extends O ? true : false : false) extends true ? K : never]?: (S[K] extends infer T_1 ? T_1 extends S[K] ? T_1 extends {
|
|
365
|
+
_zod: {
|
|
366
|
+
output: infer O_1;
|
|
367
|
+
};
|
|
368
|
+
} ? O : never : never : never) | undefined; } extends infer T ? { [K in keyof T]: T[K]; } : never;
|
|
321
369
|
safeParse(value: unknown): {
|
|
322
370
|
success: true;
|
|
323
|
-
data: { [K in keyof S
|
|
371
|
+
data: { [K in keyof S as (S[K] extends {
|
|
324
372
|
_zod: {
|
|
325
373
|
output: infer O;
|
|
326
374
|
};
|
|
327
|
-
} ? O : never
|
|
375
|
+
} ? undefined extends O ? true : false : false) extends true ? never : K]: S[K] extends infer T_1 ? T_1 extends S[K] ? T_1 extends {
|
|
376
|
+
_zod: {
|
|
377
|
+
output: infer O_1;
|
|
378
|
+
};
|
|
379
|
+
} ? O_1 : never : never : never; } & { [K in keyof S as (S[K] extends {
|
|
380
|
+
_zod: {
|
|
381
|
+
output: infer O;
|
|
382
|
+
};
|
|
383
|
+
} ? undefined extends O ? true : false : false) extends true ? K : never]?: (S[K] extends infer T_1 ? T_1 extends S[K] ? T_1 extends {
|
|
384
|
+
_zod: {
|
|
385
|
+
output: infer O_1;
|
|
386
|
+
};
|
|
387
|
+
} ? O : never : never : never) | undefined; } extends infer T ? { [K in keyof T]: T[K]; } : never;
|
|
328
388
|
} | {
|
|
329
389
|
success: false;
|
|
330
390
|
error: unknown;
|
|
331
391
|
};
|
|
332
392
|
check(...checks: import("./zod.js").Check[]): /*elided*/ any;
|
|
333
393
|
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): /*elided*/ any;
|
|
334
|
-
}
|
|
394
|
+
}>>;
|
|
335
395
|
/** A fixed-stride element — bound it with `.max(n)` or `.length(n)` before field.array. */
|
|
336
|
-
array: <E extends z.ZodTypeAny>(element: E) => import("./zod.js").Fluent<{
|
|
396
|
+
array: <E extends z.ZodTypeAny>(element: E) => import("./zod.js").Fluent<import("./zod.js").Fluent<{
|
|
337
397
|
readonly _zod: {
|
|
338
398
|
output: (E extends {
|
|
339
399
|
_zod: {
|
|
@@ -373,5 +433,5 @@ export declare const reef: {
|
|
|
373
433
|
};
|
|
374
434
|
check(...checks: import("./zod.js").Check[]): /*elided*/ any;
|
|
375
435
|
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): /*elided*/ any;
|
|
376
|
-
}
|
|
436
|
+
}>>;
|
|
377
437
|
};
|
package/dist/contract/zod.d.ts
CHANGED
|
@@ -52,6 +52,10 @@ export interface SchemaDef {
|
|
|
52
52
|
format?: string;
|
|
53
53
|
shape?: Record<string, ZodLike>;
|
|
54
54
|
element?: ZodLike;
|
|
55
|
+
/** union members. */
|
|
56
|
+
options?: readonly ZodLike[];
|
|
57
|
+
/** literal value. */
|
|
58
|
+
literal?: unknown;
|
|
55
59
|
cls?: abstract new (...args: any[]) => unknown;
|
|
56
60
|
}
|
|
57
61
|
export declare class SchemaError extends Error {
|
|
@@ -143,13 +147,23 @@ declare class ZodUnknown extends ZodType<unknown> {
|
|
|
143
147
|
declare class ZodInstanceof<T> extends ZodType<T> {
|
|
144
148
|
inner(v: unknown): T;
|
|
145
149
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
150
|
+
/** Members whose output admits `undefined` become optional keys — mirroring
|
|
151
|
+
* zod's `z.optional()` object-member semantics (message-domain schemas like
|
|
152
|
+
* island prop contracts need this; reef's fixed-width members never produce
|
|
153
|
+
* it, so the split preserves their all-required output). */
|
|
154
|
+
type IsOptional<S, K extends keyof S> = S[K] extends {
|
|
155
|
+
_zod: {
|
|
156
|
+
output: infer O;
|
|
157
|
+
};
|
|
158
|
+
} ? undefined extends O ? true : false : false;
|
|
159
|
+
type Flatten<T> = {
|
|
160
|
+
[K in keyof T]: T[K];
|
|
152
161
|
};
|
|
162
|
+
type ShapeOutput<S extends Record<string, ZodLike>> = Flatten<{
|
|
163
|
+
[K in keyof S as IsOptional<S, K> extends true ? never : K]: OutputOf<S[K]>;
|
|
164
|
+
} & {
|
|
165
|
+
[K in keyof S as IsOptional<S, K> extends true ? K : never]?: OutputOf<S[K]>;
|
|
166
|
+
}>;
|
|
153
167
|
/** Strips unknown keys like zod's object parse — output is the shape only. */
|
|
154
168
|
declare class ZodObjectSchema<S extends Record<string, ZodLike>> extends ZodType<ShapeOutput<S>> {
|
|
155
169
|
readonly _zod: {
|
|
@@ -179,14 +193,90 @@ type OutputOf<S> = S extends {
|
|
|
179
193
|
output: infer O;
|
|
180
194
|
};
|
|
181
195
|
} ? O : never;
|
|
182
|
-
declare
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
196
|
+
declare class ZodOptional<E extends ZodLike> extends ZodType<OutputOf<E> | undefined> {
|
|
197
|
+
readonly _zod: {
|
|
198
|
+
output: OutputOf<E> | undefined;
|
|
199
|
+
input: OutputOf<E> | undefined;
|
|
200
|
+
def: SchemaDef & {
|
|
201
|
+
type: 'optional';
|
|
202
|
+
element: E;
|
|
203
|
+
};
|
|
204
|
+
};
|
|
205
|
+
inner(v: unknown): OutputOf<E> | undefined;
|
|
206
|
+
}
|
|
207
|
+
declare class ZodNullable<E extends ZodLike> extends ZodType<OutputOf<E> | null> {
|
|
208
|
+
readonly _zod: {
|
|
209
|
+
output: OutputOf<E> | null;
|
|
210
|
+
input: OutputOf<E> | null;
|
|
211
|
+
def: SchemaDef & {
|
|
212
|
+
type: 'nullable';
|
|
213
|
+
element: E;
|
|
214
|
+
};
|
|
215
|
+
};
|
|
216
|
+
inner(v: unknown): OutputOf<E> | null;
|
|
217
|
+
}
|
|
218
|
+
declare class ZodLiteral<V extends string | number | boolean> extends ZodType<V> {
|
|
219
|
+
readonly _zod: {
|
|
220
|
+
output: V;
|
|
221
|
+
input: V;
|
|
222
|
+
def: SchemaDef & {
|
|
223
|
+
type: 'literal';
|
|
224
|
+
};
|
|
225
|
+
};
|
|
226
|
+
inner(v: unknown): V;
|
|
227
|
+
}
|
|
228
|
+
declare class ZodUnion<O extends readonly ZodLike[]> extends ZodType<OutputOf<O[number]>> {
|
|
229
|
+
readonly _zod: {
|
|
230
|
+
output: OutputOf<O[number]>;
|
|
231
|
+
input: OutputOf<O[number]>;
|
|
232
|
+
def: SchemaDef & {
|
|
233
|
+
type: 'union';
|
|
234
|
+
options: O;
|
|
235
|
+
};
|
|
236
|
+
};
|
|
237
|
+
inner(v: unknown): OutputOf<O[number]>;
|
|
238
|
+
}
|
|
239
|
+
declare class ZodRecord<E extends ZodLike> extends ZodType<Record<string, OutputOf<E>>> {
|
|
240
|
+
readonly _zod: {
|
|
241
|
+
output: Record<string, OutputOf<E>>;
|
|
242
|
+
input: Record<string, OutputOf<E>>;
|
|
243
|
+
def: SchemaDef & {
|
|
244
|
+
type: 'record';
|
|
245
|
+
element: E;
|
|
246
|
+
};
|
|
247
|
+
};
|
|
248
|
+
inner(v: unknown): Record<string, OutputOf<E>>;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Function-typed members — how a props schema declares a `callbackProp`
|
|
252
|
+
* slot: the wire carries a `{__cb:id}` handle that `unmarshalCallbackProps`
|
|
253
|
+
* restores to a callable BEFORE contract validation runs, so at parse time
|
|
254
|
+
* the member is a real function.
|
|
255
|
+
*/
|
|
256
|
+
declare class ZodCallback<F extends (...args: any[]) => any = (...args: unknown[]) => unknown> extends ZodType<F> {
|
|
257
|
+
readonly _zod: {
|
|
258
|
+
output: F;
|
|
259
|
+
input: F;
|
|
260
|
+
def: SchemaDef & {
|
|
261
|
+
type: 'function';
|
|
262
|
+
};
|
|
263
|
+
};
|
|
264
|
+
inner(v: unknown): F;
|
|
265
|
+
}
|
|
266
|
+
declare const number: () => Fluent<ZodNumber>;
|
|
267
|
+
declare const string: () => Fluent<ZodString>;
|
|
268
|
+
declare const boolean_: () => Fluent<ZodBoolean>;
|
|
269
|
+
declare const bigint_: () => Fluent<ZodBigint>;
|
|
270
|
+
declare const unknown_: () => Fluent<ZodUnknown>;
|
|
271
|
+
declare const instanceof_: <T extends abstract new (...args: any[]) => any>(cls: T) => Fluent<ZodInstanceof<InstanceType<T>>>;
|
|
272
|
+
declare const object_: <S extends Record<string, ZodLike>>(shape: S) => Fluent<ZodObjectSchema<S>>;
|
|
273
|
+
declare const array: <E extends ZodLike>(element: E) => Fluent<ZodArraySchema<E>>;
|
|
274
|
+
declare const optional: <E extends ZodLike>(element: E) => Fluent<ZodOptional<E>>;
|
|
275
|
+
declare const nullable: <E extends ZodLike>(element: E) => Fluent<ZodNullable<E>>;
|
|
276
|
+
declare const literal: <V extends string | number | boolean>(value: V) => Fluent<ZodLiteral<V>>;
|
|
277
|
+
declare const union: <O extends readonly [ZodLike, ...ZodLike[]]>(options: O) => Fluent<ZodUnion<O>>;
|
|
278
|
+
declare const record: <E extends ZodLike>(element: E) => Fluent<ZodRecord<E>>;
|
|
279
|
+
declare const callback: <F extends (...args: any[]) => any = (...args: unknown[]) => unknown>() => Fluent<ZodCallback<F>>;
|
|
190
280
|
declare const int32: () => ZodNumber;
|
|
191
281
|
declare const uint32: () => ZodNumber;
|
|
192
282
|
declare const float32: () => ZodNumber;
|
|
@@ -204,6 +294,10 @@ export type Fluent<S extends ZodLike> = S & {
|
|
|
204
294
|
max(value: number | bigint): Fluent<S>;
|
|
205
295
|
length(n: number): Fluent<S>;
|
|
206
296
|
int(): Fluent<S>;
|
|
297
|
+
/** Wraps in an optional member — the `label?: string` spelling. */
|
|
298
|
+
optional(): Fluent<ZodOptional<S>>;
|
|
299
|
+
/** Wraps in a nullable member — `T | null`. */
|
|
300
|
+
nullable(): Fluent<ZodNullable<S>>;
|
|
207
301
|
};
|
|
208
302
|
/** Attaches the `Fluent` methods as non-enumerable own properties. */
|
|
209
303
|
export declare function fluent<S extends ZodType>(schema: S): Fluent<S>;
|
|
@@ -216,6 +310,12 @@ export declare const z: {
|
|
|
216
310
|
array: typeof array;
|
|
217
311
|
instanceof: typeof instanceof_;
|
|
218
312
|
unknown: typeof unknown_;
|
|
313
|
+
optional: typeof optional;
|
|
314
|
+
nullable: typeof nullable;
|
|
315
|
+
literal: typeof literal;
|
|
316
|
+
union: typeof union;
|
|
317
|
+
record: typeof record;
|
|
318
|
+
callback: typeof callback;
|
|
219
319
|
int32: typeof int32;
|
|
220
320
|
uint32: typeof uint32;
|
|
221
321
|
float32: typeof float32;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { bindSharedMemories, defineSharedMemory, field, getDefinedSharedMemoryCount, jsonCodec, registerConnectorFactory } from './contract/sharedMemory.js';
|
|
2
2
|
export { reef } from './contract/reef.js';
|
|
3
|
+
export { z, SchemaError } from './contract/zod.js';
|
|
4
|
+
export type { ZodLike } from './contract/zod.js';
|
|
3
5
|
export type { Codec, Connector, ConnectorContext, ConnectorFactory, FieldDescriptor, FieldGroup, FieldSchema, FixedArrayDescriptor, FixedObjectDescriptor, FlatKey, InferField, PathConnector, SpecPath, SpecSchemas, SharedAccess, SharedMemory, SharedMemoryOptions, SharedSpec, ScalarKind, ListConnector, ListDescriptor, ListFieldSpec, ListFields, ListMember, ListRecord, ListSpec, } from './contract/sharedMemory.js';
|
|
4
6
|
export { msgpackrCodec } from './contract/msgpackrCodec.js';
|
|
5
7
|
export { listSchema } from './contract/listSchema.js';
|
package/dist/index.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { msgpackrCodec as e } from "./index2.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
|
|
2
|
+
import { SchemaError as t, z as n } from "./index3.js";
|
|
3
|
+
import { listSchema as r } from "./index4.js";
|
|
4
|
+
import { getLogLevel as i, log as a, scoped as o, setLogLevel as s, setLogSink as c } from "./index5.js";
|
|
5
|
+
import { bindSharedMemories as l, defineSharedMemory as u, field as d, getDefinedSharedMemoryCount as f, jsonCodec as p, registerConnectorFactory as m } from "./index6.js";
|
|
6
|
+
import { reef as h } from "./index7.js";
|
|
7
|
+
import { MemoryManager as g } from "./index8.js";
|
|
8
|
+
import { PoolQueueFullError as _, TaskAbortedError as v, TaskTimeoutError as y, WorkerCrashedError as b } from "./index9.js";
|
|
9
|
+
import { WorkerPool as x } from "./index10.js";
|
|
10
|
+
import { connectWorker as S, workerClient as C } from "./index11.js";
|
|
11
|
+
import { connectSharedWorker as w } from "./index12.js";
|
|
12
|
+
import { TaskRegistry as T } from "./index13.js";
|
|
13
|
+
import { sharedWorkerHost as E } from "./index14.js";
|
|
14
|
+
import { createClient as D, defineService as O, implementService as k, rpc as A, serviceMethod as j } from "./index15.js";
|
|
15
|
+
import { RESERVED_CLIENT_KEYS as M, defineWorker as N } from "./index17.js";
|
|
16
|
+
import { reactive as P, shallowEqual as F, watch as I } from "./index18.js";
|
|
17
|
+
import { observe as L } from "./index19.js";
|
|
18
|
+
import { defineTask as R, isAsyncTask as z, toTask as B } from "./index20.js";
|
|
19
|
+
export { g as MemoryManager, _ as PoolQueueFullError, M as RESERVED_CLIENT_KEYS, t as SchemaError, v as TaskAbortedError, T as TaskRegistry, y as TaskTimeoutError, b as WorkerCrashedError, x as WorkerPool, l as bindSharedMemories, w as connectSharedWorker, S as connectWorker, D as createClient, O as defineService, u as defineSharedMemory, R as defineTask, N as defineWorker, d as field, f as getDefinedSharedMemoryCount, i as getLogLevel, k as implementService, z as isAsyncTask, p as jsonCodec, r as listSchema, a as log, e as msgpackrCodec, L as observe, P as reactive, h as reef, m as registerConnectorFactory, A as rpc, o as scoped, j as serviceMethod, s as setLogLevel, c as setLogSink, F as shallowEqual, E as sharedWorkerHost, B as toTask, I as watch, C as workerClient, n as z };
|
package/dist/index18.js
CHANGED
|
@@ -1,59 +1,88 @@
|
|
|
1
1
|
import { scoped as e } from "./index5.js";
|
|
2
|
-
import { createEffect as t, createMemo as n,
|
|
2
|
+
import { createEffect as t, createMemo as n, createRenderEffect as r, createRoot as i, createSignal as a } from "solid-js";
|
|
3
3
|
//#region src/reactive.ts
|
|
4
|
-
var
|
|
5
|
-
function
|
|
4
|
+
var o = e("reactive");
|
|
5
|
+
function s(e, t) {
|
|
6
6
|
if (e === t) return !0;
|
|
7
7
|
if (e == null || t == null) return !1;
|
|
8
8
|
let n = Object.keys(e), r = Object.keys(t);
|
|
9
9
|
return n.length === r.length && n.every((n) => Object.is(e[n], t[n]));
|
|
10
10
|
}
|
|
11
|
-
|
|
12
|
-
let
|
|
11
|
+
var c = (e, t) => {
|
|
12
|
+
let n = e._version;
|
|
13
|
+
if (!n) throw Error("This connector does not support remote observation.");
|
|
14
|
+
let r = !1, i = Atomics.load(n.view, n.index);
|
|
15
|
+
if (typeof Atomics.waitAsync == "function") return o.debug(`observing remote writes (offset ${e.byteOffset}, waitAsync)`), (async () => {
|
|
16
|
+
for (; !r;) {
|
|
17
|
+
let a = Atomics.waitAsync(n.view, n.index, i);
|
|
18
|
+
a.async && await a.value, i = Atomics.load(n.view, n.index), r || (o.trace(`remote write observed (offset ${e.byteOffset})`), t());
|
|
19
|
+
}
|
|
20
|
+
o.debug(`stopped observing (offset ${e.byteOffset})`);
|
|
21
|
+
})(), () => {
|
|
22
|
+
r = !0;
|
|
23
|
+
};
|
|
24
|
+
o.warn(`Atomics.waitAsync unavailable — observing via 50ms poll (offset ${e.byteOffset})`);
|
|
25
|
+
let a = setInterval(() => {
|
|
26
|
+
let e = Atomics.load(n.view, n.index);
|
|
27
|
+
e !== i && (i = e, t());
|
|
28
|
+
}, 50);
|
|
29
|
+
return () => {
|
|
30
|
+
r = !0, clearInterval(a);
|
|
31
|
+
};
|
|
32
|
+
}, l = null, u = () => {
|
|
33
|
+
if (l !== null) return l;
|
|
34
|
+
try {
|
|
35
|
+
let e = 0, t;
|
|
36
|
+
i(() => {
|
|
37
|
+
let [n, i] = a(0);
|
|
38
|
+
t = i, r(() => {
|
|
39
|
+
n(), e++;
|
|
40
|
+
});
|
|
41
|
+
}), t?.(1), l = e > 1;
|
|
42
|
+
} catch {
|
|
43
|
+
l = !1;
|
|
44
|
+
}
|
|
45
|
+
return l || o.warn("solid-js resolved to the SSR build — watch() falls back to direct version watching"), l;
|
|
46
|
+
};
|
|
47
|
+
function d(e) {
|
|
48
|
+
let [t, n] = a(e.read(), { equals: !1 }), r = () => n(() => e.read());
|
|
13
49
|
return {
|
|
14
50
|
get: t,
|
|
15
51
|
peek: () => e.read(),
|
|
16
52
|
set: (t) => {
|
|
17
53
|
e.write(t), r();
|
|
18
54
|
},
|
|
19
|
-
observeRemote: () =>
|
|
20
|
-
let t = e._version;
|
|
21
|
-
if (!t) throw Error("This connector does not support remote observation.");
|
|
22
|
-
let n = !1, i = Atomics.load(t.view, t.index);
|
|
23
|
-
if (typeof Atomics.waitAsync == "function") return a.debug(`observing remote writes (offset ${e.byteOffset}, waitAsync)`), (async () => {
|
|
24
|
-
for (; !n;) {
|
|
25
|
-
let o = Atomics.waitAsync(t.view, t.index, i);
|
|
26
|
-
o.async && await o.value, i = Atomics.load(t.view, t.index), n || (a.trace(`remote write observed (offset ${e.byteOffset})`), r());
|
|
27
|
-
}
|
|
28
|
-
a.debug(`stopped observing (offset ${e.byteOffset})`);
|
|
29
|
-
})(), () => {
|
|
30
|
-
n = !0;
|
|
31
|
-
};
|
|
32
|
-
a.warn(`Atomics.waitAsync unavailable — observing via 50ms poll (offset ${e.byteOffset})`);
|
|
33
|
-
let o = setInterval(() => {
|
|
34
|
-
let e = Atomics.load(t.view, t.index);
|
|
35
|
-
e !== i && (i = e, r());
|
|
36
|
-
}, 50);
|
|
37
|
-
return () => {
|
|
38
|
-
n = !0, clearInterval(o);
|
|
39
|
-
};
|
|
40
|
-
}
|
|
55
|
+
observeRemote: () => c(e, r)
|
|
41
56
|
};
|
|
42
57
|
}
|
|
43
|
-
function
|
|
44
|
-
let l =
|
|
58
|
+
function f(e, r, a, s) {
|
|
59
|
+
let l = a ? r : ((e) => e), f = a ?? r;
|
|
60
|
+
if (!u()) {
|
|
61
|
+
let t = (e, t) => e === void 0 || t === void 0 ? e === t : (s?.equals ?? Object.is)(e, t), n, r = () => {
|
|
62
|
+
let r = e.read(), i = r == null ? void 0 : l(r);
|
|
63
|
+
if (i === void 0 || t(n, i)) return;
|
|
64
|
+
let a = n;
|
|
65
|
+
n = i, f(i, a);
|
|
66
|
+
};
|
|
67
|
+
r();
|
|
68
|
+
let i = c(e, r);
|
|
69
|
+
return o.debug(`watching connector at offset ${e.byteOffset} (direct)`), () => {
|
|
70
|
+
o.debug(`watch stopped (offset ${e.byteOffset})`), i();
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
let p = d(e), m = p.observeRemote(), h = i((e) => {
|
|
45
74
|
let r = n(() => {
|
|
46
|
-
let e =
|
|
75
|
+
let e = p.get();
|
|
47
76
|
return e == null ? void 0 : l(e);
|
|
48
|
-
}, void 0,
|
|
77
|
+
}, void 0, s?.equals ? { equals: (e, t) => e === void 0 || t === void 0 ? e === t : s.equals(e, t) } : void 0);
|
|
49
78
|
return t((e) => {
|
|
50
79
|
let t = r();
|
|
51
|
-
return t !== void 0 &&
|
|
80
|
+
return t !== void 0 && f(t, e), t;
|
|
52
81
|
}), e;
|
|
53
82
|
});
|
|
54
|
-
return
|
|
55
|
-
|
|
83
|
+
return o.debug(`watching connector at offset ${e.byteOffset}`), () => {
|
|
84
|
+
o.debug(`watch stopped (offset ${e.byteOffset})`), m(), h();
|
|
56
85
|
};
|
|
57
86
|
}
|
|
58
87
|
//#endregion
|
|
59
|
-
export {
|
|
88
|
+
export { d as reactive, s as shallowEqual, f as watch };
|
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,9 +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,
|
|
262
|
+
export { h as SchemaError, g as ZodType, $ as fluent, m as globalRegistry, te as z };
|
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",
|
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,
|
package/src/reactive.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createEffect, createMemo, createRoot, createSignal } from 'solid-js';
|
|
1
|
+
import { createEffect, createMemo, createRenderEffect, createRoot, createSignal } from 'solid-js';
|
|
2
2
|
import { Connector } from './contract/sharedMemory';
|
|
3
3
|
import { scoped } from './log';
|
|
4
4
|
|
|
@@ -40,6 +40,87 @@ export interface ReactiveConnector<T> {
|
|
|
40
40
|
observeRemote(): () => void;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Park on the connector's shared version counter and invoke `onBump` on each
|
|
45
|
+
* write — local or remote, both bump it. waitAsync when available, 50ms poll
|
|
46
|
+
* otherwise. No solid-js involved: this is the whole remote-write mechanism.
|
|
47
|
+
*/
|
|
48
|
+
const watchVersion = <T>(connector: Connector<T>, onBump: () => void): (() => void) => {
|
|
49
|
+
const version = connector._version;
|
|
50
|
+
if (!version) {
|
|
51
|
+
throw new Error('This connector does not support remote observation.');
|
|
52
|
+
}
|
|
53
|
+
let stopped = false;
|
|
54
|
+
let last = Atomics.load(version.view, version.index);
|
|
55
|
+
|
|
56
|
+
if (typeof Atomics.waitAsync === 'function') {
|
|
57
|
+
reactiveLog.debug(`observing remote writes (offset ${connector.byteOffset}, waitAsync)`);
|
|
58
|
+
void (async () => {
|
|
59
|
+
while (!stopped) {
|
|
60
|
+
const result = Atomics.waitAsync(version.view, version.index, last);
|
|
61
|
+
if (result.async) {
|
|
62
|
+
await result.value;
|
|
63
|
+
}
|
|
64
|
+
last = Atomics.load(version.view, version.index);
|
|
65
|
+
if (!stopped) {
|
|
66
|
+
reactiveLog.trace(`remote write observed (offset ${connector.byteOffset})`);
|
|
67
|
+
onBump();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
reactiveLog.debug(`stopped observing (offset ${connector.byteOffset})`);
|
|
71
|
+
})();
|
|
72
|
+
return () => { stopped = true; };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
reactiveLog.warn(`Atomics.waitAsync unavailable — observing via 50ms poll (offset ${connector.byteOffset})`);
|
|
76
|
+
const timer = setInterval(() => {
|
|
77
|
+
const current = Atomics.load(version.view, version.index);
|
|
78
|
+
if (current !== last) {
|
|
79
|
+
last = current;
|
|
80
|
+
onBump();
|
|
81
|
+
}
|
|
82
|
+
}, 50);
|
|
83
|
+
return () => {
|
|
84
|
+
stopped = true;
|
|
85
|
+
clearInterval(timer);
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Under `node`/`worker`/`deno` export conditions, `solid-js` resolves to the
|
|
91
|
+
* SSR build — `createEffect` is a no-op, so signal-driven `watch`/`observe`
|
|
92
|
+
* die silently. Probe once. `createRenderEffect` is the discriminator: it
|
|
93
|
+
* runs synchronously at creation in BOTH builds but only re-fires on `set`
|
|
94
|
+
* in the client build. `createEffect` can't be used — the client build
|
|
95
|
+
* defers it past the synchronous `set` below, probing a false negative.
|
|
96
|
+
* The write must land AFTER the root's create pass returns for the same
|
|
97
|
+
* reason (a set issued mid-subscription is swallowed).
|
|
98
|
+
*/
|
|
99
|
+
let solidLive: boolean | null = null;
|
|
100
|
+
const solidIsLive = (): boolean => {
|
|
101
|
+
if (solidLive !== null) return solidLive;
|
|
102
|
+
try {
|
|
103
|
+
let runs = 0;
|
|
104
|
+
let bump: ((v: number) => number) | undefined;
|
|
105
|
+
createRoot(() => {
|
|
106
|
+
const [get, set] = createSignal(0);
|
|
107
|
+
bump = set;
|
|
108
|
+
createRenderEffect(() => {
|
|
109
|
+
get();
|
|
110
|
+
runs++;
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
bump?.(1);
|
|
114
|
+
solidLive = runs > 1;
|
|
115
|
+
} catch {
|
|
116
|
+
solidLive = false;
|
|
117
|
+
}
|
|
118
|
+
if (!solidLive) {
|
|
119
|
+
reactiveLog.warn('solid-js resolved to the SSR build — watch() falls back to direct version watching');
|
|
120
|
+
}
|
|
121
|
+
return solidLive;
|
|
122
|
+
};
|
|
123
|
+
|
|
43
124
|
export function reactive<T>(connector: Connector<T>): ReactiveConnector<T> {
|
|
44
125
|
const [value, setValue] = createSignal<T>(connector.read(), { equals: false });
|
|
45
126
|
const bump = () => setValue(() => connector.read());
|
|
@@ -51,47 +132,7 @@ export function reactive<T>(connector: Connector<T>): ReactiveConnector<T> {
|
|
|
51
132
|
connector.write(v);
|
|
52
133
|
bump();
|
|
53
134
|
},
|
|
54
|
-
observeRemote: () =>
|
|
55
|
-
const version = connector._version;
|
|
56
|
-
if (!version) {
|
|
57
|
-
throw new Error('This connector does not support remote observation.');
|
|
58
|
-
}
|
|
59
|
-
let stopped = false;
|
|
60
|
-
let last = Atomics.load(version.view, version.index);
|
|
61
|
-
|
|
62
|
-
if (typeof Atomics.waitAsync === 'function') {
|
|
63
|
-
reactiveLog.debug(`observing remote writes (offset ${connector.byteOffset}, waitAsync)`);
|
|
64
|
-
void (async () => {
|
|
65
|
-
while (!stopped) {
|
|
66
|
-
const result = Atomics.waitAsync(version.view, version.index, last);
|
|
67
|
-
if (result.async) {
|
|
68
|
-
await result.value;
|
|
69
|
-
}
|
|
70
|
-
last = Atomics.load(version.view, version.index);
|
|
71
|
-
if (!stopped) {
|
|
72
|
-
reactiveLog.trace(`remote write observed (offset ${connector.byteOffset})`);
|
|
73
|
-
bump();
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
reactiveLog.debug(`stopped observing (offset ${connector.byteOffset})`);
|
|
77
|
-
})();
|
|
78
|
-
return () => { stopped = true; };
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Fallback for environments without Atomics.waitAsync
|
|
82
|
-
reactiveLog.warn(`Atomics.waitAsync unavailable — observing via 50ms poll (offset ${connector.byteOffset})`);
|
|
83
|
-
const timer = setInterval(() => {
|
|
84
|
-
const current = Atomics.load(version.view, version.index);
|
|
85
|
-
if (current !== last) {
|
|
86
|
-
last = current;
|
|
87
|
-
bump();
|
|
88
|
-
}
|
|
89
|
-
}, 50);
|
|
90
|
-
return () => {
|
|
91
|
-
stopped = true;
|
|
92
|
-
clearInterval(timer);
|
|
93
|
-
};
|
|
94
|
-
},
|
|
135
|
+
observeRemote: () => watchVersion(connector, bump),
|
|
95
136
|
};
|
|
96
137
|
}
|
|
97
138
|
|
|
@@ -127,6 +168,30 @@ export function watch<T, S = T>(
|
|
|
127
168
|
const select = onChange ? (selOrCb as (value: T) => S) : ((v: T) => v as unknown as S);
|
|
128
169
|
const cb = (onChange ?? selOrCb) as (slice: S, previous: S | undefined) => void;
|
|
129
170
|
|
|
171
|
+
// SSR solid build (node/worker conditions): effects never re-run, so the
|
|
172
|
+
// signal pipeline below would silently never emit. Same semantics, driven
|
|
173
|
+
// straight off the version counter instead.
|
|
174
|
+
if (!solidIsLive()) {
|
|
175
|
+
const eq = (a: S | undefined, b: S | undefined): boolean =>
|
|
176
|
+
a === undefined || b === undefined ? a === b : (options?.equals ?? Object.is)(a, b);
|
|
177
|
+
let prev: S | undefined;
|
|
178
|
+
const emit = () => {
|
|
179
|
+
const v = connector.read() as T | null | undefined;
|
|
180
|
+
const s = v == null ? undefined : select(v);
|
|
181
|
+
if (s === undefined || eq(prev, s)) return;
|
|
182
|
+
const old = prev;
|
|
183
|
+
prev = s;
|
|
184
|
+
cb(s, old);
|
|
185
|
+
};
|
|
186
|
+
emit();
|
|
187
|
+
const stop = watchVersion(connector, emit);
|
|
188
|
+
reactiveLog.debug(`watching connector at offset ${connector.byteOffset} (direct)`);
|
|
189
|
+
return () => {
|
|
190
|
+
reactiveLog.debug(`watch stopped (offset ${connector.byteOffset})`);
|
|
191
|
+
stop();
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
130
195
|
const sig = reactive(connector);
|
|
131
196
|
const stopRemote = sig.observeRemote();
|
|
132
197
|
const dispose = createRoot((d) => {
|