@legendapp/state 3.0.0-beta.29 → 3.0.0-beta.30
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.d.mts +18 -0
- package/index.d.ts +18 -0
- package/index.js +112 -0
- package/index.mjs +112 -0
- package/package.json +1 -1
- package/sync.js +222 -211
- package/sync.mjs +222 -211
package/index.d.mts
CHANGED
|
@@ -391,6 +391,23 @@ interface ObservablePrimitiveState {
|
|
|
391
391
|
}
|
|
392
392
|
declare function ObservablePrimitiveClass<T>(this: ObservablePrimitive<T> & ObservablePrimitiveState, node: NodeInfo): void;
|
|
393
393
|
|
|
394
|
+
type MiddlewareEventType = 'listener-added' | 'listener-removed' | 'listeners-cleared';
|
|
395
|
+
interface MiddlewareEvent {
|
|
396
|
+
type: MiddlewareEventType;
|
|
397
|
+
node: NodeInfo;
|
|
398
|
+
listener?: NodeListener;
|
|
399
|
+
timestamp: number;
|
|
400
|
+
}
|
|
401
|
+
type MiddlewareHandler = (event: MiddlewareEvent) => void;
|
|
402
|
+
/**
|
|
403
|
+
* Register a middleware handler for a specific node and event type
|
|
404
|
+
* @param node The node to register the middleware handler for
|
|
405
|
+
* @param type The event type to handle
|
|
406
|
+
* @param handler The middleware handler function
|
|
407
|
+
* @returns A function to remove the handler
|
|
408
|
+
*/
|
|
409
|
+
declare function registerMiddleware(node: NodeInfo, type: MiddlewareEventType, handler: MiddlewareHandler): () => void;
|
|
410
|
+
|
|
394
411
|
declare const internal: {
|
|
395
412
|
createPreviousHandler: typeof createPreviousHandler;
|
|
396
413
|
clone: typeof clone;
|
|
@@ -425,6 +442,7 @@ declare const internal: {
|
|
|
425
442
|
observableFns: Map<string, (node: NodeInfo, ...args: any[]) => any>;
|
|
426
443
|
optimized: symbol;
|
|
427
444
|
peek: typeof peek;
|
|
445
|
+
registerMiddleware: typeof registerMiddleware;
|
|
428
446
|
safeParse: typeof safeParse;
|
|
429
447
|
safeStringify: typeof safeStringify;
|
|
430
448
|
set: typeof set;
|
package/index.d.ts
CHANGED
|
@@ -391,6 +391,23 @@ interface ObservablePrimitiveState {
|
|
|
391
391
|
}
|
|
392
392
|
declare function ObservablePrimitiveClass<T>(this: ObservablePrimitive<T> & ObservablePrimitiveState, node: NodeInfo): void;
|
|
393
393
|
|
|
394
|
+
type MiddlewareEventType = 'listener-added' | 'listener-removed' | 'listeners-cleared';
|
|
395
|
+
interface MiddlewareEvent {
|
|
396
|
+
type: MiddlewareEventType;
|
|
397
|
+
node: NodeInfo;
|
|
398
|
+
listener?: NodeListener;
|
|
399
|
+
timestamp: number;
|
|
400
|
+
}
|
|
401
|
+
type MiddlewareHandler = (event: MiddlewareEvent) => void;
|
|
402
|
+
/**
|
|
403
|
+
* Register a middleware handler for a specific node and event type
|
|
404
|
+
* @param node The node to register the middleware handler for
|
|
405
|
+
* @param type The event type to handle
|
|
406
|
+
* @param handler The middleware handler function
|
|
407
|
+
* @returns A function to remove the handler
|
|
408
|
+
*/
|
|
409
|
+
declare function registerMiddleware(node: NodeInfo, type: MiddlewareEventType, handler: MiddlewareHandler): () => void;
|
|
410
|
+
|
|
394
411
|
declare const internal: {
|
|
395
412
|
createPreviousHandler: typeof createPreviousHandler;
|
|
396
413
|
clone: typeof clone;
|
|
@@ -425,6 +442,7 @@ declare const internal: {
|
|
|
425
442
|
observableFns: Map<string, (node: NodeInfo, ...args: any[]) => any>;
|
|
426
443
|
optimized: symbol;
|
|
427
444
|
peek: typeof peek;
|
|
445
|
+
registerMiddleware: typeof registerMiddleware;
|
|
428
446
|
safeParse: typeof safeParse;
|
|
429
447
|
safeStringify: typeof safeStringify;
|
|
430
448
|
set: typeof set;
|
package/index.js
CHANGED
|
@@ -818,6 +818,109 @@ function linked(params, options) {
|
|
|
818
818
|
return ret;
|
|
819
819
|
}
|
|
820
820
|
|
|
821
|
+
// src/middleware.ts
|
|
822
|
+
var nodeMiddlewareHandlers = /* @__PURE__ */ new WeakMap();
|
|
823
|
+
var queuedNodes = [];
|
|
824
|
+
var queuedListeners = [];
|
|
825
|
+
var queuedTypes = [];
|
|
826
|
+
var queueSize = 0;
|
|
827
|
+
var isMicrotaskScheduled = false;
|
|
828
|
+
function registerMiddleware(node, type, handler) {
|
|
829
|
+
let handlersMap = nodeMiddlewareHandlers.get(node);
|
|
830
|
+
if (!handlersMap) {
|
|
831
|
+
handlersMap = /* @__PURE__ */ new Map();
|
|
832
|
+
nodeMiddlewareHandlers.set(node, handlersMap);
|
|
833
|
+
}
|
|
834
|
+
let handlers = handlersMap.get(type);
|
|
835
|
+
if (!handlers) {
|
|
836
|
+
handlers = /* @__PURE__ */ new Set();
|
|
837
|
+
handlersMap.set(type, handlers);
|
|
838
|
+
}
|
|
839
|
+
handlers.add(handler);
|
|
840
|
+
return () => {
|
|
841
|
+
const handlersMap2 = nodeMiddlewareHandlers.get(node);
|
|
842
|
+
if (!handlersMap2)
|
|
843
|
+
return;
|
|
844
|
+
const handlers2 = handlersMap2.get(type);
|
|
845
|
+
if (!handlers2)
|
|
846
|
+
return;
|
|
847
|
+
handlers2.delete(handler);
|
|
848
|
+
if (handlers2.size === 0) {
|
|
849
|
+
handlersMap2.delete(type);
|
|
850
|
+
if (handlersMap2.size === 0) {
|
|
851
|
+
nodeMiddlewareHandlers.delete(node);
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
};
|
|
855
|
+
}
|
|
856
|
+
function dispatchMiddlewareEvent(node, listener, type) {
|
|
857
|
+
const handlersMap = nodeMiddlewareHandlers.get(node);
|
|
858
|
+
if (!handlersMap || !handlersMap.has(type)) {
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
const handlers = handlersMap.get(type);
|
|
862
|
+
if (!handlers || handlers.size === 0) {
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
queuedNodes[queueSize] = node;
|
|
866
|
+
queuedListeners[queueSize] = listener;
|
|
867
|
+
queuedTypes[queueSize] = type;
|
|
868
|
+
queueSize++;
|
|
869
|
+
if (!isMicrotaskScheduled) {
|
|
870
|
+
isMicrotaskScheduled = true;
|
|
871
|
+
queueMicrotask(processQueuedEvents);
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
var eventObj = {
|
|
875
|
+
type: "listener-added",
|
|
876
|
+
node: null,
|
|
877
|
+
listener: void 0,
|
|
878
|
+
timestamp: 0
|
|
879
|
+
};
|
|
880
|
+
function processQueuedEvents() {
|
|
881
|
+
isMicrotaskScheduled = false;
|
|
882
|
+
const timestamp = typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
883
|
+
eventObj.timestamp = timestamp;
|
|
884
|
+
for (let i = 0; i < queueSize; i++) {
|
|
885
|
+
const node = queuedNodes[i];
|
|
886
|
+
const listener = queuedListeners[i];
|
|
887
|
+
const type = queuedTypes[i];
|
|
888
|
+
const handlersMap = nodeMiddlewareHandlers.get(node);
|
|
889
|
+
if (!handlersMap)
|
|
890
|
+
continue;
|
|
891
|
+
const handlers = handlersMap.get(type);
|
|
892
|
+
if (!handlers || handlers.size === 0)
|
|
893
|
+
continue;
|
|
894
|
+
const nodeListeners = node.listeners;
|
|
895
|
+
const nodeListenersImmediate = node.listenersImmediate;
|
|
896
|
+
if (!nodeListeners && !nodeListenersImmediate) {
|
|
897
|
+
continue;
|
|
898
|
+
}
|
|
899
|
+
let isValid = false;
|
|
900
|
+
if (type === "listener-added") {
|
|
901
|
+
isValid = !!(nodeListeners == null ? void 0 : nodeListeners.has(listener)) || !!(nodeListenersImmediate == null ? void 0 : nodeListenersImmediate.has(listener));
|
|
902
|
+
} else if (type === "listener-removed") {
|
|
903
|
+
isValid = !(nodeListeners == null ? void 0 : nodeListeners.has(listener)) && !(nodeListenersImmediate == null ? void 0 : nodeListenersImmediate.has(listener));
|
|
904
|
+
} else {
|
|
905
|
+
isValid = !(nodeListeners == null ? void 0 : nodeListeners.size) && !(nodeListenersImmediate == null ? void 0 : nodeListenersImmediate.size);
|
|
906
|
+
}
|
|
907
|
+
if (isValid) {
|
|
908
|
+
eventObj.type = type;
|
|
909
|
+
eventObj.node = node;
|
|
910
|
+
eventObj.listener = listener;
|
|
911
|
+
const iterableHandlers = Array.from(handlers);
|
|
912
|
+
for (let j = 0; j < iterableHandlers.length; j++) {
|
|
913
|
+
try {
|
|
914
|
+
iterableHandlers[j](eventObj);
|
|
915
|
+
} catch (error) {
|
|
916
|
+
console.error(`Error in middleware handler for ${type}:`, error);
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
queueSize = 0;
|
|
922
|
+
}
|
|
923
|
+
|
|
821
924
|
// src/onChange.ts
|
|
822
925
|
function onChange(node, callback, options = {}, fromLinks) {
|
|
823
926
|
var _a;
|
|
@@ -888,6 +991,7 @@ function onChange(node, callback, options = {}, fromLinks) {
|
|
|
888
991
|
pathParent = [parent.key, ...pathParent];
|
|
889
992
|
parent = parent.parent;
|
|
890
993
|
}
|
|
994
|
+
dispatchMiddlewareEvent(node, listener, "listener-added");
|
|
891
995
|
return () => {
|
|
892
996
|
listeners.delete(listener);
|
|
893
997
|
extraDisposes == null ? void 0 : extraDisposes.forEach((fn) => fn());
|
|
@@ -896,6 +1000,10 @@ function onChange(node, callback, options = {}, fromLinks) {
|
|
|
896
1000
|
parent2.numListenersRecursive--;
|
|
897
1001
|
parent2 = parent2.parent;
|
|
898
1002
|
}
|
|
1003
|
+
dispatchMiddlewareEvent(node, listener, "listener-removed");
|
|
1004
|
+
if (listeners.size === 0) {
|
|
1005
|
+
dispatchMiddlewareEvent(node, void 0, "listeners-cleared");
|
|
1006
|
+
}
|
|
899
1007
|
};
|
|
900
1008
|
}
|
|
901
1009
|
function createCb(linkedFromNode, path, callback) {
|
|
@@ -2005,6 +2113,9 @@ function activateNodeFunction(node, lazyFn) {
|
|
|
2005
2113
|
value = (_d = (_c = activated2.get) == null ? void 0 : _c.call(activated2)) != null ? _d : activated2.initial;
|
|
2006
2114
|
}
|
|
2007
2115
|
}
|
|
2116
|
+
if (ignoreThisUpdate) {
|
|
2117
|
+
activatedValue = value;
|
|
2118
|
+
}
|
|
2008
2119
|
wasPromise = wasPromise || isPromise(value);
|
|
2009
2120
|
return value;
|
|
2010
2121
|
},
|
|
@@ -2354,6 +2465,7 @@ var internal = {
|
|
|
2354
2465
|
observableFns,
|
|
2355
2466
|
optimized,
|
|
2356
2467
|
peek,
|
|
2468
|
+
registerMiddleware,
|
|
2357
2469
|
safeParse,
|
|
2358
2470
|
safeStringify,
|
|
2359
2471
|
set,
|
package/index.mjs
CHANGED
|
@@ -816,6 +816,109 @@ function linked(params, options) {
|
|
|
816
816
|
return ret;
|
|
817
817
|
}
|
|
818
818
|
|
|
819
|
+
// src/middleware.ts
|
|
820
|
+
var nodeMiddlewareHandlers = /* @__PURE__ */ new WeakMap();
|
|
821
|
+
var queuedNodes = [];
|
|
822
|
+
var queuedListeners = [];
|
|
823
|
+
var queuedTypes = [];
|
|
824
|
+
var queueSize = 0;
|
|
825
|
+
var isMicrotaskScheduled = false;
|
|
826
|
+
function registerMiddleware(node, type, handler) {
|
|
827
|
+
let handlersMap = nodeMiddlewareHandlers.get(node);
|
|
828
|
+
if (!handlersMap) {
|
|
829
|
+
handlersMap = /* @__PURE__ */ new Map();
|
|
830
|
+
nodeMiddlewareHandlers.set(node, handlersMap);
|
|
831
|
+
}
|
|
832
|
+
let handlers = handlersMap.get(type);
|
|
833
|
+
if (!handlers) {
|
|
834
|
+
handlers = /* @__PURE__ */ new Set();
|
|
835
|
+
handlersMap.set(type, handlers);
|
|
836
|
+
}
|
|
837
|
+
handlers.add(handler);
|
|
838
|
+
return () => {
|
|
839
|
+
const handlersMap2 = nodeMiddlewareHandlers.get(node);
|
|
840
|
+
if (!handlersMap2)
|
|
841
|
+
return;
|
|
842
|
+
const handlers2 = handlersMap2.get(type);
|
|
843
|
+
if (!handlers2)
|
|
844
|
+
return;
|
|
845
|
+
handlers2.delete(handler);
|
|
846
|
+
if (handlers2.size === 0) {
|
|
847
|
+
handlersMap2.delete(type);
|
|
848
|
+
if (handlersMap2.size === 0) {
|
|
849
|
+
nodeMiddlewareHandlers.delete(node);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
};
|
|
853
|
+
}
|
|
854
|
+
function dispatchMiddlewareEvent(node, listener, type) {
|
|
855
|
+
const handlersMap = nodeMiddlewareHandlers.get(node);
|
|
856
|
+
if (!handlersMap || !handlersMap.has(type)) {
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
const handlers = handlersMap.get(type);
|
|
860
|
+
if (!handlers || handlers.size === 0) {
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
queuedNodes[queueSize] = node;
|
|
864
|
+
queuedListeners[queueSize] = listener;
|
|
865
|
+
queuedTypes[queueSize] = type;
|
|
866
|
+
queueSize++;
|
|
867
|
+
if (!isMicrotaskScheduled) {
|
|
868
|
+
isMicrotaskScheduled = true;
|
|
869
|
+
queueMicrotask(processQueuedEvents);
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
var eventObj = {
|
|
873
|
+
type: "listener-added",
|
|
874
|
+
node: null,
|
|
875
|
+
listener: void 0,
|
|
876
|
+
timestamp: 0
|
|
877
|
+
};
|
|
878
|
+
function processQueuedEvents() {
|
|
879
|
+
isMicrotaskScheduled = false;
|
|
880
|
+
const timestamp = typeof performance !== "undefined" ? performance.now() : Date.now();
|
|
881
|
+
eventObj.timestamp = timestamp;
|
|
882
|
+
for (let i = 0; i < queueSize; i++) {
|
|
883
|
+
const node = queuedNodes[i];
|
|
884
|
+
const listener = queuedListeners[i];
|
|
885
|
+
const type = queuedTypes[i];
|
|
886
|
+
const handlersMap = nodeMiddlewareHandlers.get(node);
|
|
887
|
+
if (!handlersMap)
|
|
888
|
+
continue;
|
|
889
|
+
const handlers = handlersMap.get(type);
|
|
890
|
+
if (!handlers || handlers.size === 0)
|
|
891
|
+
continue;
|
|
892
|
+
const nodeListeners = node.listeners;
|
|
893
|
+
const nodeListenersImmediate = node.listenersImmediate;
|
|
894
|
+
if (!nodeListeners && !nodeListenersImmediate) {
|
|
895
|
+
continue;
|
|
896
|
+
}
|
|
897
|
+
let isValid = false;
|
|
898
|
+
if (type === "listener-added") {
|
|
899
|
+
isValid = !!(nodeListeners == null ? void 0 : nodeListeners.has(listener)) || !!(nodeListenersImmediate == null ? void 0 : nodeListenersImmediate.has(listener));
|
|
900
|
+
} else if (type === "listener-removed") {
|
|
901
|
+
isValid = !(nodeListeners == null ? void 0 : nodeListeners.has(listener)) && !(nodeListenersImmediate == null ? void 0 : nodeListenersImmediate.has(listener));
|
|
902
|
+
} else {
|
|
903
|
+
isValid = !(nodeListeners == null ? void 0 : nodeListeners.size) && !(nodeListenersImmediate == null ? void 0 : nodeListenersImmediate.size);
|
|
904
|
+
}
|
|
905
|
+
if (isValid) {
|
|
906
|
+
eventObj.type = type;
|
|
907
|
+
eventObj.node = node;
|
|
908
|
+
eventObj.listener = listener;
|
|
909
|
+
const iterableHandlers = Array.from(handlers);
|
|
910
|
+
for (let j = 0; j < iterableHandlers.length; j++) {
|
|
911
|
+
try {
|
|
912
|
+
iterableHandlers[j](eventObj);
|
|
913
|
+
} catch (error) {
|
|
914
|
+
console.error(`Error in middleware handler for ${type}:`, error);
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
queueSize = 0;
|
|
920
|
+
}
|
|
921
|
+
|
|
819
922
|
// src/onChange.ts
|
|
820
923
|
function onChange(node, callback, options = {}, fromLinks) {
|
|
821
924
|
var _a;
|
|
@@ -886,6 +989,7 @@ function onChange(node, callback, options = {}, fromLinks) {
|
|
|
886
989
|
pathParent = [parent.key, ...pathParent];
|
|
887
990
|
parent = parent.parent;
|
|
888
991
|
}
|
|
992
|
+
dispatchMiddlewareEvent(node, listener, "listener-added");
|
|
889
993
|
return () => {
|
|
890
994
|
listeners.delete(listener);
|
|
891
995
|
extraDisposes == null ? void 0 : extraDisposes.forEach((fn) => fn());
|
|
@@ -894,6 +998,10 @@ function onChange(node, callback, options = {}, fromLinks) {
|
|
|
894
998
|
parent2.numListenersRecursive--;
|
|
895
999
|
parent2 = parent2.parent;
|
|
896
1000
|
}
|
|
1001
|
+
dispatchMiddlewareEvent(node, listener, "listener-removed");
|
|
1002
|
+
if (listeners.size === 0) {
|
|
1003
|
+
dispatchMiddlewareEvent(node, void 0, "listeners-cleared");
|
|
1004
|
+
}
|
|
897
1005
|
};
|
|
898
1006
|
}
|
|
899
1007
|
function createCb(linkedFromNode, path, callback) {
|
|
@@ -2003,6 +2111,9 @@ function activateNodeFunction(node, lazyFn) {
|
|
|
2003
2111
|
value = (_d = (_c = activated2.get) == null ? void 0 : _c.call(activated2)) != null ? _d : activated2.initial;
|
|
2004
2112
|
}
|
|
2005
2113
|
}
|
|
2114
|
+
if (ignoreThisUpdate) {
|
|
2115
|
+
activatedValue = value;
|
|
2116
|
+
}
|
|
2006
2117
|
wasPromise = wasPromise || isPromise(value);
|
|
2007
2118
|
return value;
|
|
2008
2119
|
},
|
|
@@ -2352,6 +2463,7 @@ var internal = {
|
|
|
2352
2463
|
observableFns,
|
|
2353
2464
|
optimized,
|
|
2354
2465
|
peek,
|
|
2466
|
+
registerMiddleware,
|
|
2355
2467
|
safeParse,
|
|
2356
2468
|
safeStringify,
|
|
2357
2469
|
set,
|
package/package.json
CHANGED
package/sync.js
CHANGED
|
@@ -234,7 +234,17 @@ function createRevertChanges(obs$, changes) {
|
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
// src/sync/syncObservable.ts
|
|
237
|
-
var {
|
|
237
|
+
var {
|
|
238
|
+
clone: clone2,
|
|
239
|
+
createPreviousHandler,
|
|
240
|
+
deepMerge,
|
|
241
|
+
getNode,
|
|
242
|
+
getNodeValue,
|
|
243
|
+
getValueAtPath,
|
|
244
|
+
globalState,
|
|
245
|
+
registerMiddleware,
|
|
246
|
+
symbolLinked
|
|
247
|
+
} = state.internal;
|
|
238
248
|
var mapSyncPlugins = /* @__PURE__ */ new WeakMap();
|
|
239
249
|
var allSyncStates = /* @__PURE__ */ new Map();
|
|
240
250
|
var metadatas = /* @__PURE__ */ new WeakMap();
|
|
@@ -937,236 +947,237 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
937
947
|
}
|
|
938
948
|
const lastSync = (_a = metadatas.get(obs$)) == null ? void 0 : _a.lastSync;
|
|
939
949
|
const pending = localState.pendingChanges;
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
950
|
+
const { waitFor } = syncOptions;
|
|
951
|
+
const runGet = () => {
|
|
952
|
+
var _a2;
|
|
953
|
+
const onChange = async ({ value, mode, lastSync: lastSync2 }) => {
|
|
954
|
+
mode = mode || syncOptions.mode || "set";
|
|
955
|
+
if (value !== void 0) {
|
|
956
|
+
value = transformLoadData(value, syncOptions, true, "get");
|
|
957
|
+
if (state.isPromise(value)) {
|
|
958
|
+
value = await value;
|
|
959
|
+
}
|
|
960
|
+
const pending2 = localState.pendingChanges;
|
|
961
|
+
const currentValue = obs$.peek();
|
|
962
|
+
if (pending2) {
|
|
963
|
+
let didChangeMetadata = false;
|
|
964
|
+
Object.keys(pending2).forEach((key) => {
|
|
965
|
+
const p = key.split("/").filter((k) => k !== "");
|
|
966
|
+
const { v, t } = pending2[key];
|
|
967
|
+
if (t.length === 0 || !value) {
|
|
968
|
+
const oldValue = clone2(value);
|
|
969
|
+
pending2[key].p = key ? oldValue[key] : oldValue;
|
|
970
|
+
if (state.isObject(value) && state.isObject(v)) {
|
|
971
|
+
Object.assign(value, key ? { [key]: v } : v);
|
|
972
|
+
} else if (!key) {
|
|
973
|
+
value = v;
|
|
974
|
+
}
|
|
975
|
+
} else if (value[p[0]] !== void 0) {
|
|
976
|
+
const curValue = getValueAtPath(currentValue, p);
|
|
977
|
+
const newValue = getValueAtPath(value, p);
|
|
978
|
+
if (JSON.stringify(curValue) === JSON.stringify(newValue)) {
|
|
979
|
+
delete pending2[key];
|
|
980
|
+
didChangeMetadata = true;
|
|
981
|
+
} else {
|
|
959
982
|
const oldValue = clone2(value);
|
|
960
|
-
pending2[key].p =
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
p,
|
|
979
|
-
t,
|
|
980
|
-
v,
|
|
981
|
-
"merge",
|
|
982
|
-
obs$.peek(),
|
|
983
|
-
(path, value2) => {
|
|
984
|
-
delete pending2[key];
|
|
985
|
-
pending2[path.join("/")] = {
|
|
986
|
-
p: null,
|
|
987
|
-
v: value2,
|
|
988
|
-
t: t.slice(0, path.length)
|
|
989
|
-
};
|
|
990
|
-
}
|
|
991
|
-
);
|
|
992
|
-
}
|
|
983
|
+
pending2[key].p = getValueAtPath(oldValue, p);
|
|
984
|
+
didChangeMetadata = true;
|
|
985
|
+
value = state.setAtPath(
|
|
986
|
+
value,
|
|
987
|
+
p,
|
|
988
|
+
t,
|
|
989
|
+
v,
|
|
990
|
+
"merge",
|
|
991
|
+
obs$.peek(),
|
|
992
|
+
(path, value2) => {
|
|
993
|
+
delete pending2[key];
|
|
994
|
+
pending2[path.join("/")] = {
|
|
995
|
+
p: null,
|
|
996
|
+
v: value2,
|
|
997
|
+
t: t.slice(0, path.length)
|
|
998
|
+
};
|
|
999
|
+
}
|
|
1000
|
+
);
|
|
993
1001
|
}
|
|
994
|
-
});
|
|
995
|
-
if (didChangeMetadata && syncOptions.persist) {
|
|
996
|
-
updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
|
|
997
|
-
pending: pending2
|
|
998
|
-
});
|
|
999
1002
|
}
|
|
1003
|
+
});
|
|
1004
|
+
if (didChangeMetadata && syncOptions.persist) {
|
|
1005
|
+
updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
|
|
1006
|
+
pending: pending2
|
|
1007
|
+
});
|
|
1000
1008
|
}
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1009
|
+
}
|
|
1010
|
+
onChangeRemote2(() => {
|
|
1011
|
+
if (state.isPlainObject(value)) {
|
|
1012
|
+
value = state.ObservableHint.plain(value);
|
|
1013
|
+
}
|
|
1014
|
+
if (mode === "assign") {
|
|
1015
|
+
obs$.assign(value);
|
|
1016
|
+
} else if (mode === "append") {
|
|
1017
|
+
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && !state.isArray(value)) {
|
|
1018
|
+
console.error("[legend-state] mode:append expects the value to be an array");
|
|
1004
1019
|
}
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
console.error("[legend-state] mode:append expects the value to be an array");
|
|
1010
|
-
}
|
|
1011
|
-
obs$.push(...value);
|
|
1012
|
-
} else if (mode === "prepend") {
|
|
1013
|
-
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && !state.isArray(value)) {
|
|
1014
|
-
console.error("[legend-state] mode:prepend expects the value to be an array");
|
|
1015
|
-
}
|
|
1016
|
-
obs$.splice(0, 0, ...value);
|
|
1017
|
-
} else if (mode === "merge") {
|
|
1018
|
-
state.mergeIntoObservable(obs$, value);
|
|
1019
|
-
} else {
|
|
1020
|
-
obs$.set(value);
|
|
1020
|
+
obs$.push(...value);
|
|
1021
|
+
} else if (mode === "prepend") {
|
|
1022
|
+
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && !state.isArray(value)) {
|
|
1023
|
+
console.error("[legend-state] mode:prepend expects the value to be an array");
|
|
1021
1024
|
}
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
};
|
|
1030
|
-
if (node.activationState) {
|
|
1031
|
-
node.activationState.onChange = onChange;
|
|
1025
|
+
obs$.splice(0, 0, ...value);
|
|
1026
|
+
} else if (mode === "merge") {
|
|
1027
|
+
state.mergeIntoObservable(obs$, value);
|
|
1028
|
+
} else {
|
|
1029
|
+
obs$.set(value);
|
|
1030
|
+
}
|
|
1031
|
+
});
|
|
1032
1032
|
}
|
|
1033
|
-
if (
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
const subscribeParams = {
|
|
1038
|
-
node,
|
|
1039
|
-
value$: obs$,
|
|
1040
|
-
lastSync,
|
|
1041
|
-
update: (params) => {
|
|
1042
|
-
state.when(
|
|
1043
|
-
() => !get || syncState$.isLoaded.get(),
|
|
1044
|
-
() => {
|
|
1045
|
-
state.when(waitFor || true, () => {
|
|
1046
|
-
params.mode || (params.mode = syncOptions.mode || "merge");
|
|
1047
|
-
onChange(params);
|
|
1048
|
-
if (!syncState$.isLoaded.peek()) {
|
|
1049
|
-
syncState$.assign({
|
|
1050
|
-
isLoaded: syncStateValue.numPendingRemoteLoads < 1,
|
|
1051
|
-
error: void 0,
|
|
1052
|
-
isGetting: syncStateValue.numPendingGets > 0
|
|
1053
|
-
});
|
|
1054
|
-
}
|
|
1055
|
-
});
|
|
1056
|
-
}
|
|
1057
|
-
);
|
|
1058
|
-
},
|
|
1059
|
-
refresh: () => state.when(syncState$.isLoaded, sync),
|
|
1060
|
-
onError: (error) => onGetError(error, {
|
|
1061
|
-
source: "subscribe",
|
|
1062
|
-
subscribeParams,
|
|
1063
|
-
type: "get",
|
|
1064
|
-
retry: {}
|
|
1065
|
-
})
|
|
1066
|
-
};
|
|
1067
|
-
unsubscribe = subscribe2(subscribeParams);
|
|
1068
|
-
};
|
|
1069
|
-
if (waitFor) {
|
|
1070
|
-
state.whenReady(waitFor, doSubscribe);
|
|
1071
|
-
} else {
|
|
1072
|
-
doSubscribe();
|
|
1073
|
-
}
|
|
1033
|
+
if (lastSync2 && syncOptions.persist) {
|
|
1034
|
+
updateMetadata(obs$, localState, syncState$, syncOptions, {
|
|
1035
|
+
lastSync: lastSync2
|
|
1036
|
+
});
|
|
1074
1037
|
}
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1038
|
+
};
|
|
1039
|
+
if (node.activationState) {
|
|
1040
|
+
node.activationState.onChange = onChange;
|
|
1041
|
+
}
|
|
1042
|
+
if (!isSubscribed && syncOptions.subscribe) {
|
|
1043
|
+
const subscribe2 = syncOptions.subscribe;
|
|
1044
|
+
const doSubscribe = () => {
|
|
1045
|
+
isSubscribed = true;
|
|
1046
|
+
const subscribeParams = {
|
|
1078
1047
|
node,
|
|
1079
1048
|
value$: obs$,
|
|
1080
|
-
value: state.isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked]) ? void 0 : existingValue,
|
|
1081
|
-
mode: syncOptions.mode,
|
|
1082
|
-
refresh: sync,
|
|
1083
|
-
options: syncOptions,
|
|
1084
1049
|
lastSync,
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
var _a3;
|
|
1103
|
-
modeBeforeReset = getParams.mode;
|
|
1104
|
-
getParams.mode = "set";
|
|
1105
|
-
return (_a3 = syncStateValue.resetPersistence) == null ? void 0 : _a3.call(syncStateValue);
|
|
1050
|
+
update: (params) => {
|
|
1051
|
+
state.when(
|
|
1052
|
+
() => !get || syncState$.isLoaded.get(),
|
|
1053
|
+
() => {
|
|
1054
|
+
state.when(waitFor || true, () => {
|
|
1055
|
+
params.mode || (params.mode = syncOptions.mode || "merge");
|
|
1056
|
+
onChange(params);
|
|
1057
|
+
if (!syncState$.isLoaded.peek()) {
|
|
1058
|
+
syncState$.assign({
|
|
1059
|
+
isLoaded: syncStateValue.numPendingRemoteLoads < 1,
|
|
1060
|
+
error: void 0,
|
|
1061
|
+
isGetting: syncStateValue.numPendingGets > 0
|
|
1062
|
+
});
|
|
1063
|
+
}
|
|
1064
|
+
});
|
|
1065
|
+
}
|
|
1066
|
+
);
|
|
1106
1067
|
},
|
|
1107
|
-
|
|
1068
|
+
refresh: () => state.when(syncState$.isLoaded, sync),
|
|
1069
|
+
onError: (error) => onGetError(error, {
|
|
1070
|
+
source: "subscribe",
|
|
1071
|
+
subscribeParams,
|
|
1072
|
+
type: "get",
|
|
1073
|
+
retry: {}
|
|
1074
|
+
})
|
|
1108
1075
|
};
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1076
|
+
unsubscribe = subscribe2(subscribeParams);
|
|
1077
|
+
registerMiddleware(node, "listeners-cleared", () => {
|
|
1078
|
+
if (unsubscribe) {
|
|
1079
|
+
isSubscribed = false;
|
|
1080
|
+
unsubscribe();
|
|
1081
|
+
unsubscribe = void 0;
|
|
1082
|
+
}
|
|
1083
|
+
});
|
|
1084
|
+
registerMiddleware(node, "listener-added", () => {
|
|
1085
|
+
if (!isSubscribed) {
|
|
1086
|
+
doSubscribe();
|
|
1087
|
+
}
|
|
1088
|
+
});
|
|
1089
|
+
};
|
|
1090
|
+
if (waitFor) {
|
|
1091
|
+
state.whenReady(waitFor, doSubscribe);
|
|
1092
|
+
} else {
|
|
1093
|
+
doSubscribe();
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
const existingValue = getNodeValue(node);
|
|
1097
|
+
if (get) {
|
|
1098
|
+
const getParams = {
|
|
1099
|
+
node,
|
|
1100
|
+
value$: obs$,
|
|
1101
|
+
value: state.isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked]) ? void 0 : existingValue,
|
|
1102
|
+
mode: syncOptions.mode,
|
|
1103
|
+
refresh: sync,
|
|
1104
|
+
options: syncOptions,
|
|
1105
|
+
lastSync,
|
|
1106
|
+
updateLastSync: (lastSync2) => getParams.lastSync = lastSync2,
|
|
1107
|
+
onError: onGetError,
|
|
1108
|
+
retryNum: 0,
|
|
1109
|
+
cancelRetry: false
|
|
1110
|
+
};
|
|
1111
|
+
let modeBeforeReset = void 0;
|
|
1112
|
+
const beforeGetParams = {
|
|
1113
|
+
value: getParams.value,
|
|
1114
|
+
lastSync,
|
|
1115
|
+
pendingChanges: pending && !state.isEmpty(pending) ? pending : void 0,
|
|
1116
|
+
clearPendingChanges: async () => {
|
|
1117
|
+
localState.pendingChanges = {};
|
|
1118
|
+
await updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
|
|
1119
|
+
pending: localState.pendingChanges
|
|
1120
1120
|
});
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1121
|
+
},
|
|
1122
|
+
resetCache: () => {
|
|
1123
|
+
var _a3;
|
|
1124
|
+
modeBeforeReset = getParams.mode;
|
|
1125
|
+
getParams.mode = "set";
|
|
1126
|
+
return (_a3 = syncStateValue.resetPersistence) == null ? void 0 : _a3.call(syncStateValue);
|
|
1127
|
+
},
|
|
1128
|
+
cancel: false
|
|
1129
|
+
};
|
|
1130
|
+
(_a2 = syncOptions.onBeforeGet) == null ? void 0 : _a2.call(syncOptions, beforeGetParams);
|
|
1131
|
+
if (!beforeGetParams.cancel) {
|
|
1132
|
+
syncState$.assign({
|
|
1133
|
+
numPendingGets: (syncStateValue.numPendingGets || 0) + 1,
|
|
1134
|
+
isGetting: true
|
|
1135
|
+
});
|
|
1136
|
+
const got = runWithRetry(getParams, syncOptions.retry, node, (retryEvent) => {
|
|
1137
|
+
const params = getParams;
|
|
1138
|
+
params.cancelRetry = retryEvent.cancelRetry;
|
|
1139
|
+
params.retryNum = retryEvent.retryNum;
|
|
1140
|
+
return get(params);
|
|
1141
|
+
});
|
|
1142
|
+
const numGets = node.numGets = (node.numGets || 0) + 1;
|
|
1143
|
+
const handle = (value) => {
|
|
1144
|
+
syncState$.numPendingGets.set((v) => v - 1);
|
|
1145
|
+
if (isWaitingForLoad) {
|
|
1146
|
+
isWaitingForLoad = false;
|
|
1147
|
+
syncStateValue.numPendingRemoteLoads--;
|
|
1148
|
+
}
|
|
1149
|
+
if (numGets >= (node.getNumResolved || 0)) {
|
|
1150
|
+
node.getNumResolved = node.numGets;
|
|
1151
|
+
onChange({
|
|
1152
|
+
value,
|
|
1153
|
+
lastSync: getParams.lastSync,
|
|
1154
|
+
mode: getParams.mode
|
|
1153
1155
|
});
|
|
1154
|
-
} else {
|
|
1155
|
-
handle(got);
|
|
1156
1156
|
}
|
|
1157
|
+
if (modeBeforeReset) {
|
|
1158
|
+
getParams.mode = modeBeforeReset;
|
|
1159
|
+
modeBeforeReset = void 0;
|
|
1160
|
+
}
|
|
1161
|
+
syncState$.assign({
|
|
1162
|
+
isLoaded: syncStateValue.numPendingRemoteLoads < 1,
|
|
1163
|
+
error: void 0,
|
|
1164
|
+
isGetting: syncStateValue.numPendingGets > 0
|
|
1165
|
+
});
|
|
1166
|
+
};
|
|
1167
|
+
if (state.isPromise(got)) {
|
|
1168
|
+
got.then(handle).catch((error) => {
|
|
1169
|
+
onGetError(error, { getParams, source: "get", type: "get", retry: getParams }, true);
|
|
1170
|
+
});
|
|
1171
|
+
} else {
|
|
1172
|
+
handle(got);
|
|
1157
1173
|
}
|
|
1158
1174
|
}
|
|
1159
|
-
};
|
|
1160
|
-
if (waitFor) {
|
|
1161
|
-
state.whenReady(waitFor, () => state.trackSelector(runGet, sync));
|
|
1162
|
-
} else {
|
|
1163
|
-
state.trackSelector(runGet, sync);
|
|
1164
1175
|
}
|
|
1176
|
+
};
|
|
1177
|
+
if (waitFor) {
|
|
1178
|
+
state.whenReady(waitFor, () => state.trackSelector(runGet, sync));
|
|
1165
1179
|
} else {
|
|
1166
|
-
|
|
1167
|
-
isLoaded: true,
|
|
1168
|
-
error: void 0
|
|
1169
|
-
});
|
|
1180
|
+
state.trackSelector(runGet, sync);
|
|
1170
1181
|
}
|
|
1171
1182
|
if (!isSynced) {
|
|
1172
1183
|
isSynced = true;
|
package/sync.mjs
CHANGED
|
@@ -232,7 +232,17 @@ function createRevertChanges(obs$, changes) {
|
|
|
232
232
|
}
|
|
233
233
|
|
|
234
234
|
// src/sync/syncObservable.ts
|
|
235
|
-
var {
|
|
235
|
+
var {
|
|
236
|
+
clone: clone2,
|
|
237
|
+
createPreviousHandler,
|
|
238
|
+
deepMerge,
|
|
239
|
+
getNode,
|
|
240
|
+
getNodeValue,
|
|
241
|
+
getValueAtPath,
|
|
242
|
+
globalState,
|
|
243
|
+
registerMiddleware,
|
|
244
|
+
symbolLinked
|
|
245
|
+
} = internal;
|
|
236
246
|
var mapSyncPlugins = /* @__PURE__ */ new WeakMap();
|
|
237
247
|
var allSyncStates = /* @__PURE__ */ new Map();
|
|
238
248
|
var metadatas = /* @__PURE__ */ new WeakMap();
|
|
@@ -935,236 +945,237 @@ function syncObservable(obs$, syncOptionsOrSynced) {
|
|
|
935
945
|
}
|
|
936
946
|
const lastSync = (_a = metadatas.get(obs$)) == null ? void 0 : _a.lastSync;
|
|
937
947
|
const pending = localState.pendingChanges;
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
948
|
+
const { waitFor } = syncOptions;
|
|
949
|
+
const runGet = () => {
|
|
950
|
+
var _a2;
|
|
951
|
+
const onChange = async ({ value, mode, lastSync: lastSync2 }) => {
|
|
952
|
+
mode = mode || syncOptions.mode || "set";
|
|
953
|
+
if (value !== void 0) {
|
|
954
|
+
value = transformLoadData(value, syncOptions, true, "get");
|
|
955
|
+
if (isPromise$1(value)) {
|
|
956
|
+
value = await value;
|
|
957
|
+
}
|
|
958
|
+
const pending2 = localState.pendingChanges;
|
|
959
|
+
const currentValue = obs$.peek();
|
|
960
|
+
if (pending2) {
|
|
961
|
+
let didChangeMetadata = false;
|
|
962
|
+
Object.keys(pending2).forEach((key) => {
|
|
963
|
+
const p = key.split("/").filter((k) => k !== "");
|
|
964
|
+
const { v, t } = pending2[key];
|
|
965
|
+
if (t.length === 0 || !value) {
|
|
966
|
+
const oldValue = clone2(value);
|
|
967
|
+
pending2[key].p = key ? oldValue[key] : oldValue;
|
|
968
|
+
if (isObject(value) && isObject(v)) {
|
|
969
|
+
Object.assign(value, key ? { [key]: v } : v);
|
|
970
|
+
} else if (!key) {
|
|
971
|
+
value = v;
|
|
972
|
+
}
|
|
973
|
+
} else if (value[p[0]] !== void 0) {
|
|
974
|
+
const curValue = getValueAtPath(currentValue, p);
|
|
975
|
+
const newValue = getValueAtPath(value, p);
|
|
976
|
+
if (JSON.stringify(curValue) === JSON.stringify(newValue)) {
|
|
977
|
+
delete pending2[key];
|
|
978
|
+
didChangeMetadata = true;
|
|
979
|
+
} else {
|
|
957
980
|
const oldValue = clone2(value);
|
|
958
|
-
pending2[key].p =
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
p,
|
|
977
|
-
t,
|
|
978
|
-
v,
|
|
979
|
-
"merge",
|
|
980
|
-
obs$.peek(),
|
|
981
|
-
(path, value2) => {
|
|
982
|
-
delete pending2[key];
|
|
983
|
-
pending2[path.join("/")] = {
|
|
984
|
-
p: null,
|
|
985
|
-
v: value2,
|
|
986
|
-
t: t.slice(0, path.length)
|
|
987
|
-
};
|
|
988
|
-
}
|
|
989
|
-
);
|
|
990
|
-
}
|
|
981
|
+
pending2[key].p = getValueAtPath(oldValue, p);
|
|
982
|
+
didChangeMetadata = true;
|
|
983
|
+
value = setAtPath(
|
|
984
|
+
value,
|
|
985
|
+
p,
|
|
986
|
+
t,
|
|
987
|
+
v,
|
|
988
|
+
"merge",
|
|
989
|
+
obs$.peek(),
|
|
990
|
+
(path, value2) => {
|
|
991
|
+
delete pending2[key];
|
|
992
|
+
pending2[path.join("/")] = {
|
|
993
|
+
p: null,
|
|
994
|
+
v: value2,
|
|
995
|
+
t: t.slice(0, path.length)
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
);
|
|
991
999
|
}
|
|
992
|
-
});
|
|
993
|
-
if (didChangeMetadata && syncOptions.persist) {
|
|
994
|
-
updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
|
|
995
|
-
pending: pending2
|
|
996
|
-
});
|
|
997
1000
|
}
|
|
1001
|
+
});
|
|
1002
|
+
if (didChangeMetadata && syncOptions.persist) {
|
|
1003
|
+
updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
|
|
1004
|
+
pending: pending2
|
|
1005
|
+
});
|
|
998
1006
|
}
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1007
|
+
}
|
|
1008
|
+
onChangeRemote2(() => {
|
|
1009
|
+
if (isPlainObject(value)) {
|
|
1010
|
+
value = ObservableHint.plain(value);
|
|
1011
|
+
}
|
|
1012
|
+
if (mode === "assign") {
|
|
1013
|
+
obs$.assign(value);
|
|
1014
|
+
} else if (mode === "append") {
|
|
1015
|
+
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && !isArray(value)) {
|
|
1016
|
+
console.error("[legend-state] mode:append expects the value to be an array");
|
|
1002
1017
|
}
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
console.error("[legend-state] mode:append expects the value to be an array");
|
|
1008
|
-
}
|
|
1009
|
-
obs$.push(...value);
|
|
1010
|
-
} else if (mode === "prepend") {
|
|
1011
|
-
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && !isArray(value)) {
|
|
1012
|
-
console.error("[legend-state] mode:prepend expects the value to be an array");
|
|
1013
|
-
}
|
|
1014
|
-
obs$.splice(0, 0, ...value);
|
|
1015
|
-
} else if (mode === "merge") {
|
|
1016
|
-
mergeIntoObservable(obs$, value);
|
|
1017
|
-
} else {
|
|
1018
|
-
obs$.set(value);
|
|
1018
|
+
obs$.push(...value);
|
|
1019
|
+
} else if (mode === "prepend") {
|
|
1020
|
+
if ((process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") && !isArray(value)) {
|
|
1021
|
+
console.error("[legend-state] mode:prepend expects the value to be an array");
|
|
1019
1022
|
}
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
}
|
|
1026
|
-
}
|
|
1027
|
-
};
|
|
1028
|
-
if (node.activationState) {
|
|
1029
|
-
node.activationState.onChange = onChange;
|
|
1023
|
+
obs$.splice(0, 0, ...value);
|
|
1024
|
+
} else if (mode === "merge") {
|
|
1025
|
+
mergeIntoObservable(obs$, value);
|
|
1026
|
+
} else {
|
|
1027
|
+
obs$.set(value);
|
|
1028
|
+
}
|
|
1029
|
+
});
|
|
1030
1030
|
}
|
|
1031
|
-
if (
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
const subscribeParams = {
|
|
1036
|
-
node,
|
|
1037
|
-
value$: obs$,
|
|
1038
|
-
lastSync,
|
|
1039
|
-
update: (params) => {
|
|
1040
|
-
when(
|
|
1041
|
-
() => !get || syncState$.isLoaded.get(),
|
|
1042
|
-
() => {
|
|
1043
|
-
when(waitFor || true, () => {
|
|
1044
|
-
params.mode || (params.mode = syncOptions.mode || "merge");
|
|
1045
|
-
onChange(params);
|
|
1046
|
-
if (!syncState$.isLoaded.peek()) {
|
|
1047
|
-
syncState$.assign({
|
|
1048
|
-
isLoaded: syncStateValue.numPendingRemoteLoads < 1,
|
|
1049
|
-
error: void 0,
|
|
1050
|
-
isGetting: syncStateValue.numPendingGets > 0
|
|
1051
|
-
});
|
|
1052
|
-
}
|
|
1053
|
-
});
|
|
1054
|
-
}
|
|
1055
|
-
);
|
|
1056
|
-
},
|
|
1057
|
-
refresh: () => when(syncState$.isLoaded, sync),
|
|
1058
|
-
onError: (error) => onGetError(error, {
|
|
1059
|
-
source: "subscribe",
|
|
1060
|
-
subscribeParams,
|
|
1061
|
-
type: "get",
|
|
1062
|
-
retry: {}
|
|
1063
|
-
})
|
|
1064
|
-
};
|
|
1065
|
-
unsubscribe = subscribe2(subscribeParams);
|
|
1066
|
-
};
|
|
1067
|
-
if (waitFor) {
|
|
1068
|
-
whenReady(waitFor, doSubscribe);
|
|
1069
|
-
} else {
|
|
1070
|
-
doSubscribe();
|
|
1071
|
-
}
|
|
1031
|
+
if (lastSync2 && syncOptions.persist) {
|
|
1032
|
+
updateMetadata(obs$, localState, syncState$, syncOptions, {
|
|
1033
|
+
lastSync: lastSync2
|
|
1034
|
+
});
|
|
1072
1035
|
}
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1036
|
+
};
|
|
1037
|
+
if (node.activationState) {
|
|
1038
|
+
node.activationState.onChange = onChange;
|
|
1039
|
+
}
|
|
1040
|
+
if (!isSubscribed && syncOptions.subscribe) {
|
|
1041
|
+
const subscribe2 = syncOptions.subscribe;
|
|
1042
|
+
const doSubscribe = () => {
|
|
1043
|
+
isSubscribed = true;
|
|
1044
|
+
const subscribeParams = {
|
|
1076
1045
|
node,
|
|
1077
1046
|
value$: obs$,
|
|
1078
|
-
value: isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked]) ? void 0 : existingValue,
|
|
1079
|
-
mode: syncOptions.mode,
|
|
1080
|
-
refresh: sync,
|
|
1081
|
-
options: syncOptions,
|
|
1082
1047
|
lastSync,
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
var _a3;
|
|
1101
|
-
modeBeforeReset = getParams.mode;
|
|
1102
|
-
getParams.mode = "set";
|
|
1103
|
-
return (_a3 = syncStateValue.resetPersistence) == null ? void 0 : _a3.call(syncStateValue);
|
|
1048
|
+
update: (params) => {
|
|
1049
|
+
when(
|
|
1050
|
+
() => !get || syncState$.isLoaded.get(),
|
|
1051
|
+
() => {
|
|
1052
|
+
when(waitFor || true, () => {
|
|
1053
|
+
params.mode || (params.mode = syncOptions.mode || "merge");
|
|
1054
|
+
onChange(params);
|
|
1055
|
+
if (!syncState$.isLoaded.peek()) {
|
|
1056
|
+
syncState$.assign({
|
|
1057
|
+
isLoaded: syncStateValue.numPendingRemoteLoads < 1,
|
|
1058
|
+
error: void 0,
|
|
1059
|
+
isGetting: syncStateValue.numPendingGets > 0
|
|
1060
|
+
});
|
|
1061
|
+
}
|
|
1062
|
+
});
|
|
1063
|
+
}
|
|
1064
|
+
);
|
|
1104
1065
|
},
|
|
1105
|
-
|
|
1066
|
+
refresh: () => when(syncState$.isLoaded, sync),
|
|
1067
|
+
onError: (error) => onGetError(error, {
|
|
1068
|
+
source: "subscribe",
|
|
1069
|
+
subscribeParams,
|
|
1070
|
+
type: "get",
|
|
1071
|
+
retry: {}
|
|
1072
|
+
})
|
|
1106
1073
|
};
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1074
|
+
unsubscribe = subscribe2(subscribeParams);
|
|
1075
|
+
registerMiddleware(node, "listeners-cleared", () => {
|
|
1076
|
+
if (unsubscribe) {
|
|
1077
|
+
isSubscribed = false;
|
|
1078
|
+
unsubscribe();
|
|
1079
|
+
unsubscribe = void 0;
|
|
1080
|
+
}
|
|
1081
|
+
});
|
|
1082
|
+
registerMiddleware(node, "listener-added", () => {
|
|
1083
|
+
if (!isSubscribed) {
|
|
1084
|
+
doSubscribe();
|
|
1085
|
+
}
|
|
1086
|
+
});
|
|
1087
|
+
};
|
|
1088
|
+
if (waitFor) {
|
|
1089
|
+
whenReady(waitFor, doSubscribe);
|
|
1090
|
+
} else {
|
|
1091
|
+
doSubscribe();
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
const existingValue = getNodeValue(node);
|
|
1095
|
+
if (get) {
|
|
1096
|
+
const getParams = {
|
|
1097
|
+
node,
|
|
1098
|
+
value$: obs$,
|
|
1099
|
+
value: isFunction(existingValue) || (existingValue == null ? void 0 : existingValue[symbolLinked]) ? void 0 : existingValue,
|
|
1100
|
+
mode: syncOptions.mode,
|
|
1101
|
+
refresh: sync,
|
|
1102
|
+
options: syncOptions,
|
|
1103
|
+
lastSync,
|
|
1104
|
+
updateLastSync: (lastSync2) => getParams.lastSync = lastSync2,
|
|
1105
|
+
onError: onGetError,
|
|
1106
|
+
retryNum: 0,
|
|
1107
|
+
cancelRetry: false
|
|
1108
|
+
};
|
|
1109
|
+
let modeBeforeReset = void 0;
|
|
1110
|
+
const beforeGetParams = {
|
|
1111
|
+
value: getParams.value,
|
|
1112
|
+
lastSync,
|
|
1113
|
+
pendingChanges: pending && !isEmpty(pending) ? pending : void 0,
|
|
1114
|
+
clearPendingChanges: async () => {
|
|
1115
|
+
localState.pendingChanges = {};
|
|
1116
|
+
await updateMetadataImmediate(obs$, localState, syncState$, syncOptions, {
|
|
1117
|
+
pending: localState.pendingChanges
|
|
1118
1118
|
});
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1119
|
+
},
|
|
1120
|
+
resetCache: () => {
|
|
1121
|
+
var _a3;
|
|
1122
|
+
modeBeforeReset = getParams.mode;
|
|
1123
|
+
getParams.mode = "set";
|
|
1124
|
+
return (_a3 = syncStateValue.resetPersistence) == null ? void 0 : _a3.call(syncStateValue);
|
|
1125
|
+
},
|
|
1126
|
+
cancel: false
|
|
1127
|
+
};
|
|
1128
|
+
(_a2 = syncOptions.onBeforeGet) == null ? void 0 : _a2.call(syncOptions, beforeGetParams);
|
|
1129
|
+
if (!beforeGetParams.cancel) {
|
|
1130
|
+
syncState$.assign({
|
|
1131
|
+
numPendingGets: (syncStateValue.numPendingGets || 0) + 1,
|
|
1132
|
+
isGetting: true
|
|
1133
|
+
});
|
|
1134
|
+
const got = runWithRetry(getParams, syncOptions.retry, node, (retryEvent) => {
|
|
1135
|
+
const params = getParams;
|
|
1136
|
+
params.cancelRetry = retryEvent.cancelRetry;
|
|
1137
|
+
params.retryNum = retryEvent.retryNum;
|
|
1138
|
+
return get(params);
|
|
1139
|
+
});
|
|
1140
|
+
const numGets = node.numGets = (node.numGets || 0) + 1;
|
|
1141
|
+
const handle = (value) => {
|
|
1142
|
+
syncState$.numPendingGets.set((v) => v - 1);
|
|
1143
|
+
if (isWaitingForLoad) {
|
|
1144
|
+
isWaitingForLoad = false;
|
|
1145
|
+
syncStateValue.numPendingRemoteLoads--;
|
|
1146
|
+
}
|
|
1147
|
+
if (numGets >= (node.getNumResolved || 0)) {
|
|
1148
|
+
node.getNumResolved = node.numGets;
|
|
1149
|
+
onChange({
|
|
1150
|
+
value,
|
|
1151
|
+
lastSync: getParams.lastSync,
|
|
1152
|
+
mode: getParams.mode
|
|
1151
1153
|
});
|
|
1152
|
-
} else {
|
|
1153
|
-
handle(got);
|
|
1154
1154
|
}
|
|
1155
|
+
if (modeBeforeReset) {
|
|
1156
|
+
getParams.mode = modeBeforeReset;
|
|
1157
|
+
modeBeforeReset = void 0;
|
|
1158
|
+
}
|
|
1159
|
+
syncState$.assign({
|
|
1160
|
+
isLoaded: syncStateValue.numPendingRemoteLoads < 1,
|
|
1161
|
+
error: void 0,
|
|
1162
|
+
isGetting: syncStateValue.numPendingGets > 0
|
|
1163
|
+
});
|
|
1164
|
+
};
|
|
1165
|
+
if (isPromise$1(got)) {
|
|
1166
|
+
got.then(handle).catch((error) => {
|
|
1167
|
+
onGetError(error, { getParams, source: "get", type: "get", retry: getParams }, true);
|
|
1168
|
+
});
|
|
1169
|
+
} else {
|
|
1170
|
+
handle(got);
|
|
1155
1171
|
}
|
|
1156
1172
|
}
|
|
1157
|
-
};
|
|
1158
|
-
if (waitFor) {
|
|
1159
|
-
whenReady(waitFor, () => trackSelector(runGet, sync));
|
|
1160
|
-
} else {
|
|
1161
|
-
trackSelector(runGet, sync);
|
|
1162
1173
|
}
|
|
1174
|
+
};
|
|
1175
|
+
if (waitFor) {
|
|
1176
|
+
whenReady(waitFor, () => trackSelector(runGet, sync));
|
|
1163
1177
|
} else {
|
|
1164
|
-
|
|
1165
|
-
isLoaded: true,
|
|
1166
|
-
error: void 0
|
|
1167
|
-
});
|
|
1178
|
+
trackSelector(runGet, sync);
|
|
1168
1179
|
}
|
|
1169
1180
|
if (!isSynced) {
|
|
1170
1181
|
isSynced = true;
|