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