@legendapp/state 3.0.0-alpha.1 → 3.0.0-alpha.3

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 (327) hide show
  1. package/.DS_Store +0 -0
  2. package/CHANGELOG.md +1 -831
  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 +4 -2
  95. package/helpers/trackHistory.js +13 -16
  96. package/helpers/trackHistory.mjs +13 -16
  97. package/helpers/undoRedo.d.mts +37 -0
  98. package/helpers/undoRedo.d.ts +5 -3
  99. package/helpers/undoRedo.js +59 -94
  100. package/helpers/undoRedo.mjs +59 -94
  101. package/index.d.mts +404 -0
  102. package/index.d.ts +371 -28
  103. package/index.js +2015 -2166
  104. package/index.mjs +2015 -2166
  105. package/package.json +254 -195
  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 -352
  113. package/persist-plugins/indexeddb.mjs +331 -352
  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 +910 -964
  169. package/sync.mjs +920 -974
  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/helpers/trackHistory.js.map +0 -1
  195. package/helpers/trackHistory.mjs.map +0 -1
  196. package/helpers/undoRedo.js.map +0 -1
  197. package/helpers/undoRedo.mjs.map +0 -1
  198. package/history.d.ts +0 -1
  199. package/history.js +0 -24
  200. package/history.js.map +0 -1
  201. package/history.mjs +0 -22
  202. package/history.mjs.map +0 -1
  203. package/index.js.map +0 -1
  204. package/index.mjs.map +0 -1
  205. package/persist-plugins/async-storage.js.map +0 -1
  206. package/persist-plugins/async-storage.mjs.map +0 -1
  207. package/persist-plugins/indexeddb.js.map +0 -1
  208. package/persist-plugins/indexeddb.mjs.map +0 -1
  209. package/persist-plugins/local-storage.js.map +0 -1
  210. package/persist-plugins/local-storage.mjs.map +0 -1
  211. package/persist-plugins/mmkv.js.map +0 -1
  212. package/persist-plugins/mmkv.mjs.map +0 -1
  213. package/react-hooks/createObservableHook.js.map +0 -1
  214. package/react-hooks/createObservableHook.mjs.map +0 -1
  215. package/react-hooks/useHover.js.map +0 -1
  216. package/react-hooks/useHover.mjs.map +0 -1
  217. package/react-hooks/useMeasure.js.map +0 -1
  218. package/react-hooks/useMeasure.mjs.map +0 -1
  219. package/react-hooks/useObservableNextRouter.js.map +0 -1
  220. package/react-hooks/useObservableNextRouter.mjs.map +0 -1
  221. package/react.js.map +0 -1
  222. package/react.mjs.map +0 -1
  223. package/src/ObservableObject.ts +0 -1350
  224. package/src/ObservablePrimitive.ts +0 -62
  225. package/src/babel/index.ts +0 -83
  226. package/src/batching.ts +0 -357
  227. package/src/computed.ts +0 -18
  228. package/src/config/enable$GetSet.ts +0 -30
  229. package/src/config/enableReactComponents.ts +0 -26
  230. package/src/config/enableReactNativeComponents.ts +0 -102
  231. package/src/config/enableReactTracking.ts +0 -62
  232. package/src/config/enableReactUse.ts +0 -32
  233. package/src/config/enable_PeekAssign.ts +0 -31
  234. package/src/config.ts +0 -47
  235. package/src/createObservable.ts +0 -47
  236. package/src/event.ts +0 -26
  237. package/src/globals.ts +0 -235
  238. package/src/helpers/pageHash.ts +0 -41
  239. package/src/helpers/pageHashParams.ts +0 -55
  240. package/src/helpers/time.ts +0 -30
  241. package/src/helpers/trackHistory.ts +0 -29
  242. package/src/helpers/undoRedo.ts +0 -111
  243. package/src/helpers.ts +0 -231
  244. package/src/is.ts +0 -63
  245. package/src/linked.ts +0 -17
  246. package/src/observable.ts +0 -32
  247. package/src/observableInterfaces.ts +0 -151
  248. package/src/observableTypes.ts +0 -232
  249. package/src/observe.ts +0 -89
  250. package/src/old-plugins/firebase.ts +0 -1053
  251. package/src/onChange.ts +0 -146
  252. package/src/persist/configureObservablePersistence.ts +0 -7
  253. package/src/persist/fieldTransformer.ts +0 -149
  254. package/src/persist/observablePersistRemoteFunctionsAdapter.ts +0 -39
  255. package/src/persist/persistObservable.ts +0 -1034
  256. package/src/persist-plugins/async-storage.ts +0 -99
  257. package/src/persist-plugins/indexeddb.ts +0 -439
  258. package/src/persist-plugins/local-storage.ts +0 -86
  259. package/src/persist-plugins/mmkv.ts +0 -91
  260. package/src/proxy.ts +0 -28
  261. package/src/react/Computed.tsx +0 -8
  262. package/src/react/For.tsx +0 -116
  263. package/src/react/Memo.tsx +0 -4
  264. package/src/react/Reactive.tsx +0 -53
  265. package/src/react/Show.tsx +0 -33
  266. package/src/react/Switch.tsx +0 -43
  267. package/src/react/react-globals.ts +0 -3
  268. package/src/react/reactInterfaces.ts +0 -32
  269. package/src/react/reactive-observer.tsx +0 -210
  270. package/src/react/useComputed.ts +0 -36
  271. package/src/react/useEffectOnce.ts +0 -41
  272. package/src/react/useIsMounted.ts +0 -16
  273. package/src/react/useMount.ts +0 -15
  274. package/src/react/useObservable.ts +0 -24
  275. package/src/react/useObservableReducer.ts +0 -52
  276. package/src/react/useObservableState.ts +0 -30
  277. package/src/react/useObserve.ts +0 -54
  278. package/src/react/useObserveEffect.ts +0 -40
  279. package/src/react/usePauseProvider.tsx +0 -16
  280. package/src/react/useSelector.ts +0 -167
  281. package/src/react/useUnmount.ts +0 -8
  282. package/src/react/useWhen.ts +0 -9
  283. package/src/react-hooks/createObservableHook.ts +0 -53
  284. package/src/react-hooks/useHover.ts +0 -40
  285. package/src/react-hooks/useMeasure.ts +0 -48
  286. package/src/react-hooks/useObservableNextRouter.ts +0 -137
  287. package/src/retry.ts +0 -71
  288. package/src/setupTracking.ts +0 -26
  289. package/src/sync/activateSyncedNode.ts +0 -128
  290. package/src/sync/configureObservableSync.ts +0 -7
  291. package/src/sync/persistTypes.ts +0 -216
  292. package/src/sync/syncHelpers.ts +0 -180
  293. package/src/sync/syncObservable.ts +0 -1056
  294. package/src/sync/syncObservableAdapter.ts +0 -31
  295. package/src/sync/syncTypes.ts +0 -189
  296. package/src/sync/synced.ts +0 -21
  297. package/src/sync-plugins/crud.ts +0 -412
  298. package/src/sync-plugins/fetch.ts +0 -80
  299. package/src/sync-plugins/keel.ts +0 -495
  300. package/src/sync-plugins/supabase.ts +0 -249
  301. package/src/sync-plugins/tanstack-query.ts +0 -113
  302. package/src/sync-plugins/tanstack-react-query.ts +0 -12
  303. package/src/trace/traceHelpers.ts +0 -11
  304. package/src/trace/useTraceListeners.ts +0 -34
  305. package/src/trace/useTraceUpdates.ts +0 -24
  306. package/src/trace/useVerifyNotTracking.ts +0 -33
  307. package/src/trace/useVerifyOneRender.ts +0 -10
  308. package/src/trackSelector.ts +0 -52
  309. package/src/tracking.ts +0 -43
  310. package/src/types/babel.d.ts +0 -12
  311. package/src/when.ts +0 -75
  312. package/sync-plugins/crud.js.map +0 -1
  313. package/sync-plugins/crud.mjs.map +0 -1
  314. package/sync-plugins/fetch.js.map +0 -1
  315. package/sync-plugins/fetch.mjs.map +0 -1
  316. package/sync-plugins/keel.js.map +0 -1
  317. package/sync-plugins/keel.mjs.map +0 -1
  318. package/sync-plugins/supabase.js.map +0 -1
  319. package/sync-plugins/supabase.mjs.map +0 -1
  320. package/sync-plugins/tanstack-query.js.map +0 -1
  321. package/sync-plugins/tanstack-query.mjs.map +0 -1
  322. package/sync-plugins/tanstack-react-query.js.map +0 -1
  323. package/sync-plugins/tanstack-react-query.mjs.map +0 -1
  324. package/sync.js.map +0 -1
  325. package/sync.mjs.map +0 -1
  326. package/trace.js.map +0 -1
  327. 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
- }