@atolljs/core 0.1.6 → 0.1.8
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/README.md +1 -1
- package/dist/contract/memoryDevtools.d.ts +30 -0
- package/dist/contract/sharedMemory.d.ts +6 -2
- package/dist/contract/types.d.ts +13 -0
- package/dist/devtools.d.ts +346 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.js +19 -16
- package/dist/index10.js +28 -184
- package/dist/index11.js +18 -48
- package/dist/index12.js +29 -63
- package/dist/index13.js +49 -24
- package/dist/index14.js +57 -59
- package/dist/index15.js +335 -45
- package/dist/index16.js +242 -47
- package/dist/index17.js +57 -38
- package/dist/index18.js +9 -86
- package/dist/index19.js +58 -48
- package/dist/index20.js +24 -56
- package/dist/index21.js +61 -0
- package/dist/index22.js +48 -0
- package/dist/index23.js +68 -0
- package/dist/index24.js +41 -0
- package/dist/index25.js +46 -0
- package/dist/index26.js +113 -0
- package/dist/index27.js +60 -0
- package/dist/index28.js +57 -0
- package/dist/index5.js +227 -35
- package/dist/index6.js +143 -471
- package/dist/index7.js +51 -20
- package/dist/index8.js +507 -27
- package/dist/index9.js +19 -18
- package/dist/pool/dedicatedWorker.d.ts +63 -0
- package/dist/pool/devtoolsCommands.d.ts +54 -0
- package/dist/pool/subWorkerClient.d.ts +50 -0
- package/dist/pool/workerChannel.d.ts +44 -0
- package/dist/pool/workerClient.d.ts +38 -8
- package/dist/pool/workerPool.d.ts +13 -0
- package/dist/reactive.d.ts +15 -0
- package/dist/reactiveGraph.d.ts +9 -0
- package/dist/userTiming.d.ts +27 -0
- package/package.json +2 -1
- package/src/contract/memoryDevtools.ts +249 -0
- package/src/contract/sharedMemory.ts +39 -9
- package/src/contract/types.ts +13 -0
- package/src/devtools.ts +735 -0
- package/src/index.ts +27 -1
- package/src/log.ts +22 -0
- package/src/observable.ts +16 -3
- package/src/pool/dedicatedWorker.ts +332 -0
- package/src/pool/devtoolsCommands.ts +165 -0
- package/src/pool/subWorkerClient.ts +70 -0
- package/src/pool/workerChannel.ts +99 -0
- package/src/pool/workerClient.ts +64 -15
- package/src/pool/workerPool.ts +115 -36
- package/src/reactive.ts +87 -12
- package/src/reactiveGraph.ts +91 -0
- package/src/testing/inProcessWorker.ts +4 -3
- package/src/userTiming.ts +71 -0
- package/src/worker/workerBootstrap.ts +29 -3
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Prettify, Schema } from './types';
|
|
2
2
|
import { msgpackrCodec } from './msgpackrCodec';
|
|
3
3
|
import { memberToSpec, zodArrayInfo, zodObjectShape, zodStringBytes } from './listSchema';
|
|
4
|
+
import { devtoolsEnabled, emitDevtools } from '../devtools';
|
|
5
|
+
import { checkWatchOnWrite, ensureMemoryCommands, memoryWatches } from './memoryDevtools';
|
|
4
6
|
import { fmtBytes, scoped } from '../log';
|
|
5
7
|
import { z, fluent } from './zod';
|
|
6
8
|
|
|
@@ -101,6 +103,8 @@ export interface ConnectorContext {
|
|
|
101
103
|
codec: Codec;
|
|
102
104
|
/** Slot in the shared version counter — bump + notify on granular writes. */
|
|
103
105
|
version?: { view: Int32Array; index: number };
|
|
106
|
+
/** The field's contract path — for devtools write events on granular commits. */
|
|
107
|
+
path?: string;
|
|
104
108
|
}
|
|
105
109
|
|
|
106
110
|
/**
|
|
@@ -141,6 +145,8 @@ export interface Connector<T> {
|
|
|
141
145
|
write(value: T): void;
|
|
142
146
|
/** Internal: slot in the shared version counter block, bumped on every write. */
|
|
143
147
|
readonly _version?: { view: Int32Array; index: number };
|
|
148
|
+
/** Internal: the field's contract path — devtools node labels. */
|
|
149
|
+
readonly _path?: string;
|
|
144
150
|
}
|
|
145
151
|
|
|
146
152
|
/* ------------------------------------------------------------------ */
|
|
@@ -670,10 +676,13 @@ function listFactory(d: FieldDescriptor, ctx: ConnectorContext, byteOffset: numb
|
|
|
670
676
|
writeAt: writeAt as ListConnector<any>['writeAt'],
|
|
671
677
|
commit: () => {
|
|
672
678
|
if (ctx.version) {
|
|
673
|
-
Atomics.add(ctx.version.view, ctx.version.index, 1);
|
|
679
|
+
const prev = Atomics.add(ctx.version.view, ctx.version.index, 1);
|
|
674
680
|
// Wake EVERY waitAsync observer — several watchers may share this
|
|
675
681
|
// field's counter; a bounded notify starves all but one.
|
|
676
682
|
Atomics.notify(ctx.version.view, ctx.version.index);
|
|
683
|
+
if (ctx.path && devtoolsEnabled()) {
|
|
684
|
+
emitDevtools({ type: 'memory:write', path: ctx.path, version: prev + 1 });
|
|
685
|
+
}
|
|
677
686
|
}
|
|
678
687
|
},
|
|
679
688
|
read: () => Array.from({ length: count }, (_, i) => readAt(i)),
|
|
@@ -803,8 +812,9 @@ export class SharedMemory<S extends SharedSpec = SharedSpec> {
|
|
|
803
812
|
throw new Error(`Unknown shared memory field kind: ${descriptor.kind}`);
|
|
804
813
|
}
|
|
805
814
|
memLog.debug(`bind "${path}" (${descriptor.kind}, ${fmtBytes(descriptor.byteLength)}) via ${this.plugins?.[descriptor.kind] ? 'plugin' : 'built-in'} factory`);
|
|
806
|
-
const ctx: ConnectorContext = { buffer, codec: this.codec, version: { view: versionView, index } };
|
|
815
|
+
const ctx: ConnectorContext = { buffer, codec: this.codec, version: { view: versionView, index }, path };
|
|
807
816
|
const raw = factory(descriptor, ctx, this.offsets.get(path)!);
|
|
817
|
+
const commit = (raw as Partial<ListConnector<unknown>>).commit;
|
|
808
818
|
this.connectors.set(path, {
|
|
809
819
|
...raw,
|
|
810
820
|
write: (v) => {
|
|
@@ -812,12 +822,35 @@ export class SharedMemory<S extends SharedSpec = SharedSpec> {
|
|
|
812
822
|
// Bump the version counter and explicitly wake waitAsync observers —
|
|
813
823
|
// V8 only resolves waitAsync waiters on notify, not on value changes.
|
|
814
824
|
// No count bound: every watcher on this field must wake.
|
|
815
|
-
Atomics.add(versionView, index, 1);
|
|
825
|
+
const prev = Atomics.add(versionView, index, 1);
|
|
816
826
|
Atomics.notify(versionView, index);
|
|
827
|
+
if (devtoolsEnabled()) {
|
|
828
|
+
emitDevtools({ type: 'memory:write', path, version: prev + 1 });
|
|
829
|
+
if (memoryWatches.size) checkWatchOnWrite(this, path, prev + 1);
|
|
830
|
+
}
|
|
817
831
|
},
|
|
832
|
+
// List commits bump inside the factory — wrapped for watchpoints only
|
|
833
|
+
// when devtools is on at bind time, so the plain path stays direct.
|
|
834
|
+
...(commit && devtoolsEnabled()
|
|
835
|
+
? {
|
|
836
|
+
commit: () => {
|
|
837
|
+
commit();
|
|
838
|
+
if (memoryWatches.size) checkWatchOnWrite(this, path, Atomics.load(versionView, index));
|
|
839
|
+
},
|
|
840
|
+
}
|
|
841
|
+
: {}),
|
|
818
842
|
_version: { view: versionView, index },
|
|
843
|
+
_path: path,
|
|
819
844
|
});
|
|
820
845
|
});
|
|
846
|
+
if (devtoolsEnabled()) {
|
|
847
|
+
ensureMemoryCommands(() => definedSharedMemories);
|
|
848
|
+
emitDevtools({
|
|
849
|
+
type: 'memory:bind',
|
|
850
|
+
fields: this.entries.map((e, i) => [i, e.path]),
|
|
851
|
+
totalBytes: this.totalBytes,
|
|
852
|
+
});
|
|
853
|
+
}
|
|
821
854
|
this.isBound = true;
|
|
822
855
|
this.boundBuffer = buffer;
|
|
823
856
|
for (const cb of [...this.boundListeners]) cb();
|
|
@@ -854,15 +887,12 @@ export class SharedMemory<S extends SharedSpec = SharedSpec> {
|
|
|
854
887
|
}
|
|
855
888
|
|
|
856
889
|
/**
|
|
857
|
-
* Fires when the contract is bound on this thread —
|
|
858
|
-
* bound. Returns an unsubscribe function.
|
|
890
|
+
* Fires when the contract is bound on this thread — on every bind, and
|
|
891
|
+
* immediately if already bound. Returns an unsubscribe function.
|
|
859
892
|
*/
|
|
860
893
|
public onBound(cb: () => void): () => void {
|
|
861
|
-
if (this.isBound) {
|
|
862
|
-
cb();
|
|
863
|
-
return () => {};
|
|
864
|
-
}
|
|
865
894
|
this.boundListeners.add(cb);
|
|
895
|
+
if (this.isBound) cb();
|
|
866
896
|
return () => this.boundListeners.delete(cb);
|
|
867
897
|
}
|
|
868
898
|
|
package/src/contract/types.ts
CHANGED
|
@@ -57,6 +57,17 @@ export interface WorkerPoolConfig<S extends SharedSpec = SharedSpec, T extends T
|
|
|
57
57
|
* skipped and workers receive a plain `{ type: 'INIT' }` handshake.
|
|
58
58
|
*/
|
|
59
59
|
sharedMemory?: SharedMemory<S> & Prettify<SharedAccess<S>>;
|
|
60
|
+
/**
|
|
61
|
+
* Hand an existing SharedArrayBuffer to every spawned worker instead of
|
|
62
|
+
* allocating a fresh `WebAssembly.Memory` — the worker-shell case: a worker
|
|
63
|
+
* already bound to a contract spawns sub-workers on the SAME buffer
|
|
64
|
+
* (`sharedBuffer: contract.buffer`), or a second pool shares the first
|
|
65
|
+
* pool's `pool.sharedBuffer`. A thunk is resolved once, when the pool
|
|
66
|
+
* constructs. With `sharedMemory` the contract binds locally to this
|
|
67
|
+
* buffer; without it the buffer still ships via INIT_MEMORY and the
|
|
68
|
+
* workers bind their own defined contracts.
|
|
69
|
+
*/
|
|
70
|
+
sharedBuffer?: SharedArrayBuffer | (() => SharedArrayBuffer | undefined);
|
|
60
71
|
/**
|
|
61
72
|
* Persistence adapter for `sharedMemory` — invoked with the contract right
|
|
62
73
|
* after the pool binds it, and its `stop()` runs on `terminate()`.
|
|
@@ -65,6 +76,8 @@ export interface WorkerPoolConfig<S extends SharedSpec = SharedSpec, T extends T
|
|
|
65
76
|
persistence?: (memory: SharedMemory<S>) => MemoryPersistence | undefined;
|
|
66
77
|
/** Worker count — a number, or 'auto' (the default) for navigator.hardwareConcurrency ?? 4. */
|
|
67
78
|
poolSize?: number | 'auto';
|
|
79
|
+
/** Display label for devtools/dashboards — falls back to a generated id. */
|
|
80
|
+
name?: string;
|
|
68
81
|
memory?: MemoryConfig;
|
|
69
82
|
/** Max in-flight tasks per worker (default 1); excess tasks queue FIFO. */
|
|
70
83
|
concurrency?: number;
|