@mmstack/worker 22.0.0 → 22.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -20
- package/fesm2022/mmstack-worker-host.mjs +43 -87
- package/fesm2022/mmstack-worker-host.mjs.map +1 -1
- package/fesm2022/mmstack-worker-protocol.mjs +0 -1
- package/fesm2022/mmstack-worker-protocol.mjs.map +1 -1
- package/fesm2022/mmstack-worker.mjs +118 -110
- package/fesm2022/mmstack-worker.mjs.map +1 -1
- package/package.json +2 -2
- package/types/mmstack-worker-host.d.ts +7 -0
- package/types/mmstack-worker-protocol.d.ts +6 -23
- package/types/mmstack-worker.d.ts +19 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mmstack/worker",
|
|
3
|
-
"version": "22.
|
|
3
|
+
"version": "22.2.0",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"angular",
|
|
6
6
|
"signals",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"peerDependencies": {
|
|
20
20
|
"@angular/core": ">=22 <23",
|
|
21
21
|
"@angular/common": ">=22 <23",
|
|
22
|
-
"@mmstack/primitives": ">=22.
|
|
22
|
+
"@mmstack/primitives": ">=22.8 <23"
|
|
23
23
|
},
|
|
24
24
|
"sideEffects": false,
|
|
25
25
|
"module": "fesm2022/mmstack-worker.mjs",
|
|
@@ -41,6 +41,13 @@ type WorkerHost<M extends WorkerSchema = WorkerSchema> = HasSchema<M> & {
|
|
|
41
41
|
readonly hostId: string;
|
|
42
42
|
/** Serve an additional transport (multi-client / tests). Returns a disconnect handle. */
|
|
43
43
|
connect(port: WorkerPortLike): () => void;
|
|
44
|
+
/**
|
|
45
|
+
* Apply an AUTHORITATIVE owner correction to an owned store: writes made inside `fn` are stamped
|
|
46
|
+
* at a bumped epoch, so they deterministically win the merge against any concurrent replica write
|
|
47
|
+
* (owner authority rides the epoch fold). Readers can gate effects on owner-settled values by the
|
|
48
|
+
* winning op's epoch. No-op for a read-only (published) or unknown store.
|
|
49
|
+
*/
|
|
50
|
+
override(store: string, fn: () => void): void;
|
|
44
51
|
/**
|
|
45
52
|
* Synchronously emit any pending owned-store changes to subscribers NOW, instead of waiting for
|
|
46
53
|
* the microtask driver. Makes the mirror deterministic (tests call it before asserting) and is
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { OpSyncCheckpoint, OpEnvelope } from '@mmstack/primitives';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* A structured-clone-safe rendering of an `Error` for cross-thread propagation. A worker throw
|
|
@@ -24,7 +24,7 @@ type RemoteStatus = 'idle' | 'loading' | 'reloading' | 'resolved' | 'error';
|
|
|
24
24
|
/**
|
|
25
25
|
* Every message exchanged over a {@link WorkerPortLike}. One discriminated union shared by the
|
|
26
26
|
* main-thread client and the worker host (and, later, `@mmstack/mesh`), so the two sides can never
|
|
27
|
-
* drift.
|
|
27
|
+
* drift.
|
|
28
28
|
*/
|
|
29
29
|
type WorkerEnvelope = {
|
|
30
30
|
type: 'hello';
|
|
@@ -64,30 +64,13 @@ type WorkerEnvelope = {
|
|
|
64
64
|
store: string;
|
|
65
65
|
clientId: string;
|
|
66
66
|
} | {
|
|
67
|
-
type: 'store:
|
|
67
|
+
type: 'store:checkpoint';
|
|
68
68
|
store: string;
|
|
69
|
-
|
|
70
|
-
value: unknown;
|
|
71
|
-
} | {
|
|
72
|
-
type: 'store:ops';
|
|
73
|
-
store: string;
|
|
74
|
-
batch: OpBatch;
|
|
69
|
+
checkpoint: OpSyncCheckpoint;
|
|
75
70
|
} | {
|
|
76
|
-
type: 'store:
|
|
71
|
+
type: 'store:sync';
|
|
77
72
|
store: string;
|
|
78
|
-
|
|
79
|
-
clientId: string;
|
|
80
|
-
ops: readonly StoreOp[];
|
|
81
|
-
} | {
|
|
82
|
-
type: 'store:write:ack';
|
|
83
|
-
store: string;
|
|
84
|
-
writeId: number;
|
|
85
|
-
version: number;
|
|
86
|
-
} | {
|
|
87
|
-
type: 'store:write:error';
|
|
88
|
-
store: string;
|
|
89
|
-
writeId: number;
|
|
90
|
-
error: SerializedError;
|
|
73
|
+
env: OpEnvelope;
|
|
91
74
|
} | {
|
|
92
75
|
type: 'store:unsubscribe';
|
|
93
76
|
store: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { WorkerSchema, HasSchema, TaskInput, TaskOutput, WorkerEnvelope, WorkerPortLike, SchemaOf, StoreKeys, StoreValueOf, IsWritableKey } from '@mmstack/worker/protocol';
|
|
2
2
|
export * from '@mmstack/worker/protocol';
|
|
3
3
|
import { Injector, Signal, ValueEqualityFn, ResourceStatus } from '@angular/core';
|
|
4
|
-
import {
|
|
4
|
+
import { WritableSignalStore, SignalStore } from '@mmstack/primitives';
|
|
5
5
|
|
|
6
6
|
/** What the worker advertised in its `ready` handshake. */
|
|
7
7
|
type WorkerManifest = {
|
|
@@ -117,16 +117,21 @@ type WorkerStoreOptions<T> = {
|
|
|
117
117
|
/** The write path — present only on OWNED (writable) subtrees; absent on published (read-only) ones. */
|
|
118
118
|
type WorkerStoreWrite<T> = {
|
|
119
119
|
/**
|
|
120
|
-
* Route a write to the OWNER:
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
120
|
+
* Route a write to the OWNER: `recipe` applies optimistically to the store, its diff ships as a
|
|
121
|
+
* stamped op envelope, and the owner folds it in and echoes it back. Resolves once the owner has
|
|
122
|
+
* acknowledged it (its echo reconciles this replica). The owner can override with a higher-epoch
|
|
123
|
+
* correction that wins the merge. To hide the value until the owner confirms it, fork the store
|
|
124
|
+
* and reveal on resolve. Rejects if the worker is disconnected or the store is read-only.
|
|
124
125
|
*/
|
|
125
126
|
write(recipe: (draft: WritableSignalStore<T>) => void): Promise<void>;
|
|
126
127
|
};
|
|
127
128
|
type WorkerStoreRef<T, W extends boolean = true> = {
|
|
128
|
-
/**
|
|
129
|
-
|
|
129
|
+
/**
|
|
130
|
+
* The live store. For an OWNED subtree it is a full {@link WritableSignalStore}: writes apply
|
|
131
|
+
* optimistically and route to the owner, and other op-log readers (`meshSync`, `persist`) can
|
|
132
|
+
* attach to it. For a PUBLISHED subtree it is a read-only {@link SignalStore} mirror.
|
|
133
|
+
*/
|
|
134
|
+
readonly store: W extends true ? WritableSignalStore<T> : SignalStore<T>;
|
|
130
135
|
/** The replica root value (undefined before hydration). */
|
|
131
136
|
readonly value: Signal<T | undefined>;
|
|
132
137
|
readonly status: Signal<ResourceStatus>;
|
|
@@ -138,11 +143,13 @@ type WorkerStoreRef<T, W extends boolean = true> = {
|
|
|
138
143
|
destroy(): void;
|
|
139
144
|
} & (W extends true ? WorkerStoreWrite<T> : object);
|
|
140
145
|
/**
|
|
141
|
-
* A live
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
+
* A live replica of a store subtree OWNED by the worker. It runs its own `opSync` over the worker
|
|
147
|
+
* transport: it hydrates from the owner's checkpoint, then folds each owner (or peer) envelope into
|
|
148
|
+
* a main-thread `store` convergently. For an owned subtree the store is WRITABLE: a write applies
|
|
149
|
+
* optimistically and its stamped envelope routes to the owner (which folds it and echoes it back),
|
|
150
|
+
* and any op-log reader — `meshSync`, `persist` — can attach to the same store, so a persisted,
|
|
151
|
+
* meshed, worker-owned graph is just extra readers. Satisfies `ResourceLike`/`UseSource`, so it
|
|
152
|
+
* participates in transition scopes and nests in `latest()`/`use()`.
|
|
146
153
|
*/
|
|
147
154
|
declare function workerStore<M extends WorkerSchema, K extends StoreKeys<M>>(worker: WorkerRef<M>, key: K, opt?: WorkerStoreOptions<StoreValueOf<M, K> & object>): WorkerStoreRef<StoreValueOf<M, K> & object, IsWritableKey<M, K>>;
|
|
148
155
|
declare function workerStore<T extends object>(worker: WorkerRef, key: string, opt?: WorkerStoreOptions<T>): WorkerStoreRef<T, true>;
|