@legendapp/state 0.23.2 → 1.0.0-rc.2

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.
Files changed (63) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +4 -0
  3. package/helpers/pageHash.js +1 -1
  4. package/helpers/pageHash.js.map +1 -1
  5. package/helpers/pageHash.mjs +1 -1
  6. package/helpers/pageHash.mjs.map +1 -1
  7. package/helpers/pageHashParams.js +1 -1
  8. package/helpers/pageHashParams.js.map +1 -1
  9. package/helpers/pageHashParams.mjs +1 -1
  10. package/helpers/pageHashParams.mjs.map +1 -1
  11. package/history.js +3 -3
  12. package/history.js.map +1 -1
  13. package/history.mjs +4 -4
  14. package/history.mjs.map +1 -1
  15. package/index.d.ts +2 -2
  16. package/index.js +151 -81
  17. package/index.js.map +1 -1
  18. package/index.mjs +148 -78
  19. package/index.mjs.map +1 -1
  20. package/package.json +1 -1
  21. package/persist-plugins/indexeddb-preloader.js +16 -10
  22. package/persist-plugins/indexeddb-preloader.js.map +1 -1
  23. package/persist-plugins/indexeddb-preloader.mjs +16 -10
  24. package/persist-plugins/indexeddb-preloader.mjs.map +1 -1
  25. package/persist-plugins/indexeddb.d.ts +3 -2
  26. package/persist-plugins/indexeddb.js +92 -56
  27. package/persist-plugins/indexeddb.js.map +1 -1
  28. package/persist-plugins/indexeddb.mjs +93 -57
  29. package/persist-plugins/indexeddb.mjs.map +1 -1
  30. package/persist-plugins/local-storage.d.ts +4 -3
  31. package/persist-plugins/local-storage.js +18 -8
  32. package/persist-plugins/local-storage.js.map +1 -1
  33. package/persist-plugins/local-storage.mjs +18 -8
  34. package/persist-plugins/local-storage.mjs.map +1 -1
  35. package/persist-plugins/mmkv.d.ts +3 -2
  36. package/persist-plugins/mmkv.js +27 -18
  37. package/persist-plugins/mmkv.js.map +1 -1
  38. package/persist-plugins/mmkv.mjs +27 -18
  39. package/persist-plugins/mmkv.mjs.map +1 -1
  40. package/persist.d.ts +3 -2
  41. package/persist.js +292 -113
  42. package/persist.js.map +1 -1
  43. package/persist.mjs +292 -114
  44. package/persist.mjs.map +1 -1
  45. package/react-hooks/usePersistedObservable.js.map +1 -1
  46. package/react-hooks/usePersistedObservable.mjs.map +1 -1
  47. package/react.js +1 -1
  48. package/react.js.map +1 -1
  49. package/react.mjs +2 -2
  50. package/react.mjs.map +1 -1
  51. package/src/batching.d.ts +3 -10
  52. package/src/helpers.d.ts +5 -4
  53. package/src/notify.d.ts +1 -1
  54. package/src/observableInterfaces.d.ts +56 -17
  55. package/src/onChange.d.ts +4 -1
  56. package/src/persist/fieldTransformer.d.ts +8 -3
  57. package/src/persist/persistHelpers.d.ts +2 -0
  58. package/src/persist/persistObservable.d.ts +7 -3
  59. package/src/persist-plugins/indexeddb.d.ts +3 -2
  60. package/src/persist-plugins/local-storage.d.ts +4 -3
  61. package/src/persist-plugins/mmkv.d.ts +3 -2
  62. package/trace.js.map +1 -1
  63. package/trace.mjs.map +1 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,28 @@
1
+ ## 1.0.0-rc.2
2
+
3
+ - Feature: `batch` has a new `onComplete `batch(callback, onComplete)` parameter to run a function after the batch commits. This can be useful for cleaning up a temporary state while batching.
4
+ - Fix: onChange with `initial` option fires immediately rather than going through batching process
5
+ - Fix: Applying pending changes on load was writing back to local persistence unnecessarily
6
+ - Perf: Improve performance of `mergeIntoObservable` by just doing a `set` if a target property is empty and doesn't need merging logic
7
+ - Perf: Improve persistence overall by using more targeted approaches than `mergeIntoObservable`
8
+
9
+ ## 1.0.0-rc.1
10
+
11
+ - Fix: Incrementing a value from 0 with a function (`value.set((prev) => prev + 1)`) was not firing a callback the first time
12
+
13
+
14
+ ## 1.0.0-rc.0
15
+
16
+ - Breaking: `onChange` function changed to take an options object as a second parameter with a new `initial` option that makes it fire immediately with the current value.
17
+ - Breaking: `onChange` callback receives an object parameter instead of many arguments. This adds more flexibility for callers who care about different values in the change object.
18
+ - Fix: `mergeIntoObservable` was not working correctly in some edge cases.
19
+ - Fix: IndexedDB persistence improved for many edge cases, with some fixes and performance improvements
20
+ - Fix: Persistence layers overall improved with more stability and better performance
21
+
22
+ ## 0.23.1
23
+
24
+ - Fix: Not notifying on change of dates
25
+
1
26
  ## 0.23.0
2
27
 
3
28
  - Breaking: Improved the criteria of when to notify up parents for changes on objects to run only when something inside it has changed, so setting/assigning the same object onto itself will not notify. It's unlikely but possible that may be a breaking change for you if you depended on things re-computing/re-rendering even if nothing changed.
package/README.md CHANGED
@@ -106,6 +106,10 @@ const Component = observer(function Component() {
106
106
 
107
107
  See [the documentation site](https://www.legendapp.com/open-source/state/).
108
108
 
109
+ ## Community
110
+
111
+ Join us on [Slack](https://join.slack.com/t/legendappcommunity/shared_invite/zt-1mfjknpna-vUL2s1qOuNeZL12~t2RruQ) to get involved with the Legend community.
112
+
109
113
  ## Road to 1.0
110
114
 
111
115
  - [ ] Improve documentation
@@ -11,7 +11,7 @@ const pageHash = state.observable(hasWindow ? window.location.hash.slice(1) : ''
11
11
  if (hasWindow) {
12
12
  let isSetting = false;
13
13
  // Set the page hash when the observable changes
14
- pageHash.onChange((value) => {
14
+ pageHash.onChange(({ value }) => {
15
15
  if (!isSetting) {
16
16
  const hash = '#' + value;
17
17
  const setter = (_options === null || _options === void 0 ? void 0 : _options.setter) || 'hash';
@@ -1 +1 @@
1
- {"version":3,"file":"pageHash.js","sources":["../../../../src/helpers/pageHash.ts"],"sourcesContent":[null],"names":["observable"],"mappings":";;;;AAKA,IAAI,QAAQ,GAAY,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAE3C,SAAS,iBAAiB,CAAC,OAAgB,EAAA;IACvC,QAAQ,GAAG,OAAO,CAAC;AACvB,CAAC;AAED,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC;AAC1C,MAAA,QAAQ,GAAuBA,gBAAU,CAAC,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE;AAEhG,IAAI,SAAS,EAAE;IACX,IAAI,SAAS,GAAG,KAAK,CAAC;;AAEtB,IAAA,QAAQ,CAAC,QAAQ,CAAC,CAAC,KAAK,KAAI;QACxB,IAAI,CAAC,SAAS,EAAE;AACZ,YAAA,MAAM,IAAI,GAAG,GAAG,GAAG,KAAK,CAAC;AACzB,YAAA,MAAM,MAAM,GAAG,CAAA,QAAQ,KAAR,IAAA,IAAA,QAAQ,KAAR,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,QAAQ,CAAE,MAAM,KAAI,MAAM,CAAC;YAC1C,IAAI,MAAM,KAAK,WAAW,EAAE;gBACxB,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACvC,aAAA;iBAAM,IAAI,MAAM,KAAK,cAAc,EAAE;gBAClC,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC1C,aAAA;AAAM,iBAAA;AACH,gBAAA,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;AACxB,aAAA;AACJ,SAAA;AACL,KAAC,CAAC,CAAC;;IAEH,MAAM,EAAE,GAAG,MAAK;QACZ,SAAS,GAAG,IAAI,CAAC;AACjB,QAAA,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,SAAS,GAAG,KAAK,CAAC;AACtB,KAAC,CAAC;;AAEF,IAAA,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AAC7C;;;;;"}
1
+ {"version":3,"file":"pageHash.js","sources":["../../../../src/helpers/pageHash.ts"],"sourcesContent":[null],"names":["observable"],"mappings":";;;;AAKA,IAAI,QAAQ,GAAY,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAE3C,SAAS,iBAAiB,CAAC,OAAgB,EAAA;IACvC,QAAQ,GAAG,OAAO,CAAC;AACvB,CAAC;AAED,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC;AAC1C,MAAA,QAAQ,GAAuBA,gBAAU,CAAC,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE;AAEhG,IAAI,SAAS,EAAE;IACX,IAAI,SAAS,GAAG,KAAK,CAAC;;IAEtB,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,KAAI;QAC5B,IAAI,CAAC,SAAS,EAAE;AACZ,YAAA,MAAM,IAAI,GAAG,GAAG,GAAG,KAAK,CAAC;AACzB,YAAA,MAAM,MAAM,GAAG,CAAA,QAAQ,KAAR,IAAA,IAAA,QAAQ,KAAR,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,QAAQ,CAAE,MAAM,KAAI,MAAM,CAAC;YAC1C,IAAI,MAAM,KAAK,WAAW,EAAE;gBACxB,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACvC,aAAA;iBAAM,IAAI,MAAM,KAAK,cAAc,EAAE;gBAClC,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC1C,aAAA;AAAM,iBAAA;AACH,gBAAA,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;AACxB,aAAA;AACJ,SAAA;AACL,KAAC,CAAC,CAAC;;IAEH,MAAM,EAAE,GAAG,MAAK;QACZ,SAAS,GAAG,IAAI,CAAC;AACjB,QAAA,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,SAAS,GAAG,KAAK,CAAC;AACtB,KAAC,CAAC;;AAEF,IAAA,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AAC7C;;;;;"}
@@ -9,7 +9,7 @@ const pageHash = observable(hasWindow ? window.location.hash.slice(1) : '');
9
9
  if (hasWindow) {
10
10
  let isSetting = false;
11
11
  // Set the page hash when the observable changes
12
- pageHash.onChange((value) => {
12
+ pageHash.onChange(({ value }) => {
13
13
  if (!isSetting) {
14
14
  const hash = '#' + value;
15
15
  const setter = (_options === null || _options === void 0 ? void 0 : _options.setter) || 'hash';
@@ -1 +1 @@
1
- {"version":3,"file":"pageHash.mjs","sources":["../../../../src/helpers/pageHash.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAKA,IAAI,QAAQ,GAAY,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAE3C,SAAS,iBAAiB,CAAC,OAAgB,EAAA;IACvC,QAAQ,GAAG,OAAO,CAAC;AACvB,CAAC;AAED,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC;AAC1C,MAAA,QAAQ,GAAuB,UAAU,CAAC,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE;AAEhG,IAAI,SAAS,EAAE;IACX,IAAI,SAAS,GAAG,KAAK,CAAC;;AAEtB,IAAA,QAAQ,CAAC,QAAQ,CAAC,CAAC,KAAK,KAAI;QACxB,IAAI,CAAC,SAAS,EAAE;AACZ,YAAA,MAAM,IAAI,GAAG,GAAG,GAAG,KAAK,CAAC;AACzB,YAAA,MAAM,MAAM,GAAG,CAAA,QAAQ,KAAR,IAAA,IAAA,QAAQ,KAAR,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,QAAQ,CAAE,MAAM,KAAI,MAAM,CAAC;YAC1C,IAAI,MAAM,KAAK,WAAW,EAAE;gBACxB,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACvC,aAAA;iBAAM,IAAI,MAAM,KAAK,cAAc,EAAE;gBAClC,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC1C,aAAA;AAAM,iBAAA;AACH,gBAAA,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;AACxB,aAAA;AACJ,SAAA;AACL,KAAC,CAAC,CAAC;;IAEH,MAAM,EAAE,GAAG,MAAK;QACZ,SAAS,GAAG,IAAI,CAAC;AACjB,QAAA,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,SAAS,GAAG,KAAK,CAAC;AACtB,KAAC,CAAC;;AAEF,IAAA,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AAC7C;;;;"}
1
+ {"version":3,"file":"pageHash.mjs","sources":["../../../../src/helpers/pageHash.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAKA,IAAI,QAAQ,GAAY,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAE3C,SAAS,iBAAiB,CAAC,OAAgB,EAAA;IACvC,QAAQ,GAAG,OAAO,CAAC;AACvB,CAAC;AAED,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC;AAC1C,MAAA,QAAQ,GAAuB,UAAU,CAAC,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,EAAE;AAEhG,IAAI,SAAS,EAAE;IACX,IAAI,SAAS,GAAG,KAAK,CAAC;;IAEtB,QAAQ,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,KAAI;QAC5B,IAAI,CAAC,SAAS,EAAE;AACZ,YAAA,MAAM,IAAI,GAAG,GAAG,GAAG,KAAK,CAAC;AACzB,YAAA,MAAM,MAAM,GAAG,CAAA,QAAQ,KAAR,IAAA,IAAA,QAAQ,KAAR,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,QAAQ,CAAE,MAAM,KAAI,MAAM,CAAC;YAC1C,IAAI,MAAM,KAAK,WAAW,EAAE;gBACxB,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACvC,aAAA;iBAAM,IAAI,MAAM,KAAK,cAAc,EAAE;gBAClC,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC1C,aAAA;AAAM,iBAAA;AACH,gBAAA,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;AACxB,aAAA;AACJ,SAAA;AACL,KAAC,CAAC,CAAC;;IAEH,MAAM,EAAE,GAAG,MAAK;QACZ,SAAS,GAAG,IAAI,CAAC;AACjB,QAAA,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,SAAS,GAAG,KAAK,CAAC;AACtB,KAAC,CAAC;;AAEF,IAAA,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AAC7C;;;;"}
@@ -22,7 +22,7 @@ const pageHashParams = state.observable(hasWindow ? toParams(window.location.has
22
22
  if (hasWindow) {
23
23
  let isSetting = false;
24
24
  // Set the page hash when the observable changes
25
- pageHashParams.onChange((value) => {
25
+ pageHashParams.onChange(({ value }) => {
26
26
  if (!isSetting) {
27
27
  const hash = '#' + toString(value);
28
28
  const setter = (_options === null || _options === void 0 ? void 0 : _options.setter) || 'hash';
@@ -1 +1 @@
1
- {"version":3,"file":"pageHashParams.js","sources":["../../../../src/helpers/pageHashParams.ts"],"sourcesContent":[null],"names":["observable"],"mappings":";;;;AAKA,IAAI,QAAQ,GAAY,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAE3C,SAAS,uBAAuB,CAAC,OAAgB,EAAA;IAC7C,QAAQ,GAAG,OAAO,CAAC;AACvB,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW,EAAA;IACzB,MAAM,GAAG,GAA2B,EAAE,CAAC;AACvC,IAAA,MAAM,YAAY,GAAG,IAAI,eAAe,CAAC,GAAG,CAAC,CAAC;IAC9C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,YAAY,EAAE;AACrC,QAAA,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AACpB,KAAA;AACD,IAAA,OAAO,GAAG,CAAC;AACf,CAAC;AACD,SAAS,QAAQ,CAAC,MAA8B,EAAA;IAC5C,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC;AAC1C,MAAA,cAAc,GAAuCA,gBAAU,CACjE,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAC1D;AAEF,IAAI,SAAS,EAAE;IACX,IAAI,SAAS,GAAG,KAAK,CAAC;;AAEtB,IAAA,cAAc,CAAC,QAAQ,CAAC,CAAC,KAAK,KAAI;QAC9B,IAAI,CAAC,SAAS,EAAE;YACZ,MAAM,IAAI,GAAG,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;AACnC,YAAA,MAAM,MAAM,GAAG,CAAA,QAAQ,KAAR,IAAA,IAAA,QAAQ,KAAR,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,QAAQ,CAAE,MAAM,KAAI,MAAM,CAAC;YAC1C,IAAI,MAAM,KAAK,WAAW,EAAE;gBACxB,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACvC,aAAA;iBAAM,IAAI,MAAM,KAAK,cAAc,EAAE;gBAClC,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC1C,aAAA;AAAM,iBAAA;AACH,gBAAA,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;AACxB,aAAA;AACJ,SAAA;AACL,KAAC,CAAC,CAAC;;IAEH,MAAM,EAAE,GAAG,MAAK;QACZ,SAAS,GAAG,IAAI,CAAC;AACjB,QAAA,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,SAAS,GAAG,KAAK,CAAC;AACtB,KAAC,CAAC;;AAEF,IAAA,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AAC7C;;;;;"}
1
+ {"version":3,"file":"pageHashParams.js","sources":["../../../../src/helpers/pageHashParams.ts"],"sourcesContent":[null],"names":["observable"],"mappings":";;;;AAKA,IAAI,QAAQ,GAAY,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAE3C,SAAS,uBAAuB,CAAC,OAAgB,EAAA;IAC7C,QAAQ,GAAG,OAAO,CAAC;AACvB,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW,EAAA;IACzB,MAAM,GAAG,GAA2B,EAAE,CAAC;AACvC,IAAA,MAAM,YAAY,GAAG,IAAI,eAAe,CAAC,GAAG,CAAC,CAAC;IAC9C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,YAAY,EAAE;AACrC,QAAA,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AACpB,KAAA;AACD,IAAA,OAAO,GAAG,CAAC;AACf,CAAC;AACD,SAAS,QAAQ,CAAC,MAA8B,EAAA;IAC5C,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC;AAC1C,MAAA,cAAc,GAAuCA,gBAAU,CACjE,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAC1D;AAEF,IAAI,SAAS,EAAE;IACX,IAAI,SAAS,GAAG,KAAK,CAAC;;IAEtB,cAAc,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,KAAI;QAClC,IAAI,CAAC,SAAS,EAAE;YACZ,MAAM,IAAI,GAAG,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;AACnC,YAAA,MAAM,MAAM,GAAG,CAAA,QAAQ,KAAR,IAAA,IAAA,QAAQ,KAAR,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,QAAQ,CAAE,MAAM,KAAI,MAAM,CAAC;YAC1C,IAAI,MAAM,KAAK,WAAW,EAAE;gBACxB,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACvC,aAAA;iBAAM,IAAI,MAAM,KAAK,cAAc,EAAE;gBAClC,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC1C,aAAA;AAAM,iBAAA;AACH,gBAAA,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;AACxB,aAAA;AACJ,SAAA;AACL,KAAC,CAAC,CAAC;;IAEH,MAAM,EAAE,GAAG,MAAK;QACZ,SAAS,GAAG,IAAI,CAAC;AACjB,QAAA,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,SAAS,GAAG,KAAK,CAAC;AACtB,KAAC,CAAC;;AAEF,IAAA,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AAC7C;;;;;"}
@@ -20,7 +20,7 @@ const pageHashParams = observable(hasWindow ? toParams(window.location.hash.slic
20
20
  if (hasWindow) {
21
21
  let isSetting = false;
22
22
  // Set the page hash when the observable changes
23
- pageHashParams.onChange((value) => {
23
+ pageHashParams.onChange(({ value }) => {
24
24
  if (!isSetting) {
25
25
  const hash = '#' + toString(value);
26
26
  const setter = (_options === null || _options === void 0 ? void 0 : _options.setter) || 'hash';
@@ -1 +1 @@
1
- {"version":3,"file":"pageHashParams.mjs","sources":["../../../../src/helpers/pageHashParams.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAKA,IAAI,QAAQ,GAAY,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAE3C,SAAS,uBAAuB,CAAC,OAAgB,EAAA;IAC7C,QAAQ,GAAG,OAAO,CAAC;AACvB,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW,EAAA;IACzB,MAAM,GAAG,GAA2B,EAAE,CAAC;AACvC,IAAA,MAAM,YAAY,GAAG,IAAI,eAAe,CAAC,GAAG,CAAC,CAAC;IAC9C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,YAAY,EAAE;AACrC,QAAA,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AACpB,KAAA;AACD,IAAA,OAAO,GAAG,CAAC;AACf,CAAC;AACD,SAAS,QAAQ,CAAC,MAA8B,EAAA;IAC5C,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC;AAC1C,MAAA,cAAc,GAAuC,UAAU,CACjE,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAC1D;AAEF,IAAI,SAAS,EAAE;IACX,IAAI,SAAS,GAAG,KAAK,CAAC;;AAEtB,IAAA,cAAc,CAAC,QAAQ,CAAC,CAAC,KAAK,KAAI;QAC9B,IAAI,CAAC,SAAS,EAAE;YACZ,MAAM,IAAI,GAAG,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;AACnC,YAAA,MAAM,MAAM,GAAG,CAAA,QAAQ,KAAR,IAAA,IAAA,QAAQ,KAAR,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,QAAQ,CAAE,MAAM,KAAI,MAAM,CAAC;YAC1C,IAAI,MAAM,KAAK,WAAW,EAAE;gBACxB,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACvC,aAAA;iBAAM,IAAI,MAAM,KAAK,cAAc,EAAE;gBAClC,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC1C,aAAA;AAAM,iBAAA;AACH,gBAAA,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;AACxB,aAAA;AACJ,SAAA;AACL,KAAC,CAAC,CAAC;;IAEH,MAAM,EAAE,GAAG,MAAK;QACZ,SAAS,GAAG,IAAI,CAAC;AACjB,QAAA,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,SAAS,GAAG,KAAK,CAAC;AACtB,KAAC,CAAC;;AAEF,IAAA,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AAC7C;;;;"}
1
+ {"version":3,"file":"pageHashParams.mjs","sources":["../../../../src/helpers/pageHashParams.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAKA,IAAI,QAAQ,GAAY,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAE3C,SAAS,uBAAuB,CAAC,OAAgB,EAAA;IAC7C,QAAQ,GAAG,OAAO,CAAC;AACvB,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW,EAAA;IACzB,MAAM,GAAG,GAA2B,EAAE,CAAC;AACvC,IAAA,MAAM,YAAY,GAAG,IAAI,eAAe,CAAC,GAAG,CAAC,CAAC;IAC9C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,YAAY,EAAE;AACrC,QAAA,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AACpB,KAAA;AACD,IAAA,OAAO,GAAG,CAAC;AACf,CAAC;AACD,SAAS,QAAQ,CAAC,MAA8B,EAAA;IAC5C,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,SAAS,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC;AAC1C,MAAA,cAAc,GAAuC,UAAU,CACjE,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,EAC1D;AAEF,IAAI,SAAS,EAAE;IACX,IAAI,SAAS,GAAG,KAAK,CAAC;;IAEtB,cAAc,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,KAAI;QAClC,IAAI,CAAC,SAAS,EAAE;YACZ,MAAM,IAAI,GAAG,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;AACnC,YAAA,MAAM,MAAM,GAAG,CAAA,QAAQ,KAAR,IAAA,IAAA,QAAQ,KAAR,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,QAAQ,CAAE,MAAM,KAAI,MAAM,CAAC;YAC1C,IAAI,MAAM,KAAK,WAAW,EAAE;gBACxB,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AACvC,aAAA;iBAAM,IAAI,MAAM,KAAK,cAAc,EAAE;gBAClC,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC1C,aAAA;AAAM,iBAAA;AACH,gBAAA,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC;AACxB,aAAA;AACJ,SAAA;AACL,KAAC,CAAC,CAAC;;IAEH,MAAM,EAAE,GAAG,MAAK;QACZ,SAAS,GAAG,IAAI,CAAC;AACjB,QAAA,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,SAAS,GAAG,KAAK,CAAC;AACtB,KAAC,CAAC;;AAEF,IAAA,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AAC7C;;;;"}
package/history.js CHANGED
@@ -4,17 +4,17 @@ var state = require('@legendapp/state');
4
4
 
5
5
  function trackHistory(obs, targetObservable) {
6
6
  const history = targetObservable !== null && targetObservable !== void 0 ? targetObservable : state.observable();
7
- obs.onChange((_, __, changes) => {
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
10
  if (!state.tracking.inRemoteChange) {
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++) {
14
- const { path, prevAtPath } = changes[i];
14
+ const { path, prevAtPath, pathTypes } = changes[i];
15
15
  if (path[path.length - 1] === state.symbolDateModified)
16
16
  continue;
17
- const obj = state.constructObject(path, prevAtPath);
17
+ const obj = state.constructObjectWithPath(path, prevAtPath, pathTypes);
18
18
  state.mergeIntoObservable(history[time], obj);
19
19
  }
20
20
  }
package/history.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"history.js","sources":["../../src/history/trackHistory.ts"],"sourcesContent":[null],"names":["observable","tracking","symbolDateModified","constructObject","mergeIntoObservable"],"mappings":";;;;AAagB,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,CAAC,EAAE,EAAE,EAAE,OAAO,KAAI;;;AAG5B,QAAA,IAAI,CAACC,cAAQ,CAAC,cAAc,EAAE;YAC1B,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;gBACrC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;gBACxC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,KAAMC,wBAA0B;oBAAE,SAAS;gBAEpE,MAAM,GAAG,GAAGC,qBAAe,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;gBAC9CC,yBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AAC3C,aAAA;AACJ,SAAA;AACL,KAAC,CAAC,CAAC;AAEH,IAAA,OAAO,OAAO,CAAC;AACnB;;;;"}
1
+ {"version":3,"file":"history.js","sources":["../../src/history/trackHistory.ts"],"sourcesContent":[null],"names":["observable","tracking","symbolDateModified","constructObjectWithPath","mergeIntoObservable"],"mappings":";;;;AAagB,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,cAAc,EAAE;YAC1B,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;gBACnD,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,KAAMC,wBAA0B;oBAAE,SAAS;gBAEpE,MAAM,GAAG,GAAGC,6BAAuB,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;gBACjEC,yBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AAC3C,aAAA;AACJ,SAAA;AACL,KAAC,CAAC,CAAC;AAEH,IAAA,OAAO,OAAO,CAAC;AACnB;;;;"}
package/history.mjs CHANGED
@@ -1,18 +1,18 @@
1
- import { observable, tracking, symbolDateModified, constructObject, mergeIntoObservable } from '@legendapp/state';
1
+ import { observable, tracking, symbolDateModified, 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
- obs.onChange((_, __, changes) => {
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
8
  if (!tracking.inRemoteChange) {
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++) {
12
- const { path, prevAtPath } = changes[i];
12
+ const { path, prevAtPath, pathTypes } = changes[i];
13
13
  if (path[path.length - 1] === symbolDateModified)
14
14
  continue;
15
- const obj = constructObject(path, prevAtPath);
15
+ const obj = constructObjectWithPath(path, prevAtPath, pathTypes);
16
16
  mergeIntoObservable(history[time], obj);
17
17
  }
18
18
  }
package/history.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"history.mjs","sources":["../../src/history/trackHistory.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAagB,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,CAAC,EAAE,EAAE,EAAE,OAAO,KAAI;;;AAG5B,QAAA,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE;YAC1B,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;gBACrC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;gBACxC,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,KAAM,kBAA0B;oBAAE,SAAS;gBAEpE,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;gBAC9C,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AAC3C,aAAA;AACJ,SAAA;AACL,KAAC,CAAC,CAAC;AAEH,IAAA,OAAO,OAAO,CAAC;AACnB;;;;"}
1
+ {"version":3,"file":"history.mjs","sources":["../../src/history/trackHistory.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAagB,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;YAC1B,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;gBACnD,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,KAAM,kBAA0B;oBAAE,SAAS;gBAEpE,MAAM,GAAG,GAAG,uBAAuB,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;gBACjE,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;AAC3C,aAAA;AACJ,SAAA;AACL,KAAC,CAAC,CAAC;AAEH,IAAA,OAAO,OAAO,CAAC;AACnB;;;;"}
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { opaqueObject, isObservable, mergeIntoObservable, getObservableIndex, computeSelector } from './src/helpers';
1
+ export { opaqueObject, isObservable, mergeIntoObservable, getObservableIndex, computeSelector, constructObjectWithPath, deconstructObjectWithPath, setAtPath, setInObservableAtPath } from './src/helpers';
2
2
  export { observable, observablePrimitive } from './src/observable';
3
3
  export { batch, beginBatch, endBatch } from './src/batching';
4
4
  export { computed } from './src/computed';
@@ -6,5 +6,5 @@ export { event } from './src/event';
6
6
  export { observe } from './src/observe';
7
7
  export { when } from './src/when';
8
8
  export * from './src/observableInterfaces';
9
- export { isEmpty, isArray, isBoolean, isFunction, isObject, isPrimitive, isPromise, isString, isSymbol } from './src/is';
9
+ export { isEmpty, isArray, isBoolean, isFunction, isObject, isPrimitive, isPromise, isString, isSymbol, } from './src/is';
10
10
  export { lockObservable } from './src/helpers';
package/index.js CHANGED
@@ -130,6 +130,7 @@ function getChildNode(node, key) {
130
130
  if (isString(key)) {
131
131
  const n = +key;
132
132
  // Convert to number if it's a string representing a valid number
133
+ // This is faster than isNaN
133
134
  if (n - n < 1)
134
135
  key = n;
135
136
  }
@@ -197,51 +198,95 @@ function lockObservable(obs, value) {
197
198
  root.locked = value;
198
199
  }
199
200
  }
201
+ function setAtPath(obj, path, pathTypes, value) {
202
+ let o = obj;
203
+ for (let i = 0; i < path.length; i++) {
204
+ const p = path[i];
205
+ if (i === path.length - 1) {
206
+ o[p] = value;
207
+ }
208
+ else if (o[p] === undefined) {
209
+ o[p] = pathTypes[i] === 'array' ? [] : {};
210
+ }
211
+ o = o[p];
212
+ }
213
+ }
214
+ function setInObservableAtPath(obs, path, value, mode) {
215
+ let o = obs;
216
+ let v = value;
217
+ for (let i = 0; i < path.length; i++) {
218
+ const p = path[i];
219
+ o = obs[p];
220
+ v = value[p];
221
+ }
222
+ if (v === symbolDelete) {
223
+ o.delete();
224
+ }
225
+ // Assign if possible, or set otherwise
226
+ else if (mode === 'assign' && o.assign) {
227
+ o.assign(v);
228
+ }
229
+ else {
230
+ o.set(v);
231
+ }
232
+ }
200
233
  function mergeIntoObservable(target, ...sources) {
201
- var _a, _b;
234
+ var _a;
202
235
  if (!sources.length)
203
236
  return target;
204
- const source = sources.shift();
205
- const needsSet = isObservable(target);
206
- const targetValue = needsSet ? target.peek() : target;
207
- const isTargetObj = isObject(targetValue);
208
- const isTargetArr = isArray(targetValue);
209
- if ((isTargetObj && isObject(source)) || (isTargetArr && isArray(source))) {
210
- const keys = isTargetArr ? source : Object.keys(source);
211
- if (source[symbolDateModified]) {
212
- keys.push(symbolDateModified);
213
- }
214
- for (let i = 0; i < keys.length; i++) {
215
- const key = isTargetArr ? i : keys[i];
216
- const sourceValue = source[key];
217
- if (isObject(sourceValue)) {
218
- if (!needsSet && (!targetValue[key] || !isObject(targetValue[key]))) {
219
- target[key] = {};
237
+ for (let u = 0; u < sources.length; u++) {
238
+ const source = sources[u];
239
+ const needsSet = isObservable(target);
240
+ let targetValue = needsSet ? target.peek() : target;
241
+ const isTargetArr = isArray(targetValue);
242
+ const isTargetObj = !isTargetArr && isObject(targetValue);
243
+ if ((isTargetObj && isObject(source) && !isEmpty(targetValue)) ||
244
+ (isTargetArr && isArray(source) && targetValue.length > 0)) {
245
+ const keys = isTargetArr ? source : Object.keys(source);
246
+ let dateModified = source[symbolDateModified];
247
+ for (let i = 0; i < keys.length; i++) {
248
+ const key = isTargetArr ? i : keys[i];
249
+ const sourceValue = source[key];
250
+ if (sourceValue === symbolDelete) {
251
+ needsSet && ((_a = target[key]) === null || _a === void 0 ? void 0 : _a.delete)
252
+ ? target[key].delete()
253
+ : delete target[key];
254
+ }
255
+ else {
256
+ const isObj = isObject(sourceValue);
257
+ const isArr = !isObj && isArray(sourceValue);
258
+ const targetValue = target[key];
259
+ if ((isObj || isArr) && target[key] && (isObj ? !isEmpty(targetValue) : targetValue.length > 0)) {
260
+ if (!needsSet && (!target[key] || (isObj ? !isObject(target[key]) : !isArray(target[key])))) {
261
+ target[key] = isObj ? {} : [];
262
+ }
263
+ mergeIntoObservable(target[key], sourceValue);
264
+ dateModified = Math.max(dateModified || 0, sourceValue[symbolDateModified] || 0);
265
+ }
266
+ else {
267
+ needsSet ? target[key].set(sourceValue) : (target[key] = sourceValue);
268
+ }
220
269
  }
221
- mergeIntoObservable(target[key], sourceValue);
222
- }
223
- else if (sourceValue === symbolDelete) {
224
- needsSet && ((_a = target[key]) === null || _a === void 0 ? void 0 : _a.delete) ? target[key].delete() : delete target[key];
225
270
  }
226
- else {
227
- needsSet && ((_b = target[key]) === null || _b === void 0 ? void 0 : _b.set)
228
- ? target[key].set(sourceValue)
229
- : (target[key] = sourceValue);
271
+ if (dateModified) {
272
+ needsSet
273
+ ? target[symbolDateModified].set(dateModified)
274
+ : (target[symbolDateModified] = dateModified);
230
275
  }
231
276
  }
277
+ else {
278
+ needsSet ? target.set(source) : (target = source);
279
+ }
232
280
  }
233
- else if (needsSet && !(isTargetObj && source === undefined)) {
234
- target.set(source);
235
- }
236
- return mergeIntoObservable(target, ...sources);
281
+ return target;
237
282
  }
238
- function constructObject(path, value) {
283
+ function constructObjectWithPath(path, value, pathTypes) {
239
284
  let out;
240
285
  if (path.length > 0) {
241
286
  let o = (out = {});
242
287
  for (let i = 0; i < path.length; i++) {
243
288
  const p = path[i];
244
- o[p] = i === path.length - 1 ? value : {};
289
+ o[p] = i === path.length - 1 ? value : pathTypes[i] === 'array' ? [] : {};
245
290
  o = o[p];
246
291
  }
247
292
  }
@@ -250,7 +295,7 @@ function constructObject(path, value) {
250
295
  }
251
296
  return out;
252
297
  }
253
- function deconstructObject(path, value) {
298
+ function deconstructObjectWithPath(path, value) {
254
299
  let o = value;
255
300
  for (let i = 0; i < path.length; i++) {
256
301
  const p = path[i];
@@ -258,13 +303,11 @@ function deconstructObject(path, value) {
258
303
  }
259
304
  return o;
260
305
  }
261
- function clone(obj) {
262
- return JSON.parse(JSON.stringify(obj));
263
- }
264
306
 
265
307
  let timeout;
266
308
  let numInBatch = 0;
267
309
  let _batch = [];
310
+ let _afterBatch = [];
268
311
  // Use a Map of callbacks for fast lookups to update the BatchItem
269
312
  let _batchMap = new Map();
270
313
  function onActionTimeout() {
@@ -284,8 +327,9 @@ function batchNotify(b) {
284
327
  // If this callback already exists, make sure it has the latest value but do not add it
285
328
  if (existing) {
286
329
  if (!isFunc) {
287
- existing.value = b.value;
288
- existing.changes.push(...b.changes);
330
+ const params = existing.params;
331
+ params.value = b.params.value;
332
+ params.changes.push(...b.params.changes);
289
333
  }
290
334
  }
291
335
  else {
@@ -294,10 +338,13 @@ function batchNotify(b) {
294
338
  }
295
339
  }
296
340
  else {
297
- isFunc ? b() : b.cb(b.value, b.getPrevious, b.changes, b.node);
341
+ isFunc ? b() : b.cb(b.params);
298
342
  }
299
343
  }
300
- function batch(fn) {
344
+ function batch(fn, after) {
345
+ if (after) {
346
+ _afterBatch.push(after);
347
+ }
301
348
  beginBatch();
302
349
  fn();
303
350
  endBatch();
@@ -318,18 +365,23 @@ function endBatch(force) {
318
365
  // Save batch locally and reset _batch first because a new batch could begin while looping over callbacks.
319
366
  // This can happen with observableComputed for example.
320
367
  const batch = _batch;
368
+ const after = _afterBatch;
321
369
  _batch = [];
322
370
  _batchMap = new Map();
371
+ _afterBatch = [];
323
372
  for (let i = 0; i < batch.length; i++) {
324
373
  const b = batch[i];
325
374
  if (isFunction(b)) {
326
375
  b();
327
376
  }
328
377
  else {
329
- const { cb, value, getPrevious: prev, changes, node } = b;
330
- cb(value, prev, changes, node);
378
+ const { cb } = b;
379
+ cb(b.params);
331
380
  }
332
381
  }
382
+ for (let i = 0; i < after.length; i++) {
383
+ after[i]();
384
+ }
333
385
  }
334
386
  }
335
387
 
@@ -351,7 +403,7 @@ function createPreviousHandler(value, path, prevAtPath) {
351
403
  return clone;
352
404
  };
353
405
  }
354
- function doNotify(node, value, path, valueAtPath, prevAtPath, level, whenOptimizedOnlyIf) {
406
+ function doNotify(node, value, path, pathTypes, valueAtPath, prevAtPath, level, whenOptimizedOnlyIf) {
355
407
  const listeners = node.listeners;
356
408
  if (listeners) {
357
409
  let getPrevious;
@@ -359,7 +411,11 @@ function doNotify(node, value, path, valueAtPath, prevAtPath, level, whenOptimiz
359
411
  for (let i = 0; i < arr.length; i++) {
360
412
  const listenerFn = arr[i];
361
413
  const { track, noArgs } = listenerFn;
362
- const ok = track === true ? level <= 0 : track === 'optimize' ? whenOptimizedOnlyIf && level <= 0 : true;
414
+ const ok = track === true || track === 'shallow'
415
+ ? level <= 0
416
+ : track === 'optimize'
417
+ ? whenOptimizedOnlyIf && level <= 0
418
+ : true;
363
419
  // Notify if listener is not shallow or if this is the first level
364
420
  if (ok) {
365
421
  // Create a function to get the previous data. Computing a clone of previous data can be expensive if doing
@@ -371,45 +427,62 @@ function doNotify(node, value, path, valueAtPath, prevAtPath, level, whenOptimiz
371
427
  ? listenerFn.listener
372
428
  : {
373
429
  cb: listenerFn.listener,
374
- value,
375
- getPrevious,
376
- changes: [
377
- {
378
- path,
379
- valueAtPath,
380
- prevAtPath,
381
- },
382
- ],
383
- node,
430
+ params: {
431
+ value,
432
+ getPrevious,
433
+ changes: [
434
+ {
435
+ path,
436
+ pathTypes,
437
+ valueAtPath,
438
+ prevAtPath,
439
+ },
440
+ ],
441
+ },
384
442
  });
385
443
  }
386
444
  }
387
445
  }
388
446
  }
389
- function _notifyParents(node, value, path, valueAtPath, prevAtPath, level, whenOptimizedOnlyIf) {
447
+ function _notifyParents(node, value, path, pathTypes, valueAtPath, prevAtPath, level, whenOptimizedOnlyIf) {
390
448
  // Do the notify
391
- doNotify(node, value, path, valueAtPath, prevAtPath, level, whenOptimizedOnlyIf);
449
+ doNotify(node, value, path, pathTypes, valueAtPath, prevAtPath, level, whenOptimizedOnlyIf);
392
450
  // If not root notify up through parents
393
451
  if (node.parent) {
394
452
  const parent = node.parent;
395
453
  if (parent) {
396
454
  const parentValue = getNodeValue(parent);
397
- _notifyParents(parent, parentValue, [node.key].concat(path), valueAtPath, prevAtPath, level + 1, whenOptimizedOnlyIf);
455
+ _notifyParents(parent, parentValue, [node.key].concat(path), [(isArray(value) ? 'array' : 'object')].concat(pathTypes), valueAtPath, prevAtPath, level + 1, whenOptimizedOnlyIf);
398
456
  }
399
457
  }
400
458
  }
401
459
  function notify(node, value, prev, level, whenOptimizedOnlyIf) {
402
460
  // Notify self and up through parents
403
- _notifyParents(node, value, [], value, prev, level, whenOptimizedOnlyIf);
461
+ _notifyParents(node, value, [], [], value, prev, level, whenOptimizedOnlyIf);
404
462
  }
405
463
 
406
- function onChange(node, callback, track, noArgs) {
464
+ function onChange(node, callback, options, noArgs) {
407
465
  let listeners = node.listeners;
408
466
  if (!listeners) {
409
467
  node.listeners = listeners = new Set();
410
468
  }
411
- const listener = { listener: callback, track: track, noArgs };
469
+ const listener = { listener: callback, track: options === null || options === void 0 ? void 0 : options.trackingType, noArgs };
412
470
  listeners.add(listener);
471
+ if (options === null || options === void 0 ? void 0 : options.initial) {
472
+ const value = getNodeValue(node);
473
+ callback({
474
+ value,
475
+ changes: [
476
+ {
477
+ path: [],
478
+ pathTypes: [],
479
+ prevAtPath: value,
480
+ valueAtPath: value,
481
+ },
482
+ ],
483
+ getPrevious: () => undefined,
484
+ });
485
+ }
413
486
  return () => listeners.delete(listener);
414
487
  }
415
488
 
@@ -459,7 +532,7 @@ ObservablePrimitiveClass.prototype.set = function (value) {
459
532
  const root = this._node.root;
460
533
  const prev = root._;
461
534
  root._ = value;
462
- doNotify(this._node, value, [], value, prev, 0);
535
+ doNotify(this._node, value, [], [], value, prev, 0);
463
536
  return this;
464
537
  };
465
538
  ObservablePrimitiveClass.prototype.toggle = function () {
@@ -473,8 +546,8 @@ ObservablePrimitiveClass.prototype.toggle = function () {
473
546
  return !value;
474
547
  };
475
548
  // Listener
476
- ObservablePrimitiveClass.prototype.onChange = function (cb, track, noArgs) {
477
- return onChange(this._node, cb, track, noArgs);
549
+ ObservablePrimitiveClass.prototype.onChange = function (cb, options, noArgs) {
550
+ return onChange(this._node, cb, options, noArgs);
478
551
  };
479
552
 
480
553
  let inSet = false;
@@ -492,7 +565,6 @@ const ArrayModifiers = new Set([
492
565
  'unshift',
493
566
  ]);
494
567
  const ArrayLoopers = new Set(['every', 'some', 'filter', 'forEach', 'map', 'join']);
495
- const NotifySpecifically = new Set([symbolDateModified]);
496
568
  const objectFns = new Map([
497
569
  ['get', get],
498
570
  ['set', set],
@@ -519,11 +591,11 @@ function collectionSetter(node, target, prop, ...args) {
519
591
  return ret;
520
592
  }
521
593
  function updateNodes(parent, obj, prevValue) {
522
- if (isObject(obj) && obj[symbolOpaque]) {
594
+ if ((isObject(obj) && obj[symbolOpaque]) || (isObject(prevValue) && prevValue[symbolOpaque])) {
523
595
  const isDiff = obj !== prevValue;
524
596
  if (isDiff) {
525
597
  if (parent.listeners) {
526
- doNotify(parent, obj, [], obj, prevValue, 0);
598
+ doNotify(parent, obj, [], [], obj, prevValue, 0);
527
599
  }
528
600
  }
529
601
  return isDiff;
@@ -573,7 +645,7 @@ function updateNodes(parent, obj, prevValue) {
573
645
  updateNodes(child, undefined, prev);
574
646
  }
575
647
  if (child.listeners) {
576
- doNotify(child, undefined, [], undefined, prev, 0);
648
+ doNotify(child, undefined, [], [], undefined, prev, 0);
577
649
  }
578
650
  }
579
651
  }
@@ -619,10 +691,12 @@ function updateNodes(parent, obj, prevValue) {
619
691
  }
620
692
  if (isDiff) {
621
693
  // Array has a new / modified element
622
- hasADiff = true;
623
694
  // If object iterate through its children
624
- if (!isPrimitive(value)) {
625
- updateNodes(child, value, prev);
695
+ if (isPrimitive(value)) {
696
+ hasADiff = true;
697
+ }
698
+ else {
699
+ hasADiff = hasADiff || updateNodes(child, value, prev);
626
700
  }
627
701
  }
628
702
  if (isDiff || !isArrDiff) {
@@ -631,7 +705,7 @@ function updateNodes(parent, obj, prevValue) {
631
705
  // But do not notify child if the parent is an array with changing length -
632
706
  // the array's listener will cover it
633
707
  if (child.listeners) {
634
- doNotify(child, value, [], value, prev, 0, !isArrDiff);
708
+ doNotify(child, value, [], [], value, prev, 0, !isArrDiff);
635
709
  }
636
710
  }
637
711
  }
@@ -683,7 +757,7 @@ const proxyHandler = {
683
757
  return l > 2 ? fn(node, a, b, c) : l > 1 ? fn(node, a, b) : fn(node, a);
684
758
  };
685
759
  }
686
- let value = getNodeValue(node);
760
+ let value = peek(node);
687
761
  const isValuePrimitive = isPrimitive(value);
688
762
  if (value === undefined || value === null || isValuePrimitive) {
689
763
  if (extraPrimitiveProps.size && (node.isActivatedPrimitive || extraPrimitiveActivators.has(p))) {
@@ -852,11 +926,7 @@ function setKey(node, key, newValue, level) {
852
926
  whenOptimizedOnlyIf = (newValue === null || newValue === void 0 ? void 0 : newValue.length) !== (prevValue === null || prevValue === void 0 ? void 0 : prevValue.length);
853
927
  }
854
928
  }
855
- if (NotifySpecifically.has(key)) {
856
- // Notify specifically at the child, not through children or parents
857
- doNotify(childNode, newValue, [], newValue, prevValue, 0);
858
- }
859
- else if (isPrim ? newValue !== prevValue : hasADiff) {
929
+ if (isPrim ? newValue !== prevValue : hasADiff) {
860
930
  // Notify for this element if something inside it has changed
861
931
  notify(isPrim && isRoot ? node : childNode, newValue, prevValue, (level !== null && level !== void 0 ? level : prevValue === undefined) ? -1 : hasADiff ? 0 : 1, whenOptimizedOnlyIf);
862
932
  }
@@ -924,7 +994,7 @@ function setupTracking(nodes, update, noArgs) {
924
994
  if (nodes) {
925
995
  for (let tracked of nodes.values()) {
926
996
  const { node, track } = tracked;
927
- listeners.push(onChange(node, update, track, noArgs));
997
+ listeners.push(onChange(node, update, { trackingType: track }, noArgs));
928
998
  }
929
999
  }
930
1000
  return () => {
@@ -1079,12 +1149,11 @@ exports.ObservablePrimitiveClass = ObservablePrimitiveClass;
1079
1149
  exports.batch = batch;
1080
1150
  exports.beginBatch = beginBatch;
1081
1151
  exports.beginTracking = beginTracking;
1082
- exports.clone = clone;
1083
1152
  exports.computeSelector = computeSelector;
1084
1153
  exports.computed = computed;
1085
- exports.constructObject = constructObject;
1154
+ exports.constructObjectWithPath = constructObjectWithPath;
1086
1155
  exports.dateModifiedKey = dateModifiedKey;
1087
- exports.deconstructObject = deconstructObject;
1156
+ exports.deconstructObjectWithPath = deconstructObjectWithPath;
1088
1157
  exports.endBatch = endBatch;
1089
1158
  exports.endTracking = endTracking;
1090
1159
  exports.event = event;
@@ -1109,11 +1178,12 @@ exports.observablePrimitive = observablePrimitive;
1109
1178
  exports.observe = observe;
1110
1179
  exports.onChange = onChange;
1111
1180
  exports.opaqueObject = opaqueObject;
1181
+ exports.setAtPath = setAtPath;
1182
+ exports.setInObservableAtPath = setInObservableAtPath;
1112
1183
  exports.symbolDateModified = symbolDateModified;
1113
1184
  exports.symbolDelete = symbolDelete;
1114
1185
  exports.symbolIsEvent = symbolIsEvent;
1115
1186
  exports.symbolIsObservable = symbolIsObservable;
1116
- exports.symbolUndef = symbolUndef;
1117
1187
  exports.tracking = tracking;
1118
1188
  exports.updateTracking = updateTracking;
1119
1189
  exports.when = when;