@legendapp/state 2.2.0-next.36 → 2.2.0-next.38

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.ts CHANGED
@@ -4,7 +4,7 @@ export { computed } from './src/computed';
4
4
  export { configureLegendState } from './src/config';
5
5
  export { event } from './src/event';
6
6
  export { isObservable } from './src/globals';
7
- export { computeSelector, constructObjectWithPath, deconstructObjectWithPath, getObservableIndex, isObservableValueReady, lockObservable, mergeIntoObservable, opaqueObject, setAtPath, setInObservableAtPath, setSilently, } from './src/helpers';
7
+ export { computeSelector, constructObjectWithPath, deconstructObjectWithPath, getObservableIndex, isObservableValueReady, mergeIntoObservable, opaqueObject, setAtPath, setInObservableAtPath, setSilently, } from './src/helpers';
8
8
  export { hasOwnProperty, isArray, isBoolean, isEmpty, isFunction, isObject, isPrimitive, isPromise, isString, isSymbol, } from './src/is';
9
9
  export { observable, observablePrimitive, syncState } from './src/observable';
10
10
  export * from './src/observableInterfaces';
package/index.js CHANGED
@@ -73,24 +73,11 @@ const globalState = {
73
73
  function isObservable(obs) {
74
74
  return !!obs && !!obs[symbolGetNode];
75
75
  }
76
- function isComputed(obs) {
77
- var _a;
78
- return obs && ((_a = obs[symbolGetNode]) === null || _a === void 0 ? void 0 : _a.isComputed);
79
- }
80
- function checkActivate(node) {
81
- var _a;
82
- const root = node.root;
83
- (_a = root.activate) === null || _a === void 0 ? void 0 : _a.call(root);
84
- if (root.toActivate) {
85
- root.toActivate.forEach(checkActivate);
86
- delete root.toActivate;
87
- }
88
- }
89
76
  function getNode(obs) {
90
77
  return obs && obs[symbolGetNode];
91
78
  }
92
79
  function setNodeValue(node, newValue) {
93
- var _a;
80
+ var _a, _b, _c;
94
81
  const parentNode = (_a = node.parent) !== null && _a !== void 0 ? _a : node;
95
82
  const key = node.parent ? node.key : '_';
96
83
  const isDelete = newValue === symbolDelete;
@@ -105,28 +92,30 @@ function setNodeValue(node, newValue) {
105
92
  // Compute newValue if newValue is a function or an observable
106
93
  newValue = !parentNode.isAssigning && isFunc ? newValue(prevValue) : newValue;
107
94
  // If setting an observable, set a link to the observable instead
108
- if (isObservable(newValue) && !isComputed(newValue)) {
95
+ if (isObservable(newValue)) {
109
96
  const val = newValue;
110
97
  node.lazy = true;
111
98
  node.lazyFn = () => val;
112
99
  newValue = undefined;
113
100
  }
114
- try {
115
- parentNode.isSetting = (parentNode.isSetting || 0) + 1;
116
- // Save the new value
117
- if (isDelete) {
118
- delete parentValue[key];
101
+ if (!globalState.isMerging ||
102
+ prevValue === undefined ||
103
+ isFunction(prevValue) ||
104
+ !((_c = (_b = node.parent) === null || _b === void 0 ? void 0 : _b.functions) === null || _c === void 0 ? void 0 : _c.get(key))) {
105
+ try {
106
+ parentNode.isSetting = (parentNode.isSetting || 0) + 1;
107
+ // Save the new value
108
+ if (isDelete) {
109
+ delete parentValue[key];
110
+ }
111
+ else {
112
+ parentValue[key] = newValue;
113
+ }
119
114
  }
120
- else {
121
- parentValue[key] = newValue;
115
+ finally {
116
+ parentNode.isSetting--;
122
117
  }
123
118
  }
124
- finally {
125
- parentNode.isSetting--;
126
- }
127
- if (parentNode.root.locked && parentNode.root.set) {
128
- parentNode.root.set(parentNode.root._);
129
- }
130
119
  return { prevValue, newValue, parentValue };
131
120
  }
132
121
  const arrNodeKeys = [];
@@ -210,18 +199,11 @@ function findIDKey(obj, node) {
210
199
  }
211
200
  return idKey;
212
201
  }
213
- function extractFunction(node, key, fnOrComputed, computedChildNode) {
202
+ function extractFunction(node, key, fnOrComputed) {
214
203
  if (!node.functions) {
215
204
  node.functions = new Map();
216
205
  }
217
206
  node.functions.set(key, fnOrComputed);
218
- if (computedChildNode) {
219
- computedChildNode.parentOther = getChildNode(node, key);
220
- if (!node.root.toActivate) {
221
- node.root.toActivate = [];
222
- }
223
- node.root.toActivate.push(computedChildNode);
224
- }
225
207
  }
226
208
 
227
209
  function activated(params) {
@@ -524,13 +506,6 @@ function opaqueObject(value) {
524
506
  }
525
507
  return value;
526
508
  }
527
- function lockObservable(obs, value) {
528
- var _a;
529
- const root = (_a = getNode(obs)) === null || _a === void 0 ? void 0 : _a.root;
530
- if (root) {
531
- root.locked = value;
532
- }
533
- }
534
509
  function setAtPath(obj, path, pathTypes, value, fullObj, restore) {
535
510
  let o = obj;
536
511
  let oFull = fullObj;
@@ -686,7 +661,6 @@ function onChange(node, callback, options = {}) {
686
661
  node.listeners = listeners;
687
662
  }
688
663
  }
689
- checkActivate(node);
690
664
  const listener = {
691
665
  listener: callback,
692
666
  track: trackingType,
@@ -708,7 +682,14 @@ function onChange(node, callback, options = {}) {
708
682
  getPrevious: () => undefined,
709
683
  });
710
684
  }
711
- return () => listeners.delete(listener);
685
+ let extraDispose;
686
+ if (node.linkedToNode) {
687
+ extraDispose = onChange(node.linkedToNode, callback, options);
688
+ }
689
+ return () => {
690
+ listeners.delete(listener);
691
+ extraDispose === null || extraDispose === void 0 ? void 0 : extraDispose();
692
+ };
712
693
  }
713
694
 
714
695
  function setupTracking(nodes, update, noArgs, immediate) {
@@ -1018,6 +999,7 @@ if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
1018
999
  function collectionSetter(node, target, prop, ...args) {
1019
1000
  var _a;
1020
1001
  if (prop === 'push' && args.length === 1) {
1002
+ // Fast path for push to just append to the end
1021
1003
  setKey(node, target.length + '', args[0]);
1022
1004
  }
1023
1005
  else {
@@ -1141,7 +1123,7 @@ function updateNodes(parent, obj, prevValue) {
1141
1123
  let didMove = false;
1142
1124
  for (let i = 0; i < length; i++) {
1143
1125
  const key = isArr ? i + '' : keys[i];
1144
- const value = isMap ? obj.get(key) : obj[key];
1126
+ let value = isMap ? obj.get(key) : obj[key];
1145
1127
  const prev = isPrevMap ? prevValue === null || prevValue === void 0 ? void 0 : prevValue.get(key) : prevValue === null || prevValue === void 0 ? void 0 : prevValue[key];
1146
1128
  let isDiff = value !== prev;
1147
1129
  if (isDiff) {
@@ -1150,8 +1132,12 @@ function updateNodes(parent, obj, prevValue) {
1150
1132
  ? idField(value)
1151
1133
  : value[idField]
1152
1134
  : undefined;
1135
+ if (isObservable(value)) {
1136
+ const obs = value;
1137
+ value = () => obs;
1138
+ }
1153
1139
  let child = getChildNode(parent, key, isFunction(value) ? value : undefined);
1154
- if (child.linkedToNode && (isFunction(value) || isObservable(value))) {
1140
+ if (!child.lazy && (isFunction(value) || isObservable(value))) {
1155
1141
  reactivateNode(child, value);
1156
1142
  peek(child);
1157
1143
  }
@@ -1255,7 +1241,7 @@ const proxyHandler = {
1255
1241
  if (p === symbolGetNode) {
1256
1242
  return node;
1257
1243
  }
1258
- const value = peek(node);
1244
+ let value = peek(node);
1259
1245
  // If this node is linked to another observable then forward to the target's handler.
1260
1246
  // The exception is onChange because it needs to listen to this node for changes.
1261
1247
  // This needs to be below peek because it activates there.
@@ -1292,14 +1278,6 @@ const proxyHandler = {
1292
1278
  }
1293
1279
  };
1294
1280
  }
1295
- if (node.isComputed) {
1296
- if (node.proxyFn && !fn) {
1297
- return node.proxyFn(p);
1298
- }
1299
- else {
1300
- checkActivate(node);
1301
- }
1302
- }
1303
1281
  const property = observableProperties.get(p);
1304
1282
  if (property) {
1305
1283
  return property.get(node);
@@ -1318,7 +1296,7 @@ const proxyHandler = {
1318
1296
  }
1319
1297
  }
1320
1298
  // /TODOV3 Remove this
1321
- const vProp = value === null || value === void 0 ? void 0 : value[p];
1299
+ let vProp = value === null || value === void 0 ? void 0 : value[p];
1322
1300
  if (isObject(value) && value[symbolOpaque]) {
1323
1301
  return vProp;
1324
1302
  }
@@ -1331,6 +1309,11 @@ const proxyHandler = {
1331
1309
  return getProxy(node, p, fnOrComputed);
1332
1310
  }
1333
1311
  }
1312
+ if (value === undefined && vProp === undefined && (ArrayModifiers.has(p) || ArrayLoopers.has(p))) {
1313
+ value = [];
1314
+ setNodeValue(node, value);
1315
+ vProp = value[p];
1316
+ }
1334
1317
  // Handle function calls
1335
1318
  if (isFunction(vProp)) {
1336
1319
  if (isArray(value)) {
@@ -1472,20 +1455,6 @@ function setKey(node, key, newValue, level) {
1472
1455
  }
1473
1456
  }
1474
1457
  const isRoot = !node.parent && key === '_';
1475
- // TODOv3 root locking will be removed with old computeds
1476
- if (node.root.locked && !node.root.set) {
1477
- // This happens when modifying a locked observable such as a computed.
1478
- // If merging this could be happening deep in a hierarchy so we don't want to throw errors so we'll just do nothing.
1479
- // This could happen during persistence local load for example.
1480
- if (globalState.isMerging) {
1481
- return isRoot ? getProxy(node) : getProxy(node, key);
1482
- }
1483
- else {
1484
- throw new Error(process.env.NODE_ENV === 'development'
1485
- ? '[legend-state] Cannot modify an observable while it is locked. Please make sure that you unlock the observable before making changes.'
1486
- : '[legend-state] Modified locked observable');
1487
- }
1488
- }
1489
1458
  if (node.parent && !getNodeValue(node)) {
1490
1459
  return set(node, { [key]: newValue });
1491
1460
  }
@@ -1535,7 +1504,13 @@ function deleteFn(node, key) {
1535
1504
  key = node.key;
1536
1505
  node = node.parent;
1537
1506
  }
1538
- setKey(node, key !== null && key !== void 0 ? key : '_', symbolDelete, /*level*/ -1);
1507
+ const value = getNodeValue(node);
1508
+ if (isArray(value)) {
1509
+ collectionSetter(node, value, 'splice', key, 1);
1510
+ }
1511
+ else {
1512
+ setKey(node, key !== null && key !== void 0 ? key : '_', symbolDelete, /*level*/ -1);
1513
+ }
1539
1514
  }
1540
1515
  function handlerMapSet(node, p, value) {
1541
1516
  const vProp = value === null || value === void 0 ? void 0 : value[p];
@@ -1661,6 +1636,11 @@ function extractFunctionOrComputed(node, obj, k, v) {
1661
1636
  extractPromise(childNode, v);
1662
1637
  setNodeValue(childNode, undefined);
1663
1638
  }
1639
+ else if (isObservable(v)) {
1640
+ const value = getNodeValue(node);
1641
+ value[k] = () => v;
1642
+ extractFunction(node, k, value[k]);
1643
+ }
1664
1644
  else if (typeof v === 'function') {
1665
1645
  const childNode = (_a = node.children) === null || _a === void 0 ? void 0 : _a.get(k);
1666
1646
  extractFunction(node, k, v);
@@ -1673,16 +1653,9 @@ function extractFunctionOrComputed(node, obj, k, v) {
1673
1653
  }
1674
1654
  }
1675
1655
  else if (typeof v == 'object' && v !== null && v !== undefined) {
1676
- const childNode = getNode(v);
1677
- if (childNode === null || childNode === void 0 ? void 0 : childNode.isComputed) {
1678
- extractFunction(node, k, v, childNode);
1679
- }
1680
- else if (isObservable(v)) {
1656
+ if (isObservable(v)) {
1681
1657
  extractFunction(node, k, v);
1682
1658
  }
1683
- else {
1684
- return true;
1685
- }
1686
1659
  }
1687
1660
  }
1688
1661
  function get(node, options) {
@@ -1703,13 +1676,7 @@ function peek(node) {
1703
1676
  if (lazy) {
1704
1677
  const lazyFn = node.lazyFn;
1705
1678
  delete node.lazy;
1706
- if (isFunction(node) || isFunction(lazy)) {
1707
- if (node.parent) {
1708
- const parentValue = getNodeValue(node.parent);
1709
- if (parentValue) {
1710
- delete parentValue[node.key];
1711
- }
1712
- }
1679
+ if (isFunction(node) || isFunction(lazyFn)) {
1713
1680
  value = activateNodeFunction(node, lazyFn);
1714
1681
  }
1715
1682
  }
@@ -1720,8 +1687,6 @@ function peek(node) {
1720
1687
  }
1721
1688
  }
1722
1689
  }
1723
- // Check if computed needs to activate
1724
- checkActivate(node);
1725
1690
  return value;
1726
1691
  }
1727
1692
  function reactivateNode(node, lazyFn) {
@@ -1837,11 +1802,16 @@ function activateNodeFunction(node, lazyFn) {
1837
1802
  }
1838
1803
  else {
1839
1804
  activatedValue = value;
1840
- set(node, value);
1841
- node.state.assign({
1842
- isLoaded: true,
1843
- error: undefined,
1844
- });
1805
+ if (node.state.isLoaded.peek()) {
1806
+ set(node, value);
1807
+ }
1808
+ else {
1809
+ setNodeValue(node, value);
1810
+ node.state.assign({
1811
+ isLoaded: true,
1812
+ error: undefined,
1813
+ });
1814
+ }
1845
1815
  }
1846
1816
  }
1847
1817
  disposes.forEach((fn) => fn());
@@ -2015,7 +1985,7 @@ function setToObservable(node, value) {
2015
1985
  // If the computed is a proxy to another observable
2016
1986
  // link it to the target observable
2017
1987
  const linkedNode = getNode(value);
2018
- if (linkedNode !== node) {
1988
+ if (linkedNode !== node && (linkedNode === null || linkedNode === void 0 ? void 0 : linkedNode.linkedToNode) !== node) {
2019
1989
  const prevNode = node.linkedToNode;
2020
1990
  node.linkedToNode = linkedNode;
2021
1991
  if (!linkedNode.linkedFromNodes) {
@@ -2103,87 +2073,15 @@ function syncState(obs) {
2103
2073
  }
2104
2074
  globalState.isLoadingRemote$ = observable(false);
2105
2075
 
2106
- function computed(compute, set$1) {
2107
- // Create an observable for this computed variable
2108
- const obs = observable();
2109
- lockObservable(obs, true);
2110
- const node = getNode(obs);
2111
- node.isComputed = true;
2112
- let isSetAfterActivated = false;
2113
- const setInner = function (val) {
2114
- const prevNode = node.linkedToNode;
2115
- // If it was previously linked to a node remove self
2116
- // from its linkedFromNodes
2117
- if (prevNode) {
2118
- prevNode.linkedFromNodes.delete(node);
2119
- node.linkedToNode = undefined;
2120
- }
2121
- const { parentOther } = node;
2122
- if (isObservable(val)) {
2123
- // If the computed is a proxy to another observable
2124
- // link it to the target observable
2125
- const linkedNode = getNode(val);
2126
- node.linkedToNode = linkedNode;
2127
- if (!linkedNode.linkedFromNodes) {
2128
- linkedNode.linkedFromNodes = new Set();
2129
- }
2130
- linkedNode.linkedFromNodes.add(node);
2131
- if (node.parentOther) {
2132
- onChange(linkedNode, ({ value }) => {
2133
- setNodeValue(node.parentOther, value);
2134
- }, { initial: true });
2135
- }
2136
- // If the target observable is different then notify for the change
2137
- if (prevNode) {
2138
- const value = getNodeValue(linkedNode);
2139
- const prevValue = getNodeValue(prevNode);
2140
- notify(node, value, prevValue, 0);
2141
- }
2142
- }
2143
- else if (val !== obs.peek()) {
2144
- // Unlock computed node before setting the value
2145
- lockObservable(obs, false);
2146
- const setter = isSetAfterActivated ? set : setNodeValue;
2147
- // Update the computed value
2148
- setter(node, val);
2149
- // If the computed is a child of an observable set the value on it
2150
- if (parentOther) {
2151
- let didUnlock = false;
2152
- if (parentOther.root.locked) {
2153
- parentOther.root.locked = false;
2154
- didUnlock = true;
2155
- }
2156
- setter(parentOther, val);
2157
- if (didUnlock) {
2158
- parentOther.root.locked = true;
2159
- }
2160
- }
2161
- // Re-lock the computed node
2162
- lockObservable(obs, true);
2163
- }
2164
- else if (parentOther) {
2165
- setNodeValue(parentOther, val);
2166
- }
2167
- isSetAfterActivated = true;
2168
- };
2169
- // Lazily activate the observable when get is called
2170
- node.root.activate = () => {
2171
- node.root.activate = undefined;
2172
- observe(compute, ({ value }) => {
2173
- if (isPromise(value)) {
2174
- value.then((v) => setInner(v));
2175
- }
2176
- else {
2177
- setInner(value);
2178
- }
2179
- }, { immediate: true, fromComputed: true });
2180
- };
2181
- if (set$1) {
2182
- node.root.set = (value) => {
2183
- batch(() => set$1(value));
2184
- };
2185
- }
2186
- return obs;
2076
+ function computed(compute, set) {
2077
+ // @ts-expect-error asdf
2078
+ return observable(set
2079
+ ? activated({
2080
+ // @ts-expect-error asdf
2081
+ get: compute,
2082
+ onSet: ({ value }) => set(value),
2083
+ })
2084
+ : compute);
2187
2085
  }
2188
2086
 
2189
2087
  function configureLegendState({ observableFunctions, observableProperties: observableProperties$1, }) {
@@ -2237,32 +2135,14 @@ function event() {
2237
2135
  }
2238
2136
 
2239
2137
  function proxy(get, set) {
2240
- // Create an observable for this computed variable
2241
- const obs = observable({});
2242
- lockObservable(obs, true);
2243
- const mapTargets = new Map();
2244
- const node = getNode(obs);
2245
- node.isComputed = true;
2246
- node.proxyFn = (key) => {
2247
- let target = mapTargets.get(key);
2248
- if (!target) {
2249
- // Note: Coercing typescript to allow undefined for set in computed because we don't want the public interface to allow undefined
2250
- target = computed(() => get(key), (set ? (value) => set(key, value) : undefined));
2251
- mapTargets.set(key, target);
2252
- extractFunction(node, key, target, getNode(target));
2253
- if (node.parentOther) {
2254
- onChange(getNode(target), ({ value, getPrevious }) => {
2255
- const previous = getPrevious();
2256
- // Set the raw value on the proxy's parent
2257
- setNodeValue(node.parentOther, node.root._);
2258
- // Notify the proxy
2259
- notify(getChildNode(node, key), value, previous, 0);
2260
- });
2261
- }
2262
- }
2263
- return target;
2264
- };
2265
- return obs;
2138
+ return observable(activated({
2139
+ lookup: (key) => set
2140
+ ? activated({
2141
+ get: () => get(key),
2142
+ onSet: ({ value }) => set(key, value),
2143
+ })
2144
+ : get(key),
2145
+ }));
2266
2146
  }
2267
2147
 
2268
2148
  const internal = {
@@ -2288,7 +2168,6 @@ exports.activated = activated;
2288
2168
  exports.batch = batch;
2289
2169
  exports.beginBatch = beginBatch;
2290
2170
  exports.beginTracking = beginTracking;
2291
- exports.checkActivate = checkActivate;
2292
2171
  exports.computeSelector = computeSelector;
2293
2172
  exports.computed = computed;
2294
2173
  exports.configureLegendState = configureLegendState;
@@ -2316,7 +2195,6 @@ exports.isPrimitive = isPrimitive;
2316
2195
  exports.isPromise = isPromise;
2317
2196
  exports.isString = isString;
2318
2197
  exports.isSymbol = isSymbol;
2319
- exports.lockObservable = lockObservable;
2320
2198
  exports.mergeIntoObservable = mergeIntoObservable;
2321
2199
  exports.observable = observable;
2322
2200
  exports.observablePrimitive = observablePrimitive;