@legendapp/state 1.10.3 → 1.11.1

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.mjs CHANGED
@@ -104,6 +104,7 @@ const globalState = {
104
104
  isLoadingLocal: false,
105
105
  isLoadingRemote: false,
106
106
  isMerging: false,
107
+ noDepWarn: false,
107
108
  };
108
109
  function checkActivate(node) {
109
110
  var _a;
@@ -498,184 +499,14 @@ function afterBatch(fn) {
498
499
  }
499
500
  }
500
501
 
501
- function isObservable(obs) {
502
- return obs && !!obs[symbolGetNode];
503
- }
504
- function isEvent(obs) {
505
- var _a;
506
- return obs && ((_a = obs[symbolGetNode]) === null || _a === void 0 ? void 0 : _a.isEvent);
507
- }
508
- function computeSelector(selector, e, retainObservable) {
509
- let c = selector;
510
- if (isFunction(c)) {
511
- c = e ? c(e) : c();
512
- }
513
- return isObservable(c) && !retainObservable ? c.get() : c;
514
- }
515
- function getObservableIndex(obs) {
516
- const node = getNode(obs);
517
- const n = +node.key;
518
- return n - n < 1 ? +n : -1;
519
- }
520
- function opaqueObject(value) {
521
- if (value) {
522
- value[symbolOpaque] = true;
523
- }
524
- return value;
525
- }
526
- function lockObservable(obs, value) {
527
- var _a;
528
- const root = (_a = getNode(obs)) === null || _a === void 0 ? void 0 : _a.root;
529
- if (root) {
530
- root.locked = value;
531
- }
532
- }
533
- function setAtPath(obj, path, pathTypes, value, fullObj, restore) {
534
- let o = obj;
535
- let oFull = fullObj;
536
- if (path.length > 0) {
537
- for (let i = 0; i < path.length; i++) {
538
- const p = path[i];
539
- if (i === path.length - 1) {
540
- // Don't set if the value is the same. This prevents creating a new key
541
- // when setting undefined on an object without this key
542
- if (o[p] !== value) {
543
- o[p] = value;
544
- }
545
- }
546
- else if (o[p] === symbolDelete) {
547
- // If this was previously deleted, restore it
548
- if (oFull) {
549
- o[p] = oFull[p];
550
- restore === null || restore === void 0 ? void 0 : restore(path.slice(0, i + 1), o[p]);
551
- }
552
- break;
553
- }
554
- else if (o[p] === undefined || o[p] === null) {
555
- o[p] = pathTypes[i] === 'array' ? [] : {};
556
- }
557
- o = o[p];
558
- if (oFull) {
559
- oFull = oFull[p];
560
- }
561
- }
562
- }
563
- else {
564
- obj = value;
565
- }
566
- return obj;
567
- }
568
- function setInObservableAtPath(obs, path, value, mode) {
569
- let o = obs;
570
- let v = value;
571
- for (let i = 0; i < path.length; i++) {
572
- const p = path[i];
573
- o = o[p];
574
- v = v[p];
575
- }
576
- if (v === symbolDelete) {
577
- o.delete();
578
- }
579
- // Assign if possible, or set otherwise
580
- else if (mode === 'assign' && o.assign && isObject(o.peek())) {
581
- o.assign(v);
582
- }
583
- else {
584
- o.set(v);
585
- }
586
- }
587
- function mergeIntoObservable(target, ...sources) {
588
- beginBatch();
589
- globalState.isMerging = true;
590
- const value = _mergeIntoObservable(target, ...sources);
591
- globalState.isMerging = false;
592
- endBatch();
593
- return value;
594
- }
595
- function _mergeIntoObservable(target, ...sources) {
596
- var _a;
597
- if (!sources.length)
598
- return target;
599
- for (let u = 0; u < sources.length; u++) {
600
- const source = sources[u];
601
- const needsSet = isObservable(target);
602
- const targetValue = needsSet ? target.peek() : target;
603
- const isTargetArr = isArray(targetValue);
604
- const isTargetObj = !isTargetArr && isObject(targetValue);
605
- if ((isTargetObj && isObject(source) && !isEmpty(targetValue)) ||
606
- (isTargetArr && isArray(source) && targetValue.length > 0)) {
607
- for (const key in source) {
608
- const sourceValue = source[key];
609
- if (sourceValue === symbolDelete) {
610
- needsSet && ((_a = target[key]) === null || _a === void 0 ? void 0 : _a.delete)
611
- ? target[key].delete()
612
- : delete target[key];
613
- }
614
- else {
615
- const isObj = isObject(sourceValue);
616
- const isArr = !isObj && isArray(sourceValue);
617
- const targetChild = target[key];
618
- if ((isObj || isArr) && targetChild && (needsSet || !isEmpty(targetChild))) {
619
- if (!needsSet && (!targetChild || (isObj ? !isObject(targetChild) : !isArray(targetChild)))) {
620
- target[key] = sourceValue;
621
- }
622
- else {
623
- _mergeIntoObservable(targetChild, sourceValue);
624
- }
625
- }
626
- else {
627
- needsSet
628
- ? targetChild.set(sourceValue)
629
- : (target[key] = sourceValue);
630
- }
631
- }
632
- }
633
- }
634
- else if (source !== undefined) {
635
- needsSet ? target.set(source) : (target = source);
636
- }
637
- }
638
- return target;
639
- }
640
- function constructObjectWithPath(path, value, pathTypes) {
641
- let out;
642
- if (path.length > 0) {
643
- let o = (out = {});
644
- for (let i = 0; i < path.length; i++) {
645
- const p = path[i];
646
- o[p] = i === path.length - 1 ? value : pathTypes[i] === 'array' ? [] : {};
647
- o = o[p];
648
- }
649
- }
650
- else {
651
- out = value;
652
- }
653
- return out;
654
- }
655
- function deconstructObjectWithPath(path, value) {
656
- let o = value;
657
- for (let i = 0; i < path.length; i++) {
658
- const p = path[i];
659
- o = o[p];
660
- }
661
- return o;
662
- }
663
- function isObservableValueReady(value) {
664
- return !!value && ((!isObject(value) && !isArray(value)) || !isEmpty(value));
665
- }
666
- function setSilently(obs, newValue) {
667
- const node = getNode(obs);
668
- return setNodeValue(node, newValue).newValue;
669
- }
670
-
671
502
  function onChange(node, callback, options = {}) {
672
503
  const { initial, immediate, noArgs } = options;
673
504
  let { trackingType } = options;
674
505
  // Temporary migration of string to symbol
675
506
  // TODOV2 remove this
676
507
  if (trackingType === 'optimize') {
677
- if (process.env.NODE_ENV === 'development') {
678
- console.log('[legend-state]: "optimize" prop is deprecated and will be removed in the next major version. Please import { optimize } from "@legendapp/state" and use that instead.');
508
+ if (process.env.NODE_ENV === 'development' && !globalState.noDepWarn) {
509
+ console.warn('[legend-state]: "optimize" prop is deprecated and will be removed in version 2.0. Please import { optimize } from "@legendapp/state" and use that instead.');
679
510
  }
680
511
  trackingType = optimized;
681
512
  }
@@ -719,65 +550,6 @@ function onChange(node, callback, options = {}) {
719
550
  return () => listeners.delete(listener);
720
551
  }
721
552
 
722
- function setupTracking(nodes, update, noArgs, immediate) {
723
- let listeners = [];
724
- // Listen to tracked nodes
725
- nodes === null || nodes === void 0 ? void 0 : nodes.forEach((tracked) => {
726
- const { node, track } = tracked;
727
- listeners.push(onChange(node, update, { trackingType: track, immediate, noArgs }));
728
- });
729
- return () => {
730
- if (listeners) {
731
- for (let i = 0; i < listeners.length; i++) {
732
- listeners[i]();
733
- }
734
- listeners = undefined;
735
- }
736
- };
737
- }
738
-
739
- function trackSelector(selector, update, observeEvent, observeOptions, createResubscribe, inRender) {
740
- var _a;
741
- let nodes;
742
- let value;
743
- let dispose;
744
- let tracker;
745
- let resubscribe;
746
- let updateFn = update;
747
- let noArgs = true;
748
- if (isObservable(selector)) {
749
- value = selector.peek();
750
- dispose = selector.onChange(update, { noArgs: true });
751
- resubscribe = createResubscribe ? selector.onChange(update, { noArgs: true }) : undefined;
752
- }
753
- else {
754
- // Compute the selector inside a tracking context
755
- beginTracking(inRender);
756
- value = selector ? computeSelector(selector, observeEvent, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.retainObservable) : selector;
757
- tracker = tracking.current;
758
- nodes = tracker.nodes;
759
- endTracking(inRender);
760
- if ((process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') && tracker && nodes) {
761
- (_a = tracker.traceListeners) === null || _a === void 0 ? void 0 : _a.call(tracker, nodes);
762
- if (tracker.traceUpdates) {
763
- noArgs = false;
764
- updateFn = tracker.traceUpdates(update);
765
- }
766
- // Clear tracing so it doesn't leak to other components
767
- tracker.traceListeners = undefined;
768
- tracker.traceUpdates = undefined;
769
- }
770
- }
771
- if (!(observeEvent === null || observeEvent === void 0 ? void 0 : observeEvent.cancel)) {
772
- // Do tracing if it was requested
773
- // useSyncExternalStore doesn't subscribe until after the component mount.
774
- // We want to subscribe immediately so we don't miss any updates
775
- dispose = setupTracking(nodes, updateFn, noArgs, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.immediate);
776
- resubscribe = createResubscribe ? () => setupTracking(nodes, updateFn, noArgs) : undefined;
777
- }
778
- return { value, dispose, resubscribe };
779
- }
780
-
781
553
  const ArrayModifiers = new Set([
782
554
  'copyWithin',
783
555
  'fill',
@@ -1386,29 +1158,199 @@ function updateNodesAndNotify(node, newValue, prevValue, childNode, isPrim, isRo
1386
1158
  endBatch();
1387
1159
  }
1388
1160
 
1389
- const fns = ['get', 'set', 'peek', 'onChange', 'toggle'];
1390
- function ObservablePrimitiveClass(node) {
1391
- this._node = node;
1392
- // Bind to this
1393
- for (let i = 0; i < fns.length; i++) {
1394
- const key = fns[i];
1395
- this[key] = this[key].bind(this);
1396
- }
1161
+ function isObservable(obs) {
1162
+ return obs && !!obs[symbolGetNode];
1397
1163
  }
1398
- // Add observable functions to prototype
1399
- function proto(key, fn) {
1400
- ObservablePrimitiveClass.prototype[key] = function (...args) {
1401
- return fn.call(this, this._node, ...args);
1402
- };
1164
+ function isEvent(obs) {
1165
+ var _a;
1166
+ return obs && ((_a = obs[symbolGetNode]) === null || _a === void 0 ? void 0 : _a.isEvent);
1403
1167
  }
1404
- proto('peek', peek);
1405
- proto('get', get);
1406
- proto('set', set);
1407
- proto('onChange', onChange);
1408
- // Getters
1409
- Object.defineProperty(ObservablePrimitiveClass.prototype, symbolGetNode, {
1410
- configurable: true,
1411
- get() {
1168
+ function computeSelector(selector, e, retainObservable) {
1169
+ let c = selector;
1170
+ if (isFunction(c)) {
1171
+ c = e ? c(e) : c();
1172
+ }
1173
+ return isObservable(c) && !retainObservable ? c.get() : c;
1174
+ }
1175
+ function getObservableIndex(obs) {
1176
+ const node = getNode(obs);
1177
+ const n = +node.key;
1178
+ return n - n < 1 ? +n : -1;
1179
+ }
1180
+ function opaqueObject(value) {
1181
+ if (value) {
1182
+ value[symbolOpaque] = true;
1183
+ }
1184
+ return value;
1185
+ }
1186
+ function lockObservable(obs, value) {
1187
+ var _a;
1188
+ const root = (_a = getNode(obs)) === null || _a === void 0 ? void 0 : _a.root;
1189
+ if (root) {
1190
+ root.locked = value;
1191
+ }
1192
+ }
1193
+ function setAtPath(obj, path, pathTypes, value, fullObj, restore) {
1194
+ let o = obj;
1195
+ let oFull = fullObj;
1196
+ if (path.length > 0) {
1197
+ for (let i = 0; i < path.length; i++) {
1198
+ const p = path[i];
1199
+ if (i === path.length - 1) {
1200
+ // Don't set if the value is the same. This prevents creating a new key
1201
+ // when setting undefined on an object without this key
1202
+ if (o[p] !== value) {
1203
+ o[p] = value;
1204
+ }
1205
+ }
1206
+ else if (o[p] === symbolDelete) {
1207
+ // If this was previously deleted, restore it
1208
+ if (oFull) {
1209
+ o[p] = oFull[p];
1210
+ restore === null || restore === void 0 ? void 0 : restore(path.slice(0, i + 1), o[p]);
1211
+ }
1212
+ break;
1213
+ }
1214
+ else if (o[p] === undefined || o[p] === null) {
1215
+ o[p] = pathTypes[i] === 'array' ? [] : {};
1216
+ }
1217
+ o = o[p];
1218
+ if (oFull) {
1219
+ oFull = oFull[p];
1220
+ }
1221
+ }
1222
+ }
1223
+ else {
1224
+ obj = value;
1225
+ }
1226
+ return obj;
1227
+ }
1228
+ function setInObservableAtPath(obs, path, value, mode) {
1229
+ let o = obs;
1230
+ let v = value;
1231
+ for (let i = 0; i < path.length; i++) {
1232
+ const p = path[i];
1233
+ o = o[p];
1234
+ v = v[p];
1235
+ }
1236
+ if (v === symbolDelete) {
1237
+ o.delete();
1238
+ }
1239
+ // Assign if possible, or set otherwise
1240
+ else if (mode === 'assign' && o.assign && isObject(o.peek())) {
1241
+ o.assign(v);
1242
+ }
1243
+ else {
1244
+ o.set(v);
1245
+ }
1246
+ }
1247
+ function mergeIntoObservable(target, ...sources) {
1248
+ beginBatch();
1249
+ globalState.isMerging = true;
1250
+ const value = _mergeIntoObservable(target, ...sources);
1251
+ globalState.isMerging = false;
1252
+ endBatch();
1253
+ return value;
1254
+ }
1255
+ function _mergeIntoObservable(target, ...sources) {
1256
+ var _a;
1257
+ if (!sources.length)
1258
+ return target;
1259
+ for (let u = 0; u < sources.length; u++) {
1260
+ const source = sources[u];
1261
+ const needsSet = isObservable(target);
1262
+ const targetValue = needsSet ? target.peek() : target;
1263
+ const isTargetArr = isArray(targetValue);
1264
+ const isTargetObj = !isTargetArr && isObject(targetValue);
1265
+ if ((isTargetObj && isObject(source) && !isEmpty(targetValue)) ||
1266
+ (isTargetArr && isArray(source) && targetValue.length > 0)) {
1267
+ for (const key in source) {
1268
+ const sourceValue = source[key];
1269
+ if (sourceValue === symbolDelete) {
1270
+ needsSet && ((_a = target[key]) === null || _a === void 0 ? void 0 : _a.delete)
1271
+ ? target[key].delete()
1272
+ : delete target[key];
1273
+ }
1274
+ else {
1275
+ const isObj = isObject(sourceValue);
1276
+ const isArr = !isObj && isArray(sourceValue);
1277
+ const targetChild = target[key];
1278
+ if ((isObj || isArr) && targetChild && (needsSet || !isEmpty(targetChild))) {
1279
+ if (!needsSet && (!targetChild || (isObj ? !isObject(targetChild) : !isArray(targetChild)))) {
1280
+ target[key] = sourceValue;
1281
+ }
1282
+ else {
1283
+ _mergeIntoObservable(targetChild, sourceValue);
1284
+ }
1285
+ }
1286
+ else {
1287
+ needsSet
1288
+ ? targetChild.set(sourceValue)
1289
+ : (target[key] = sourceValue);
1290
+ }
1291
+ }
1292
+ }
1293
+ }
1294
+ else if (source !== undefined) {
1295
+ needsSet ? target.set(source) : (target = source);
1296
+ }
1297
+ }
1298
+ return target;
1299
+ }
1300
+ function constructObjectWithPath(path, value, pathTypes) {
1301
+ let out;
1302
+ if (path.length > 0) {
1303
+ let o = (out = {});
1304
+ for (let i = 0; i < path.length; i++) {
1305
+ const p = path[i];
1306
+ o[p] = i === path.length - 1 ? value : pathTypes[i] === 'array' ? [] : {};
1307
+ o = o[p];
1308
+ }
1309
+ }
1310
+ else {
1311
+ out = value;
1312
+ }
1313
+ return out;
1314
+ }
1315
+ function deconstructObjectWithPath(path, value) {
1316
+ let o = value;
1317
+ for (let i = 0; i < path.length; i++) {
1318
+ const p = path[i];
1319
+ o = o[p];
1320
+ }
1321
+ return o;
1322
+ }
1323
+ function isObservableValueReady(value) {
1324
+ return !!value && ((!isObject(value) && !isArray(value)) || !isEmpty(value));
1325
+ }
1326
+ function setSilently(obs, newValue) {
1327
+ const node = getNode(obs);
1328
+ return setNodeValue(node, newValue).newValue;
1329
+ }
1330
+
1331
+ const fns = ['get', 'set', 'peek', 'onChange', 'toggle'];
1332
+ function ObservablePrimitiveClass(node) {
1333
+ this._node = node;
1334
+ // Bind to this
1335
+ for (let i = 0; i < fns.length; i++) {
1336
+ const key = fns[i];
1337
+ this[key] = this[key].bind(this);
1338
+ }
1339
+ }
1340
+ // Add observable functions to prototype
1341
+ function proto(key, fn) {
1342
+ ObservablePrimitiveClass.prototype[key] = function (...args) {
1343
+ return fn.call(this, this._node, ...args);
1344
+ };
1345
+ }
1346
+ proto('peek', peek);
1347
+ proto('get', get);
1348
+ proto('set', set);
1349
+ proto('onChange', onChange);
1350
+ // Getters
1351
+ Object.defineProperty(ObservablePrimitiveClass.prototype, symbolGetNode, {
1352
+ configurable: true,
1353
+ get() {
1412
1354
  return this._node;
1413
1355
  },
1414
1356
  });
@@ -1464,6 +1406,65 @@ function observablePrimitive(value) {
1464
1406
  return createObservable(value, /*makePrimitive*/ true);
1465
1407
  }
1466
1408
 
1409
+ function setupTracking(nodes, update, noArgs, immediate) {
1410
+ let listeners = [];
1411
+ // Listen to tracked nodes
1412
+ nodes === null || nodes === void 0 ? void 0 : nodes.forEach((tracked) => {
1413
+ const { node, track } = tracked;
1414
+ listeners.push(onChange(node, update, { trackingType: track, immediate, noArgs }));
1415
+ });
1416
+ return () => {
1417
+ if (listeners) {
1418
+ for (let i = 0; i < listeners.length; i++) {
1419
+ listeners[i]();
1420
+ }
1421
+ listeners = undefined;
1422
+ }
1423
+ };
1424
+ }
1425
+
1426
+ function trackSelector(selector, update, observeEvent, observeOptions, createResubscribe, inRender) {
1427
+ var _a;
1428
+ let nodes;
1429
+ let value;
1430
+ let dispose;
1431
+ let tracker;
1432
+ let resubscribe;
1433
+ let updateFn = update;
1434
+ let noArgs = true;
1435
+ if (isObservable(selector)) {
1436
+ value = selector.peek();
1437
+ dispose = selector.onChange(update, { noArgs: true });
1438
+ resubscribe = createResubscribe ? selector.onChange(update, { noArgs: true }) : undefined;
1439
+ }
1440
+ else {
1441
+ // Compute the selector inside a tracking context
1442
+ beginTracking(inRender);
1443
+ value = selector ? computeSelector(selector, observeEvent, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.retainObservable) : selector;
1444
+ tracker = tracking.current;
1445
+ nodes = tracker.nodes;
1446
+ endTracking(inRender);
1447
+ if ((process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') && tracker && nodes) {
1448
+ (_a = tracker.traceListeners) === null || _a === void 0 ? void 0 : _a.call(tracker, nodes);
1449
+ if (tracker.traceUpdates) {
1450
+ noArgs = false;
1451
+ updateFn = tracker.traceUpdates(update);
1452
+ }
1453
+ // Clear tracing so it doesn't leak to other components
1454
+ tracker.traceListeners = undefined;
1455
+ tracker.traceUpdates = undefined;
1456
+ }
1457
+ }
1458
+ if (!(observeEvent === null || observeEvent === void 0 ? void 0 : observeEvent.cancel)) {
1459
+ // Do tracing if it was requested
1460
+ // useSyncExternalStore doesn't subscribe until after the component mount.
1461
+ // We want to subscribe immediately so we don't miss any updates
1462
+ dispose = setupTracking(nodes, updateFn, noArgs, observeOptions === null || observeOptions === void 0 ? void 0 : observeOptions.immediate);
1463
+ resubscribe = createResubscribe ? () => setupTracking(nodes, updateFn, noArgs) : undefined;
1464
+ }
1465
+ return { value, dispose, resubscribe };
1466
+ }
1467
+
1467
1468
  function observe(selectorOrRun, reactionOrOptions, options) {
1468
1469
  let reaction;
1469
1470
  if (isFunction(reactionOrOptions)) {
@@ -1598,6 +1599,33 @@ function computed(compute, set$1) {
1598
1599
  return obs;
1599
1600
  }
1600
1601
 
1602
+ function configureLegendState({ observableFunctions, observableProperties: observableProperties$1, }) {
1603
+ if (observableFunctions) {
1604
+ for (const key in observableFunctions) {
1605
+ const fn = observableFunctions[key];
1606
+ observableFns.set(key, fn);
1607
+ ObservablePrimitiveClass.prototype[key] = function (...args) {
1608
+ return fn.call(this, this._node, ...args);
1609
+ };
1610
+ }
1611
+ }
1612
+ if (observableProperties$1) {
1613
+ for (const key in observableProperties$1) {
1614
+ const fns = observableProperties$1[key];
1615
+ observableProperties.set(key, fns);
1616
+ Object.defineProperty(ObservablePrimitiveClass.prototype, key, {
1617
+ configurable: true,
1618
+ get() {
1619
+ return fns.get.call(this, this._node);
1620
+ },
1621
+ set(value) {
1622
+ return fns.set.call(this, this._node, value);
1623
+ },
1624
+ });
1625
+ }
1626
+ }
1627
+ }
1628
+
1601
1629
  function event() {
1602
1630
  // event simply wraps around a number observable
1603
1631
  // which increments its value to dispatch change events
@@ -1694,33 +1722,6 @@ function whenReady(predicate, effect) {
1694
1722
  return _when(predicate, effect, true);
1695
1723
  }
1696
1724
 
1697
- function configureLegendState({ observableFunctions, observableProperties: observableProperties$1, }) {
1698
- if (observableFunctions) {
1699
- for (const key in observableFunctions) {
1700
- const fn = observableFunctions[key];
1701
- observableFns.set(key, fn);
1702
- ObservablePrimitiveClass.prototype[key] = function (...args) {
1703
- return fn.call(this, this._node, ...args);
1704
- };
1705
- }
1706
- }
1707
- if (observableProperties$1) {
1708
- for (const key in observableProperties$1) {
1709
- const fns = observableProperties$1[key];
1710
- observableProperties.set(key, fns);
1711
- Object.defineProperty(ObservablePrimitiveClass.prototype, key, {
1712
- configurable: true,
1713
- get() {
1714
- return fns.get.call(this, this._node);
1715
- },
1716
- set(value) {
1717
- return fns.set.call(this, this._node, value);
1718
- },
1719
- });
1720
- }
1721
- }
1722
- }
1723
-
1724
1725
  const internal = {
1725
1726
  ensureNodeValue,
1726
1727
  findIDKey,