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 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
- path: [this.key],
328
+ key: this.key,
329
+ path: [],
320
330
  value: newVal
321
331
  });
322
- this.value = createDeepProxy(newVal, [this.key], this.onPatch);
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
- if (patch.path.length === 0) continue;
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
- if (patch.path.length === 0) return;
396
+ const fullPath = [patch.key, ...patch.path];
388
397
  if (patch.op === "clear" || patch.op === "add") {
389
- const target = navigatePath(obj, patch.path, 0, patch.path.length);
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, patch.path, 0, patch.path.length - 1);
398
- const lastKey = patch.path[patch.path.length - 1];
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 === 1) {
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, 1, patch.path.length - 1);
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
- 1,
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, 1, patch.path.length - 1);
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
- 1,
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, 1, patch.path.length);
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
- 1,
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, 1, patch.path.length);
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
- 1,
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.1",
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
+ }