@legendapp/state 3.0.0-alpha.21 → 3.0.0-alpha.23

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/index.d.mts CHANGED
@@ -17,14 +17,17 @@ interface ObservableObjectFunctions<T = Record<string, any>> extends ObservableP
17
17
  }
18
18
  type MapKey<T extends Map<any, any> | WeakMap<any, any>> = Parameters<T['has']>[0];
19
19
  type MapValue<T extends Map<any, any> | WeakMap<any, any>> = Parameters<T['get']>[0];
20
- type ObservableMap<T extends Map<any, any> | WeakMap<any, any>> = Omit<T, 'get' | 'size'> & Omit<ObservablePrimitive<T>, 'get' | 'size'> & {
20
+ type ObservableMap<T extends Map<any, any> | WeakMap<any, any>> = Omit<T, 'get' | 'size' | 'set'> & Omit<ObservablePrimitive<T>, 'get' | 'size'> & {
21
21
  get(key: Parameters<T['get']>[0]): Observable<Parameters<T['set']>[1]>;
22
22
  get(): T;
23
- size: ImmutableObservableBase<number>;
23
+ size: number;
24
+ set(key: MapKey<T>, value: MapValue<T>): Observable<T>;
24
25
  assign(value: Record<MapKey<T>, MapValue<T>> | Map<MapKey<T>, MapValue<T>> | WeakMap<MapKey<T>, MapValue<T>>): Observable<T>;
25
26
  };
26
- type ObservableSet<T extends Set<any> | WeakSet<any>> = Omit<T, 'size'> & Omit<ObservablePrimitive<T>, 'size'> & {
27
- size: ImmutableObservableBase<number>;
27
+ type SetValue<T extends Set<any> | WeakSet<any>> = Parameters<T['has']>[0];
28
+ type ObservableSet<T extends Set<any> | WeakSet<any>> = Omit<T, 'size' | 'add'> & Omit<ObservablePrimitive<T>, 'size'> & {
29
+ size: number;
30
+ add: (value: SetValue<T>) => Observable<T>;
28
31
  };
29
32
  interface ObservableBoolean extends ObservablePrimitive<boolean> {
30
33
  toggle(): void;
@@ -316,7 +319,7 @@ declare function setSilently(value$: ObservableParam, newValue: any): any;
316
319
  declare function initializePathType(pathType: TypeAtPath): any;
317
320
  declare function applyChange<T extends object>(value: T, change: Change, applyPrevious?: boolean): T;
318
321
  declare function applyChanges<T extends object>(value: T, changes: Change[], applyPrevious?: boolean): T;
319
- declare function deepMerge<T extends object>(target: T, ...sources: any[]): T;
322
+ declare function deepMerge<T>(target: T, ...sources: any[]): T;
320
323
 
321
324
  declare const hasOwnProperty: (v: PropertyKey) => boolean;
322
325
  declare function isArray(obj: unknown): obj is Array<any>;
package/index.d.ts CHANGED
@@ -17,14 +17,17 @@ interface ObservableObjectFunctions<T = Record<string, any>> extends ObservableP
17
17
  }
18
18
  type MapKey<T extends Map<any, any> | WeakMap<any, any>> = Parameters<T['has']>[0];
19
19
  type MapValue<T extends Map<any, any> | WeakMap<any, any>> = Parameters<T['get']>[0];
20
- type ObservableMap<T extends Map<any, any> | WeakMap<any, any>> = Omit<T, 'get' | 'size'> & Omit<ObservablePrimitive<T>, 'get' | 'size'> & {
20
+ type ObservableMap<T extends Map<any, any> | WeakMap<any, any>> = Omit<T, 'get' | 'size' | 'set'> & Omit<ObservablePrimitive<T>, 'get' | 'size'> & {
21
21
  get(key: Parameters<T['get']>[0]): Observable<Parameters<T['set']>[1]>;
22
22
  get(): T;
23
- size: ImmutableObservableBase<number>;
23
+ size: number;
24
+ set(key: MapKey<T>, value: MapValue<T>): Observable<T>;
24
25
  assign(value: Record<MapKey<T>, MapValue<T>> | Map<MapKey<T>, MapValue<T>> | WeakMap<MapKey<T>, MapValue<T>>): Observable<T>;
25
26
  };
26
- type ObservableSet<T extends Set<any> | WeakSet<any>> = Omit<T, 'size'> & Omit<ObservablePrimitive<T>, 'size'> & {
27
- size: ImmutableObservableBase<number>;
27
+ type SetValue<T extends Set<any> | WeakSet<any>> = Parameters<T['has']>[0];
28
+ type ObservableSet<T extends Set<any> | WeakSet<any>> = Omit<T, 'size' | 'add'> & Omit<ObservablePrimitive<T>, 'size'> & {
29
+ size: number;
30
+ add: (value: SetValue<T>) => Observable<T>;
28
31
  };
29
32
  interface ObservableBoolean extends ObservablePrimitive<boolean> {
30
33
  toggle(): void;
@@ -316,7 +319,7 @@ declare function setSilently(value$: ObservableParam, newValue: any): any;
316
319
  declare function initializePathType(pathType: TypeAtPath): any;
317
320
  declare function applyChange<T extends object>(value: T, change: Change, applyPrevious?: boolean): T;
318
321
  declare function applyChanges<T extends object>(value: T, changes: Change[], applyPrevious?: boolean): T;
319
- declare function deepMerge<T extends object>(target: T, ...sources: any[]): T;
322
+ declare function deepMerge<T>(target: T, ...sources: any[]): T;
320
323
 
321
324
  declare const hasOwnProperty: (v: PropertyKey) => boolean;
322
325
  declare function isArray(obj: unknown): obj is Array<any>;
package/index.js CHANGED
@@ -31,10 +31,10 @@ function isPromise(obj) {
31
31
  return obj instanceof Promise;
32
32
  }
33
33
  function isMap(obj) {
34
- return obj instanceof Map;
34
+ return obj instanceof Map || obj instanceof WeakMap;
35
35
  }
36
36
  function isSet(obj) {
37
- return obj instanceof Set;
37
+ return obj instanceof Set || obj instanceof WeakSet;
38
38
  }
39
39
  function isNumber(obj) {
40
40
  const n = obj;
@@ -152,22 +152,24 @@ function setNodeValue(node, newValue) {
152
152
  if (isDelete)
153
153
  newValue = void 0;
154
154
  const parentValue = node.parent ? ensureNodeValue(parentNode) : parentNode.root;
155
- const prevValue = parentValue[key];
155
+ const useSetFn = isSet(parentValue);
156
+ const useMapFn = isMap(parentValue);
157
+ const prevValue = useSetFn ? key : useMapFn ? parentValue.get(key) : parentValue[key];
156
158
  const isFunc = isFunction(newValue);
157
159
  newValue = !parentNode.isAssigning && isFunc && !isFunction(prevValue) ? newValue(prevValue) : newValue;
158
160
  if (newValue !== prevValue) {
159
161
  try {
160
162
  parentNode.isSetting = (parentNode.isSetting || 0) + 1;
161
- const useMapFn = isMap(parentValue);
162
163
  if (isDelete) {
163
- if (useMapFn) {
164
+ if (useMapFn || useSetFn) {
164
165
  parentValue.delete(key);
165
166
  } else {
166
167
  delete parentValue[key];
167
168
  }
168
169
  } else {
169
- const useMapFn2 = isMap(parentValue);
170
- if (useMapFn2) {
170
+ if (useSetFn) {
171
+ parentValue.add(newValue);
172
+ } else if (useMapFn) {
171
173
  parentValue.set(key, newValue);
172
174
  } else {
173
175
  parentValue[key] = newValue;
@@ -310,13 +312,13 @@ function setAtPath(obj, path, pathTypes, value, mode, fullObj, restore) {
310
312
  }
311
313
  if (p === void 0) {
312
314
  if (mode === "merge") {
313
- obj = deepMerge(obj, value, false, 0);
315
+ obj = deepMerge(obj, value);
314
316
  } else {
315
317
  obj = value;
316
318
  }
317
319
  } else {
318
320
  if (mode === "merge") {
319
- o[p] = deepMerge(o[p], value, false, 0);
321
+ o[p] = deepMerge(o[p], value);
320
322
  } else if (isMap(o)) {
321
323
  o.set(p, value);
322
324
  } else {
@@ -454,7 +456,10 @@ function applyChanges(value, changes, applyPrevious) {
454
456
  return value;
455
457
  }
456
458
  function deepMerge(target, ...sources) {
457
- const result = { ...target };
459
+ if (isPrimitive(target)) {
460
+ return sources[sources.length - 1];
461
+ }
462
+ const result = isArray(target) ? [...target] : { ...target };
458
463
  for (let i = 0; i < sources.length; i++) {
459
464
  const obj2 = sources[i];
460
465
  for (const key in obj2) {
@@ -1369,7 +1374,7 @@ var proxyHandler = {
1369
1374
  if (targetNode && p !== "onChange") {
1370
1375
  return proxyHandler.get(targetNode, p, receiver);
1371
1376
  }
1372
- if (isMap(value) || value instanceof WeakMap || value instanceof Set || value instanceof WeakSet) {
1377
+ if (isMap(value) || isSet(value)) {
1373
1378
  const ret = handlerMapSet(node, p, value);
1374
1379
  if (ret !== void 0) {
1375
1380
  return ret;
@@ -1461,7 +1466,7 @@ var proxyHandler = {
1461
1466
  return vProp.bind(value);
1462
1467
  }
1463
1468
  if (isPrimitive(vProp)) {
1464
- if (isArray(value) && p === "length") {
1469
+ if (p === "length" && isArray(value)) {
1465
1470
  updateTracking(node, true);
1466
1471
  return vProp;
1467
1472
  }
@@ -1625,7 +1630,8 @@ function deleteFn(node, key) {
1625
1630
  function handlerMapSet(node, p, value) {
1626
1631
  const vProp = value == null ? void 0 : value[p];
1627
1632
  if (p === "size") {
1628
- return getProxy(node, p);
1633
+ updateTracking(node, true);
1634
+ return value[p];
1629
1635
  } else if (isFunction(vProp)) {
1630
1636
  return function(a, b, c) {
1631
1637
  const l = arguments.length;
@@ -1636,23 +1642,16 @@ function handlerMapSet(node, p, value) {
1636
1642
  }
1637
1643
  } else if (p === "set") {
1638
1644
  if (l === 2) {
1639
- const prev = valueMap.get(a);
1640
- const ret = valueMap.set(a, b);
1641
- if (prev !== b) {
1642
- updateNodesAndNotify(getChildNode(node, a), b, prev);
1643
- }
1644
- return ret;
1645
+ set(getChildNode(node, a), b);
1645
1646
  } else if (l === 1 && isMap(value)) {
1646
1647
  set(node, a);
1647
1648
  }
1649
+ return getProxy(node);
1648
1650
  } else if (p === "delete") {
1649
1651
  if (l > 0) {
1650
1652
  const prev = value.get ? valueMap.get(a) : a;
1651
- const ret = value.delete(a);
1652
- if (ret) {
1653
- updateNodesAndNotify(getChildNode(node, a), void 0, prev);
1654
- }
1655
- return ret;
1653
+ deleteFn(node, a);
1654
+ return prev !== void 0;
1656
1655
  }
1657
1656
  } else if (p === "clear") {
1658
1657
  const prev = new Map(valueMap);
@@ -1668,7 +1667,7 @@ function handlerMapSet(node, p, value) {
1668
1667
  if (!value.has(p)) {
1669
1668
  notify(node, ret, prev, 0);
1670
1669
  }
1671
- return ret;
1670
+ return getProxy(node);
1672
1671
  }
1673
1672
  const fn = observableFns.get(p);
1674
1673
  if (fn) {
package/index.mjs CHANGED
@@ -29,10 +29,10 @@ function isPromise(obj) {
29
29
  return obj instanceof Promise;
30
30
  }
31
31
  function isMap(obj) {
32
- return obj instanceof Map;
32
+ return obj instanceof Map || obj instanceof WeakMap;
33
33
  }
34
34
  function isSet(obj) {
35
- return obj instanceof Set;
35
+ return obj instanceof Set || obj instanceof WeakSet;
36
36
  }
37
37
  function isNumber(obj) {
38
38
  const n = obj;
@@ -150,22 +150,24 @@ function setNodeValue(node, newValue) {
150
150
  if (isDelete)
151
151
  newValue = void 0;
152
152
  const parentValue = node.parent ? ensureNodeValue(parentNode) : parentNode.root;
153
- const prevValue = parentValue[key];
153
+ const useSetFn = isSet(parentValue);
154
+ const useMapFn = isMap(parentValue);
155
+ const prevValue = useSetFn ? key : useMapFn ? parentValue.get(key) : parentValue[key];
154
156
  const isFunc = isFunction(newValue);
155
157
  newValue = !parentNode.isAssigning && isFunc && !isFunction(prevValue) ? newValue(prevValue) : newValue;
156
158
  if (newValue !== prevValue) {
157
159
  try {
158
160
  parentNode.isSetting = (parentNode.isSetting || 0) + 1;
159
- const useMapFn = isMap(parentValue);
160
161
  if (isDelete) {
161
- if (useMapFn) {
162
+ if (useMapFn || useSetFn) {
162
163
  parentValue.delete(key);
163
164
  } else {
164
165
  delete parentValue[key];
165
166
  }
166
167
  } else {
167
- const useMapFn2 = isMap(parentValue);
168
- if (useMapFn2) {
168
+ if (useSetFn) {
169
+ parentValue.add(newValue);
170
+ } else if (useMapFn) {
169
171
  parentValue.set(key, newValue);
170
172
  } else {
171
173
  parentValue[key] = newValue;
@@ -308,13 +310,13 @@ function setAtPath(obj, path, pathTypes, value, mode, fullObj, restore) {
308
310
  }
309
311
  if (p === void 0) {
310
312
  if (mode === "merge") {
311
- obj = deepMerge(obj, value, false, 0);
313
+ obj = deepMerge(obj, value);
312
314
  } else {
313
315
  obj = value;
314
316
  }
315
317
  } else {
316
318
  if (mode === "merge") {
317
- o[p] = deepMerge(o[p], value, false, 0);
319
+ o[p] = deepMerge(o[p], value);
318
320
  } else if (isMap(o)) {
319
321
  o.set(p, value);
320
322
  } else {
@@ -452,7 +454,10 @@ function applyChanges(value, changes, applyPrevious) {
452
454
  return value;
453
455
  }
454
456
  function deepMerge(target, ...sources) {
455
- const result = { ...target };
457
+ if (isPrimitive(target)) {
458
+ return sources[sources.length - 1];
459
+ }
460
+ const result = isArray(target) ? [...target] : { ...target };
456
461
  for (let i = 0; i < sources.length; i++) {
457
462
  const obj2 = sources[i];
458
463
  for (const key in obj2) {
@@ -1367,7 +1372,7 @@ var proxyHandler = {
1367
1372
  if (targetNode && p !== "onChange") {
1368
1373
  return proxyHandler.get(targetNode, p, receiver);
1369
1374
  }
1370
- if (isMap(value) || value instanceof WeakMap || value instanceof Set || value instanceof WeakSet) {
1375
+ if (isMap(value) || isSet(value)) {
1371
1376
  const ret = handlerMapSet(node, p, value);
1372
1377
  if (ret !== void 0) {
1373
1378
  return ret;
@@ -1459,7 +1464,7 @@ var proxyHandler = {
1459
1464
  return vProp.bind(value);
1460
1465
  }
1461
1466
  if (isPrimitive(vProp)) {
1462
- if (isArray(value) && p === "length") {
1467
+ if (p === "length" && isArray(value)) {
1463
1468
  updateTracking(node, true);
1464
1469
  return vProp;
1465
1470
  }
@@ -1623,7 +1628,8 @@ function deleteFn(node, key) {
1623
1628
  function handlerMapSet(node, p, value) {
1624
1629
  const vProp = value == null ? void 0 : value[p];
1625
1630
  if (p === "size") {
1626
- return getProxy(node, p);
1631
+ updateTracking(node, true);
1632
+ return value[p];
1627
1633
  } else if (isFunction(vProp)) {
1628
1634
  return function(a, b, c) {
1629
1635
  const l = arguments.length;
@@ -1634,23 +1640,16 @@ function handlerMapSet(node, p, value) {
1634
1640
  }
1635
1641
  } else if (p === "set") {
1636
1642
  if (l === 2) {
1637
- const prev = valueMap.get(a);
1638
- const ret = valueMap.set(a, b);
1639
- if (prev !== b) {
1640
- updateNodesAndNotify(getChildNode(node, a), b, prev);
1641
- }
1642
- return ret;
1643
+ set(getChildNode(node, a), b);
1643
1644
  } else if (l === 1 && isMap(value)) {
1644
1645
  set(node, a);
1645
1646
  }
1647
+ return getProxy(node);
1646
1648
  } else if (p === "delete") {
1647
1649
  if (l > 0) {
1648
1650
  const prev = value.get ? valueMap.get(a) : a;
1649
- const ret = value.delete(a);
1650
- if (ret) {
1651
- updateNodesAndNotify(getChildNode(node, a), void 0, prev);
1652
- }
1653
- return ret;
1651
+ deleteFn(node, a);
1652
+ return prev !== void 0;
1654
1653
  }
1655
1654
  } else if (p === "clear") {
1656
1655
  const prev = new Map(valueMap);
@@ -1666,7 +1665,7 @@ function handlerMapSet(node, p, value) {
1666
1665
  if (!value.has(p)) {
1667
1666
  notify(node, ret, prev, 0);
1668
1667
  }
1669
- return ret;
1668
+ return getProxy(node);
1670
1669
  }
1671
1670
  const fn = observableFns.get(p);
1672
1671
  if (fn) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/state",
3
- "version": "3.0.0-alpha.21",
3
+ "version": "3.0.0-alpha.23",
4
4
  "description": "legend-state",
5
5
  "sideEffects": false,
6
6
  "private": false,
@@ -232,6 +232,9 @@ function syncedFirebase(props) {
232
232
  return;
233
233
  const key = snap.key;
234
234
  const val = snap.val();
235
+ if (fieldId && !val[fieldId]) {
236
+ val[fieldId] = key;
237
+ }
235
238
  if (saving$[key].get()) {
236
239
  pendingIncoming$[key].set(val);
237
240
  } else {
@@ -230,6 +230,9 @@ function syncedFirebase(props) {
230
230
  return;
231
231
  const key = snap.key;
232
232
  const val = snap.val();
233
+ if (fieldId && !val[fieldId]) {
234
+ val[fieldId] = key;
235
+ }
233
236
  if (saving$[key].get()) {
234
237
  pendingIncoming$[key].set(val);
235
238
  } else {
package/sync.js CHANGED
@@ -777,6 +777,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
777
777
  const pending = localState.pendingChanges;
778
778
  const get = syncOptions.get;
779
779
  if (get) {
780
+ const { waitFor } = syncOptions;
780
781
  const runGet = () => {
781
782
  var _a2;
782
783
  const onChange = async ({ value, mode, lastSync: lastSync2 }) => {
@@ -865,22 +866,30 @@ function syncObservable(obs$, syncOptionsOrSynced) {
865
866
  node.activationState.onChange = onChange;
866
867
  }
867
868
  if (!isSubscribed && syncOptions.subscribe) {
869
+ const subscribe = syncOptions.subscribe;
868
870
  isSubscribed = true;
869
- unsubscribe = syncOptions.subscribe({
870
- node,
871
- value$: obs$,
872
- lastSync,
873
- update: (params) => {
874
- state.when(syncState$.isLoaded, () => {
875
- state.when(waitFor || true, () => {
876
- params.mode || (params.mode = syncOptions.mode || "merge");
877
- onChange(params);
871
+ const doSubscribe = () => {
872
+ unsubscribe = subscribe({
873
+ node,
874
+ value$: obs$,
875
+ lastSync,
876
+ update: (params) => {
877
+ state.when(syncState$.isLoaded, () => {
878
+ state.when(waitFor || true, () => {
879
+ params.mode || (params.mode = syncOptions.mode || "merge");
880
+ onChange(params);
881
+ });
878
882
  });
879
- });
880
- },
881
- refresh: () => state.when(syncState$.isLoaded, sync),
882
- onError: (error) => onError(error, void 0, "subscribe")
883
- });
883
+ },
884
+ refresh: () => state.when(syncState$.isLoaded, sync),
885
+ onError: (error) => onError(error, void 0, "subscribe")
886
+ });
887
+ };
888
+ if (waitFor) {
889
+ state.whenReady(waitFor, doSubscribe);
890
+ } else {
891
+ doSubscribe();
892
+ }
884
893
  }
885
894
  const existingValue = getNodeValue(node);
886
895
  const getParams = {
@@ -953,7 +962,6 @@ function syncObservable(obs$, syncOptionsOrSynced) {
953
962
  handle(got);
954
963
  }
955
964
  };
956
- const { waitFor } = syncOptions;
957
965
  if (waitFor) {
958
966
  if (node.activationState) {
959
967
  node.activationState.waitFor = void 0;
package/sync.mjs CHANGED
@@ -775,6 +775,7 @@ function syncObservable(obs$, syncOptionsOrSynced) {
775
775
  const pending = localState.pendingChanges;
776
776
  const get = syncOptions.get;
777
777
  if (get) {
778
+ const { waitFor } = syncOptions;
778
779
  const runGet = () => {
779
780
  var _a2;
780
781
  const onChange = async ({ value, mode, lastSync: lastSync2 }) => {
@@ -863,22 +864,30 @@ function syncObservable(obs$, syncOptionsOrSynced) {
863
864
  node.activationState.onChange = onChange;
864
865
  }
865
866
  if (!isSubscribed && syncOptions.subscribe) {
867
+ const subscribe = syncOptions.subscribe;
866
868
  isSubscribed = true;
867
- unsubscribe = syncOptions.subscribe({
868
- node,
869
- value$: obs$,
870
- lastSync,
871
- update: (params) => {
872
- when(syncState$.isLoaded, () => {
873
- when(waitFor || true, () => {
874
- params.mode || (params.mode = syncOptions.mode || "merge");
875
- onChange(params);
869
+ const doSubscribe = () => {
870
+ unsubscribe = subscribe({
871
+ node,
872
+ value$: obs$,
873
+ lastSync,
874
+ update: (params) => {
875
+ when(syncState$.isLoaded, () => {
876
+ when(waitFor || true, () => {
877
+ params.mode || (params.mode = syncOptions.mode || "merge");
878
+ onChange(params);
879
+ });
876
880
  });
877
- });
878
- },
879
- refresh: () => when(syncState$.isLoaded, sync),
880
- onError: (error) => onError(error, void 0, "subscribe")
881
- });
881
+ },
882
+ refresh: () => when(syncState$.isLoaded, sync),
883
+ onError: (error) => onError(error, void 0, "subscribe")
884
+ });
885
+ };
886
+ if (waitFor) {
887
+ whenReady(waitFor, doSubscribe);
888
+ } else {
889
+ doSubscribe();
890
+ }
882
891
  }
883
892
  const existingValue = getNodeValue(node);
884
893
  const getParams = {
@@ -951,7 +960,6 @@ function syncObservable(obs$, syncOptionsOrSynced) {
951
960
  handle(got);
952
961
  }
953
962
  };
954
- const { waitFor } = syncOptions;
955
963
  if (waitFor) {
956
964
  if (node.activationState) {
957
965
  node.activationState.waitFor = void 0;