@legendapp/state 2.0.0-next.2 → 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 -143
- package/index.js.map +1 -1
- package/index.mjs +138 -143
- 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,53 +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
|
-
? targetChild.set(sourceValue)
|
|
615
|
-
: (target[key] = sourceValue);
|
|
607
|
+
_mergeIntoObservable(targetChild, sourceValue);
|
|
616
608
|
}
|
|
617
609
|
}
|
|
610
|
+
else {
|
|
611
|
+
needsSet
|
|
612
|
+
? targetChild.set(sourceValue)
|
|
613
|
+
: (target[key] = sourceValue);
|
|
614
|
+
}
|
|
618
615
|
}
|
|
619
616
|
}
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
617
|
+
}
|
|
618
|
+
else if (source !== undefined) {
|
|
619
|
+
needsSet ? target.set(source) : (target = source);
|
|
623
620
|
}
|
|
624
621
|
return target;
|
|
625
622
|
}
|
|
@@ -682,11 +679,6 @@ function onChange(node, callback, options = {}) {
|
|
|
682
679
|
noArgs,
|
|
683
680
|
};
|
|
684
681
|
listeners.add(listener);
|
|
685
|
-
let parent = node.parent;
|
|
686
|
-
while (parent && !parent.descendantHasListener) {
|
|
687
|
-
parent.descendantHasListener = true;
|
|
688
|
-
parent = parent.parent;
|
|
689
|
-
}
|
|
690
682
|
if (initial) {
|
|
691
683
|
const value = getNodeValue(node);
|
|
692
684
|
callback({
|
|
@@ -915,75 +907,74 @@ function updateNodes(parent, obj, prevValue) {
|
|
|
915
907
|
hasADiff = hasADiff || (keys === null || keys === void 0 ? void 0 : keys.length) !== (keysPrev === null || keysPrev === void 0 ? void 0 : keysPrev.length);
|
|
916
908
|
const isArrDiff = hasADiff;
|
|
917
909
|
let didMove = false;
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
}
|
|
941
|
-
else if (prevChild !== undefined && prevChild.key !== key) {
|
|
942
|
-
const valuePrevChild = prevValue[prevChild.key];
|
|
943
|
-
// If array length changed then move the original node to the current position.
|
|
944
|
-
// That should be faster than notifying every single element that
|
|
945
|
-
// it's in a new position.
|
|
946
|
-
if (isArrDiff) {
|
|
947
|
-
child = prevChild;
|
|
948
|
-
parent.children.delete(child.key);
|
|
949
|
-
child.key = key;
|
|
950
|
-
moved.push([key, child]);
|
|
951
|
-
}
|
|
952
|
-
didMove = true;
|
|
953
|
-
// And check for diff against the previous value in the previous position
|
|
954
|
-
isDiff = valuePrevChild !== value;
|
|
955
|
-
}
|
|
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;
|
|
956
932
|
}
|
|
957
|
-
if (
|
|
958
|
-
|
|
959
|
-
// If
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
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]);
|
|
967
943
|
}
|
|
944
|
+
didMove = true;
|
|
945
|
+
// And check for diff against the previous value in the previous position
|
|
946
|
+
isDiff = valuePrevChild !== value;
|
|
968
947
|
}
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
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;
|
|
977
959
|
}
|
|
978
960
|
}
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
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
|
+
}
|
|
984
969
|
}
|
|
985
970
|
}
|
|
986
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
|
+
}
|
|
987
978
|
// The full array does not need to re-render if the length is the same
|
|
988
979
|
// So don't notify shallow listeners
|
|
989
980
|
retValue = hasADiff || didMove;
|
|
@@ -1196,10 +1187,7 @@ const proxyHandler = {
|
|
|
1196
1187
|
},
|
|
1197
1188
|
};
|
|
1198
1189
|
function set(node, newValue) {
|
|
1199
|
-
if (
|
|
1200
|
-
newValue.then((v) => set(node, v)).catch((error) => set(node, { error }));
|
|
1201
|
-
}
|
|
1202
|
-
else if (node.parent) {
|
|
1190
|
+
if (node.parent) {
|
|
1203
1191
|
return setKey(node.parent, node.key, newValue);
|
|
1204
1192
|
}
|
|
1205
1193
|
else {
|
|
@@ -1239,12 +1227,13 @@ function setKey(node, key, newValue, level) {
|
|
|
1239
1227
|
// Get the child node for updating and notifying
|
|
1240
1228
|
const childNode = isRoot ? node : getChildNode(node, key);
|
|
1241
1229
|
// Set the raw value on the parent object
|
|
1242
|
-
const { newValue: savedValue, prevValue } = setNodeValue(childNode, newValue);
|
|
1243
|
-
const isFunc = isFunction(
|
|
1230
|
+
const { newValue: savedValue, prevValue, parentValue } = setNodeValue(childNode, newValue);
|
|
1231
|
+
const isFunc = isFunction(savedValue);
|
|
1244
1232
|
const isPrim = isPrimitive(savedValue) || savedValue instanceof Date;
|
|
1245
1233
|
if (savedValue !== prevValue) {
|
|
1246
1234
|
updateNodesAndNotify(node, savedValue, prevValue, childNode, isPrim, isRoot, level);
|
|
1247
1235
|
}
|
|
1236
|
+
extractFunctionOrComputed(node, parentValue, key, newValue);
|
|
1248
1237
|
return isFunc ? savedValue : isRoot ? getProxy(node) : getProxy(node, key);
|
|
1249
1238
|
}
|
|
1250
1239
|
function assign(node, value) {
|
|
@@ -1370,13 +1359,48 @@ function updateNodesAndNotify(node, newValue, prevValue, childNode, isPrim, isRo
|
|
|
1370
1359
|
}
|
|
1371
1360
|
function extractPromise(node, value) {
|
|
1372
1361
|
value.status = 'pending';
|
|
1373
|
-
value
|
|
1374
|
-
|
|
1375
|
-
});
|
|
1376
|
-
value.then((value) => {
|
|
1362
|
+
value
|
|
1363
|
+
.then((value) => {
|
|
1377
1364
|
set(node, value);
|
|
1365
|
+
})
|
|
1366
|
+
.catch((error) => {
|
|
1367
|
+
set(node, { error, status: 'rejected' });
|
|
1378
1368
|
});
|
|
1379
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
|
+
}
|
|
1380
1404
|
|
|
1381
1405
|
const fns = ['get', 'set', 'peek', 'onChange', 'toggle'];
|
|
1382
1406
|
function ObservablePrimitiveClass(node) {
|
|
@@ -1419,35 +1443,6 @@ ObservablePrimitiveClass.prototype.delete = function () {
|
|
|
1419
1443
|
return this;
|
|
1420
1444
|
};
|
|
1421
1445
|
|
|
1422
|
-
const __devExtractFunctionsAndComputedsNodes = process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test' ? new Set() : undefined;
|
|
1423
|
-
function extractFunctionsAndComputeds(node, obj) {
|
|
1424
|
-
if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
|
|
1425
|
-
if (__devExtractFunctionsAndComputedsNodes.has(obj)) {
|
|
1426
|
-
console.error('[legend-state] Circular reference detected in object. You may want to use opaqueObject to stop traversing child nodes.', obj);
|
|
1427
|
-
return false;
|
|
1428
|
-
}
|
|
1429
|
-
__devExtractFunctionsAndComputedsNodes.add(obj);
|
|
1430
|
-
}
|
|
1431
|
-
for (const k in obj) {
|
|
1432
|
-
const v = obj[k];
|
|
1433
|
-
if (isPromise(v)) {
|
|
1434
|
-
extractPromise(getChildNode(node, k), v);
|
|
1435
|
-
}
|
|
1436
|
-
else if (typeof v === 'function') {
|
|
1437
|
-
extractFunction(node, k, v);
|
|
1438
|
-
}
|
|
1439
|
-
else if (typeof v == 'object' && v !== null && v !== undefined) {
|
|
1440
|
-
const childNode = getNode(v);
|
|
1441
|
-
if (childNode === null || childNode === void 0 ? void 0 : childNode.isComputed) {
|
|
1442
|
-
extractFunction(node, k, v, childNode);
|
|
1443
|
-
delete obj[k];
|
|
1444
|
-
}
|
|
1445
|
-
else if (!v[symbolOpaque]) {
|
|
1446
|
-
extractFunctionsAndComputeds(getChildNode(node, k), obj[k]);
|
|
1447
|
-
}
|
|
1448
|
-
}
|
|
1449
|
-
}
|
|
1450
|
-
}
|
|
1451
1446
|
function createObservable(value, makePrimitive) {
|
|
1452
1447
|
const valueIsPromise = isPromise(value);
|
|
1453
1448
|
const root = {
|