@legendapp/state 3.0.0-alpha.0 → 3.0.0-alpha.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 (323) hide show
  1. package/.DS_Store +0 -0
  2. package/CHANGELOG.md +1 -827
  3. package/LICENSE +1 -21
  4. package/README.md +1 -141
  5. package/as/arrayAsRecord.d.mts +5 -0
  6. package/as/arrayAsRecord.d.ts +5 -0
  7. package/as/arrayAsRecord.js +28 -0
  8. package/as/arrayAsRecord.mjs +26 -0
  9. package/as/arrayAsSet.d.mts +5 -0
  10. package/as/arrayAsSet.d.ts +5 -0
  11. package/as/arrayAsSet.js +13 -0
  12. package/as/arrayAsSet.mjs +11 -0
  13. package/as/arrayAsString.d.mts +5 -0
  14. package/as/arrayAsString.d.ts +5 -0
  15. package/as/arrayAsString.js +13 -0
  16. package/as/arrayAsString.mjs +11 -0
  17. package/as/numberAsString.d.mts +5 -0
  18. package/as/numberAsString.d.ts +5 -0
  19. package/as/numberAsString.js +13 -0
  20. package/as/numberAsString.mjs +11 -0
  21. package/as/recordAsArray.d.mts +5 -0
  22. package/as/recordAsArray.d.ts +5 -0
  23. package/as/recordAsArray.js +25 -0
  24. package/as/recordAsArray.mjs +23 -0
  25. package/as/recordAsString.d.mts +5 -0
  26. package/as/recordAsString.d.ts +5 -0
  27. package/as/recordAsString.js +13 -0
  28. package/as/recordAsString.mjs +11 -0
  29. package/as/setAsArray.d.mts +5 -0
  30. package/as/setAsArray.d.ts +5 -0
  31. package/as/setAsArray.js +13 -0
  32. package/as/setAsArray.mjs +11 -0
  33. package/as/setAsString.d.mts +5 -0
  34. package/as/setAsString.d.ts +5 -0
  35. package/as/setAsString.js +13 -0
  36. package/as/setAsString.mjs +11 -0
  37. package/as/stringAsArray.d.mts +5 -0
  38. package/as/stringAsArray.d.ts +5 -0
  39. package/as/stringAsArray.js +13 -0
  40. package/as/stringAsArray.mjs +11 -0
  41. package/as/stringAsNumber.d.mts +5 -0
  42. package/as/stringAsNumber.d.ts +5 -0
  43. package/as/stringAsNumber.js +16 -0
  44. package/as/stringAsNumber.mjs +14 -0
  45. package/as/stringAsRecord.d.mts +5 -0
  46. package/as/stringAsRecord.d.ts +5 -0
  47. package/as/stringAsRecord.js +15 -0
  48. package/as/stringAsRecord.mjs +13 -0
  49. package/as/stringAsSet.d.mts +5 -0
  50. package/as/stringAsSet.d.ts +5 -0
  51. package/as/stringAsSet.js +13 -0
  52. package/as/stringAsSet.mjs +11 -0
  53. package/babel.d.mts +21 -0
  54. package/babel.d.ts +21 -2
  55. package/babel.js +57 -53
  56. package/babel.mjs +65 -0
  57. package/config/enable$GetSet.js +13 -14
  58. package/config/enable$GetSet.mjs +13 -14
  59. package/config/enableReactComponents.d.mts +9 -0
  60. package/config/enableReactComponents.d.ts +4 -2
  61. package/config/enableReactComponents.js +13 -10
  62. package/config/enableReactComponents.mjs +13 -10
  63. package/config/enableReactNativeComponents.d.mts +22 -0
  64. package/config/enableReactNativeComponents.d.ts +6 -4
  65. package/config/enableReactNativeComponents.js +43 -47
  66. package/config/enableReactNativeComponents.mjs +43 -47
  67. package/config/enableReactTracking.d.mts +7 -0
  68. package/config/enableReactTracking.d.ts +3 -2
  69. package/config/enableReactTracking.js +33 -38
  70. package/config/enableReactTracking.mjs +33 -38
  71. package/config/enableReactUse.d.mts +10 -0
  72. package/config/enableReactUse.d.ts +4 -1
  73. package/config/enableReactUse.js +15 -14
  74. package/config/enableReactUse.mjs +15 -14
  75. package/config/{enable$GetSet.d.ts → enable_GetSet.d.mts} +4 -2
  76. package/config/enable_GetSet.d.ts +10 -0
  77. package/config/enable_PeekAssign.d.mts +10 -0
  78. package/config/enable_PeekAssign.d.ts +4 -2
  79. package/config/enable_PeekAssign.js +13 -14
  80. package/config/enable_PeekAssign.mjs +13 -14
  81. package/helpers/pageHash.d.mts +9 -0
  82. package/helpers/pageHash.d.ts +2 -0
  83. package/helpers/pageHash.js +25 -30
  84. package/helpers/pageHash.mjs +25 -30
  85. package/helpers/pageHashParams.d.mts +9 -0
  86. package/helpers/pageHashParams.d.ts +2 -0
  87. package/helpers/pageHashParams.js +34 -37
  88. package/helpers/pageHashParams.mjs +34 -37
  89. package/helpers/time.d.mts +6 -0
  90. package/helpers/time.d.ts +6 -3
  91. package/helpers/time.js +17 -17
  92. package/helpers/time.mjs +17 -17
  93. package/helpers/trackHistory.d.mts +6 -0
  94. package/helpers/trackHistory.d.ts +6 -0
  95. package/helpers/trackHistory.js +21 -0
  96. package/helpers/trackHistory.mjs +19 -0
  97. package/helpers/undoRedo.d.mts +37 -0
  98. package/helpers/undoRedo.d.ts +37 -0
  99. package/helpers/undoRedo.js +68 -0
  100. package/helpers/undoRedo.mjs +66 -0
  101. package/index.d.mts +404 -0
  102. package/index.d.ts +371 -28
  103. package/index.js +2003 -2164
  104. package/index.mjs +2003 -2164
  105. package/package.json +254 -185
  106. package/persist-plugins/async-storage.d.mts +18 -0
  107. package/persist-plugins/async-storage.d.ts +6 -3
  108. package/persist-plugins/async-storage.js +79 -86
  109. package/persist-plugins/async-storage.mjs +79 -86
  110. package/persist-plugins/indexeddb.d.mts +29 -0
  111. package/persist-plugins/indexeddb.d.ts +6 -3
  112. package/persist-plugins/indexeddb.js +331 -348
  113. package/persist-plugins/indexeddb.mjs +331 -348
  114. package/persist-plugins/local-storage.d.mts +23 -0
  115. package/persist-plugins/local-storage.d.ts +8 -5
  116. package/persist-plugins/local-storage.js +74 -76
  117. package/persist-plugins/local-storage.mjs +74 -76
  118. package/persist-plugins/mmkv.d.mts +18 -0
  119. package/persist-plugins/mmkv.d.ts +6 -3
  120. package/persist-plugins/mmkv.js +82 -86
  121. package/persist-plugins/mmkv.mjs +82 -86
  122. package/react-hooks/createObservableHook.d.mts +5 -0
  123. package/react-hooks/createObservableHook.d.ts +4 -1
  124. package/react-hooks/createObservableHook.js +29 -30
  125. package/react-hooks/createObservableHook.mjs +25 -30
  126. package/react-hooks/useHover.d.mts +5 -0
  127. package/react-hooks/useHover.d.ts +5 -3
  128. package/react-hooks/useHover.js +29 -29
  129. package/react-hooks/useHover.mjs +29 -29
  130. package/react-hooks/useMeasure.d.mts +9 -0
  131. package/react-hooks/useMeasure.d.ts +5 -2
  132. package/react-hooks/useMeasure.js +30 -32
  133. package/react-hooks/useMeasure.mjs +30 -32
  134. package/react-hooks/useObservableNextRouter.d.mts +35 -0
  135. package/react-hooks/useObservableNextRouter.d.ts +9 -7
  136. package/react-hooks/useObservableNextRouter.js +64 -77
  137. package/react-hooks/useObservableNextRouter.mjs +60 -77
  138. package/react.d.mts +157 -0
  139. package/react.d.ts +157 -21
  140. package/react.js +458 -749
  141. package/react.mjs +457 -752
  142. package/sync-plugins/crud.d.mts +54 -0
  143. package/sync-plugins/crud.d.ts +12 -10
  144. package/sync-plugins/crud.js +253 -270
  145. package/sync-plugins/crud.mjs +253 -270
  146. package/sync-plugins/fetch.d.mts +21 -0
  147. package/sync-plugins/fetch.d.ts +7 -4
  148. package/sync-plugins/fetch.js +50 -37
  149. package/sync-plugins/fetch.mjs +50 -37
  150. package/sync-plugins/keel.d.mts +108 -0
  151. package/sync-plugins/keel.d.ts +17 -15
  152. package/sync-plugins/keel.js +229 -462
  153. package/sync-plugins/keel.mjs +227 -464
  154. package/sync-plugins/supabase.d.mts +39 -0
  155. package/sync-plugins/supabase.d.ts +16 -14
  156. package/sync-plugins/supabase.js +128 -128
  157. package/sync-plugins/supabase.mjs +128 -128
  158. package/sync-plugins/tanstack-query.d.mts +14 -0
  159. package/sync-plugins/tanstack-query.d.ts +7 -4
  160. package/sync-plugins/tanstack-query.js +51 -57
  161. package/sync-plugins/tanstack-query.mjs +51 -57
  162. package/sync-plugins/tanstack-react-query.d.mts +8 -0
  163. package/sync-plugins/tanstack-react-query.d.ts +6 -1
  164. package/sync-plugins/tanstack-react-query.js +2 -2
  165. package/sync-plugins/tanstack-react-query.mjs +2 -2
  166. package/sync.d.mts +351 -0
  167. package/sync.d.ts +349 -9
  168. package/sync.js +909 -962
  169. package/sync.mjs +919 -972
  170. package/trace.d.mts +9 -0
  171. package/trace.d.ts +9 -4
  172. package/trace.js +72 -62
  173. package/trace.mjs +72 -62
  174. package/types/babel.d.ts +1 -12
  175. package/babel.js.map +0 -1
  176. package/config/enable$GetSet.js.map +0 -1
  177. package/config/enable$GetSet.mjs.map +0 -1
  178. package/config/enableReactComponents.js.map +0 -1
  179. package/config/enableReactComponents.mjs.map +0 -1
  180. package/config/enableReactNativeComponents.js.map +0 -1
  181. package/config/enableReactNativeComponents.mjs.map +0 -1
  182. package/config/enableReactTracking.js.map +0 -1
  183. package/config/enableReactTracking.mjs.map +0 -1
  184. package/config/enableReactUse.js.map +0 -1
  185. package/config/enableReactUse.mjs.map +0 -1
  186. package/config/enable_PeekAssign.js.map +0 -1
  187. package/config/enable_PeekAssign.mjs.map +0 -1
  188. package/helpers/pageHash.js.map +0 -1
  189. package/helpers/pageHash.mjs.map +0 -1
  190. package/helpers/pageHashParams.js.map +0 -1
  191. package/helpers/pageHashParams.mjs.map +0 -1
  192. package/helpers/time.js.map +0 -1
  193. package/helpers/time.mjs.map +0 -1
  194. package/history.d.ts +0 -1
  195. package/history.js +0 -24
  196. package/history.js.map +0 -1
  197. package/history.mjs +0 -22
  198. package/history.mjs.map +0 -1
  199. package/index.js.map +0 -1
  200. package/index.mjs.map +0 -1
  201. package/persist-plugins/async-storage.js.map +0 -1
  202. package/persist-plugins/async-storage.mjs.map +0 -1
  203. package/persist-plugins/indexeddb.js.map +0 -1
  204. package/persist-plugins/indexeddb.mjs.map +0 -1
  205. package/persist-plugins/local-storage.js.map +0 -1
  206. package/persist-plugins/local-storage.mjs.map +0 -1
  207. package/persist-plugins/mmkv.js.map +0 -1
  208. package/persist-plugins/mmkv.mjs.map +0 -1
  209. package/react-hooks/createObservableHook.js.map +0 -1
  210. package/react-hooks/createObservableHook.mjs.map +0 -1
  211. package/react-hooks/useHover.js.map +0 -1
  212. package/react-hooks/useHover.mjs.map +0 -1
  213. package/react-hooks/useMeasure.js.map +0 -1
  214. package/react-hooks/useMeasure.mjs.map +0 -1
  215. package/react-hooks/useObservableNextRouter.js.map +0 -1
  216. package/react-hooks/useObservableNextRouter.mjs.map +0 -1
  217. package/react.js.map +0 -1
  218. package/react.mjs.map +0 -1
  219. package/src/ObservableObject.ts +0 -1350
  220. package/src/ObservablePrimitive.ts +0 -62
  221. package/src/babel/index.ts +0 -83
  222. package/src/batching.ts +0 -357
  223. package/src/computed.ts +0 -18
  224. package/src/config/enable$GetSet.ts +0 -30
  225. package/src/config/enableReactComponents.ts +0 -26
  226. package/src/config/enableReactNativeComponents.ts +0 -102
  227. package/src/config/enableReactTracking.ts +0 -62
  228. package/src/config/enableReactUse.ts +0 -32
  229. package/src/config/enable_PeekAssign.ts +0 -31
  230. package/src/config.ts +0 -47
  231. package/src/createObservable.ts +0 -47
  232. package/src/event.ts +0 -26
  233. package/src/globals.ts +0 -235
  234. package/src/helpers/pageHash.ts +0 -41
  235. package/src/helpers/pageHashParams.ts +0 -55
  236. package/src/helpers/time.ts +0 -30
  237. package/src/helpers.ts +0 -231
  238. package/src/history/trackHistory.ts +0 -29
  239. package/src/history/undoRedo.ts +0 -111
  240. package/src/is.ts +0 -63
  241. package/src/linked.ts +0 -17
  242. package/src/observable.ts +0 -32
  243. package/src/observableInterfaces.ts +0 -151
  244. package/src/observableTypes.ts +0 -232
  245. package/src/observe.ts +0 -89
  246. package/src/old-plugins/firebase.ts +0 -1053
  247. package/src/onChange.ts +0 -146
  248. package/src/persist/configureObservablePersistence.ts +0 -7
  249. package/src/persist/fieldTransformer.ts +0 -149
  250. package/src/persist/observablePersistRemoteFunctionsAdapter.ts +0 -39
  251. package/src/persist/persistObservable.ts +0 -1034
  252. package/src/persist-plugins/async-storage.ts +0 -99
  253. package/src/persist-plugins/indexeddb.ts +0 -432
  254. package/src/persist-plugins/local-storage.ts +0 -86
  255. package/src/persist-plugins/mmkv.ts +0 -91
  256. package/src/proxy.ts +0 -28
  257. package/src/react/Computed.tsx +0 -8
  258. package/src/react/For.tsx +0 -116
  259. package/src/react/Memo.tsx +0 -4
  260. package/src/react/Reactive.tsx +0 -53
  261. package/src/react/Show.tsx +0 -33
  262. package/src/react/Switch.tsx +0 -43
  263. package/src/react/react-globals.ts +0 -3
  264. package/src/react/reactInterfaces.ts +0 -32
  265. package/src/react/reactive-observer.tsx +0 -210
  266. package/src/react/useComputed.ts +0 -36
  267. package/src/react/useEffectOnce.ts +0 -41
  268. package/src/react/useIsMounted.ts +0 -16
  269. package/src/react/useMount.ts +0 -15
  270. package/src/react/useObservable.ts +0 -24
  271. package/src/react/useObservableReducer.ts +0 -52
  272. package/src/react/useObservableState.ts +0 -30
  273. package/src/react/useObserve.ts +0 -54
  274. package/src/react/useObserveEffect.ts +0 -40
  275. package/src/react/usePauseProvider.tsx +0 -16
  276. package/src/react/useSelector.ts +0 -167
  277. package/src/react/useUnmount.ts +0 -8
  278. package/src/react/useWhen.ts +0 -9
  279. package/src/react-hooks/createObservableHook.ts +0 -53
  280. package/src/react-hooks/useHover.ts +0 -40
  281. package/src/react-hooks/useMeasure.ts +0 -48
  282. package/src/react-hooks/useObservableNextRouter.ts +0 -137
  283. package/src/retry.ts +0 -71
  284. package/src/setupTracking.ts +0 -26
  285. package/src/sync/activateSyncedNode.ts +0 -128
  286. package/src/sync/configureObservableSync.ts +0 -7
  287. package/src/sync/persistTypes.ts +0 -216
  288. package/src/sync/syncHelpers.ts +0 -180
  289. package/src/sync/syncObservable.ts +0 -1056
  290. package/src/sync/syncObservableAdapter.ts +0 -31
  291. package/src/sync/syncTypes.ts +0 -189
  292. package/src/sync/synced.ts +0 -21
  293. package/src/sync-plugins/crud.ts +0 -412
  294. package/src/sync-plugins/fetch.ts +0 -80
  295. package/src/sync-plugins/keel.ts +0 -495
  296. package/src/sync-plugins/supabase.ts +0 -249
  297. package/src/sync-plugins/tanstack-query.ts +0 -113
  298. package/src/sync-plugins/tanstack-react-query.ts +0 -12
  299. package/src/trace/traceHelpers.ts +0 -11
  300. package/src/trace/useTraceListeners.ts +0 -34
  301. package/src/trace/useTraceUpdates.ts +0 -24
  302. package/src/trace/useVerifyNotTracking.ts +0 -33
  303. package/src/trace/useVerifyOneRender.ts +0 -10
  304. package/src/trackSelector.ts +0 -52
  305. package/src/tracking.ts +0 -43
  306. package/src/types/babel.d.ts +0 -12
  307. package/src/when.ts +0 -75
  308. package/sync-plugins/crud.js.map +0 -1
  309. package/sync-plugins/crud.mjs.map +0 -1
  310. package/sync-plugins/fetch.js.map +0 -1
  311. package/sync-plugins/fetch.mjs.map +0 -1
  312. package/sync-plugins/keel.js.map +0 -1
  313. package/sync-plugins/keel.mjs.map +0 -1
  314. package/sync-plugins/supabase.js.map +0 -1
  315. package/sync-plugins/supabase.mjs.map +0 -1
  316. package/sync-plugins/tanstack-query.js.map +0 -1
  317. package/sync-plugins/tanstack-query.mjs.map +0 -1
  318. package/sync-plugins/tanstack-react-query.js.map +0 -1
  319. package/sync-plugins/tanstack-react-query.mjs.map +0 -1
  320. package/sync.js.map +0 -1
  321. package/sync.mjs.map +0 -1
  322. package/trace.js.map +0 -1
  323. package/trace.mjs.map +0 -1
@@ -1,62 +0,0 @@
1
- import { set, get, peek, flushPending } from './ObservableObject';
2
- import { symbolGetNode } from './globals';
3
- import { isBoolean } from './is';
4
- import type { NodeValue, TrackingType } from './observableInterfaces';
5
- import type { ObservablePrimitive, ObservableBoolean } from './observableTypes';
6
- import { onChange } from './onChange';
7
-
8
- interface ObservablePrimitiveState {
9
- _node: NodeValue;
10
- toggle: () => void;
11
- }
12
-
13
- const fns: (keyof ObservableBoolean)[] = ['get', 'set', 'peek', 'onChange', 'toggle'];
14
-
15
- export function ObservablePrimitiveClass<T>(this: ObservablePrimitive<T> & ObservablePrimitiveState, node: NodeValue) {
16
- this._node = node;
17
-
18
- // Bind to this
19
- for (let i = 0; i < fns.length; i++) {
20
- const key: keyof typeof this = fns[i];
21
- this[key] = (this[key] as Function).bind(this);
22
- }
23
- }
24
-
25
- // Add observable functions to prototype
26
- function proto(key: string, fn: Function) {
27
- ObservablePrimitiveClass.prototype[key] = function (...args: any[]) {
28
- return fn.call(this, this._node, ...args);
29
- };
30
- }
31
- proto('peek', (node: NodeValue) => {
32
- flushPending();
33
- return peek(node);
34
- });
35
- proto('get', (node: NodeValue, options?: TrackingType) => {
36
- flushPending();
37
- return get(node, options);
38
- });
39
- proto('set', set);
40
- proto('onChange', onChange);
41
-
42
- // Getters
43
- Object.defineProperty(ObservablePrimitiveClass.prototype, symbolGetNode, {
44
- configurable: true,
45
- get() {
46
- return this._node;
47
- },
48
- });
49
-
50
- ObservablePrimitiveClass.prototype.toggle = function (): void {
51
- const value = this.peek();
52
- if (value === undefined || value === null || isBoolean(value)) {
53
- this.set(!value);
54
- } else if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
55
- throw new Error('[legend-state] Cannot toggle a non-boolean value');
56
- }
57
- };
58
- ObservablePrimitiveClass.prototype.delete = function () {
59
- this.set(undefined);
60
-
61
- return this;
62
- };
@@ -1,83 +0,0 @@
1
- import {
2
- arrowFunctionExpression,
3
- jsxClosingElement,
4
- jsxClosingFragment,
5
- jsxElement,
6
- jsxExpressionContainer,
7
- jsxFragment,
8
- jsxIdentifier,
9
- jsxOpeningElement,
10
- jsxOpeningFragment,
11
- } from '@babel/types';
12
-
13
- export default function () {
14
- let hasLegendImport = false;
15
- return {
16
- visitor: {
17
- ImportDeclaration: {
18
- enter(path: { node: any; replaceWith: (param: any) => any; skip: () => void }) {
19
- if (path.node.source.value === '@legendapp/state/react') {
20
- const specifiers = path.node.specifiers;
21
- for (let i = 0; i < specifiers.length; i++) {
22
- const s = specifiers[i].imported.name;
23
- if (!hasLegendImport && (s === 'Computed' || s === 'Memo' || s === 'Show')) {
24
- hasLegendImport = true;
25
- path.skip();
26
- break;
27
- }
28
- }
29
- }
30
- },
31
- },
32
- JSXElement: {
33
- enter(path: {
34
- node: any;
35
- replaceWith: (param: any) => any;
36
- skip: () => void;
37
- traverse: (path: any) => any;
38
- }) {
39
- if (!hasLegendImport) {
40
- path.skip();
41
- return;
42
- }
43
-
44
- const openingElement = path.node.openingElement;
45
- const name = openingElement.name.name;
46
-
47
- if (name === 'Computed' || name === 'Memo' || name === 'Show') {
48
- const children = removeEmptyText(path.node.children);
49
- if (children.length === 0) return;
50
-
51
- if (
52
- children[0].type === 'JSXElement' ||
53
- (children[0].type === 'JSXExpressionContainer' &&
54
- children[0].expression.type !== 'ArrowFunctionExpression' &&
55
- children[0].expression.type !== 'FunctionExpression' &&
56
- children[0].expression.type !== 'MemberExpression' &&
57
- children[0].expression.type !== 'Identifier')
58
- ) {
59
- const attrs = openingElement.attributes;
60
- path.replaceWith(
61
- jsxElement(
62
- jsxOpeningElement(jsxIdentifier(name), attrs),
63
- jsxClosingElement(jsxIdentifier(name)),
64
- [jsxExpressionContainer(arrowFunctionExpression([], maybeWrapFragment(children)))],
65
- ),
66
- );
67
- }
68
- }
69
- },
70
- },
71
- },
72
- };
73
- }
74
-
75
- function maybeWrapFragment(children: any[]) {
76
- if (children.length === 1 && children[0].type == 'JSXElement') return children[0];
77
- if (children.length === 1 && children[0].type == 'JSXExpressionContainer') return children[0].expression;
78
- return jsxFragment(jsxOpeningFragment(), jsxClosingFragment(), children);
79
- }
80
-
81
- function removeEmptyText(nodes: any[]) {
82
- return nodes.filter((node) => !(node.type === 'JSXText' && node.value.trim().length === 0));
83
- }
package/src/batching.ts DELETED
@@ -1,357 +0,0 @@
1
- import { clone, getChildNode, getNodeValue, getPathType, globalState, optimized } from './globals';
2
- import { applyChanges } from './helpers';
3
- import type { Change, ListenerFn, ListenerParams, NodeValue, TypeAtPath } from './observableInterfaces';
4
-
5
- interface BatchItem {
6
- value: any;
7
- prev: any;
8
- level: number;
9
- loading: boolean;
10
- remote: boolean;
11
- whenOptimizedOnlyIf?: boolean;
12
- }
13
- interface ChangeInBatch {
14
- value: any;
15
- level: number;
16
- remote: boolean;
17
- loading: boolean;
18
- whenOptimizedOnlyIf?: boolean;
19
- changes: Change[];
20
- }
21
- let timeout: ReturnType<typeof setTimeout> | undefined;
22
- let numInBatch = 0;
23
- let isRunningBatch = false;
24
- let didDelayEndBatch = false;
25
- let _batchMap = new Map<NodeValue, BatchItem>();
26
-
27
- function onActionTimeout() {
28
- if (_batchMap.size > 0) {
29
- if (process.env.NODE_ENV === 'development') {
30
- console.error(
31
- 'Forcibly completing observableBatcher because end() was never called. This may be due to an uncaught error between begin() and end().',
32
- );
33
- }
34
- endBatch(/*force*/ true);
35
- }
36
- }
37
-
38
- export function isArraySubset<T>(mainArr: T[], subsetArr: T[]) {
39
- for (let i = 0; i < mainArr.length; i++) {
40
- if (mainArr[i] !== subsetArr[i]) {
41
- return false;
42
- }
43
- }
44
-
45
- return true;
46
- }
47
-
48
- function createPreviousHandlerInner(value: any, changes: Change[]) {
49
- try {
50
- // Clones the current state and inject the previous data at the changed path
51
- return applyChanges(value ? clone(value) : {}, changes, true);
52
- } catch {
53
- return undefined;
54
- }
55
- }
56
-
57
- export function createPreviousHandler(value: any, changes: Change[]) {
58
- // Create a function that generates the previous state
59
- // We don't want to always do this because cloning is expensive
60
- // so it's better to run on demand.
61
- return function () {
62
- return createPreviousHandlerInner(value, changes);
63
- };
64
- }
65
-
66
- export function notify(node: NodeValue, value: any, prev: any, level: number, whenOptimizedOnlyIf?: boolean) {
67
- // Run immediate listeners if there are any
68
- const changesInBatch = new Map<NodeValue, ChangeInBatch>();
69
- computeChangesRecursive(
70
- changesInBatch,
71
- node,
72
- /*loading*/ globalState.isLoadingLocal,
73
- /*remote*/ globalState.isLoadingRemote,
74
- value,
75
- [],
76
- [],
77
- value,
78
- prev,
79
- /*immediate*/ true,
80
- level,
81
- whenOptimizedOnlyIf,
82
- );
83
- if (changesInBatch.size) {
84
- batchNotifyChanges(changesInBatch, /*immediate*/ true);
85
- }
86
-
87
- // Update the current batch
88
- const existing = _batchMap.get(node);
89
- if (existing) {
90
- existing.value = value;
91
- // TODO: level, whenOptimizedOnlyIf
92
- } else {
93
- _batchMap.set(node, {
94
- value,
95
- prev,
96
- level,
97
- whenOptimizedOnlyIf,
98
- remote: globalState.isLoadingRemote,
99
- loading: globalState.isLoadingLocal,
100
- });
101
- }
102
-
103
- // If not in a batch run it immediately
104
- if (numInBatch <= 0) {
105
- runBatch();
106
- }
107
- }
108
-
109
- function computeChangesAtNode(
110
- changesInBatch: Map<NodeValue, ChangeInBatch>,
111
- node: NodeValue,
112
- loading: boolean,
113
- remote: boolean,
114
- value: any,
115
- path: string[],
116
- pathTypes: TypeAtPath[],
117
- valueAtPath: any,
118
- prevAtPath: any,
119
- immediate: boolean,
120
- level: number,
121
- whenOptimizedOnlyIf?: boolean,
122
- ) {
123
- // If there are listeners at this node compute the changes that need to be run
124
- if (immediate ? node.listenersImmediate : node.listeners) {
125
- const change: Change = {
126
- path,
127
- pathTypes,
128
- valueAtPath,
129
- prevAtPath,
130
- };
131
-
132
- const changeInBatch = changesInBatch.get(node);
133
- // If the node itself has been changed then we can ignore all the child changes
134
- if (changeInBatch && path.length > 0) {
135
- const { changes } = changeInBatch;
136
- if (!isArraySubset(changes[0].path, change.path)) {
137
- changes.push(change);
138
- }
139
- } else {
140
- changesInBatch.set(node, {
141
- level,
142
- value,
143
- remote,
144
- loading,
145
- whenOptimizedOnlyIf,
146
- changes: [change],
147
- });
148
- }
149
- }
150
- }
151
-
152
- function computeChangesRecursive(
153
- changesInBatch: Map<NodeValue, ChangeInBatch>,
154
- node: NodeValue,
155
- loading: boolean,
156
- remote: boolean,
157
- value: any,
158
- path: string[],
159
- pathTypes: TypeAtPath[],
160
- valueAtPath: any,
161
- prevAtPath: any,
162
- immediate: boolean,
163
- level: number,
164
- whenOptimizedOnlyIf?: boolean,
165
- ) {
166
- // Do the compute at this node
167
- computeChangesAtNode(
168
- changesInBatch,
169
- node,
170
- loading,
171
- remote,
172
- value,
173
- path,
174
- pathTypes,
175
- valueAtPath,
176
- prevAtPath,
177
- immediate,
178
- level,
179
- whenOptimizedOnlyIf,
180
- );
181
- if (node.linkedFromNodes) {
182
- for (const linkedFromNode of node.linkedFromNodes) {
183
- const childNode = getNodeAtPath(linkedFromNode, path);
184
- computeChangesRecursive(
185
- changesInBatch,
186
- childNode,
187
- loading,
188
- remote,
189
- valueAtPath,
190
- [],
191
- [],
192
- valueAtPath,
193
- prevAtPath,
194
- immediate,
195
- 0,
196
- whenOptimizedOnlyIf,
197
- );
198
- }
199
- }
200
- // If not root notify up through parents
201
- if (node.parent) {
202
- const parent = node.parent;
203
- if (parent) {
204
- const parentValue = getNodeValue(parent);
205
- computeChangesRecursive(
206
- changesInBatch,
207
- parent,
208
- loading,
209
- remote,
210
- parentValue,
211
- [node.key].concat(path),
212
- [getPathType(value)].concat(pathTypes),
213
- valueAtPath,
214
- prevAtPath,
215
- immediate,
216
- level + 1,
217
- whenOptimizedOnlyIf,
218
- );
219
- }
220
- }
221
- }
222
-
223
- function batchNotifyChanges(changesInBatch: Map<NodeValue, ChangeInBatch>, immediate: boolean) {
224
- const listenersNotified = new Set<ListenerFn>();
225
- // For each change in the batch, notify all of the listeners
226
- changesInBatch.forEach(({ changes, level, value, loading, remote, whenOptimizedOnlyIf }, node) => {
227
- const listeners = immediate ? node.listenersImmediate : node.listeners;
228
- if (listeners) {
229
- let listenerParams: ListenerParams | undefined;
230
- // Need to convert to an array here instead of using a for...of loop because listeners can change while iterating
231
- const arr = Array.from(listeners);
232
- for (let i = 0; i < arr.length; i++) {
233
- const listenerFn = arr[i];
234
- const { track, noArgs, listener } = listenerFn;
235
- if (!listenersNotified.has(listener)) {
236
- const ok =
237
- track === true ? level <= 0 : track === optimized ? whenOptimizedOnlyIf && level <= 0 : true;
238
-
239
- // Notify if listener is not shallow or if this is the first level
240
- if (ok) {
241
- // Create listenerParams if not already created
242
- if (!noArgs && !listenerParams) {
243
- listenerParams = {
244
- value,
245
- loading,
246
- remote,
247
- getPrevious: createPreviousHandler(value, changes),
248
- changes,
249
- };
250
- }
251
-
252
- if (!track) {
253
- listenersNotified.add(listener);
254
- }
255
-
256
- listener(listenerParams!);
257
- }
258
- }
259
- }
260
- }
261
- });
262
- }
263
-
264
- export function runBatch() {
265
- const dirtyNodes = Array.from(globalState.dirtyNodes);
266
- globalState.dirtyNodes.clear();
267
- dirtyNodes.forEach((node) => {
268
- const dirtyFn = node.dirtyFn;
269
- if (dirtyFn) {
270
- node.dirtyFn = undefined;
271
- dirtyFn();
272
- }
273
- });
274
- // Save batch locally and reset _batchMap first because a new batch could begin while looping over callbacks.
275
- // This can happen with computeds for example.
276
- const map = _batchMap;
277
- _batchMap = new Map();
278
- const changesInBatch = new Map<NodeValue, ChangeInBatch>();
279
- // First compute all of the changes at each node. It's important to do this first before
280
- // running all the notifications because createPreviousHandler depends on knowing
281
- // all of the changes happening at the node.
282
- map.forEach(({ value, prev, level, loading, remote, whenOptimizedOnlyIf }, node) => {
283
- computeChangesRecursive(
284
- changesInBatch,
285
- node,
286
- loading,
287
- remote,
288
- value,
289
- [],
290
- [],
291
- value,
292
- prev,
293
- false,
294
- level,
295
- whenOptimizedOnlyIf,
296
- );
297
- });
298
-
299
- // Once all changes are computed, notify all listeners for each node with the computed changes.
300
- if (changesInBatch.size) {
301
- batchNotifyChanges(changesInBatch, false);
302
- }
303
- }
304
-
305
- export function batch(fn: () => void) {
306
- beginBatch();
307
- try {
308
- fn();
309
- } finally {
310
- endBatch();
311
- }
312
- }
313
- export function beginBatch() {
314
- numInBatch++;
315
- if (!timeout) {
316
- timeout = setTimeout(onActionTimeout, 0);
317
- }
318
- }
319
- export function endBatch(force?: boolean) {
320
- numInBatch--;
321
-
322
- if (numInBatch <= 0 || force) {
323
- if (isRunningBatch) {
324
- // Don't want to run multiple endBatches recursively, so just note that an endBatch
325
- // was delayed so that the top level endBatch will run endBatch again after it's done.
326
- didDelayEndBatch = true;
327
- } else {
328
- if (timeout) {
329
- clearTimeout(timeout);
330
- timeout = undefined;
331
- }
332
- numInBatch = 0;
333
-
334
- isRunningBatch = true;
335
-
336
- runBatch();
337
-
338
- isRunningBatch = false;
339
-
340
- // If an endBatch was delayed run it now
341
- if (didDelayEndBatch) {
342
- didDelayEndBatch = false;
343
- endBatch(true);
344
- }
345
- }
346
- }
347
- }
348
-
349
- function getNodeAtPath(obj: NodeValue, path: string[]): NodeValue {
350
- let o: NodeValue = obj;
351
- for (let i = 0; i < path.length; i++) {
352
- const p = path[i];
353
- o = getChildNode(o, p);
354
- }
355
-
356
- return o;
357
- }
package/src/computed.ts DELETED
@@ -1,18 +0,0 @@
1
- import { linked } from './linked';
2
- import { observable } from './observable';
3
- import { LinkedOptions } from './observableInterfaces';
4
- import { Observable, ObservableParam, RecursiveValueOrFunction } from './observableTypes';
5
-
6
- export function computed<T>(get: () => RecursiveValueOrFunction<T>): Observable<T>;
7
- export function computed<T, T2 = T>(
8
- get: (() => RecursiveValueOrFunction<T>) | RecursiveValueOrFunction<T>,
9
- set: (value: T2) => void,
10
- ): Observable<T>;
11
- export function computed<T, T2 = T>(
12
- get: (() => T | Promise<T>) | ObservableParam<T> | LinkedOptions<T>,
13
- set?: (value: T2) => void,
14
- ): Observable<T> {
15
- return observable(
16
- set ? linked({ get: get as LinkedOptions['get'], set: ({ value }: any) => set(value) }) : get,
17
- ) as any;
18
- }
@@ -1,30 +0,0 @@
1
- import { configureLegendState, internal } from '@legendapp/state';
2
-
3
- export function enable$GetSet() {
4
- configureLegendState({
5
- observableProperties: {
6
- $: {
7
- get(node) {
8
- return internal.get(node);
9
- },
10
- set(node, value) {
11
- internal.set(node, value);
12
- },
13
- },
14
- },
15
- });
16
- }
17
- // TODOv4 deprecate
18
- export const enableDirectAccess = enable$GetSet;
19
-
20
- // Types:
21
-
22
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
23
- import type { ImmutableObservableBase } from '@legendapp/state';
24
-
25
- declare module '@legendapp/state' {
26
- interface ImmutableObservableBase<T> {
27
- get $(): T;
28
- set $(value: T | null | undefined);
29
- }
30
- }
@@ -1,26 +0,0 @@
1
- import { BindKeys, FCReactiveObject, configureReactive } from '@legendapp/state/react';
2
-
3
- export function enableReactComponents() {
4
- const bindInfo: BindKeys = { value: { handler: 'onChange', getValue: (e) => e.target.value, defaultValue: '' } };
5
- const bindInfoInput: BindKeys = Object.assign(
6
- { checked: { handler: 'onChange', getValue: (e: { target: { checked: boolean } }) => e.target.checked } },
7
- bindInfo,
8
- );
9
- configureReactive({
10
- binders: {
11
- input: bindInfoInput,
12
- textarea: bindInfo,
13
- select: bindInfo,
14
- },
15
- });
16
- }
17
-
18
- // Types:
19
-
20
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
21
- import type { IReactive } from '@legendapp/state/react';
22
-
23
- declare module '@legendapp/state/react' {
24
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
25
- interface IReactive extends FCReactiveObject<JSX.IntrinsicElements> {}
26
- }
@@ -1,102 +0,0 @@
1
- import { useRef } from 'react';
2
- import type { Observable } from '@legendapp/state';
3
- import { FCReactive, FCReactiveObject, configureReactive, useSelector } from '@legendapp/state/react';
4
- import {
5
- ActivityIndicator,
6
- ActivityIndicatorProps,
7
- Button,
8
- ButtonProps,
9
- FlatList,
10
- FlatListProps,
11
- Image,
12
- ImageProps,
13
- Pressable,
14
- PressableProps,
15
- ScrollView,
16
- ScrollViewProps,
17
- SectionList,
18
- SectionListProps,
19
- Switch,
20
- SwitchProps,
21
- Text,
22
- TextInput,
23
- TextInputProps,
24
- TextProps,
25
- TouchableWithoutFeedback,
26
- TouchableWithoutFeedbackProps,
27
- View,
28
- ViewProps,
29
- } from 'react-native';
30
-
31
- export function enableReactNativeComponents() {
32
- configureReactive({
33
- components: {
34
- ActivityIndicator: ActivityIndicator,
35
- Button: Button,
36
- FlatList: FlatList,
37
- Image: Image,
38
- Pressable: Pressable,
39
- ScrollView: ScrollView,
40
- SectionList: SectionList,
41
- Switch: Switch,
42
- Text: Text,
43
- TextInput: TextInput,
44
- TouchableWithoutFeedback: TouchableWithoutFeedback,
45
- View: View,
46
- },
47
- binders: {
48
- TextInput: {
49
- value: {
50
- handler: 'onChange',
51
- getValue: (e) => e.nativeEvent.text,
52
- defaultValue: '',
53
- },
54
- },
55
- Switch: {
56
- value: {
57
- handler: 'onValueChange',
58
- getValue: (e) => e,
59
- defaultValue: false,
60
- },
61
- },
62
- FlatList: {
63
- data: {
64
- selector: (propsOut: Record<string, any>, p: Observable<any>) => {
65
- const state = useRef(0);
66
- // Increment renderNum whenever the array changes shallowly
67
- const [renderNum, value] = useSelector(() => [state.current++, p.get(true)]);
68
-
69
- // Set extraData to renderNum so that it will re-render when renderNum changes.
70
- // This is necessary because the observable array is mutable so changes to it
71
- // won't trigger re-renders by default.
72
- propsOut.extraData = renderNum;
73
-
74
- return value;
75
- },
76
- },
77
- },
78
- },
79
- });
80
- }
81
-
82
- // Types:
83
-
84
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
85
- import type { IReactive } from '@legendapp/state/react';
86
-
87
- declare module '@legendapp/state/react' {
88
- interface IReactive extends FCReactiveObject<JSX.IntrinsicElements> {
89
- ActivityIndicator: FCReactive<ActivityIndicator, ActivityIndicatorProps>;
90
- Button: FCReactive<Button, ButtonProps>;
91
- FlatList: FCReactive<FlatList, FlatListProps<any>>;
92
- Image: FCReactive<Image, ImageProps>;
93
- Pressable: FCReactive<typeof Pressable, PressableProps>;
94
- ScrollView: FCReactive<ScrollView, ScrollViewProps>;
95
- SectionList: FCReactive<SectionList, SectionListProps<any>>;
96
- Switch: FCReactive<Switch, SwitchProps>;
97
- Text: FCReactive<Text, TextProps>;
98
- TextInput: FCReactive<TextInput, TextInputProps>;
99
- TouchableWithoutFeedback: FCReactive<TouchableWithoutFeedback, TouchableWithoutFeedbackProps>;
100
- View: FCReactive<View, ViewProps>;
101
- }
102
- }