@legendapp/state 2.0.0-next.3 → 2.0.0-next.4
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 +138 -145
- package/index.js.map +1 -1
- package/index.mjs +138 -145
- package/index.mjs.map +1 -1
- package/package.json +1 -1
- package/persist.js.map +1 -1
- package/persist.mjs.map +1 -1
- package/react.js +7 -2
- package/react.js.map +1 -1
- package/react.mjs +7 -2
- package/react.mjs.map +1 -1
- package/src/ObservableObject.d.ts +3 -0
- package/src/globals.d.ts +1 -0
- package/src/observable.d.ts +0 -3
- package/src/observableInterfaces.d.ts +1 -2
package/index.js
CHANGED
|
@@ -163,7 +163,7 @@ function setNodeValue(node, newValue) {
|
|
|
163
163
|
if (parentNode.root.locked && parentNode.root.set) {
|
|
164
164
|
parentNode.root.set(parentNode.root._);
|
|
165
165
|
}
|
|
166
|
-
return { prevValue, newValue };
|
|
166
|
+
return { prevValue, newValue, parentValue };
|
|
167
167
|
}
|
|
168
168
|
const arrNodeKeys = [];
|
|
169
169
|
function getNodeValue(node) {
|
|
@@ -573,55 +573,50 @@ function setInObservableAtPath(obs, path, value, mode) {
|
|
|
573
573
|
function mergeIntoObservable(target, ...sources) {
|
|
574
574
|
beginBatch();
|
|
575
575
|
globalState.isMerging = true;
|
|
576
|
-
|
|
576
|
+
for (let i = 0; i < sources.length; i++) {
|
|
577
|
+
target = _mergeIntoObservable(target, sources[i]);
|
|
578
|
+
}
|
|
577
579
|
globalState.isMerging = false;
|
|
578
580
|
endBatch();
|
|
579
|
-
return
|
|
581
|
+
return target;
|
|
580
582
|
}
|
|
581
|
-
function _mergeIntoObservable(target,
|
|
583
|
+
function _mergeIntoObservable(target, source) {
|
|
582
584
|
var _a;
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
const
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
const targetChild = target[key];
|
|
604
|
-
if ((isObj || isArr) && targetChild && (needsSet || !isEmpty(targetChild))) {
|
|
605
|
-
if (!needsSet && (!targetChild || (isObj ? !isObject(targetChild) : !isArray(targetChild)))) {
|
|
606
|
-
target[key] = sourceValue;
|
|
607
|
-
}
|
|
608
|
-
else {
|
|
609
|
-
_mergeIntoObservable(targetChild, sourceValue);
|
|
610
|
-
}
|
|
585
|
+
const needsSet = isObservable(target);
|
|
586
|
+
const targetValue = needsSet ? target.peek() : target;
|
|
587
|
+
const isTargetArr = isArray(targetValue);
|
|
588
|
+
const isTargetObj = !isTargetArr && isObject(targetValue);
|
|
589
|
+
if ((isTargetObj && isObject(source) && !isEmpty(targetValue)) ||
|
|
590
|
+
(isTargetArr && isArray(source) && targetValue.length > 0)) {
|
|
591
|
+
const keys = Object.keys(source);
|
|
592
|
+
for (let i = 0; i < keys.length; i++) {
|
|
593
|
+
const key = keys[i];
|
|
594
|
+
const sourceValue = source[key];
|
|
595
|
+
if (sourceValue === symbolDelete) {
|
|
596
|
+
needsSet && ((_a = target[key]) === null || _a === void 0 ? void 0 : _a.delete) ? target[key].delete() : delete target[key];
|
|
597
|
+
}
|
|
598
|
+
else {
|
|
599
|
+
const isObj = isObject(sourceValue);
|
|
600
|
+
const isArr = !isObj && isArray(sourceValue);
|
|
601
|
+
const targetChild = target[key];
|
|
602
|
+
if ((isObj || isArr) && targetChild && (needsSet || !isEmpty(targetChild))) {
|
|
603
|
+
if (!needsSet && (!targetChild || (isObj ? !isObject(targetChild) : !isArray(targetChild)))) {
|
|
604
|
+
target[key] = sourceValue;
|
|
611
605
|
}
|
|
612
606
|
else {
|
|
613
|
-
|
|
614
|
-
// It would be good to track down why that was happening and remove this check.
|
|
615
|
-
needsSet && isFunction(targetChild.set)
|
|
616
|
-
? targetChild.set(sourceValue)
|
|
617
|
-
: (target[key] = sourceValue);
|
|
607
|
+
_mergeIntoObservable(targetChild, sourceValue);
|
|
618
608
|
}
|
|
619
609
|
}
|
|
610
|
+
else {
|
|
611
|
+
needsSet
|
|
612
|
+
? targetChild.set(sourceValue)
|
|
613
|
+
: (target[key] = sourceValue);
|
|
614
|
+
}
|
|
620
615
|
}
|
|
621
616
|
}
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
617
|
+
}
|
|
618
|
+
else if (source !== undefined) {
|
|
619
|
+
needsSet ? target.set(source) : (target = source);
|
|
625
620
|
}
|
|
626
621
|
return target;
|
|
627
622
|
}
|
|
@@ -684,11 +679,6 @@ function onChange(node, callback, options = {}) {
|
|
|
684
679
|
noArgs,
|
|
685
680
|
};
|
|
686
681
|
listeners.add(listener);
|
|
687
|
-
let parent = node.parent;
|
|
688
|
-
while (parent && !parent.descendantHasListener) {
|
|
689
|
-
parent.descendantHasListener = true;
|
|
690
|
-
parent = parent.parent;
|
|
691
|
-
}
|
|
692
682
|
if (initial) {
|
|
693
683
|
const value = getNodeValue(node);
|
|
694
684
|
callback({
|
|
@@ -917,75 +907,74 @@ function updateNodes(parent, obj, prevValue) {
|
|
|
917
907
|
hasADiff = hasADiff || (keys === null || keys === void 0 ? void 0 : keys.length) !== (keysPrev === null || keysPrev === void 0 ? void 0 : keysPrev.length);
|
|
918
908
|
const isArrDiff = hasADiff;
|
|
919
909
|
let didMove = false;
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
}
|
|
943
|
-
else if (prevChild !== undefined && prevChild.key !== key) {
|
|
944
|
-
const valuePrevChild = prevValue[prevChild.key];
|
|
945
|
-
// If array length changed then move the original node to the current position.
|
|
946
|
-
// That should be faster than notifying every single element that
|
|
947
|
-
// it's in a new position.
|
|
948
|
-
if (isArrDiff) {
|
|
949
|
-
child = prevChild;
|
|
950
|
-
parent.children.delete(child.key);
|
|
951
|
-
child.key = key;
|
|
952
|
-
moved.push([key, child]);
|
|
953
|
-
}
|
|
954
|
-
didMove = true;
|
|
955
|
-
// And check for diff against the previous value in the previous position
|
|
956
|
-
isDiff = valuePrevChild !== value;
|
|
957
|
-
}
|
|
910
|
+
for (let i = 0; i < length; i++) {
|
|
911
|
+
const key = keys[i];
|
|
912
|
+
const value = isMap ? obj.get(key) : obj[key];
|
|
913
|
+
const prev = isMap ? prevValue === null || prevValue === void 0 ? void 0 : prevValue.get(key) : prevValue === null || prevValue === void 0 ? void 0 : prevValue[key];
|
|
914
|
+
let isDiff = value !== prev;
|
|
915
|
+
if (isDiff) {
|
|
916
|
+
extractFunctionOrComputed(parent, obj, key, value);
|
|
917
|
+
const id = idField && value
|
|
918
|
+
? isIdFieldFunction
|
|
919
|
+
? idField(value)
|
|
920
|
+
: value[idField]
|
|
921
|
+
: undefined;
|
|
922
|
+
let child = getChildNode(parent, key);
|
|
923
|
+
// Detect moves within an array. Need to move the original proxy to the new position to keep
|
|
924
|
+
// the proxy stable, so that listeners to this node will be unaffected by the array shift.
|
|
925
|
+
if (isArr && id !== undefined) {
|
|
926
|
+
// Find the previous position of this element in the array
|
|
927
|
+
const prevChild = id !== undefined ? prevChildrenById === null || prevChildrenById === void 0 ? void 0 : prevChildrenById.get(id) : undefined;
|
|
928
|
+
if (!prevChild) {
|
|
929
|
+
// This id was not in the array before so it does not need to notify children
|
|
930
|
+
isDiff = false;
|
|
931
|
+
hasADiff = true;
|
|
958
932
|
}
|
|
959
|
-
if (
|
|
960
|
-
|
|
961
|
-
// If
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
933
|
+
else if (prevChild !== undefined && prevChild.key !== key) {
|
|
934
|
+
const valuePrevChild = prevValue[prevChild.key];
|
|
935
|
+
// If array length changed then move the original node to the current position.
|
|
936
|
+
// That should be faster than notifying every single element that
|
|
937
|
+
// it's in a new position.
|
|
938
|
+
if (isArrDiff) {
|
|
939
|
+
child = prevChild;
|
|
940
|
+
parent.children.delete(child.key);
|
|
941
|
+
child.key = key;
|
|
942
|
+
moved.push([key, child]);
|
|
969
943
|
}
|
|
944
|
+
didMove = true;
|
|
945
|
+
// And check for diff against the previous value in the previous position
|
|
946
|
+
isDiff = valuePrevChild !== value;
|
|
970
947
|
}
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
948
|
+
}
|
|
949
|
+
if (isDiff) {
|
|
950
|
+
// Array has a new / modified element
|
|
951
|
+
// If object iterate through its children
|
|
952
|
+
if (isPrimitive(value)) {
|
|
953
|
+
hasADiff = true;
|
|
954
|
+
}
|
|
955
|
+
else {
|
|
956
|
+
// Always need to updateNodes so we notify through all children
|
|
957
|
+
const updatedNodes = updateNodes(child, value, prev);
|
|
958
|
+
hasADiff = hasADiff || updatedNodes;
|
|
979
959
|
}
|
|
980
960
|
}
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
961
|
+
if (isDiff || !isArrDiff) {
|
|
962
|
+
// Notify for this child if this element is different and it has listeners
|
|
963
|
+
// Or if the position changed in an array whose length did not change
|
|
964
|
+
// But do not notify child if the parent is an array with changing length -
|
|
965
|
+
// the array's listener will cover it
|
|
966
|
+
if (child.listeners || child.listenersImmediate) {
|
|
967
|
+
notify(child, value, prev, 0, !isArrDiff);
|
|
968
|
+
}
|
|
986
969
|
}
|
|
987
970
|
}
|
|
988
971
|
}
|
|
972
|
+
if (moved) {
|
|
973
|
+
for (let i = 0; i < moved.length; i++) {
|
|
974
|
+
const [key, child] = moved[i];
|
|
975
|
+
parent.children.set(key, child);
|
|
976
|
+
}
|
|
977
|
+
}
|
|
989
978
|
// The full array does not need to re-render if the length is the same
|
|
990
979
|
// So don't notify shallow listeners
|
|
991
980
|
retValue = hasADiff || didMove;
|
|
@@ -1198,10 +1187,7 @@ const proxyHandler = {
|
|
|
1198
1187
|
},
|
|
1199
1188
|
};
|
|
1200
1189
|
function set(node, newValue) {
|
|
1201
|
-
if (
|
|
1202
|
-
newValue.then((v) => set(node, v)).catch((error) => set(node, { error }));
|
|
1203
|
-
}
|
|
1204
|
-
else if (node.parent) {
|
|
1190
|
+
if (node.parent) {
|
|
1205
1191
|
return setKey(node.parent, node.key, newValue);
|
|
1206
1192
|
}
|
|
1207
1193
|
else {
|
|
@@ -1241,12 +1227,13 @@ function setKey(node, key, newValue, level) {
|
|
|
1241
1227
|
// Get the child node for updating and notifying
|
|
1242
1228
|
const childNode = isRoot ? node : getChildNode(node, key);
|
|
1243
1229
|
// Set the raw value on the parent object
|
|
1244
|
-
const { newValue: savedValue, prevValue } = setNodeValue(childNode, newValue);
|
|
1245
|
-
const isFunc = isFunction(
|
|
1230
|
+
const { newValue: savedValue, prevValue, parentValue } = setNodeValue(childNode, newValue);
|
|
1231
|
+
const isFunc = isFunction(savedValue);
|
|
1246
1232
|
const isPrim = isPrimitive(savedValue) || savedValue instanceof Date;
|
|
1247
1233
|
if (savedValue !== prevValue) {
|
|
1248
1234
|
updateNodesAndNotify(node, savedValue, prevValue, childNode, isPrim, isRoot, level);
|
|
1249
1235
|
}
|
|
1236
|
+
extractFunctionOrComputed(node, parentValue, key, newValue);
|
|
1250
1237
|
return isFunc ? savedValue : isRoot ? getProxy(node) : getProxy(node, key);
|
|
1251
1238
|
}
|
|
1252
1239
|
function assign(node, value) {
|
|
@@ -1372,13 +1359,48 @@ function updateNodesAndNotify(node, newValue, prevValue, childNode, isPrim, isRo
|
|
|
1372
1359
|
}
|
|
1373
1360
|
function extractPromise(node, value) {
|
|
1374
1361
|
value.status = 'pending';
|
|
1375
|
-
value
|
|
1376
|
-
|
|
1377
|
-
});
|
|
1378
|
-
value.then((value) => {
|
|
1362
|
+
value
|
|
1363
|
+
.then((value) => {
|
|
1379
1364
|
set(node, value);
|
|
1365
|
+
})
|
|
1366
|
+
.catch((error) => {
|
|
1367
|
+
set(node, { error, status: 'rejected' });
|
|
1380
1368
|
});
|
|
1381
1369
|
}
|
|
1370
|
+
const __devExtractFunctionsAndComputedsNodes = process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test' ? new Set() : undefined;
|
|
1371
|
+
function extractFunctionOrComputed(node, obj, k, v) {
|
|
1372
|
+
if (isPromise(v)) {
|
|
1373
|
+
extractPromise(getChildNode(node, k), v);
|
|
1374
|
+
}
|
|
1375
|
+
else if (typeof v === 'function') {
|
|
1376
|
+
extractFunction(node, k, v);
|
|
1377
|
+
}
|
|
1378
|
+
else if (typeof v == 'object' && v !== null && v !== undefined) {
|
|
1379
|
+
const childNode = getNode(v);
|
|
1380
|
+
if (childNode === null || childNode === void 0 ? void 0 : childNode.isComputed) {
|
|
1381
|
+
extractFunction(node, k, v, childNode);
|
|
1382
|
+
delete obj[k];
|
|
1383
|
+
}
|
|
1384
|
+
else {
|
|
1385
|
+
return true;
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
function extractFunctionsAndComputeds(node, obj) {
|
|
1390
|
+
if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
|
|
1391
|
+
if (__devExtractFunctionsAndComputedsNodes.has(obj)) {
|
|
1392
|
+
console.error('[legend-state] Circular reference detected in object. You may want to use opaqueObject to stop traversing child nodes.', obj);
|
|
1393
|
+
return false;
|
|
1394
|
+
}
|
|
1395
|
+
__devExtractFunctionsAndComputedsNodes.add(obj);
|
|
1396
|
+
}
|
|
1397
|
+
for (const k in obj) {
|
|
1398
|
+
const v = obj[k];
|
|
1399
|
+
if (v && extractFunctionOrComputed(node, obj, k, v) && !v[symbolOpaque]) {
|
|
1400
|
+
extractFunctionsAndComputeds(getChildNode(node, k), v);
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1382
1404
|
|
|
1383
1405
|
const fns = ['get', 'set', 'peek', 'onChange', 'toggle'];
|
|
1384
1406
|
function ObservablePrimitiveClass(node) {
|
|
@@ -1421,35 +1443,6 @@ ObservablePrimitiveClass.prototype.delete = function () {
|
|
|
1421
1443
|
return this;
|
|
1422
1444
|
};
|
|
1423
1445
|
|
|
1424
|
-
const __devExtractFunctionsAndComputedsNodes = process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test' ? new Set() : undefined;
|
|
1425
|
-
function extractFunctionsAndComputeds(node, obj) {
|
|
1426
|
-
if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
|
|
1427
|
-
if (__devExtractFunctionsAndComputedsNodes.has(obj)) {
|
|
1428
|
-
console.error('[legend-state] Circular reference detected in object. You may want to use opaqueObject to stop traversing child nodes.', obj);
|
|
1429
|
-
return false;
|
|
1430
|
-
}
|
|
1431
|
-
__devExtractFunctionsAndComputedsNodes.add(obj);
|
|
1432
|
-
}
|
|
1433
|
-
for (const k in obj) {
|
|
1434
|
-
const v = obj[k];
|
|
1435
|
-
if (isPromise(v)) {
|
|
1436
|
-
extractPromise(getChildNode(node, k), v);
|
|
1437
|
-
}
|
|
1438
|
-
else if (typeof v === 'function') {
|
|
1439
|
-
extractFunction(node, k, v);
|
|
1440
|
-
}
|
|
1441
|
-
else if (typeof v == 'object' && v !== null && v !== undefined) {
|
|
1442
|
-
const childNode = getNode(v);
|
|
1443
|
-
if (childNode === null || childNode === void 0 ? void 0 : childNode.isComputed) {
|
|
1444
|
-
extractFunction(node, k, v, childNode);
|
|
1445
|
-
delete obj[k];
|
|
1446
|
-
}
|
|
1447
|
-
else if (!v[symbolOpaque]) {
|
|
1448
|
-
extractFunctionsAndComputeds(getChildNode(node, k), obj[k]);
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
|
-
}
|
|
1452
|
-
}
|
|
1453
1446
|
function createObservable(value, makePrimitive) {
|
|
1454
1447
|
const valueIsPromise = isPromise(value);
|
|
1455
1448
|
const root = {
|