@legendapp/state 3.0.0-beta.44 → 3.0.0-beta.46

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.
Files changed (3) hide show
  1. package/index.js +54 -6
  2. package/index.mjs +54 -6
  3. package/package.json +1 -1
package/index.js CHANGED
@@ -918,16 +918,30 @@ function processQueuedEvents() {
918
918
  continue;
919
919
  const nodeListeners = node.listeners;
920
920
  const nodeListenersImmediate = node.listenersImmediate;
921
- if (!nodeListeners && !nodeListenersImmediate) {
921
+ if (!nodeListeners && !nodeListenersImmediate && node.numListenersRecursive && !(type === "listener-added" && !listener)) {
922
922
  continue;
923
923
  }
924
924
  let isValid = false;
925
925
  if (type === "listener-added") {
926
- isValid = !!(nodeListeners == null ? void 0 : nodeListeners.has(listener)) || !!(nodeListenersImmediate == null ? void 0 : nodeListenersImmediate.has(listener));
926
+ if (listener) {
927
+ isValid = !!(nodeListeners == null ? void 0 : nodeListeners.has(listener)) || !!(nodeListenersImmediate == null ? void 0 : nodeListenersImmediate.has(listener));
928
+ } else {
929
+ const hasNoLocalListeners = !(nodeListeners == null ? void 0 : nodeListeners.size) && !(nodeListenersImmediate == null ? void 0 : nodeListenersImmediate.size);
930
+ if (hasNoLocalListeners && typeof node.numListenersRecursive === "number") {
931
+ isValid = node.numListenersRecursive > 0;
932
+ } else {
933
+ isValid = false;
934
+ }
935
+ }
927
936
  } else if (type === "listener-removed") {
928
937
  isValid = !(nodeListeners == null ? void 0 : nodeListeners.has(listener)) && !(nodeListenersImmediate == null ? void 0 : nodeListenersImmediate.has(listener));
929
938
  } else {
930
- isValid = !(nodeListeners == null ? void 0 : nodeListeners.size) && !(nodeListenersImmediate == null ? void 0 : nodeListenersImmediate.size);
939
+ const hasAnyLocal = nodeListeners && nodeListeners.size > 0 || nodeListenersImmediate && nodeListenersImmediate.size > 0;
940
+ if (typeof node.numListenersRecursive === "number") {
941
+ isValid = !hasAnyLocal && node.numListenersRecursive === 0;
942
+ } else {
943
+ isValid = !hasAnyLocal;
944
+ }
931
945
  }
932
946
  if (isValid) {
933
947
  eventObj.type = type;
@@ -947,6 +961,14 @@ function processQueuedEvents() {
947
961
  }
948
962
 
949
963
  // src/onChange.ts
964
+ function isSyncedObservable(node) {
965
+ var _a;
966
+ return ((_a = node.activationState) == null ? void 0 : _a.synced) || false;
967
+ }
968
+ function shouldDispatchParentMiddlewareEvent(node) {
969
+ var _a, _b;
970
+ return !((_a = node.listeners) == null ? void 0 : _a.size) && !((_b = node.listenersImmediate) == null ? void 0 : _b.size) && isSyncedObservable(node);
971
+ }
950
972
  function onChange(node, callback, options = {}, fromLinks) {
951
973
  var _a;
952
974
  const { initial, immediate, noArgs } = options;
@@ -1013,6 +1035,9 @@ function onChange(node, callback, options = {}, fromLinks) {
1013
1035
  }
1014
1036
  }
1015
1037
  parent.numListenersRecursive++;
1038
+ if (shouldDispatchParentMiddlewareEvent(parent)) {
1039
+ dispatchMiddlewareEvent(parent, void 0, "listener-added");
1040
+ }
1016
1041
  pathParent = [parent.key, ...pathParent];
1017
1042
  parent = parent.parent;
1018
1043
  }
@@ -1020,15 +1045,24 @@ function onChange(node, callback, options = {}, fromLinks) {
1020
1045
  return () => {
1021
1046
  listeners.delete(listener);
1022
1047
  extraDisposes == null ? void 0 : extraDisposes.forEach((fn) => fn());
1048
+ const clearedRecursive = [];
1023
1049
  let parent2 = node;
1024
1050
  while (parent2) {
1025
1051
  parent2.numListenersRecursive--;
1052
+ if (parent2.numListenersRecursive === 0) {
1053
+ clearedRecursive.push(parent2);
1054
+ }
1026
1055
  parent2 = parent2.parent;
1027
1056
  }
1028
1057
  dispatchMiddlewareEvent(node, listener, "listener-removed");
1029
1058
  if (listeners.size === 0) {
1030
1059
  dispatchMiddlewareEvent(node, void 0, "listeners-cleared");
1031
1060
  }
1061
+ for (const clearedNode of clearedRecursive) {
1062
+ if (clearedNode !== node && shouldDispatchParentMiddlewareEvent(clearedNode)) {
1063
+ dispatchMiddlewareEvent(clearedNode, void 0, "listeners-cleared");
1064
+ }
1065
+ }
1032
1066
  };
1033
1067
  }
1034
1068
  function createCb(linkedFromNode, path, callback) {
@@ -1195,6 +1229,16 @@ function observe(selectorOrRun, reactionOrOptions, options) {
1195
1229
  };
1196
1230
  }
1197
1231
 
1232
+ // src/toPrimitive.ts
1233
+ function toPrimitive(node, hint) {
1234
+ const value = peek(node);
1235
+ if (value === null || value === void 0 || isPrimitive(value)) {
1236
+ return value;
1237
+ }
1238
+ const method = hint === "string" ? isFunction(value.toString) ? value.toString : value.valueOf : isFunction(value.valueOf) ? value.valueOf : value.toString;
1239
+ return isFunction(method) ? method.call(value) : value;
1240
+ }
1241
+
1198
1242
  // src/when.ts
1199
1243
  function _when(predicate, effect, checkReady) {
1200
1244
  if (isPromise(predicate)) {
@@ -1512,9 +1556,7 @@ var proxyHandler = {
1512
1556
  get(node, p, receiver) {
1513
1557
  var _a, _b, _c;
1514
1558
  if (p === symbolToPrimitive) {
1515
- throw new Error(
1516
- process.env.NODE_ENV === "development" ? "[legend-state] observable should not be used as a primitive. You may have forgotten to use .get() or .peek() to get the value of the observable." : "[legend-state] observable is not a primitive."
1517
- );
1559
+ return (hint) => toPrimitive(node, hint);
1518
1560
  }
1519
1561
  if (p === symbolGetNode) {
1520
1562
  return node;
@@ -2398,6 +2440,12 @@ Object.defineProperty(ObservablePrimitiveClass.prototype, symbolGetNode, {
2398
2440
  return this._node;
2399
2441
  }
2400
2442
  });
2443
+ Object.defineProperty(ObservablePrimitiveClass.prototype, symbolToPrimitive, {
2444
+ configurable: true,
2445
+ value(hint) {
2446
+ return toPrimitive(this._node, hint);
2447
+ }
2448
+ });
2401
2449
  ObservablePrimitiveClass.prototype.toggle = function() {
2402
2450
  const value = this.peek();
2403
2451
  if (value === void 0 || value === null || isBoolean(value)) {
package/index.mjs CHANGED
@@ -916,16 +916,30 @@ function processQueuedEvents() {
916
916
  continue;
917
917
  const nodeListeners = node.listeners;
918
918
  const nodeListenersImmediate = node.listenersImmediate;
919
- if (!nodeListeners && !nodeListenersImmediate) {
919
+ if (!nodeListeners && !nodeListenersImmediate && node.numListenersRecursive && !(type === "listener-added" && !listener)) {
920
920
  continue;
921
921
  }
922
922
  let isValid = false;
923
923
  if (type === "listener-added") {
924
- isValid = !!(nodeListeners == null ? void 0 : nodeListeners.has(listener)) || !!(nodeListenersImmediate == null ? void 0 : nodeListenersImmediate.has(listener));
924
+ if (listener) {
925
+ isValid = !!(nodeListeners == null ? void 0 : nodeListeners.has(listener)) || !!(nodeListenersImmediate == null ? void 0 : nodeListenersImmediate.has(listener));
926
+ } else {
927
+ const hasNoLocalListeners = !(nodeListeners == null ? void 0 : nodeListeners.size) && !(nodeListenersImmediate == null ? void 0 : nodeListenersImmediate.size);
928
+ if (hasNoLocalListeners && typeof node.numListenersRecursive === "number") {
929
+ isValid = node.numListenersRecursive > 0;
930
+ } else {
931
+ isValid = false;
932
+ }
933
+ }
925
934
  } else if (type === "listener-removed") {
926
935
  isValid = !(nodeListeners == null ? void 0 : nodeListeners.has(listener)) && !(nodeListenersImmediate == null ? void 0 : nodeListenersImmediate.has(listener));
927
936
  } else {
928
- isValid = !(nodeListeners == null ? void 0 : nodeListeners.size) && !(nodeListenersImmediate == null ? void 0 : nodeListenersImmediate.size);
937
+ const hasAnyLocal = nodeListeners && nodeListeners.size > 0 || nodeListenersImmediate && nodeListenersImmediate.size > 0;
938
+ if (typeof node.numListenersRecursive === "number") {
939
+ isValid = !hasAnyLocal && node.numListenersRecursive === 0;
940
+ } else {
941
+ isValid = !hasAnyLocal;
942
+ }
929
943
  }
930
944
  if (isValid) {
931
945
  eventObj.type = type;
@@ -945,6 +959,14 @@ function processQueuedEvents() {
945
959
  }
946
960
 
947
961
  // src/onChange.ts
962
+ function isSyncedObservable(node) {
963
+ var _a;
964
+ return ((_a = node.activationState) == null ? void 0 : _a.synced) || false;
965
+ }
966
+ function shouldDispatchParentMiddlewareEvent(node) {
967
+ var _a, _b;
968
+ return !((_a = node.listeners) == null ? void 0 : _a.size) && !((_b = node.listenersImmediate) == null ? void 0 : _b.size) && isSyncedObservable(node);
969
+ }
948
970
  function onChange(node, callback, options = {}, fromLinks) {
949
971
  var _a;
950
972
  const { initial, immediate, noArgs } = options;
@@ -1011,6 +1033,9 @@ function onChange(node, callback, options = {}, fromLinks) {
1011
1033
  }
1012
1034
  }
1013
1035
  parent.numListenersRecursive++;
1036
+ if (shouldDispatchParentMiddlewareEvent(parent)) {
1037
+ dispatchMiddlewareEvent(parent, void 0, "listener-added");
1038
+ }
1014
1039
  pathParent = [parent.key, ...pathParent];
1015
1040
  parent = parent.parent;
1016
1041
  }
@@ -1018,15 +1043,24 @@ function onChange(node, callback, options = {}, fromLinks) {
1018
1043
  return () => {
1019
1044
  listeners.delete(listener);
1020
1045
  extraDisposes == null ? void 0 : extraDisposes.forEach((fn) => fn());
1046
+ const clearedRecursive = [];
1021
1047
  let parent2 = node;
1022
1048
  while (parent2) {
1023
1049
  parent2.numListenersRecursive--;
1050
+ if (parent2.numListenersRecursive === 0) {
1051
+ clearedRecursive.push(parent2);
1052
+ }
1024
1053
  parent2 = parent2.parent;
1025
1054
  }
1026
1055
  dispatchMiddlewareEvent(node, listener, "listener-removed");
1027
1056
  if (listeners.size === 0) {
1028
1057
  dispatchMiddlewareEvent(node, void 0, "listeners-cleared");
1029
1058
  }
1059
+ for (const clearedNode of clearedRecursive) {
1060
+ if (clearedNode !== node && shouldDispatchParentMiddlewareEvent(clearedNode)) {
1061
+ dispatchMiddlewareEvent(clearedNode, void 0, "listeners-cleared");
1062
+ }
1063
+ }
1030
1064
  };
1031
1065
  }
1032
1066
  function createCb(linkedFromNode, path, callback) {
@@ -1193,6 +1227,16 @@ function observe(selectorOrRun, reactionOrOptions, options) {
1193
1227
  };
1194
1228
  }
1195
1229
 
1230
+ // src/toPrimitive.ts
1231
+ function toPrimitive(node, hint) {
1232
+ const value = peek(node);
1233
+ if (value === null || value === void 0 || isPrimitive(value)) {
1234
+ return value;
1235
+ }
1236
+ const method = hint === "string" ? isFunction(value.toString) ? value.toString : value.valueOf : isFunction(value.valueOf) ? value.valueOf : value.toString;
1237
+ return isFunction(method) ? method.call(value) : value;
1238
+ }
1239
+
1196
1240
  // src/when.ts
1197
1241
  function _when(predicate, effect, checkReady) {
1198
1242
  if (isPromise(predicate)) {
@@ -1510,9 +1554,7 @@ var proxyHandler = {
1510
1554
  get(node, p, receiver) {
1511
1555
  var _a, _b, _c;
1512
1556
  if (p === symbolToPrimitive) {
1513
- throw new Error(
1514
- process.env.NODE_ENV === "development" ? "[legend-state] observable should not be used as a primitive. You may have forgotten to use .get() or .peek() to get the value of the observable." : "[legend-state] observable is not a primitive."
1515
- );
1557
+ return (hint) => toPrimitive(node, hint);
1516
1558
  }
1517
1559
  if (p === symbolGetNode) {
1518
1560
  return node;
@@ -2396,6 +2438,12 @@ Object.defineProperty(ObservablePrimitiveClass.prototype, symbolGetNode, {
2396
2438
  return this._node;
2397
2439
  }
2398
2440
  });
2441
+ Object.defineProperty(ObservablePrimitiveClass.prototype, symbolToPrimitive, {
2442
+ configurable: true,
2443
+ value(hint) {
2444
+ return toPrimitive(this._node, hint);
2445
+ }
2446
+ });
2399
2447
  ObservablePrimitiveClass.prototype.toggle = function() {
2400
2448
  const value = this.peek();
2401
2449
  if (value === void 0 || value === null || isBoolean(value)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/state",
3
- "version": "3.0.0-beta.44",
3
+ "version": "3.0.0-beta.46",
4
4
  "description": "legend-state",
5
5
  "sideEffects": false,
6
6
  "private": false,