@legendapp/state 1.10.2 → 1.11.0

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