remote-state-sync 1.0.1 → 1.0.2
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/index.d.ts +4 -2
- package/dist/index.js +35 -26
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { Ref, ShallowRef } from '@vue/reactivity';
|
|
|
4
4
|
type PatchOperation = 'set' | 'delete' | 'clear' | 'add';
|
|
5
5
|
interface Patch {
|
|
6
6
|
op: PatchOperation;
|
|
7
|
+
key: string;
|
|
7
8
|
path: (string | number)[];
|
|
8
9
|
value?: unknown;
|
|
9
10
|
}
|
|
@@ -13,6 +14,7 @@ interface SyncOptions {
|
|
|
13
14
|
type SyncUpdater<T> = (state: T) => T | void;
|
|
14
15
|
type SyncBusDefinition = {
|
|
15
16
|
update: (namespace: string, patches: Patch[]) => void;
|
|
17
|
+
register: (namespace: string) => void;
|
|
16
18
|
};
|
|
17
19
|
type ReceiverItemBusDefinition<T> = {
|
|
18
20
|
update: (newValue: T, oldValue: T, patches: Patch[]) => void;
|
|
@@ -20,7 +22,7 @@ type ReceiverItemBusDefinition<T> = {
|
|
|
20
22
|
|
|
21
23
|
declare class SyncProvider {
|
|
22
24
|
private namespaces;
|
|
23
|
-
bus: Nanobus<SyncBusDefinition>;
|
|
25
|
+
readonly bus: Nanobus<SyncBusDefinition>;
|
|
24
26
|
constructor();
|
|
25
27
|
register(namespace: string): SyncNamespaceProvider;
|
|
26
28
|
getStateSnapshot(namespace: string): Promise<Record<string, unknown>>;
|
|
@@ -68,7 +70,7 @@ declare class SyncItemReceiver<T> {
|
|
|
68
70
|
private value;
|
|
69
71
|
private _ref;
|
|
70
72
|
private _shallowRef;
|
|
71
|
-
bus: Nanobus<ReceiverItemBusDefinition<T>>;
|
|
73
|
+
readonly bus: Nanobus<ReceiverItemBusDefinition<T>>;
|
|
72
74
|
constructor(key: string, initialValue: T);
|
|
73
75
|
on(event: 'update', cb: (newValue: T, oldValue: T, patches: Patch[]) => void): void;
|
|
74
76
|
toValue(): T;
|
package/dist/index.js
CHANGED
|
@@ -53,19 +53,19 @@ function clearValue(current) {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
// src/proxy.ts
|
|
56
|
-
function createDeepProxy(target, path, onPatch) {
|
|
56
|
+
function createDeepProxy(target, rootKey, path, onPatch) {
|
|
57
57
|
if (!shouldProxy(target)) {
|
|
58
58
|
return target;
|
|
59
59
|
}
|
|
60
60
|
if (target instanceof Map) {
|
|
61
|
-
return createMapProxy(target, path, onPatch);
|
|
61
|
+
return createMapProxy(target, rootKey, path, onPatch);
|
|
62
62
|
}
|
|
63
63
|
if (target instanceof Set) {
|
|
64
|
-
return createSetProxy(target, path, onPatch);
|
|
64
|
+
return createSetProxy(target, rootKey, path, onPatch);
|
|
65
65
|
}
|
|
66
|
-
return createObjectProxy(target, path, onPatch);
|
|
66
|
+
return createObjectProxy(target, rootKey, path, onPatch);
|
|
67
67
|
}
|
|
68
|
-
function createObjectProxy(target, path, onPatch) {
|
|
68
|
+
function createObjectProxy(target, rootKey, path, onPatch) {
|
|
69
69
|
const handler = {
|
|
70
70
|
get(obj, prop, receiver) {
|
|
71
71
|
const value = Reflect.get(obj, prop, receiver);
|
|
@@ -73,7 +73,7 @@ function createObjectProxy(target, path, onPatch) {
|
|
|
73
73
|
return value;
|
|
74
74
|
}
|
|
75
75
|
if (shouldProxy(value)) {
|
|
76
|
-
return createDeepProxy(value, [...path, prop], onPatch);
|
|
76
|
+
return createDeepProxy(value, rootKey, [...path, prop], onPatch);
|
|
77
77
|
}
|
|
78
78
|
return value;
|
|
79
79
|
},
|
|
@@ -85,6 +85,7 @@ function createObjectProxy(target, path, onPatch) {
|
|
|
85
85
|
if (success) {
|
|
86
86
|
onPatch({
|
|
87
87
|
op: "set",
|
|
88
|
+
key: rootKey,
|
|
88
89
|
path: [...path, prop],
|
|
89
90
|
value
|
|
90
91
|
});
|
|
@@ -99,6 +100,7 @@ function createObjectProxy(target, path, onPatch) {
|
|
|
99
100
|
if (success) {
|
|
100
101
|
onPatch({
|
|
101
102
|
op: "delete",
|
|
103
|
+
key: rootKey,
|
|
102
104
|
path: [...path, prop]
|
|
103
105
|
});
|
|
104
106
|
}
|
|
@@ -107,7 +109,7 @@ function createObjectProxy(target, path, onPatch) {
|
|
|
107
109
|
};
|
|
108
110
|
return new Proxy(target, handler);
|
|
109
111
|
}
|
|
110
|
-
function createMapProxy(target, path, onPatch) {
|
|
112
|
+
function createMapProxy(target, rootKey, path, onPatch) {
|
|
111
113
|
const handler = {
|
|
112
114
|
get(obj, prop) {
|
|
113
115
|
const value = Reflect.get(obj, prop);
|
|
@@ -120,6 +122,7 @@ function createMapProxy(target, path, onPatch) {
|
|
|
120
122
|
const result = obj.set(key, val);
|
|
121
123
|
onPatch({
|
|
122
124
|
op: "set",
|
|
125
|
+
key: rootKey,
|
|
123
126
|
path: [...path, key],
|
|
124
127
|
value: val
|
|
125
128
|
});
|
|
@@ -133,6 +136,7 @@ function createMapProxy(target, path, onPatch) {
|
|
|
133
136
|
if (hasKey) {
|
|
134
137
|
onPatch({
|
|
135
138
|
op: "delete",
|
|
139
|
+
key: rootKey,
|
|
136
140
|
path: [...path, key]
|
|
137
141
|
});
|
|
138
142
|
}
|
|
@@ -145,6 +149,7 @@ function createMapProxy(target, path, onPatch) {
|
|
|
145
149
|
const result = obj.clear();
|
|
146
150
|
onPatch({
|
|
147
151
|
op: "clear",
|
|
152
|
+
key: rootKey,
|
|
148
153
|
path
|
|
149
154
|
});
|
|
150
155
|
return result;
|
|
@@ -155,7 +160,7 @@ function createMapProxy(target, path, onPatch) {
|
|
|
155
160
|
return function(key) {
|
|
156
161
|
const getVal = obj.get(key);
|
|
157
162
|
if (shouldProxy(getVal)) {
|
|
158
|
-
return createDeepProxy(getVal, [...path, key], onPatch);
|
|
163
|
+
return createDeepProxy(getVal, rootKey, [...path, key], onPatch);
|
|
159
164
|
}
|
|
160
165
|
return getVal;
|
|
161
166
|
};
|
|
@@ -167,7 +172,7 @@ function createMapProxy(target, path, onPatch) {
|
|
|
167
172
|
};
|
|
168
173
|
return new Proxy(target, handler);
|
|
169
174
|
}
|
|
170
|
-
function createSetProxy(target, path, onPatch) {
|
|
175
|
+
function createSetProxy(target, rootKey, path, onPatch) {
|
|
171
176
|
const handler = {
|
|
172
177
|
get(obj, prop) {
|
|
173
178
|
const value = Reflect.get(obj, prop);
|
|
@@ -182,6 +187,7 @@ function createSetProxy(target, path, onPatch) {
|
|
|
182
187
|
if (!hasVal) {
|
|
183
188
|
onPatch({
|
|
184
189
|
op: "add",
|
|
190
|
+
key: rootKey,
|
|
185
191
|
// For set, we don't have a key to navigate, but we can pass the value
|
|
186
192
|
// In a true Sync scenario, Set diffing is tricky. Path is just the Set itself.
|
|
187
193
|
path,
|
|
@@ -198,6 +204,7 @@ function createSetProxy(target, path, onPatch) {
|
|
|
198
204
|
if (hasVal) {
|
|
199
205
|
onPatch({
|
|
200
206
|
op: "delete",
|
|
207
|
+
key: rootKey,
|
|
201
208
|
path,
|
|
202
209
|
// Similarly, deleting from set happens at Set boundary
|
|
203
210
|
value: val
|
|
@@ -213,6 +220,7 @@ function createSetProxy(target, path, onPatch) {
|
|
|
213
220
|
const result = obj.clear();
|
|
214
221
|
onPatch({
|
|
215
222
|
op: "clear",
|
|
223
|
+
key: rootKey,
|
|
216
224
|
path
|
|
217
225
|
});
|
|
218
226
|
return result;
|
|
@@ -239,6 +247,7 @@ var SyncProvider = class {
|
|
|
239
247
|
}
|
|
240
248
|
const ns = new SyncNamespaceProvider(namespace, this.bus);
|
|
241
249
|
this.namespaces.set(namespace, ns);
|
|
250
|
+
this.bus.emit("register", namespace);
|
|
242
251
|
return ns;
|
|
243
252
|
}
|
|
244
253
|
async getStateSnapshot(namespace) {
|
|
@@ -316,10 +325,11 @@ var SyncItemProvider = class {
|
|
|
316
325
|
setValue(newVal) {
|
|
317
326
|
this.onPatch({
|
|
318
327
|
op: "set",
|
|
319
|
-
|
|
328
|
+
key: this.key,
|
|
329
|
+
path: [],
|
|
320
330
|
value: newVal
|
|
321
331
|
});
|
|
322
|
-
this.value = createDeepProxy(newVal,
|
|
332
|
+
this.value = createDeepProxy(newVal, this.key, [], this.onPatch);
|
|
323
333
|
}
|
|
324
334
|
};
|
|
325
335
|
|
|
@@ -365,8 +375,7 @@ var SyncNamespaceReceiver = class {
|
|
|
365
375
|
applyPatches(patches) {
|
|
366
376
|
const affectedItems = /* @__PURE__ */ new Map();
|
|
367
377
|
for (const patch of patches) {
|
|
368
|
-
|
|
369
|
-
const key = patch.path[0];
|
|
378
|
+
const key = patch.key;
|
|
370
379
|
const item = this.items.get(key);
|
|
371
380
|
if (item) {
|
|
372
381
|
if (!affectedItems.has(item)) {
|
|
@@ -384,9 +393,9 @@ var SyncNamespaceReceiver = class {
|
|
|
384
393
|
}
|
|
385
394
|
}
|
|
386
395
|
applyPatchToObject(obj, patch) {
|
|
387
|
-
|
|
396
|
+
const fullPath = [patch.key, ...patch.path];
|
|
388
397
|
if (patch.op === "clear" || patch.op === "add") {
|
|
389
|
-
const target = navigatePath(obj,
|
|
398
|
+
const target = navigatePath(obj, fullPath, 0, fullPath.length);
|
|
390
399
|
if (patch.op === "clear") {
|
|
391
400
|
clearValue(target);
|
|
392
401
|
} else {
|
|
@@ -394,8 +403,8 @@ var SyncNamespaceReceiver = class {
|
|
|
394
403
|
}
|
|
395
404
|
return;
|
|
396
405
|
}
|
|
397
|
-
const current = navigatePath(obj,
|
|
398
|
-
const lastKey =
|
|
406
|
+
const current = navigatePath(obj, fullPath, 0, fullPath.length - 1);
|
|
407
|
+
const lastKey = fullPath[fullPath.length - 1];
|
|
399
408
|
if (patch.op === "set") {
|
|
400
409
|
setValueAtPath(current, lastKey, patch.value);
|
|
401
410
|
} else if (patch.op === "delete") {
|
|
@@ -431,7 +440,7 @@ var SyncItemReceiver = class {
|
|
|
431
440
|
return this._shallowRef;
|
|
432
441
|
}
|
|
433
442
|
applyPatch(patch) {
|
|
434
|
-
if (patch.path.length ===
|
|
443
|
+
if (patch.path.length === 0) {
|
|
435
444
|
if (patch.op === "set") {
|
|
436
445
|
this.value = patch.value;
|
|
437
446
|
if (this._ref) this._ref.value = patch.value;
|
|
@@ -441,41 +450,41 @@ var SyncItemReceiver = class {
|
|
|
441
450
|
}
|
|
442
451
|
const lastKey = patch.path[patch.path.length - 1];
|
|
443
452
|
if (patch.op === "set") {
|
|
444
|
-
const current = navigatePath(this.value, patch.path,
|
|
453
|
+
const current = navigatePath(this.value, patch.path, 0, patch.path.length - 1);
|
|
445
454
|
const refCurrent = navigatePath(
|
|
446
455
|
this._ref ? this._ref.value : null,
|
|
447
456
|
patch.path,
|
|
448
|
-
|
|
457
|
+
0,
|
|
449
458
|
patch.path.length - 1
|
|
450
459
|
);
|
|
451
460
|
setValueAtPath(current, lastKey, patch.value);
|
|
452
461
|
setValueAtPath(refCurrent, lastKey, patch.value);
|
|
453
462
|
} else if (patch.op === "delete") {
|
|
454
|
-
const current = navigatePath(this.value, patch.path,
|
|
463
|
+
const current = navigatePath(this.value, patch.path, 0, patch.path.length - 1);
|
|
455
464
|
const refCurrent = navigatePath(
|
|
456
465
|
this._ref ? this._ref.value : null,
|
|
457
466
|
patch.path,
|
|
458
|
-
|
|
467
|
+
0,
|
|
459
468
|
patch.path.length - 1
|
|
460
469
|
);
|
|
461
470
|
deleteValueAtPath(current, lastKey);
|
|
462
471
|
deleteValueAtPath(refCurrent, lastKey);
|
|
463
472
|
} else if (patch.op === "add") {
|
|
464
|
-
const target = navigatePath(this.value, patch.path,
|
|
473
|
+
const target = navigatePath(this.value, patch.path, 0, patch.path.length);
|
|
465
474
|
const refTarget = navigatePath(
|
|
466
475
|
this._ref ? this._ref.value : null,
|
|
467
476
|
patch.path,
|
|
468
|
-
|
|
477
|
+
0,
|
|
469
478
|
patch.path.length
|
|
470
479
|
);
|
|
471
480
|
addValueToSet(target, patch.value);
|
|
472
481
|
addValueToSet(refTarget, patch.value);
|
|
473
482
|
} else if (patch.op === "clear") {
|
|
474
|
-
const target = navigatePath(this.value, patch.path,
|
|
483
|
+
const target = navigatePath(this.value, patch.path, 0, patch.path.length);
|
|
475
484
|
const refTarget = navigatePath(
|
|
476
485
|
this._ref ? this._ref.value : null,
|
|
477
486
|
patch.path,
|
|
478
|
-
|
|
487
|
+
0,
|
|
479
488
|
patch.path.length
|
|
480
489
|
);
|
|
481
490
|
clearValue(target);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "remote-state-sync",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "A lightweight, fully type-safe unidirectional remote state synchronization library.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -68,4 +68,4 @@
|
|
|
68
68
|
"@vue/reactivity": "^3.5.28",
|
|
69
69
|
"nanobus": "^4.5.0"
|
|
70
70
|
}
|
|
71
|
-
}
|
|
71
|
+
}
|