@legendapp/state 1.9.0 → 2.0.0-next.1
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/CHANGELOG.md +3 -0
- package/config/enableReactDirectRender.js +3 -0
- package/config/enableReactDirectRender.js.map +1 -1
- package/config/enableReactDirectRender.mjs +3 -0
- package/config/enableReactDirectRender.mjs.map +1 -1
- package/history.js +1 -1
- package/history.js.map +1 -1
- package/history.mjs +2 -2
- package/history.mjs.map +1 -1
- package/index.d.ts +6 -1
- package/index.js +105 -63
- package/index.js.map +1 -1
- package/index.mjs +106 -63
- package/index.mjs.map +1 -1
- package/package.json +1 -1
- package/persist.js +8 -9
- package/persist.js.map +1 -1
- package/persist.mjs +9 -10
- package/persist.mjs.map +1 -1
- package/react.js +15 -8
- package/react.js.map +1 -1
- package/react.mjs +15 -8
- package/react.mjs.map +1 -1
- package/src/ObservableObject.d.ts +1 -0
- package/src/batching.d.ts +0 -7
- package/src/globals.d.ts +2 -2
- package/src/observable.d.ts +8 -3
- package/src/observableInterfaces.d.ts +16 -2
- package/src/proxy.d.ts +5 -3
- package/src/react/reactInterfaces.d.ts +1 -1
- package/src/tracking.d.ts +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
## 1.9.0
|
|
2
|
+
- Feat: Nested computeds set their value on the raw object so that `get()` on the parent will include the values of child computeds
|
|
3
|
+
|
|
1
4
|
## 1.8.1
|
|
2
5
|
- Feat: Added findIDKey and optimized to internal
|
|
3
6
|
- Fix: Added more safety around dev-only assertions because they were throwing errors in some build systems
|
|
@@ -8,6 +8,9 @@ let isEnabled = false;
|
|
|
8
8
|
// Extracting the forwardRef inspired by https://github.com/mobxjs/mobx/blob/main/packages/mobx-react-lite/src/observer.ts
|
|
9
9
|
const hasSymbol = typeof Symbol === 'function' && Symbol.for;
|
|
10
10
|
function enableReactDirectRender() {
|
|
11
|
+
if (process.env.NODE_ENV === 'development') {
|
|
12
|
+
console.warn('[legend-state] enableReactDirectRender is deprecated and will be removed in version 2.0. Please convert it from {value} to <Memo>{value}</Memo>. See https://legendapp.com/open-source/state/migrating for more details.');
|
|
13
|
+
}
|
|
11
14
|
if (!isEnabled) {
|
|
12
15
|
isEnabled = true;
|
|
13
16
|
// Rendering observables directly inspired by Preact Signals: https://github.com/preactjs/signals/blob/main/packages/react/src/index.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enableReactDirectRender.js","sources":["../../../../src/config/enableReactDirectRender.ts"],"sourcesContent":[null],"names":["memo","useSelector","createElement","extraPrimitiveProps","extraPrimitiveActivators","ObservablePrimitiveClass"],"mappings":";;;;;;AAQA,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB;AACO,MAAM,SAAS,GAAkB,CAAC,OAAO,MAAM,KAAK,UAAU,IAAI,MAAM,CAAC,IAAI;SAEpE,uBAAuB,GAAA;
|
|
1
|
+
{"version":3,"file":"enableReactDirectRender.js","sources":["../../../../src/config/enableReactDirectRender.ts"],"sourcesContent":[null],"names":["memo","useSelector","createElement","extraPrimitiveProps","extraPrimitiveActivators","ObservablePrimitiveClass"],"mappings":";;;;;;AAQA,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB;AACO,MAAM,SAAS,GAAkB,CAAC,OAAO,MAAM,KAAK,UAAU,IAAI,MAAM,CAAC,IAAI;SAEpE,uBAAuB,GAAA;AACnC,IAAA,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE;AACxC,QAAA,OAAO,CAAC,IAAI,CACR,0NAA0N,CAC7N,CAAC;AACL,KAAA;IACD,IAAI,CAAC,SAAS,EAAE;QACZ,SAAS,GAAG,IAAI,CAAC;;;;QAKjB,MAAM,IAAI,GAAGA,UAAI,CAAC,SAAS,IAAI,CAAC,EAAE,IAAI,EAAgC,EAAA;AAClE,YAAA,OAAOC,mBAAW,CAAC,IAAI,CAAC,CAAC;AAC7B,SAAC,CAAC,CAAC;QAEH,MAAM,iBAAiB,GAAG,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,GAAIC,mBAAa,CAAC,GAAG,CAAS,CAAC,QAAQ,CAAC;QAEzG,MAAM,CAAC,GAAGC,yBAAmB,CAAC;QAC9B,MAAM,KAAK,GAAG,EAAkC,CAAC;;AAEjD,QAAAC,8BAAwB,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC/CA,8BAAwB,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;;AAGvD,QAAA,SAAS,GAAG,CAAC,GAAW,EAAE,KAAU,EAAA;AAChC,YAAA,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAClB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;SAC9C;AACD,QAAA,GAAG,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;AACnC,QAAA,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAClB,GAAG,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACnC,QAAA,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACjB,QAAA,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACjB,QAAA,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;AACvB,QAAA,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACpB,QAAA,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;;AAGrB,QAAA,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAM,EAAE,KAAU,KAAK,KAAK,CAAC,CAAC;AACzD,QAAA,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,GAAQ,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;;AAE9C,QAAA,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG;AACxB,YAAA,YAAY,EAAE,IAAI;YAClB,GAAG,GAAA;AACC,gBAAA,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;aACtB;SACJ,CAAC;QACF,KAAK,CAAC,KAAK,GAAG;AACV,YAAA,YAAY,EAAE,IAAI;YAClB,GAAG,GAAA;AACC,gBAAA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;aACzB;SACJ,CAAC;QAEF,MAAM,CAAC,gBAAgB,CAACC,8BAAwB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AACtE,KAAA;AACL;;;;;"}
|
|
@@ -6,6 +6,9 @@ let isEnabled = false;
|
|
|
6
6
|
// Extracting the forwardRef inspired by https://github.com/mobxjs/mobx/blob/main/packages/mobx-react-lite/src/observer.ts
|
|
7
7
|
const hasSymbol = typeof Symbol === 'function' && Symbol.for;
|
|
8
8
|
function enableReactDirectRender() {
|
|
9
|
+
if (process.env.NODE_ENV === 'development') {
|
|
10
|
+
console.warn('[legend-state] enableReactDirectRender is deprecated and will be removed in version 2.0. Please convert it from {value} to <Memo>{value}</Memo>. See https://legendapp.com/open-source/state/migrating for more details.');
|
|
11
|
+
}
|
|
9
12
|
if (!isEnabled) {
|
|
10
13
|
isEnabled = true;
|
|
11
14
|
// Rendering observables directly inspired by Preact Signals: https://github.com/preactjs/signals/blob/main/packages/react/src/index.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enableReactDirectRender.mjs","sources":["../../../../src/config/enableReactDirectRender.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAQA,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB;AACO,MAAM,SAAS,GAAkB,CAAC,OAAO,MAAM,KAAK,UAAU,IAAI,MAAM,CAAC,IAAI;SAEpE,uBAAuB,GAAA;
|
|
1
|
+
{"version":3,"file":"enableReactDirectRender.mjs","sources":["../../../../src/config/enableReactDirectRender.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAQA,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB;AACO,MAAM,SAAS,GAAkB,CAAC,OAAO,MAAM,KAAK,UAAU,IAAI,MAAM,CAAC,IAAI;SAEpE,uBAAuB,GAAA;AACnC,IAAA,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE;AACxC,QAAA,OAAO,CAAC,IAAI,CACR,0NAA0N,CAC7N,CAAC;AACL,KAAA;IACD,IAAI,CAAC,SAAS,EAAE;QACZ,SAAS,GAAG,IAAI,CAAC;;;;QAKjB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,IAAI,CAAC,EAAE,IAAI,EAAgC,EAAA;AAClE,YAAA,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;AAC7B,SAAC,CAAC,CAAC;QAEH,MAAM,iBAAiB,GAAG,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,GAAI,aAAa,CAAC,GAAG,CAAS,CAAC,QAAQ,CAAC;QAEzG,MAAM,CAAC,GAAG,mBAAmB,CAAC;QAC9B,MAAM,KAAK,GAAG,EAAkC,CAAC;;AAEjD,QAAA,wBAAwB,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC/C,wBAAwB,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;;AAGvD,QAAA,SAAS,GAAG,CAAC,GAAW,EAAE,KAAU,EAAA;AAChC,YAAA,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAClB,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;SAC9C;AACD,QAAA,GAAG,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;AACnC,QAAA,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAClB,GAAG,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACnC,QAAA,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACjB,QAAA,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACjB,QAAA,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;AACvB,QAAA,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACpB,QAAA,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;;AAGrB,QAAA,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAM,EAAE,KAAU,KAAK,KAAK,CAAC,CAAC;AACzD,QAAA,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,GAAQ,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;;AAE9C,QAAA,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG;AACxB,YAAA,YAAY,EAAE,IAAI;YAClB,GAAG,GAAA;AACC,gBAAA,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;aACtB;SACJ,CAAC;QACF,KAAK,CAAC,KAAK,GAAG;AACV,YAAA,YAAY,EAAE,IAAI;YAClB,GAAG,GAAA;AACC,gBAAA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;aACzB;SACJ,CAAC;QAEF,MAAM,CAAC,gBAAgB,CAAC,wBAAwB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AACtE,KAAA;AACL;;;;"}
|
package/history.js
CHANGED
|
@@ -7,7 +7,7 @@ function trackHistory(obs, targetObservable) {
|
|
|
7
7
|
obs.onChange(({ changes }) => {
|
|
8
8
|
// Don't save history if this is a remote change.
|
|
9
9
|
// History will be saved remotely by the client making the local change.
|
|
10
|
-
if (!state.
|
|
10
|
+
if (!state.internal.globalState.isLoadingRemote && !state.internal.globalState.isLoadingLocal) {
|
|
11
11
|
const time = Date.now().toString();
|
|
12
12
|
// Save to history observable by date, with the previous value
|
|
13
13
|
for (let i = 0; i < changes.length; i++) {
|
package/history.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"history.js","sources":["../../src/history/trackHistory.ts"],"sourcesContent":[null],"names":["observable","
|
|
1
|
+
{"version":3,"file":"history.js","sources":["../../src/history/trackHistory.ts"],"sourcesContent":[null],"names":["observable","internal","constructObjectWithPath","mergeIntoObservable"],"mappings":";;;;AAYgB,SAAA,YAAY,CACxB,GAA0B,EAC1B,gBAA6E,EAAA;IAE7E,MAAM,OAAO,GAAG,gBAAgB,KAAhB,IAAA,IAAA,gBAAgB,cAAhB,gBAAgB,GAAIA,gBAAU,EAAyC,CAAC;IAExF,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,KAAI;;;AAGzB,QAAA,IAAI,CAACC,cAAQ,CAAC,WAAW,CAAC,eAAe,IAAI,CAACA,cAAQ,CAAC,WAAW,CAAC,cAAc,EAAE;YAC/E,MAAM,IAAI,GAAsB,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;;AAGtD,YAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACrC,gBAAA,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;gBAEnD,MAAM,GAAG,GAAGC,6BAAuB,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;gBACjEC,yBAAmB,CAAE,OAAe,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AACpD,aAAA;AACJ,SAAA;AACL,KAAC,CAAC,CAAC;AAEH,IAAA,OAAO,OAAO,CAAC;AACnB;;;;"}
|
package/history.mjs
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { observable,
|
|
1
|
+
import { observable, internal, constructObjectWithPath, mergeIntoObservable } from '@legendapp/state';
|
|
2
2
|
|
|
3
3
|
function trackHistory(obs, targetObservable) {
|
|
4
4
|
const history = targetObservable !== null && targetObservable !== void 0 ? targetObservable : observable();
|
|
5
5
|
obs.onChange(({ changes }) => {
|
|
6
6
|
// Don't save history if this is a remote change.
|
|
7
7
|
// History will be saved remotely by the client making the local change.
|
|
8
|
-
if (!
|
|
8
|
+
if (!internal.globalState.isLoadingRemote && !internal.globalState.isLoadingLocal) {
|
|
9
9
|
const time = Date.now().toString();
|
|
10
10
|
// Save to history observable by date, with the previous value
|
|
11
11
|
for (let i = 0; i < changes.length; i++) {
|
package/history.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"history.mjs","sources":["../../src/history/trackHistory.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAYgB,SAAA,YAAY,CACxB,GAA0B,EAC1B,gBAA6E,EAAA;IAE7E,MAAM,OAAO,GAAG,gBAAgB,KAAhB,IAAA,IAAA,gBAAgB,cAAhB,gBAAgB,GAAI,UAAU,EAAyC,CAAC;IAExF,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,KAAI;;;AAGzB,QAAA,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE;
|
|
1
|
+
{"version":3,"file":"history.mjs","sources":["../../src/history/trackHistory.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAYgB,SAAA,YAAY,CACxB,GAA0B,EAC1B,gBAA6E,EAAA;IAE7E,MAAM,OAAO,GAAG,gBAAgB,KAAhB,IAAA,IAAA,gBAAgB,cAAhB,gBAAgB,GAAI,UAAU,EAAyC,CAAC;IAExF,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,KAAI;;;AAGzB,QAAA,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,eAAe,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,cAAc,EAAE;YAC/E,MAAM,IAAI,GAAsB,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;;AAGtD,YAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AACrC,gBAAA,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;gBAEnD,MAAM,GAAG,GAAG,uBAAuB,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;gBACjE,mBAAmB,CAAE,OAAe,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AACpD,aAAA;AACJ,SAAA;AACL,KAAC,CAAC,CAAC;AAEH,IAAA,OAAO,OAAO,CAAC;AACnB;;;;"}
|
package/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { computeSelector, constructObjectWithPath, deconstructObjectWithPath, getObservableIndex, isObservable, isObservableValueReady, lockObservable, mergeIntoObservable, opaqueObject, setAtPath, setInObservableAtPath, setSilently } from './src/helpers';
|
|
2
2
|
export { trackSelector, } from './src/trackSelector';
|
|
3
3
|
export { observable, observablePrimitive } from './src/observable';
|
|
4
|
-
export { batch, beginBatch, endBatch
|
|
4
|
+
export { batch, beginBatch, endBatch } from './src/batching';
|
|
5
5
|
export { computed } from './src/computed';
|
|
6
6
|
export { event } from './src/event';
|
|
7
7
|
export { observe } from './src/observe';
|
|
@@ -19,6 +19,11 @@ export declare const internal: {
|
|
|
19
19
|
get: typeof get;
|
|
20
20
|
getNode: typeof getNode;
|
|
21
21
|
getProxy: typeof getProxy;
|
|
22
|
+
globalState: {
|
|
23
|
+
isLoadingLocal: boolean;
|
|
24
|
+
isLoadingRemote: boolean;
|
|
25
|
+
isMerging: boolean;
|
|
26
|
+
};
|
|
22
27
|
optimized: symbol;
|
|
23
28
|
peek: typeof peek;
|
|
24
29
|
set: typeof set;
|
package/index.js
CHANGED
|
@@ -54,7 +54,6 @@ let trackCount = 0;
|
|
|
54
54
|
const trackingQueue = [];
|
|
55
55
|
const tracking = {
|
|
56
56
|
current: undefined,
|
|
57
|
-
inRemoteChange: false,
|
|
58
57
|
inRender: false,
|
|
59
58
|
};
|
|
60
59
|
function beginTracking(inRender) {
|
|
@@ -102,8 +101,9 @@ const symbolOpaque = Symbol('opaque');
|
|
|
102
101
|
const optimized = Symbol('optimized');
|
|
103
102
|
const extraPrimitiveActivators = new Map();
|
|
104
103
|
const extraPrimitiveProps = new Map();
|
|
105
|
-
const __devExtractFunctionsAndComputedsNodes = process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test' ? new Set() : undefined;
|
|
106
104
|
const globalState = {
|
|
105
|
+
isLoadingLocal: false,
|
|
106
|
+
isLoadingRemote: false,
|
|
107
107
|
isMerging: false,
|
|
108
108
|
};
|
|
109
109
|
function checkActivate(node) {
|
|
@@ -244,37 +244,13 @@ function extractFunction(node, key, fnOrComputed, computedChildNode) {
|
|
|
244
244
|
node.root.computedChildrenNeedingActivation.push(computedChildNode);
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
|
-
function extractFunctionsAndComputeds(obj, node) {
|
|
248
|
-
if ((process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') &&
|
|
249
|
-
typeof __devExtractFunctionsAndComputedsNodes !== 'undefined') {
|
|
250
|
-
if (__devExtractFunctionsAndComputedsNodes.has(obj)) {
|
|
251
|
-
console.error('[legend-state] Circular reference detected in object. You may want to use opaqueObject to stop traversing child nodes.', obj);
|
|
252
|
-
return false;
|
|
253
|
-
}
|
|
254
|
-
__devExtractFunctionsAndComputedsNodes.add(obj);
|
|
255
|
-
}
|
|
256
|
-
for (const k in obj) {
|
|
257
|
-
const v = obj[k];
|
|
258
|
-
if (typeof v === 'function') {
|
|
259
|
-
extractFunction(node, k, v);
|
|
260
|
-
}
|
|
261
|
-
else if (typeof v == 'object' && v !== null && v !== undefined) {
|
|
262
|
-
const childNode = getNode(v);
|
|
263
|
-
if (childNode === null || childNode === void 0 ? void 0 : childNode.isComputed) {
|
|
264
|
-
extractFunction(node, k, v, childNode);
|
|
265
|
-
}
|
|
266
|
-
else if (!v[symbolOpaque]) {
|
|
267
|
-
extractFunctionsAndComputeds(obj[k], getChildNode(node, k));
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
247
|
|
|
273
248
|
let timeout;
|
|
274
249
|
let numInBatch = 0;
|
|
275
250
|
let isRunningBatch = false;
|
|
276
251
|
let didDelayEndBatch = false;
|
|
277
252
|
let _afterBatch = [];
|
|
253
|
+
let _queuedBatches = [];
|
|
278
254
|
let _batchMap = new Map();
|
|
279
255
|
function onActionTimeout() {
|
|
280
256
|
if (_batchMap.size > 0) {
|
|
@@ -411,6 +387,8 @@ function batchNotifyChanges(changesInBatch, immediate) {
|
|
|
411
387
|
});
|
|
412
388
|
}
|
|
413
389
|
function runBatch() {
|
|
390
|
+
// Save batch locally and reset _batchMap first because a new batch could begin while looping over callbacks.
|
|
391
|
+
// This can happen with observableComputed for example.
|
|
414
392
|
const map = _batchMap;
|
|
415
393
|
_batchMap = new Map();
|
|
416
394
|
const changesInBatch = new Map();
|
|
@@ -425,7 +403,15 @@ function runBatch() {
|
|
|
425
403
|
}
|
|
426
404
|
function batch(fn, onComplete) {
|
|
427
405
|
if (onComplete) {
|
|
428
|
-
|
|
406
|
+
// If there's an onComplete we need a batch that's fully isolated from others to ensure it wraps only the given changes.
|
|
407
|
+
// So if already batching, push this batch onto a queue and run it after the current batch is fully done.
|
|
408
|
+
if (isRunningBatch) {
|
|
409
|
+
_queuedBatches.push([fn, onComplete]);
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
_afterBatch.push(onComplete);
|
|
414
|
+
}
|
|
429
415
|
}
|
|
430
416
|
beginBatch();
|
|
431
417
|
try {
|
|
@@ -475,17 +461,17 @@ function endBatch(force) {
|
|
|
475
461
|
didDelayEndBatch = false;
|
|
476
462
|
endBatch(true);
|
|
477
463
|
}
|
|
464
|
+
const queued = _queuedBatches;
|
|
465
|
+
if (queued.length) {
|
|
466
|
+
_queuedBatches = [];
|
|
467
|
+
for (let i = 0; i < queued.length; i++) {
|
|
468
|
+
const [fn, onComplete] = queued[i];
|
|
469
|
+
batch(fn, onComplete);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
478
472
|
}
|
|
479
473
|
}
|
|
480
474
|
}
|
|
481
|
-
function afterBatch(fn) {
|
|
482
|
-
if (numInBatch > 0) {
|
|
483
|
-
_afterBatch.push(fn);
|
|
484
|
-
}
|
|
485
|
-
else {
|
|
486
|
-
fn();
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
475
|
|
|
490
476
|
function isObservable(obs) {
|
|
491
477
|
return obs && !!obs[symbolGetNode];
|
|
@@ -1020,14 +1006,6 @@ const proxyHandler = {
|
|
|
1020
1006
|
if (p === symbolGetNode) {
|
|
1021
1007
|
return node;
|
|
1022
1008
|
}
|
|
1023
|
-
if (node.isComputed) {
|
|
1024
|
-
if (node.proxyFn) {
|
|
1025
|
-
return node.proxyFn(p);
|
|
1026
|
-
}
|
|
1027
|
-
else {
|
|
1028
|
-
checkActivate(node);
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
1009
|
// If this node is linked to another observable then forward to the target's handler.
|
|
1032
1010
|
// The exception is onChange because it needs to listen to this node for changes.
|
|
1033
1011
|
if (node.linkedToNode && p !== 'onChange') {
|
|
@@ -1060,6 +1038,14 @@ const proxyHandler = {
|
|
|
1060
1038
|
}
|
|
1061
1039
|
};
|
|
1062
1040
|
}
|
|
1041
|
+
if (node.isComputed) {
|
|
1042
|
+
if (node.proxyFn && !fn) {
|
|
1043
|
+
return node.proxyFn(p);
|
|
1044
|
+
}
|
|
1045
|
+
else {
|
|
1046
|
+
checkActivate(node);
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1063
1049
|
const property = observableProperties.get(p);
|
|
1064
1050
|
if (property) {
|
|
1065
1051
|
return property.get(node);
|
|
@@ -1365,12 +1351,21 @@ function updateNodesAndNotify(node, newValue, prevValue, childNode, isPrim, isRo
|
|
|
1365
1351
|
whenOptimizedOnlyIf = (newValue === null || newValue === void 0 ? void 0 : newValue.length) !== (prevValue === null || prevValue === void 0 ? void 0 : prevValue.length);
|
|
1366
1352
|
}
|
|
1367
1353
|
}
|
|
1368
|
-
if (isPrim || !newValue || isEmpty(newValue) ? newValue !== prevValue : hasADiff) {
|
|
1354
|
+
if (isPrim || !newValue || (isEmpty(newValue) && !isEmpty(prevValue)) ? newValue !== prevValue : hasADiff) {
|
|
1369
1355
|
// Notify for this element if something inside it has changed
|
|
1370
1356
|
notify(isPrim && isRoot ? node : childNode, newValue, prevValue, (level !== null && level !== void 0 ? level : prevValue === undefined) ? -1 : hasADiff ? 0 : 1, whenOptimizedOnlyIf);
|
|
1371
1357
|
}
|
|
1372
1358
|
endBatch();
|
|
1373
1359
|
}
|
|
1360
|
+
function extractPromise(node, value) {
|
|
1361
|
+
value.status = 'pending';
|
|
1362
|
+
value.catch((error) => {
|
|
1363
|
+
set(node, { error, status: 'rejected' });
|
|
1364
|
+
});
|
|
1365
|
+
value.then((value) => {
|
|
1366
|
+
set(node, value);
|
|
1367
|
+
});
|
|
1368
|
+
}
|
|
1374
1369
|
|
|
1375
1370
|
const fns = ['get', 'set', 'peek', 'onChange', 'toggle'];
|
|
1376
1371
|
function ObservablePrimitiveClass(node) {
|
|
@@ -1413,10 +1408,39 @@ ObservablePrimitiveClass.prototype.delete = function () {
|
|
|
1413
1408
|
return this;
|
|
1414
1409
|
};
|
|
1415
1410
|
|
|
1411
|
+
const __devExtractFunctionsAndComputedsNodes = process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test' ? new Set() : undefined;
|
|
1412
|
+
function extractFunctionsAndComputeds(node, obj) {
|
|
1413
|
+
if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
|
|
1414
|
+
if (__devExtractFunctionsAndComputedsNodes.has(obj)) {
|
|
1415
|
+
console.error('[legend-state] Circular reference detected in object. You may want to use opaqueObject to stop traversing child nodes.', obj);
|
|
1416
|
+
return false;
|
|
1417
|
+
}
|
|
1418
|
+
__devExtractFunctionsAndComputedsNodes.add(obj);
|
|
1419
|
+
}
|
|
1420
|
+
for (const k in obj) {
|
|
1421
|
+
const v = obj[k];
|
|
1422
|
+
if (isPromise(v)) {
|
|
1423
|
+
extractPromise(getChildNode(node, k), v);
|
|
1424
|
+
}
|
|
1425
|
+
else if (typeof v === 'function') {
|
|
1426
|
+
extractFunction(node, k, v);
|
|
1427
|
+
}
|
|
1428
|
+
else if (typeof v == 'object' && v !== null && v !== undefined) {
|
|
1429
|
+
const childNode = getNode(v);
|
|
1430
|
+
if (childNode === null || childNode === void 0 ? void 0 : childNode.isComputed) {
|
|
1431
|
+
extractFunction(node, k, v, childNode);
|
|
1432
|
+
delete obj[k];
|
|
1433
|
+
}
|
|
1434
|
+
else if (!v[symbolOpaque]) {
|
|
1435
|
+
extractFunctionsAndComputeds(getChildNode(node, k), obj[k]);
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1416
1440
|
function createObservable(value, makePrimitive) {
|
|
1417
1441
|
const valueIsPromise = isPromise(value);
|
|
1418
1442
|
const root = {
|
|
1419
|
-
_:
|
|
1443
|
+
_: value,
|
|
1420
1444
|
};
|
|
1421
1445
|
const node = {
|
|
1422
1446
|
root,
|
|
@@ -1426,19 +1450,14 @@ function createObservable(value, makePrimitive) {
|
|
|
1426
1450
|
? new ObservablePrimitiveClass(node)
|
|
1427
1451
|
: getProxy(node);
|
|
1428
1452
|
if (valueIsPromise) {
|
|
1429
|
-
value
|
|
1430
|
-
obs.set({ error });
|
|
1431
|
-
});
|
|
1432
|
-
value.then((value) => {
|
|
1433
|
-
obs.set(value);
|
|
1434
|
-
});
|
|
1453
|
+
extractPromise(node, value);
|
|
1435
1454
|
}
|
|
1436
1455
|
else if (!prim) {
|
|
1437
1456
|
if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
|
|
1438
1457
|
__devExtractFunctionsAndComputedsNodes.clear();
|
|
1439
1458
|
}
|
|
1440
1459
|
if (value) {
|
|
1441
|
-
extractFunctionsAndComputeds(
|
|
1460
|
+
extractFunctionsAndComputeds(node, value);
|
|
1442
1461
|
}
|
|
1443
1462
|
}
|
|
1444
1463
|
return obs;
|
|
@@ -1516,6 +1535,7 @@ function computed(compute, set$1) {
|
|
|
1516
1535
|
prevNode.linkedFromNodes.delete(node);
|
|
1517
1536
|
node.linkedToNode = undefined;
|
|
1518
1537
|
}
|
|
1538
|
+
const childNode = node.computedChildOfNode;
|
|
1519
1539
|
if (isObservable(val)) {
|
|
1520
1540
|
// If the computed is a proxy to another observable
|
|
1521
1541
|
// link it to the target observable
|
|
@@ -1544,14 +1564,22 @@ function computed(compute, set$1) {
|
|
|
1544
1564
|
// Update the computed value
|
|
1545
1565
|
setter(node, val);
|
|
1546
1566
|
// If the computed is a child of an observable set the value on it
|
|
1547
|
-
if (
|
|
1548
|
-
|
|
1567
|
+
if (childNode) {
|
|
1568
|
+
let didUnlock = false;
|
|
1569
|
+
if (childNode.root.locked) {
|
|
1570
|
+
childNode.root.locked = false;
|
|
1571
|
+
didUnlock = true;
|
|
1572
|
+
}
|
|
1573
|
+
setter(childNode, val);
|
|
1574
|
+
if (didUnlock) {
|
|
1575
|
+
childNode.root.locked = true;
|
|
1576
|
+
}
|
|
1549
1577
|
}
|
|
1550
1578
|
// Re-lock the computed node
|
|
1551
1579
|
lockObservable(obs, true);
|
|
1552
1580
|
}
|
|
1553
|
-
else if (
|
|
1554
|
-
setNodeValue(
|
|
1581
|
+
else if (childNode) {
|
|
1582
|
+
setNodeValue(childNode, val);
|
|
1555
1583
|
}
|
|
1556
1584
|
isSetAfterActivated = true;
|
|
1557
1585
|
};
|
|
@@ -1598,9 +1626,9 @@ function event() {
|
|
|
1598
1626
|
};
|
|
1599
1627
|
}
|
|
1600
1628
|
|
|
1601
|
-
function proxy(get) {
|
|
1629
|
+
function proxy(get, set) {
|
|
1602
1630
|
// Create an observable for this computed variable
|
|
1603
|
-
const obs = observable();
|
|
1631
|
+
const obs = observable({});
|
|
1604
1632
|
lockObservable(obs, true);
|
|
1605
1633
|
const mapTargets = new Map();
|
|
1606
1634
|
const node = getNode(obs);
|
|
@@ -1608,8 +1636,19 @@ function proxy(get) {
|
|
|
1608
1636
|
node.proxyFn = (key) => {
|
|
1609
1637
|
let target = mapTargets.get(key);
|
|
1610
1638
|
if (!target) {
|
|
1611
|
-
|
|
1639
|
+
// Note: Coercing typescript to allow undefined for set in computed because we don't want the public interface to allow undefined
|
|
1640
|
+
target = computed(() => get(key), (set ? (value) => set(key, value) : undefined));
|
|
1612
1641
|
mapTargets.set(key, target);
|
|
1642
|
+
extractFunction(node, key, target, getNode(target));
|
|
1643
|
+
if (node.computedChildOfNode) {
|
|
1644
|
+
onChange(getNode(target), ({ value, getPrevious }) => {
|
|
1645
|
+
const previous = getPrevious();
|
|
1646
|
+
// Set the raw value on the proxy's parent
|
|
1647
|
+
setNodeValue(node.computedChildOfNode, node.root._);
|
|
1648
|
+
// Notify the proxy
|
|
1649
|
+
notify(getChildNode(node, key), value, previous, 0);
|
|
1650
|
+
});
|
|
1651
|
+
}
|
|
1613
1652
|
}
|
|
1614
1653
|
return target;
|
|
1615
1654
|
};
|
|
@@ -1621,7 +1660,7 @@ function _when(predicate, effect, checkReady) {
|
|
|
1621
1660
|
// Create a wrapping fn that calls the effect if predicate returns true
|
|
1622
1661
|
function run(e) {
|
|
1623
1662
|
const ret = computeSelector(predicate);
|
|
1624
|
-
if (checkReady ? isObservableValueReady(ret) : ret) {
|
|
1663
|
+
if (!isPromise(ret) && (checkReady ? isObservableValueReady(ret) : ret)) {
|
|
1625
1664
|
value = ret;
|
|
1626
1665
|
// If value is truthy then run the effect
|
|
1627
1666
|
effect === null || effect === void 0 ? void 0 : effect(ret);
|
|
@@ -1633,7 +1672,10 @@ function _when(predicate, effect, checkReady) {
|
|
|
1633
1672
|
observe(run);
|
|
1634
1673
|
// If first run resulted in a truthy value just return it.
|
|
1635
1674
|
// It will have set e.cancel so no need to dispose
|
|
1636
|
-
if (value
|
|
1675
|
+
if (isPromise(value)) {
|
|
1676
|
+
return effect ? value.then(effect) : value;
|
|
1677
|
+
}
|
|
1678
|
+
else if (value !== undefined) {
|
|
1637
1679
|
return Promise.resolve(value);
|
|
1638
1680
|
}
|
|
1639
1681
|
else {
|
|
@@ -1693,6 +1735,7 @@ const internal = {
|
|
|
1693
1735
|
get,
|
|
1694
1736
|
getNode,
|
|
1695
1737
|
getProxy,
|
|
1738
|
+
globalState,
|
|
1696
1739
|
optimized,
|
|
1697
1740
|
peek,
|
|
1698
1741
|
set,
|
|
@@ -1702,7 +1745,6 @@ const internal = {
|
|
|
1702
1745
|
};
|
|
1703
1746
|
|
|
1704
1747
|
exports.ObservablePrimitiveClass = ObservablePrimitiveClass;
|
|
1705
|
-
exports.afterBatch = afterBatch;
|
|
1706
1748
|
exports.batch = batch;
|
|
1707
1749
|
exports.beginBatch = beginBatch;
|
|
1708
1750
|
exports.beginTracking = beginTracking;
|