@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 {
2
- type GetOptions,
3
- configureLegendState,
4
- internal,
5
- isObject,
6
- tracking,
7
- type NodeValue,
8
- type TrackingType,
9
- } from '@legendapp/state';
10
- import { UseSelectorOptions, useSelector } from '@legendapp/state/react';
11
- import { createContext, useContext } from 'react';
12
- // @ts-expect-error Internals
13
- import { __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED as ReactInternals } from 'react';
14
-
15
- interface ReactTrackingOptions {
16
- auto?: boolean; // Make all get() calls act as useSelector() hooks
17
- warnUnobserved?: boolean; // Warn if get() is used outside of an observer
18
- }
19
-
20
- export function enableReactTracking({ auto, warnUnobserved }: ReactTrackingOptions) {
21
- const { get } = internal;
22
-
23
- if (auto || (process.env.NODE_ENV === 'development' && warnUnobserved)) {
24
- const ReactRenderContext = createContext(0);
25
-
26
- const needsSelector = () => {
27
- // If we're already tracking then we definitely don't need useSelector
28
- if (!tracking.current) {
29
- try {
30
- // If there's no dispatcher we're definitely not in React
31
- // This is an optimization to not need to run useContext. If in a future React version
32
- // this works differently we can change it or just remove it.
33
- const dispatcher = ReactInternals.ReactCurrentDispatcher.current;
34
- if (dispatcher) {
35
- // If there's a dispatcher then we may be inside of a hook.
36
- // Attempt a useContext hook, which will throw an error if outside of render.
37
- useContext(ReactRenderContext);
38
- return true;
39
- }
40
- } catch {} // eslint-disable-line no-empty
41
- }
42
- return false;
43
- };
44
-
45
- configureLegendState({
46
- observableFunctions: {
47
- get: (node: NodeValue, options?: TrackingType | (GetOptions & UseSelectorOptions)) => {
48
- if (needsSelector()) {
49
- if (auto) {
50
- return useSelector(() => get(node, options), isObject(options) ? options : undefined);
51
- } else if (process.env.NODE_ENV === 'development' && warnUnobserved) {
52
- console.warn(
53
- '[legend-state] Detected a `get()` call in an unobserved component. You may want to wrap it in observer: https://legendapp.com/open-source/state/react-api/#observer-hoc',
54
- );
55
- }
56
- }
57
- return get(node, options);
58
- },
59
- },
60
- });
61
- }
62
- }
@@ -1,32 +0,0 @@
1
- import { configureLegendState, internal, NodeValue } from '@legendapp/state';
2
- import { useSelector, UseSelectorOptions } from '@legendapp/state/react';
3
-
4
- // TODO: Deprecated, remove in v4
5
- let didWarn = false;
6
-
7
- export function enableReactUse() {
8
- configureLegendState({
9
- observableFunctions: {
10
- use: (node: NodeValue, options?: UseSelectorOptions) => {
11
- if (process.env.NODE_ENV === 'development' && !didWarn) {
12
- didWarn = true;
13
- console.warn(
14
- '[legend-state] enableReactUse() is deprecated. Please switch to using get() with observer, which is safer and more efficient. See https://legendapp.com/open-source/state/v3/react/react-api/',
15
- );
16
- }
17
- return useSelector(internal.getProxy(node), options);
18
- },
19
- },
20
- });
21
- }
22
-
23
- // Types:
24
-
25
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
26
- import type { ImmutableObservableBase } from '@legendapp/state';
27
-
28
- declare module '@legendapp/state' {
29
- interface ImmutableObservableBase<T> {
30
- use(options?: UseSelectorOptions): T;
31
- }
32
- }
@@ -1,31 +0,0 @@
1
- import { configureLegendState, internal } from '@legendapp/state';
2
-
3
- export function enable_PeekAssign() {
4
- configureLegendState({
5
- observableProperties: {
6
- _: {
7
- get(node) {
8
- return internal.peek(node);
9
- },
10
- set(node, value) {
11
- internal.setNodeValue(node, value);
12
- },
13
- },
14
- },
15
- });
16
- }
17
-
18
- // TODOv4 deprecate
19
- export const enableDirectAccess = enable_PeekAssign;
20
-
21
- // Types:
22
-
23
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
24
- import type { ImmutableObservableBase } from '@legendapp/state';
25
-
26
- declare module '@legendapp/state' {
27
- interface ImmutableObservableBase<T> {
28
- get _(): T;
29
- set _(value: T | null | undefined);
30
- }
31
- }
package/src/config.ts DELETED
@@ -1,47 +0,0 @@
1
- import { globalState } from './globals';
2
- import { observableProperties as _observableProperties, observableFns } from './ObservableObject';
3
- import { ObservablePrimitiveClass } from './ObservablePrimitive';
4
- import type { NodeValue } from './observableInterfaces';
5
-
6
- export function configureLegendState({
7
- observableFunctions,
8
- observableProperties,
9
- jsonReplacer,
10
- jsonReviver,
11
- }: {
12
- observableFunctions?: Record<string, (node: NodeValue, ...args: any[]) => any>;
13
- observableProperties?: Record<string, { get: (node: NodeValue) => any; set: (node: NodeValue, value: any) => any }>;
14
- jsonReplacer?: (this: any, key: string, value: any) => any;
15
- jsonReviver?: (this: any, key: string, value: any) => any;
16
- }) {
17
- if (observableFunctions) {
18
- for (const key in observableFunctions) {
19
- const fn = observableFunctions[key];
20
- observableFns.set(key, fn);
21
- ObservablePrimitiveClass.prototype[key] = function (...args: any[]) {
22
- return fn.call(this, this._node, ...args);
23
- };
24
- }
25
- }
26
- if (observableProperties) {
27
- for (const key in observableProperties) {
28
- const fns = observableProperties[key];
29
- _observableProperties.set(key, fns);
30
- Object.defineProperty(ObservablePrimitiveClass.prototype, key, {
31
- configurable: true,
32
- get() {
33
- return fns.get.call(this, this._node);
34
- },
35
- set(value: any) {
36
- return fns.set.call(this, this._node, value);
37
- },
38
- });
39
- }
40
- }
41
- if (jsonReplacer) {
42
- globalState.replacer = jsonReplacer;
43
- }
44
- if (jsonReviver) {
45
- globalState.reviver = jsonReviver;
46
- }
47
- }
@@ -1,47 +0,0 @@
1
- import { isObservable, setNodeValue } from './globals';
2
- import { isActualPrimitive, isFunction, isPromise } from './is';
3
- import type { ClassConstructor, ObservableRoot } from './observableInterfaces';
4
- import { NodeValue } from './observableInterfaces';
5
- import { Observable, ObservablePrimitive } from './observableTypes';
6
-
7
- export function createObservable<T>(
8
- value: T | undefined,
9
- makePrimitive: boolean,
10
- extractPromise: Function,
11
- createObject: Function,
12
- createPrimitive?: Function,
13
- ): Observable<T> {
14
- if (isObservable(value)) {
15
- return value as Observable<T>;
16
- }
17
- const valueIsPromise = isPromise<T>(value);
18
- const valueIsFunction = isFunction(value);
19
-
20
- const root: ObservableRoot = {
21
- _: value,
22
- };
23
-
24
- let node: NodeValue = {
25
- root,
26
- lazy: true,
27
- numListenersRecursive: 0,
28
- };
29
-
30
- if (valueIsFunction) {
31
- node = Object.assign(() => {}, node);
32
- node.lazyFn = value;
33
- }
34
-
35
- const prim = makePrimitive || isActualPrimitive(value);
36
-
37
- const obs = prim
38
- ? (new (createPrimitive as ClassConstructor<T>)(node) as ObservablePrimitive<T>)
39
- : (createObject(node) as Observable<T>);
40
-
41
- if (valueIsPromise) {
42
- setNodeValue(node, undefined);
43
- extractPromise(node, value);
44
- }
45
-
46
- return obs as any;
47
- }
package/src/event.ts DELETED
@@ -1,26 +0,0 @@
1
- import { getNode, symbolGetNode } from './globals';
2
- import { observable } from './observable';
3
- import type { ObservableEvent } from './observableInterfaces';
4
-
5
- export function event(): ObservableEvent {
6
- // event simply wraps around a number observable
7
- // which increments its value to dispatch change events
8
- const obs = observable(0);
9
- const node = getNode(obs);
10
- node.isEvent = true;
11
- return {
12
- fire: function () {
13
- // Notify increments the value so that the observable changes
14
- obs.set((v) => v + 1);
15
- },
16
- on: function (cb: () => void) {
17
- return obs.onChange(cb);
18
- },
19
- get: function () {
20
- // Return the value so that when will be truthy
21
- return obs.get();
22
- },
23
- // @ts-expect-error eslint doesn't like adding symbols to the object but this does work
24
- [symbolGetNode]: node,
25
- };
26
- }
package/src/globals.ts DELETED
@@ -1,235 +0,0 @@
1
- import { isArray, isChildNodeValue, isDate, isFunction, isMap, isNullOrUndefined, isObject } from './is';
2
- import type { NodeValue, ObservableEvent, TypeAtPath, UpdateFn } from './observableInterfaces';
3
- import type { Observable, ObservableParam } from './observableTypes';
4
-
5
- export const symbolToPrimitive = Symbol.toPrimitive;
6
- export const symbolGetNode = Symbol('getNode');
7
- export const symbolDelete = /* @__PURE__ */ Symbol('delete');
8
- export const symbolOpaque = Symbol('opaque');
9
- export const optimized = Symbol('optimized');
10
- export const symbolLinked = Symbol('linked');
11
-
12
- export const globalState = {
13
- isLoadingLocal: false,
14
- isMerging: false,
15
- isLoadingRemote: false,
16
- activateSyncedNode: undefined as unknown as (node: NodeValue, newValue: any) => { update: UpdateFn; value: any },
17
- pendingNodes: new Map<NodeValue, () => void>(),
18
- dirtyNodes: new Set<NodeValue>(),
19
- replacer: undefined as undefined | ((this: any, key: string, value: any) => any),
20
- reviver: undefined as undefined | ((this: any, key: string, value: any) => any),
21
- };
22
-
23
- export function getPathType(value: any): TypeAtPath {
24
- return isArray(value) ? 'array' : isMap(value) ? 'map' : value instanceof Set ? 'set' : 'object';
25
- }
26
-
27
- function replacer(key: string, value: any) {
28
- if (isMap(value)) {
29
- return {
30
- __LSType: 'Map',
31
- value: Array.from(value.entries()), // or with spread: value: [...value]
32
- };
33
- } else if (value instanceof Set) {
34
- return {
35
- __LSType: 'Set',
36
- value: Array.from(value), // or with spread: value: [...value]
37
- };
38
- } else if (globalState.replacer) {
39
- value = globalState.replacer(key, value);
40
- }
41
- return value;
42
- }
43
-
44
- const ISO8601 = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/;
45
- function reviver(key: string, value: any) {
46
- if (value) {
47
- if (typeof value === 'string' && ISO8601.test(value)) {
48
- return new Date(value);
49
- }
50
- if (typeof value === 'object') {
51
- if (value.__LSType === 'Map') {
52
- return new Map(value.value);
53
- } else if (value.__LSType === 'Set') {
54
- return new Set(value.value);
55
- }
56
- }
57
- if (globalState.reviver) {
58
- value = globalState.reviver(key, value);
59
- }
60
- }
61
- return value;
62
- }
63
-
64
- export function safeStringify(value: any) {
65
- return JSON.stringify(value, replacer);
66
- }
67
- export function safeParse(value: any) {
68
- return JSON.parse(value, reviver);
69
- }
70
- export function clone<T>(value: T) {
71
- return safeParse(safeStringify(value));
72
- }
73
-
74
- export function isObservable(value$: any): value$ is Observable {
75
- return !!value$ && !!value$[symbolGetNode as any];
76
- }
77
-
78
- export function getNode(value$: ObservableParam): NodeValue {
79
- return value$ && (value$ as any)[symbolGetNode];
80
- }
81
-
82
- export function isEvent(value$: any): value$ is ObservableEvent {
83
- return value$ && (value$[symbolGetNode as any] as NodeValue)?.isEvent;
84
- }
85
-
86
- export function setNodeValue(node: NodeValue, newValue: any) {
87
- const parentNode = node.parent ?? node;
88
- const key = node.parent ? node.key : '_';
89
-
90
- const isDelete = newValue === symbolDelete;
91
- if (isDelete) newValue = undefined;
92
-
93
- // Get the value of the parent
94
- const parentValue = node.parent ? ensureNodeValue(parentNode) : parentNode.root;
95
-
96
- // Save the previous value first
97
- const prevValue = parentValue[key];
98
-
99
- const isFunc = isFunction(newValue);
100
-
101
- // Compute newValue if newValue is a function or an observable
102
- newValue = !parentNode.isAssigning && isFunc && !isFunction(prevValue) ? newValue(prevValue) : newValue;
103
-
104
- if (
105
- !globalState.isMerging ||
106
- isNullOrUndefined(prevValue) ||
107
- isFunction(prevValue) ||
108
- !node.parent?.functions?.get(key)
109
- ) {
110
- try {
111
- parentNode.isSetting = (parentNode.isSetting || 0) + 1;
112
-
113
- const useMapFn = isMap(parentValue);
114
- // Save the new value
115
- if (isDelete) {
116
- if (useMapFn) {
117
- parentValue.delete(key);
118
- } else {
119
- delete parentValue[key];
120
- }
121
- } else {
122
- const useMapFn = isMap(parentValue);
123
- if (useMapFn) {
124
- parentValue.set(key, newValue);
125
- } else {
126
- parentValue[key] = newValue;
127
- }
128
- }
129
- } finally {
130
- parentNode.isSetting!--;
131
- }
132
- }
133
-
134
- return { prevValue, newValue };
135
- }
136
-
137
- const arrNodeKeys: string[] = [];
138
- export function getNodeValue(node: NodeValue): any {
139
- let count = 0;
140
- let n: NodeValue = node;
141
- while (isChildNodeValue(n)) {
142
- arrNodeKeys[count++] = n.key;
143
- n = n.parent;
144
- }
145
- let child = node.root._;
146
- for (let i = count - 1; child && i >= 0; i--) {
147
- const key = arrNodeKeys[i] as any;
148
- child = key !== 'size' && (isMap(child) || child instanceof WeakMap) ? child.get(key) : child[key];
149
- }
150
- return child;
151
- }
152
-
153
- export function getChildNode(node: NodeValue, key: string, asFunction?: Function): NodeValue {
154
- // Get the child by key
155
- let child = node.children?.get(key);
156
-
157
- // Create the child node if it doesn't already exist
158
- if (!child) {
159
- child = {
160
- root: node.root,
161
- parent: node,
162
- key,
163
- lazy: true,
164
- numListenersRecursive: 0,
165
- };
166
- // Lookup functions are bound with the child key
167
- if (node.lazyFn?.length === 1) {
168
- asFunction = node.lazyFn.bind(node, key);
169
- }
170
- if (isFunction(asFunction)) {
171
- child = Object.assign(() => {}, child);
172
- child.lazyFn = asFunction;
173
- }
174
- if (!node.children) {
175
- node.children = new Map();
176
- }
177
- node.children.set(key, child);
178
- }
179
-
180
- return child;
181
- }
182
-
183
- export function ensureNodeValue(node: NodeValue) {
184
- let value = getNodeValue(node);
185
- if (!value || isFunction(value)) {
186
- if (isChildNodeValue(node)) {
187
- const parent = ensureNodeValue(node.parent);
188
- value = parent[node.key] = {};
189
- } else {
190
- value = node.root._ = {};
191
- }
192
- }
193
- return value;
194
- }
195
-
196
- export function findIDKey(obj: unknown | undefined, node: NodeValue): string | ((value: any) => string) | undefined {
197
- let idKey: string | ((value: any) => string) | undefined = isObservable(obj)
198
- ? undefined
199
- : isObject(obj)
200
- ? 'id' in obj
201
- ? 'id'
202
- : 'key' in obj
203
- ? 'key'
204
- : '_id' in obj
205
- ? '_id'
206
- : '__id' in obj
207
- ? '__id'
208
- : undefined
209
- : undefined;
210
-
211
- if (!idKey && node.parent) {
212
- const k = node.key + '_keyExtractor';
213
- const keyExtractor =
214
- (node.functions?.get(k) as (value: any) => string) ??
215
- (getNodeValue(node.parent)[node.key + '_keyExtractor'] as (value: any) => string);
216
- if (keyExtractor && isFunction(keyExtractor)) {
217
- idKey = keyExtractor;
218
- }
219
- }
220
-
221
- return idKey;
222
- }
223
-
224
- export function extractFunction(node: NodeValue, key: string, fnOrComputed: Function): void;
225
- export function extractFunction(node: NodeValue, key: string, fnOrComputed: Observable): void;
226
- export function extractFunction(node: NodeValue, key: string, fnOrComputed: Function | Observable): void {
227
- if (!node.functions) {
228
- node.functions = new Map();
229
- }
230
-
231
- node.functions.set(key, fnOrComputed);
232
- }
233
- export function equals(a: unknown, b: unknown) {
234
- return a === b || (isDate(a) && isDate(b) && +a === +b);
235
- }
@@ -1,41 +0,0 @@
1
- import { observable, Observable } from '@legendapp/state';
2
-
3
- interface Options {
4
- setter: 'pushState' | 'replaceState' | 'hash';
5
- }
6
- let _options: Options = { setter: 'hash' };
7
-
8
- function configurePageHash(options: Options) {
9
- _options = options;
10
- }
11
-
12
- const hasWindow = typeof window !== 'undefined';
13
- const pageHash: Observable<string> = observable(hasWindow ? window.location.hash.slice(1) : '');
14
-
15
- if (hasWindow) {
16
- let isSetting = false;
17
- // Set the page hash when the observable changes
18
- pageHash.onChange(({ value }) => {
19
- if (!isSetting) {
20
- const hash = '#' + value;
21
- const setter = _options?.setter || 'hash';
22
- if (setter === 'pushState') {
23
- history.pushState(null, null as any, hash);
24
- } else if (setter === 'replaceState') {
25
- history.replaceState(null, null as any, hash);
26
- } else {
27
- location.hash = hash;
28
- }
29
- }
30
- });
31
- // Update the observable whenever the hash changes
32
- const cb = () => {
33
- isSetting = true;
34
- pageHash.set(window.location.hash.slice(1));
35
- isSetting = false;
36
- };
37
- // Subscribe to window hashChange event
38
- window.addEventListener('hashchange', cb);
39
- }
40
-
41
- export { configurePageHash, pageHash };
@@ -1,55 +0,0 @@
1
- import { observable, Observable } from '@legendapp/state';
2
-
3
- interface Options {
4
- setter: 'pushState' | 'replaceState' | 'hash';
5
- }
6
- let _options: Options = { setter: 'hash' };
7
-
8
- function configurePageHashParams(options: Options) {
9
- _options = options;
10
- }
11
-
12
- function toParams(str: string) {
13
- const ret: Record<string, string> = {};
14
- const searchParams = new URLSearchParams(str);
15
- for (const [key, value] of searchParams) {
16
- ret[key] = value;
17
- }
18
- return ret;
19
- }
20
- function toString(params: Record<string, string>) {
21
- return new URLSearchParams(params).toString().replace(/=$/, '');
22
- }
23
-
24
- const hasWindow = typeof window !== 'undefined';
25
- const pageHashParams: Observable<Record<string, string>> = observable(
26
- hasWindow ? toParams(window.location.hash.slice(1)) : {},
27
- );
28
-
29
- if (hasWindow) {
30
- let isSetting = false;
31
- // Set the page hash when the observable changes
32
- pageHashParams.onChange(({ value }) => {
33
- if (!isSetting) {
34
- const hash = '#' + toString(value);
35
- const setter = _options?.setter || 'hash';
36
- if (setter === 'pushState') {
37
- history.pushState(null, null as any, hash);
38
- } else if (setter === 'replaceState') {
39
- history.replaceState(null, null as any, hash);
40
- } else {
41
- location.hash = hash;
42
- }
43
- }
44
- });
45
- // Update the observable whenever the hash changes
46
- const cb = () => {
47
- isSetting = true;
48
- pageHashParams.set(toParams(window.location.hash.slice(1)));
49
- isSetting = false;
50
- };
51
- // Subscribe to window hashChange event
52
- window.addEventListener('hashchange', cb);
53
- }
54
-
55
- export { configurePageHashParams, pageHashParams };
@@ -1,30 +0,0 @@
1
- import { observable } from '@legendapp/state';
2
-
3
- const MSPerMinute = 60000;
4
-
5
- function clearTime(date: Date | number) {
6
- date = new Date(date);
7
- date.setHours(0, 0, 0, 0);
8
- return date;
9
- }
10
-
11
- let time = new Date();
12
- const currentTime = observable(time);
13
- const currentDay = observable(clearTime(time));
14
- const timeToSecond = (60 - time.getSeconds() + 1) * 1000;
15
- function update() {
16
- const now = new Date();
17
- currentTime.set(now);
18
-
19
- if (now.getDate() !== time.getDate()) {
20
- currentDay.set(clearTime(now));
21
- }
22
-
23
- time = now;
24
- }
25
- setTimeout(() => {
26
- update();
27
- setInterval(update, MSPerMinute);
28
- }, timeToSecond);
29
-
30
- export { currentTime, currentDay };
@@ -1,29 +0,0 @@
1
- import { ObservableParam, constructObjectWithPath, mergeIntoObservable, observable } from '@legendapp/state';
2
-
3
- // This type is purely for documentation.
4
- type TimestampAsString = string;
5
-
6
- export function trackHistory<T>(
7
- value$: ObservableParam<T>,
8
- targetObservable?: ObservableParam<Record<TimestampAsString, Partial<T>>>,
9
- ): ObservableParam<Record<TimestampAsString, any>> {
10
- const history = targetObservable ?? observable<Record<TimestampAsString, Partial<T>>>();
11
-
12
- value$.onChange(({ loading, remote, changes }) => {
13
- // Don't save history if this is a remote change.
14
- // History will be saved remotely by the client making the local change.
15
- if (!loading && !remote) {
16
- const time: TimestampAsString = Date.now().toString();
17
-
18
- // Save to history observable by date, with the previous value
19
- for (let i = 0; i < changes.length; i++) {
20
- const { path, prevAtPath, pathTypes } = changes[i];
21
-
22
- const obj = constructObjectWithPath(path, pathTypes, prevAtPath);
23
- mergeIntoObservable((history as any)[time], obj);
24
- }
25
- }
26
- });
27
-
28
- return history as any;
29
- }