@atolljs/core 0.1.4 → 0.1.5
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 +61 -61
- package/dist/contract/sharedMemory.d.ts +2 -2
- package/dist/contract/types.d.ts +1 -1
- package/dist/index.d.ts +29 -29
- 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 +0 -2
- package/dist/index19.js +0 -2
- package/dist/index2.js +0 -2
- package/dist/index20.js +0 -2
- package/dist/index3.js +0 -2
- 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/worker/defineWorker.ts +6 -2
- package/src/worker/workerBootstrap.ts +53 -37
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { z, type Fluent } from './zod';
|
|
2
|
-
import type { ListFieldSpec, ListFields, ListMember } from './sharedMemory';
|
|
1
|
+
import { z, type Fluent } from './zod.js';
|
|
2
|
+
import type { ListFieldSpec, ListFields, ListMember } from './sharedMemory.js';
|
|
3
3
|
/** Maps a list member to the zod shape whose inferred output type is
|
|
4
4
|
* identical to `ListRecord<F>[K]` — zod members pass through as
|
|
5
5
|
* themselves so declared bounds (e.g. `.max(3)`) stay in effect. */
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { Codec } from './sharedMemory';
|
|
1
|
+
import type { Codec } from './sharedMemory.js';
|
|
2
2
|
export declare const msgpackrCodec: Codec;
|
package/dist/contract/reef.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { z } from './zod';
|
|
1
|
+
import { z } from './zod.js';
|
|
2
2
|
/**
|
|
3
3
|
* Reef — the atoll's structural barrier: the fixed-width schema
|
|
4
4
|
* vocabulary standing between your data and the raw buffer. Every helper
|
|
@@ -24,11 +24,11 @@ import { z } from './zod';
|
|
|
24
24
|
* `_zod.def`, so `reef.object({ id: z.uint32() })` mixes freely.
|
|
25
25
|
*/
|
|
26
26
|
export declare const reef: {
|
|
27
|
-
i8: () => import("./zod").Fluent<{
|
|
27
|
+
i8: () => import("./zod.js").Fluent<{
|
|
28
28
|
readonly _zod: {
|
|
29
29
|
output: number;
|
|
30
30
|
input: number;
|
|
31
|
-
def: import("./zod").SchemaDef & {
|
|
31
|
+
def: import("./zod.js").SchemaDef & {
|
|
32
32
|
type: 'number';
|
|
33
33
|
};
|
|
34
34
|
};
|
|
@@ -41,14 +41,14 @@ export declare const reef: {
|
|
|
41
41
|
success: false;
|
|
42
42
|
error: unknown;
|
|
43
43
|
};
|
|
44
|
-
check(...checks: import("./zod").Check[]): /*elided*/ any;
|
|
45
|
-
register(registry: import("./zod").Registry, meta: Record<string, unknown>): /*elided*/ any;
|
|
44
|
+
check(...checks: import("./zod.js").Check[]): /*elided*/ any;
|
|
45
|
+
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): /*elided*/ any;
|
|
46
46
|
}>;
|
|
47
|
-
u8: () => import("./zod").Fluent<{
|
|
47
|
+
u8: () => import("./zod.js").Fluent<{
|
|
48
48
|
readonly _zod: {
|
|
49
49
|
output: number;
|
|
50
50
|
input: number;
|
|
51
|
-
def: import("./zod").SchemaDef & {
|
|
51
|
+
def: import("./zod.js").SchemaDef & {
|
|
52
52
|
type: 'number';
|
|
53
53
|
};
|
|
54
54
|
};
|
|
@@ -61,14 +61,14 @@ export declare const reef: {
|
|
|
61
61
|
success: false;
|
|
62
62
|
error: unknown;
|
|
63
63
|
};
|
|
64
|
-
check(...checks: import("./zod").Check[]): any;
|
|
65
|
-
register(registry: import("./zod").Registry, meta: Record<string, unknown>): any;
|
|
64
|
+
check(...checks: import("./zod.js").Check[]): any;
|
|
65
|
+
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): any;
|
|
66
66
|
}>;
|
|
67
|
-
i16: () => import("./zod").Fluent<{
|
|
67
|
+
i16: () => import("./zod.js").Fluent<{
|
|
68
68
|
readonly _zod: {
|
|
69
69
|
output: number;
|
|
70
70
|
input: number;
|
|
71
|
-
def: import("./zod").SchemaDef & {
|
|
71
|
+
def: import("./zod.js").SchemaDef & {
|
|
72
72
|
type: 'number';
|
|
73
73
|
};
|
|
74
74
|
};
|
|
@@ -81,14 +81,14 @@ export declare const reef: {
|
|
|
81
81
|
success: false;
|
|
82
82
|
error: unknown;
|
|
83
83
|
};
|
|
84
|
-
check(...checks: import("./zod").Check[]): any;
|
|
85
|
-
register(registry: import("./zod").Registry, meta: Record<string, unknown>): any;
|
|
84
|
+
check(...checks: import("./zod.js").Check[]): any;
|
|
85
|
+
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): any;
|
|
86
86
|
}>;
|
|
87
|
-
u16: () => import("./zod").Fluent<{
|
|
87
|
+
u16: () => import("./zod.js").Fluent<{
|
|
88
88
|
readonly _zod: {
|
|
89
89
|
output: number;
|
|
90
90
|
input: number;
|
|
91
|
-
def: import("./zod").SchemaDef & {
|
|
91
|
+
def: import("./zod.js").SchemaDef & {
|
|
92
92
|
type: 'number';
|
|
93
93
|
};
|
|
94
94
|
};
|
|
@@ -101,14 +101,14 @@ export declare const reef: {
|
|
|
101
101
|
success: false;
|
|
102
102
|
error: unknown;
|
|
103
103
|
};
|
|
104
|
-
check(...checks: import("./zod").Check[]): any;
|
|
105
|
-
register(registry: import("./zod").Registry, meta: Record<string, unknown>): any;
|
|
104
|
+
check(...checks: import("./zod.js").Check[]): any;
|
|
105
|
+
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): any;
|
|
106
106
|
}>;
|
|
107
|
-
i32: () => import("./zod").Fluent<{
|
|
107
|
+
i32: () => import("./zod.js").Fluent<{
|
|
108
108
|
readonly _zod: {
|
|
109
109
|
output: number;
|
|
110
110
|
input: number;
|
|
111
|
-
def: import("./zod").SchemaDef & {
|
|
111
|
+
def: import("./zod.js").SchemaDef & {
|
|
112
112
|
type: 'number';
|
|
113
113
|
};
|
|
114
114
|
};
|
|
@@ -121,14 +121,14 @@ export declare const reef: {
|
|
|
121
121
|
success: false;
|
|
122
122
|
error: unknown;
|
|
123
123
|
};
|
|
124
|
-
check(...checks: import("./zod").Check[]): any;
|
|
125
|
-
register(registry: import("./zod").Registry, meta: Record<string, unknown>): any;
|
|
124
|
+
check(...checks: import("./zod.js").Check[]): any;
|
|
125
|
+
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): any;
|
|
126
126
|
}>;
|
|
127
|
-
u32: () => import("./zod").Fluent<{
|
|
127
|
+
u32: () => import("./zod.js").Fluent<{
|
|
128
128
|
readonly _zod: {
|
|
129
129
|
output: number;
|
|
130
130
|
input: number;
|
|
131
|
-
def: import("./zod").SchemaDef & {
|
|
131
|
+
def: import("./zod.js").SchemaDef & {
|
|
132
132
|
type: 'number';
|
|
133
133
|
};
|
|
134
134
|
};
|
|
@@ -141,14 +141,14 @@ export declare const reef: {
|
|
|
141
141
|
success: false;
|
|
142
142
|
error: unknown;
|
|
143
143
|
};
|
|
144
|
-
check(...checks: import("./zod").Check[]): any;
|
|
145
|
-
register(registry: import("./zod").Registry, meta: Record<string, unknown>): any;
|
|
144
|
+
check(...checks: import("./zod.js").Check[]): any;
|
|
145
|
+
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): any;
|
|
146
146
|
}>;
|
|
147
|
-
f32: () => import("./zod").Fluent<{
|
|
147
|
+
f32: () => import("./zod.js").Fluent<{
|
|
148
148
|
readonly _zod: {
|
|
149
149
|
output: number;
|
|
150
150
|
input: number;
|
|
151
|
-
def: import("./zod").SchemaDef & {
|
|
151
|
+
def: import("./zod.js").SchemaDef & {
|
|
152
152
|
type: 'number';
|
|
153
153
|
};
|
|
154
154
|
};
|
|
@@ -161,14 +161,14 @@ export declare const reef: {
|
|
|
161
161
|
success: false;
|
|
162
162
|
error: unknown;
|
|
163
163
|
};
|
|
164
|
-
check(...checks: import("./zod").Check[]): any;
|
|
165
|
-
register(registry: import("./zod").Registry, meta: Record<string, unknown>): any;
|
|
164
|
+
check(...checks: import("./zod.js").Check[]): any;
|
|
165
|
+
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): any;
|
|
166
166
|
}>;
|
|
167
|
-
f64: () => import("./zod").Fluent<{
|
|
167
|
+
f64: () => import("./zod.js").Fluent<{
|
|
168
168
|
readonly _zod: {
|
|
169
169
|
output: number;
|
|
170
170
|
input: number;
|
|
171
|
-
def: import("./zod").SchemaDef & {
|
|
171
|
+
def: import("./zod.js").SchemaDef & {
|
|
172
172
|
type: 'number';
|
|
173
173
|
};
|
|
174
174
|
};
|
|
@@ -181,14 +181,14 @@ export declare const reef: {
|
|
|
181
181
|
success: false;
|
|
182
182
|
error: unknown;
|
|
183
183
|
};
|
|
184
|
-
check(...checks: import("./zod").Check[]): any;
|
|
185
|
-
register(registry: import("./zod").Registry, meta: Record<string, unknown>): any;
|
|
184
|
+
check(...checks: import("./zod.js").Check[]): any;
|
|
185
|
+
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): any;
|
|
186
186
|
}>;
|
|
187
|
-
i64: () => import("./zod").Fluent<{
|
|
187
|
+
i64: () => import("./zod.js").Fluent<{
|
|
188
188
|
readonly _zod: {
|
|
189
189
|
output: bigint;
|
|
190
190
|
input: bigint;
|
|
191
|
-
def: import("./zod").SchemaDef & {
|
|
191
|
+
def: import("./zod.js").SchemaDef & {
|
|
192
192
|
type: 'bigint';
|
|
193
193
|
};
|
|
194
194
|
};
|
|
@@ -201,14 +201,14 @@ export declare const reef: {
|
|
|
201
201
|
success: false;
|
|
202
202
|
error: unknown;
|
|
203
203
|
};
|
|
204
|
-
check(...checks: import("./zod").Check[]): /*elided*/ any;
|
|
205
|
-
register(registry: import("./zod").Registry, meta: Record<string, unknown>): /*elided*/ any;
|
|
204
|
+
check(...checks: import("./zod.js").Check[]): /*elided*/ any;
|
|
205
|
+
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): /*elided*/ any;
|
|
206
206
|
}>;
|
|
207
|
-
u64: () => import("./zod").Fluent<{
|
|
207
|
+
u64: () => import("./zod.js").Fluent<{
|
|
208
208
|
readonly _zod: {
|
|
209
209
|
output: bigint;
|
|
210
210
|
input: bigint;
|
|
211
|
-
def: import("./zod").SchemaDef & {
|
|
211
|
+
def: import("./zod.js").SchemaDef & {
|
|
212
212
|
type: 'bigint';
|
|
213
213
|
};
|
|
214
214
|
};
|
|
@@ -221,15 +221,15 @@ export declare const reef: {
|
|
|
221
221
|
success: false;
|
|
222
222
|
error: unknown;
|
|
223
223
|
};
|
|
224
|
-
check(...checks: import("./zod").Check[]): any;
|
|
225
|
-
register(registry: import("./zod").Registry, meta: Record<string, unknown>): any;
|
|
224
|
+
check(...checks: import("./zod.js").Check[]): any;
|
|
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").Fluent<{
|
|
228
|
+
int: (min: number, max: number) => import("./zod.js").Fluent<{
|
|
229
229
|
readonly _zod: {
|
|
230
230
|
output: number;
|
|
231
231
|
input: number;
|
|
232
|
-
def: import("./zod").SchemaDef & {
|
|
232
|
+
def: import("./zod.js").SchemaDef & {
|
|
233
233
|
type: 'number';
|
|
234
234
|
};
|
|
235
235
|
};
|
|
@@ -242,15 +242,15 @@ export declare const reef: {
|
|
|
242
242
|
success: false;
|
|
243
243
|
error: unknown;
|
|
244
244
|
};
|
|
245
|
-
check(...checks: import("./zod").Check[]): /*elided*/ any;
|
|
246
|
-
register(registry: import("./zod").Registry, meta: Record<string, unknown>): /*elided*/ any;
|
|
245
|
+
check(...checks: import("./zod.js").Check[]): /*elided*/ any;
|
|
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").Fluent<{
|
|
249
|
+
boolean: () => import("./zod.js").Fluent<{
|
|
250
250
|
readonly _zod: {
|
|
251
251
|
output: boolean;
|
|
252
252
|
input: boolean;
|
|
253
|
-
def: import("./zod").SchemaDef & {
|
|
253
|
+
def: import("./zod.js").SchemaDef & {
|
|
254
254
|
type: 'boolean';
|
|
255
255
|
};
|
|
256
256
|
};
|
|
@@ -263,17 +263,17 @@ export declare const reef: {
|
|
|
263
263
|
success: false;
|
|
264
264
|
error: unknown;
|
|
265
265
|
};
|
|
266
|
-
check(...checks: import("./zod").Check[]): /*elided*/ any;
|
|
267
|
-
register(registry: import("./zod").Registry, meta: Record<string, unknown>): /*elided*/ any;
|
|
266
|
+
check(...checks: import("./zod.js").Check[]): /*elided*/ any;
|
|
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").Fluent<{
|
|
272
|
+
string: (bytes: number) => import("./zod.js").Fluent<{
|
|
273
273
|
readonly _zod: {
|
|
274
274
|
output: string;
|
|
275
275
|
input: string;
|
|
276
|
-
def: import("./zod").SchemaDef & {
|
|
276
|
+
def: import("./zod.js").SchemaDef & {
|
|
277
277
|
type: 'string';
|
|
278
278
|
};
|
|
279
279
|
};
|
|
@@ -286,11 +286,11 @@ export declare const reef: {
|
|
|
286
286
|
success: false;
|
|
287
287
|
error: unknown;
|
|
288
288
|
};
|
|
289
|
-
check(...checks: import("./zod").Check[]): /*elided*/ any;
|
|
290
|
-
register(registry: import("./zod").Registry, meta: Record<string, unknown>): /*elided*/ any;
|
|
289
|
+
check(...checks: import("./zod.js").Check[]): /*elided*/ any;
|
|
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").Fluent<{
|
|
293
|
+
object: <S extends z.ZodRawShape>(shape: S) => import("./zod.js").Fluent<{
|
|
294
294
|
readonly _zod: {
|
|
295
295
|
output: { [K in keyof S]: S[K] extends {
|
|
296
296
|
_zod: {
|
|
@@ -302,7 +302,7 @@ export declare const reef: {
|
|
|
302
302
|
output: infer O;
|
|
303
303
|
};
|
|
304
304
|
} ? O : never; };
|
|
305
|
-
def: import("./zod").SchemaDef & {
|
|
305
|
+
def: import("./zod.js").SchemaDef & {
|
|
306
306
|
type: 'object';
|
|
307
307
|
shape: S;
|
|
308
308
|
};
|
|
@@ -329,11 +329,11 @@ export declare const reef: {
|
|
|
329
329
|
success: false;
|
|
330
330
|
error: unknown;
|
|
331
331
|
};
|
|
332
|
-
check(...checks: import("./zod").Check[]): /*elided*/ any;
|
|
333
|
-
register(registry: import("./zod").Registry, meta: Record<string, unknown>): /*elided*/ any;
|
|
332
|
+
check(...checks: import("./zod.js").Check[]): /*elided*/ any;
|
|
333
|
+
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): /*elided*/ any;
|
|
334
334
|
}>;
|
|
335
335
|
/** 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").Fluent<{
|
|
336
|
+
array: <E extends z.ZodTypeAny>(element: E) => import("./zod.js").Fluent<{
|
|
337
337
|
readonly _zod: {
|
|
338
338
|
output: (E extends {
|
|
339
339
|
_zod: {
|
|
@@ -345,7 +345,7 @@ export declare const reef: {
|
|
|
345
345
|
output: infer O;
|
|
346
346
|
};
|
|
347
347
|
} ? O : never)[];
|
|
348
|
-
def: import("./zod").SchemaDef & {
|
|
348
|
+
def: import("./zod.js").SchemaDef & {
|
|
349
349
|
type: 'array';
|
|
350
350
|
element: E;
|
|
351
351
|
};
|
|
@@ -371,7 +371,7 @@ export declare const reef: {
|
|
|
371
371
|
success: false;
|
|
372
372
|
error: unknown;
|
|
373
373
|
};
|
|
374
|
-
check(...checks: import("./zod").Check[]): /*elided*/ any;
|
|
375
|
-
register(registry: import("./zod").Registry, meta: Record<string, unknown>): /*elided*/ any;
|
|
374
|
+
check(...checks: import("./zod.js").Check[]): /*elided*/ any;
|
|
375
|
+
register(registry: import("./zod.js").Registry, meta: Record<string, unknown>): /*elided*/ any;
|
|
376
376
|
}>;
|
|
377
377
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Prettify, Schema } from './types';
|
|
2
|
-
import { z } from './zod';
|
|
1
|
+
import type { Prettify, Schema } from './types.js';
|
|
2
|
+
import { z } from './zod.js';
|
|
3
3
|
/**
|
|
4
4
|
* Declares the datatype of a single field in the shared memory contract.
|
|
5
5
|
* `byteLength` is the fixed region reserved for the field; structured types
|
package/dist/contract/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SharedAccess, SharedMemory, SharedSpec } from './sharedMemory';
|
|
1
|
+
import type { SharedAccess, SharedMemory, SharedSpec } from './sharedMemory.js';
|
|
2
2
|
export type ViewType = 'Int32' | 'Float64' | 'BigInt64' | 'Uint8';
|
|
3
3
|
/**
|
|
4
4
|
* Minimal validation contract — compatible with zod schemas (`z.object(...)`)
|
package/dist/index.d.ts
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
export { bindSharedMemories, defineSharedMemory, field, getDefinedSharedMemoryCount, jsonCodec, registerConnectorFactory } from './contract/sharedMemory';
|
|
2
|
-
export { reef } from './contract/reef';
|
|
3
|
-
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';
|
|
4
|
-
export { msgpackrCodec } from './contract/msgpackrCodec';
|
|
5
|
-
export { listSchema } from './contract/listSchema';
|
|
6
|
-
export type { ListZodShape } from './contract/listSchema';
|
|
7
|
-
export type { MemoryConfig, PoolTasks, Prettify, Schema, Logger, TaskContract, TaskMap, TaskMessage, TaskResult, MemoryPersistence, SharedWorkerConfig, ViewType, WorkerPoolConfig, } from './contract/types';
|
|
8
|
-
export { MemoryManager } from './pool/memory';
|
|
9
|
-
export { WorkerPool } from './pool/workerPool';
|
|
10
|
-
export type { PoolStats, RunOptions } from './pool/workerPool';
|
|
11
|
-
export { PoolQueueFullError, TaskAbortedError, TaskTimeoutError, WorkerCrashedError, } from './pool/errors';
|
|
12
|
-
export { connectWorker, workerClient } from './pool/workerClient';
|
|
13
|
-
export type { ClientMethods, ConnectWorkerConfig, WorkerClient, WorkerMethods, } from './pool/workerClient';
|
|
14
|
-
export { connectSharedWorker } from './shared/sharedWorkerClient';
|
|
15
|
-
export type { SharedWorkerClient } from './shared/sharedWorkerClient';
|
|
16
|
-
export { sharedWorkerHost } from './shared/sharedWorkerHost';
|
|
17
|
-
export { createClient, defineService, implementService, rpc, serviceMethod } from './service';
|
|
18
|
-
export type { RpcMethodDef, RpcMethodInput, RpcMethodInputMap, RpcMethodMap, ServiceClient, ServiceContract, ServiceHandlers, ServiceImpl, ServiceMethod, TaskRunner, } from './service';
|
|
19
|
-
export { TaskRegistry } from './worker/registry';
|
|
20
|
-
export { defineWorker, RESERVED_CLIENT_KEYS } from './worker/defineWorker';
|
|
21
|
-
export type { DefineWorkerConfig, WorkerDefinition, WorkerMethod, WorkerMethodMap, WorkerServiceMap, } from './worker/defineWorker';
|
|
22
|
-
export { reactive, shallowEqual, watch } from './reactive';
|
|
23
|
-
export type { EqualityFn, ReactiveConnector, SliceOptions } from './reactive';
|
|
24
|
-
export { observe } from './observable';
|
|
25
|
-
export type { ObservableValue } from './observable';
|
|
26
|
-
export { defineTask, isAsyncTask, toTask } from './task';
|
|
27
|
-
export type { AsyncTask, TaskSnapshot } from './task';
|
|
28
|
-
export { getLogLevel, log, scoped, setLogLevel, setLogSink } from './log';
|
|
29
|
-
export type { LogEntry, LogLevel, LogSink } from './log';
|
|
1
|
+
export { bindSharedMemories, defineSharedMemory, field, getDefinedSharedMemoryCount, jsonCodec, registerConnectorFactory } from './contract/sharedMemory.js';
|
|
2
|
+
export { reef } from './contract/reef.js';
|
|
3
|
+
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
|
+
export { msgpackrCodec } from './contract/msgpackrCodec.js';
|
|
5
|
+
export { listSchema } from './contract/listSchema.js';
|
|
6
|
+
export type { ListZodShape } from './contract/listSchema.js';
|
|
7
|
+
export type { MemoryConfig, PoolTasks, Prettify, Schema, Logger, TaskContract, TaskMap, TaskMessage, TaskResult, MemoryPersistence, SharedWorkerConfig, ViewType, WorkerPoolConfig, } from './contract/types.js';
|
|
8
|
+
export { MemoryManager } from './pool/memory.js';
|
|
9
|
+
export { WorkerPool } from './pool/workerPool.js';
|
|
10
|
+
export type { PoolStats, RunOptions } from './pool/workerPool.js';
|
|
11
|
+
export { PoolQueueFullError, TaskAbortedError, TaskTimeoutError, WorkerCrashedError, } from './pool/errors.js';
|
|
12
|
+
export { connectWorker, workerClient } from './pool/workerClient.js';
|
|
13
|
+
export type { ClientMethods, ConnectWorkerConfig, WorkerClient, WorkerMethods, } from './pool/workerClient.js';
|
|
14
|
+
export { connectSharedWorker } from './shared/sharedWorkerClient.js';
|
|
15
|
+
export type { SharedWorkerClient } from './shared/sharedWorkerClient.js';
|
|
16
|
+
export { sharedWorkerHost } from './shared/sharedWorkerHost.js';
|
|
17
|
+
export { createClient, defineService, implementService, rpc, serviceMethod } from './service.js';
|
|
18
|
+
export type { RpcMethodDef, RpcMethodInput, RpcMethodInputMap, RpcMethodMap, ServiceClient, ServiceContract, ServiceHandlers, ServiceImpl, ServiceMethod, TaskRunner, } from './service.js';
|
|
19
|
+
export { TaskRegistry } from './worker/registry.js';
|
|
20
|
+
export { defineWorker, RESERVED_CLIENT_KEYS } from './worker/defineWorker.js';
|
|
21
|
+
export type { DefineWorkerConfig, WorkerDefinition, WorkerMethod, WorkerMethodMap, WorkerServiceMap, } from './worker/defineWorker.js';
|
|
22
|
+
export { reactive, shallowEqual, watch } from './reactive.js';
|
|
23
|
+
export type { EqualityFn, ReactiveConnector, SliceOptions } from './reactive.js';
|
|
24
|
+
export { observe } from './observable.js';
|
|
25
|
+
export type { ObservableValue } from './observable.js';
|
|
26
|
+
export { defineTask, isAsyncTask, toTask } from './task.js';
|
|
27
|
+
export type { AsyncTask, TaskSnapshot } from './task.js';
|
|
28
|
+
export { getLogLevel, log, scoped, setLogLevel, setLogSink } from './log.js';
|
|
29
|
+
export type { LogEntry, LogLevel, LogSink } from './log.js';
|
package/dist/index10.js
CHANGED
package/dist/index11.js
CHANGED
package/dist/index12.js
CHANGED
package/dist/index13.js
CHANGED
package/dist/index14.js
CHANGED
package/dist/index15.js
CHANGED
package/dist/index16.js
CHANGED
|
@@ -2,45 +2,53 @@ import { fmtBytes as e, scoped as t } from "./index5.js";
|
|
|
2
2
|
import { bindSharedMemories as n, getDefinedSharedMemoryCount as r } from "./index6.js";
|
|
3
3
|
import { TaskRegistry as i } from "./index13.js";
|
|
4
4
|
//#region src/worker/workerBootstrap.ts
|
|
5
|
-
var a = t("worker"), o = !1;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
return;
|
|
11
|
-
}
|
|
12
|
-
if (s.type === "INIT_MEMORY") {
|
|
13
|
-
let t = s.memory;
|
|
14
|
-
n(t.buffer), o = !0, a.info(`shared memory initialized (${e(t.buffer.byteLength)})`);
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
if (s.type === "EXECUTE_TASK") {
|
|
18
|
-
let { messageId: e, taskId: t, args: n } = s;
|
|
19
|
-
if (!o) {
|
|
20
|
-
a.warn(`rejected ${t} — shared memory not initialized`), self.postMessage({
|
|
21
|
-
messageId: e,
|
|
22
|
-
success: !1,
|
|
23
|
-
error: "Shared memory not initialized in worker."
|
|
24
|
-
});
|
|
5
|
+
var a = t("worker"), o = !1, s = !1;
|
|
6
|
+
function c() {
|
|
7
|
+
if (!s) {
|
|
8
|
+
if (typeof self > "u") {
|
|
9
|
+
a.warn("workerBootstrap: no worker global found — skipping message wiring");
|
|
25
10
|
return;
|
|
26
11
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
12
|
+
s = !0, self.onmessage = async (t) => {
|
|
13
|
+
let s = t.data;
|
|
14
|
+
if (s.type === "INIT") {
|
|
15
|
+
o = !0, r() > 0 && a.warn("pool sent INIT without memory, but shared-memory contracts are defined — field access will throw until bound"), a.info("initialized (message-only pool — no shared memory)");
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (s.type === "INIT_MEMORY") {
|
|
19
|
+
let t = s.memory;
|
|
20
|
+
n(t.buffer), o = !0, a.info(`shared memory initialized (${e(t.buffer.byteLength)})`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (s.type === "EXECUTE_TASK") {
|
|
24
|
+
let { messageId: e, taskId: t, args: n } = s;
|
|
25
|
+
if (!o) {
|
|
26
|
+
a.warn(`rejected ${t} — shared memory not initialized`), self.postMessage({
|
|
27
|
+
messageId: e,
|
|
28
|
+
success: !1,
|
|
29
|
+
error: "Shared memory not initialized in worker."
|
|
30
|
+
});
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
let r = performance.now();
|
|
34
|
+
try {
|
|
35
|
+
let o = await i.execute(t, ...n || []);
|
|
36
|
+
a.debug(`task ${t} → ${(performance.now() - r).toFixed(1)}ms`), self.postMessage({
|
|
37
|
+
messageId: e,
|
|
38
|
+
success: !0,
|
|
39
|
+
result: o
|
|
40
|
+
});
|
|
41
|
+
} catch (n) {
|
|
42
|
+
a.warn(`task ${t} failed: ${n.message || String(n)}`), self.postMessage({
|
|
43
|
+
messageId: e,
|
|
44
|
+
success: !1,
|
|
45
|
+
error: n.message || String(n)
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
};
|
|
42
50
|
}
|
|
43
|
-
}
|
|
51
|
+
}
|
|
52
|
+
c();
|
|
44
53
|
//#endregion
|
|
45
|
-
|
|
46
|
-
//# sourceMappingURL=index16.js.map
|
|
54
|
+
export { c as installWorkerListener };
|
package/dist/index17.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { scoped as e } from "./index5.js";
|
|
2
2
|
import { TaskRegistry as t } from "./index13.js";
|
|
3
|
-
import "./index16.js";
|
|
3
|
+
import { installWorkerListener as n } from "./index16.js";
|
|
4
4
|
//#region src/worker/defineWorker.ts
|
|
5
|
-
var
|
|
5
|
+
var r = e("worker"), i = [
|
|
6
6
|
"start",
|
|
7
7
|
"terminate",
|
|
8
8
|
"pool",
|
|
9
9
|
"sharedMemory",
|
|
10
10
|
"then",
|
|
11
11
|
"with"
|
|
12
|
-
],
|
|
13
|
-
function
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
if (
|
|
12
|
+
], a = (e) => typeof e == "object" && !!e && "run" in e, o = new Set(i);
|
|
13
|
+
function s(e) {
|
|
14
|
+
n();
|
|
15
|
+
let i = e.methods ?? {}, s = e.services ?? {}, c = 0, l = (e, n, r, i) => {
|
|
16
|
+
if (o.has(n)) throw Error(`defineWorker: "${n}" is reserved for the client API — rename the method`);
|
|
17
|
+
if (a(r)) {
|
|
17
18
|
let { def: n } = r;
|
|
18
19
|
t.register({
|
|
19
20
|
taskId: n.taskId ?? e,
|
|
@@ -21,22 +22,20 @@ function o(e) {
|
|
|
21
22
|
...n.argsSchema ? { argsSchema: n.argsSchema } : {},
|
|
22
23
|
...n.resultSchema ? { resultSchema: n.resultSchema } : {}
|
|
23
24
|
}, r.run.bind(r));
|
|
24
|
-
} else t.register({ taskId: e }, r.bind(
|
|
25
|
-
|
|
25
|
+
} else t.register({ taskId: e }, r.bind(i));
|
|
26
|
+
c++;
|
|
26
27
|
};
|
|
27
|
-
for (let [e, t] of Object.entries(
|
|
28
|
-
for (let [e, t] of Object.entries(
|
|
29
|
-
if (
|
|
30
|
-
for (let [n, r] of Object.entries(t))
|
|
28
|
+
for (let [e, t] of Object.entries(i)) l(e, e, t, i);
|
|
29
|
+
for (let [e, t] of Object.entries(s)) {
|
|
30
|
+
if (o.has(e)) throw Error(`defineWorker: service name "${e}" is reserved for the client API — rename it`);
|
|
31
|
+
for (let [n, r] of Object.entries(t)) l(`${e}.${n}`, n, r, t);
|
|
31
32
|
}
|
|
32
|
-
|
|
33
|
-
let
|
|
34
|
-
methods:
|
|
35
|
-
services:
|
|
33
|
+
r.info(`worker defined — ${c} method(s)`);
|
|
34
|
+
let u = {
|
|
35
|
+
methods: i,
|
|
36
|
+
services: s
|
|
36
37
|
};
|
|
37
|
-
return e.sharedMemory && (
|
|
38
|
+
return e.sharedMemory && (u.sharedMemory = e.sharedMemory), u;
|
|
38
39
|
}
|
|
39
40
|
//#endregion
|
|
40
|
-
export {
|
|
41
|
-
|
|
42
|
-
//# sourceMappingURL=index17.js.map
|
|
41
|
+
export { i as RESERVED_CLIENT_KEYS, s as defineWorker };
|
package/dist/index18.js
CHANGED
package/dist/index19.js
CHANGED
package/dist/index2.js
CHANGED
package/dist/index20.js
CHANGED
package/dist/index3.js
CHANGED
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.5",
|
|
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",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import './workerBootstrap';
|
|
1
|
+
import { installWorkerListener } from './workerBootstrap';
|
|
2
2
|
import { TaskRegistry } from './registry';
|
|
3
3
|
import { scoped } from '../log';
|
|
4
4
|
import type { ServiceMethod } from '../service';
|
|
@@ -62,7 +62,7 @@ const RESERVED = new Set<string>(RESERVED_CLIENT_KEYS);
|
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
64
|
* The worker-side half of the tRPC-style pair: the worker script owns the
|
|
65
|
-
* runtime (
|
|
65
|
+
* runtime (calling this wires `self.onmessage` via workerBootstrap)
|
|
66
66
|
* and the method list — the main thread imports only `typeof` the returned
|
|
67
67
|
* definition and drives it through a {@link connectWorker} Proxy client.
|
|
68
68
|
*
|
|
@@ -88,6 +88,10 @@ export function defineWorker<
|
|
|
88
88
|
M extends WorkerMethodMap = {},
|
|
89
89
|
Svc extends WorkerServiceMap = {},
|
|
90
90
|
>(config: DefineWorkerConfig<S, M, Svc>): WorkerDefinition<S, M, Svc> {
|
|
91
|
+
// Called (not a bare import) so the wiring survives bundler tree-shaking —
|
|
92
|
+
// a `sideEffects` glob can't match renamed dist chunks (index16.js), which
|
|
93
|
+
// is how vite's dep-optimizer used to drop the entire message pump.
|
|
94
|
+
installWorkerListener();
|
|
91
95
|
const methods = (config.methods ?? {}) as M;
|
|
92
96
|
const services = (config.services ?? {}) as Svc;
|
|
93
97
|
|
|
@@ -5,52 +5,68 @@ import { fmtBytes, scoped } from '../log';
|
|
|
5
5
|
const workerLog = scoped('worker');
|
|
6
6
|
|
|
7
7
|
let memoryInitialized = false;
|
|
8
|
+
let wired = false;
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
workerLog.info('initialized (message-only pool — no shared memory)');
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (data.type === 'INIT_MEMORY') {
|
|
29
|
-
const memory = data.memory as WebAssembly.Memory;
|
|
30
|
-
bindSharedMemories(memory.buffer as unknown as SharedArrayBuffer);
|
|
31
|
-
memoryInitialized = true;
|
|
32
|
-
workerLog.info(`shared memory initialized (${fmtBytes(memory.buffer.byteLength)})`);
|
|
10
|
+
/**
|
|
11
|
+
* Wire `self.onmessage` to the pool protocol (INIT / INIT_MEMORY /
|
|
12
|
+
* EXECUTE_TASK). Runs automatically on import for the public
|
|
13
|
+
* `import '@atolljs/core/worker/workerBootstrap'` entry, and is also called
|
|
14
|
+
* from `defineWorker()` — an explicit call survives bundler tree-shaking,
|
|
15
|
+
* unlike a bare side-effect import whose `sideEffects` glob can miss
|
|
16
|
+
* renamed dist chunks. Idempotent: safe on repeated defineWorker() calls.
|
|
17
|
+
*/
|
|
18
|
+
export function installWorkerListener(): void {
|
|
19
|
+
if (wired) return;
|
|
20
|
+
if (typeof self === 'undefined') {
|
|
21
|
+
// Imported outside a worker context (e.g. a Nest entry that shares the
|
|
22
|
+
// atoll-nestjs barrel with the worker entry) — nothing to wire.
|
|
23
|
+
workerLog.warn('workerBootstrap: no worker global found — skipping message wiring');
|
|
33
24
|
return;
|
|
34
25
|
}
|
|
26
|
+
wired = true;
|
|
35
27
|
|
|
36
|
-
|
|
37
|
-
const
|
|
28
|
+
self.onmessage = async (event) => {
|
|
29
|
+
const data = event.data;
|
|
38
30
|
|
|
39
|
-
if (
|
|
40
|
-
|
|
41
|
-
|
|
31
|
+
if (data.type === 'INIT') {
|
|
32
|
+
memoryInitialized = true;
|
|
33
|
+
if (getDefinedSharedMemoryCount() > 0) {
|
|
34
|
+
workerLog.warn(
|
|
35
|
+
'pool sent INIT without memory, but shared-memory contracts are defined — field access will throw until bound',
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
workerLog.info('initialized (message-only pool — no shared memory)');
|
|
42
39
|
return;
|
|
43
40
|
}
|
|
44
41
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
workerLog.warn(`task ${taskId} failed: ${err.message || String(err)}`);
|
|
52
|
-
self.postMessage({ messageId, success: false, error: err.message || String(err) });
|
|
42
|
+
if (data.type === 'INIT_MEMORY') {
|
|
43
|
+
const memory = data.memory as WebAssembly.Memory;
|
|
44
|
+
bindSharedMemories(memory.buffer as unknown as SharedArrayBuffer);
|
|
45
|
+
memoryInitialized = true;
|
|
46
|
+
workerLog.info(`shared memory initialized (${fmtBytes(memory.buffer.byteLength)})`);
|
|
47
|
+
return;
|
|
53
48
|
}
|
|
49
|
+
|
|
50
|
+
if (data.type === 'EXECUTE_TASK') {
|
|
51
|
+
const { messageId, taskId, args } = data;
|
|
52
|
+
|
|
53
|
+
if (!memoryInitialized) {
|
|
54
|
+
workerLog.warn(`rejected ${taskId} — shared memory not initialized`);
|
|
55
|
+
self.postMessage({ messageId, success: false, error: 'Shared memory not initialized in worker.' });
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const t0 = performance.now();
|
|
60
|
+
try {
|
|
61
|
+
const result = await TaskRegistry.execute(taskId, ...(args || []));
|
|
62
|
+
workerLog.debug(`task ${taskId} → ${(performance.now() - t0).toFixed(1)}ms`);
|
|
63
|
+
self.postMessage({ messageId, success: true, result });
|
|
64
|
+
} catch (err: any) {
|
|
65
|
+
workerLog.warn(`task ${taskId} failed: ${err.message || String(err)}`);
|
|
66
|
+
self.postMessage({ messageId, success: false, error: err.message || String(err) });
|
|
67
|
+
}
|
|
54
68
|
}
|
|
55
69
|
};
|
|
56
70
|
}
|
|
71
|
+
|
|
72
|
+
installWorkerListener();
|