@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,91 +0,0 @@
1
- import type { Change } from '@legendapp/state';
2
- import { internal, setAtPath } from '@legendapp/state';
3
- import type { ObservablePersistPlugin, PersistMetadata, PersistOptions } from '@legendapp/state/sync';
4
- import { MMKV } from 'react-native-mmkv';
5
-
6
- const symbolDefault = Symbol();
7
- const MetadataSuffix = '__m';
8
-
9
- const { safeParse, safeStringify } = internal;
10
-
11
- export class ObservablePersistMMKV implements ObservablePersistPlugin {
12
- private data: Record<string, any> = {};
13
- private storages = new Map<symbol | string, MMKV>([
14
- [
15
- symbolDefault,
16
- new MMKV({
17
- id: `obsPersist`,
18
- }),
19
- ],
20
- ]);
21
- // Gets
22
- public getTable<T = any>(table: string, init: object, config: PersistOptions): T {
23
- const storage = this.getStorage(config);
24
- if (this.data[table] === undefined) {
25
- try {
26
- const value = storage.getString(table);
27
- this.data[table] = value ? safeParse(value) : init;
28
- } catch {
29
- console.error('[legend-state] MMKV failed to parse', table);
30
- }
31
- }
32
- return this.data[table];
33
- }
34
- public getMetadata(table: string, config: PersistOptions): PersistMetadata {
35
- return this.getTable(table + MetadataSuffix, {}, config);
36
- }
37
- // Sets
38
- public set(table: string, changes: Change[], config: PersistOptions) {
39
- if (!this.data[table]) {
40
- this.data[table] = {};
41
- }
42
- for (let i = 0; i < changes.length; i++) {
43
- const { path, valueAtPath, pathTypes } = changes[i];
44
- this.data[table] = setAtPath(this.data[table], path as string[], pathTypes, valueAtPath);
45
- }
46
- this.save(table, config);
47
- }
48
- public setMetadata(table: string, metadata: PersistMetadata, config: PersistOptions) {
49
- return this.setValue(table + MetadataSuffix, metadata, config);
50
- }
51
- public deleteTable(table: string, config: PersistOptions): void {
52
- const storage = this.getStorage(config);
53
- delete this.data[table];
54
- storage.delete(table);
55
- }
56
- public deleteMetadata(table: string, config: PersistOptions) {
57
- this.deleteTable(table + MetadataSuffix, config);
58
- }
59
- // Private
60
- private getStorage(config: PersistOptions): MMKV {
61
- const { mmkv } = config;
62
- if (mmkv) {
63
- const key = JSON.stringify(mmkv);
64
- let storage = this.storages.get(key);
65
- if (!storage) {
66
- storage = new MMKV(mmkv);
67
- this.storages.set(key, storage);
68
- }
69
- return storage;
70
- } else {
71
- return this.storages.get(symbolDefault)!;
72
- }
73
- }
74
- private async setValue(table: string, value: any, config: PersistOptions) {
75
- this.data[table] = value;
76
- this.save(table, config);
77
- }
78
- private save(table: string, config: PersistOptions) {
79
- const storage = this.getStorage(config);
80
- const v = this.data[table];
81
- if (v !== undefined) {
82
- try {
83
- storage.set(table, safeStringify(v));
84
- } catch (err) {
85
- console.error(err);
86
- }
87
- } else {
88
- storage.delete(table);
89
- }
90
- }
91
- }
package/src/proxy.ts DELETED
@@ -1,28 +0,0 @@
1
- import { linked } from './linked';
2
- import { observable } from './observable';
3
- import { Observable, ObservableParam } from './observableTypes';
4
-
5
- // Deprecated. Remove in v4
6
-
7
- export function proxy<T, T2 = T>(
8
- get: (key: string) => T,
9
- set: (key: string, value: T2) => void,
10
- ): Observable<Record<string, T>>;
11
- export function proxy<T extends Record<string, any>>(
12
- get: <K extends keyof T>(key: K) => ObservableParam<T[K]>,
13
- ): Observable<T>;
14
- export function proxy<T>(get: (key: string) => ObservableParam<T>): Observable<Record<string, T>>;
15
- export function proxy<T>(get: (key: string) => T): Observable<Record<string, T>>;
16
- export function proxy<T extends Record<string, any>, T2 = T>(
17
- get: (key: any) => ObservableParam<any>,
18
- set?: (key: any, value: T2) => void,
19
- ): any {
20
- return observable((key: string) =>
21
- set
22
- ? linked({
23
- get: () => get(key),
24
- set: ({ value }) => set(key, value as any),
25
- })
26
- : get(key),
27
- );
28
- }
@@ -1,8 +0,0 @@
1
- import { computeSelector } from '@legendapp/state';
2
- import { ReactElement, ReactNode } from 'react';
3
- import type { ObservableParam } from '../observableTypes';
4
- import { useSelector } from './useSelector';
5
-
6
- export function Computed({ children }: { children: ObservableParam | (() => ReactNode) }): ReactElement {
7
- return useSelector(() => computeSelector(computeSelector(children)), { skipCheck: true }) as ReactElement;
8
- }
package/src/react/For.tsx DELETED
@@ -1,116 +0,0 @@
1
- import type { Observable, ObservableObject, ObservableParam } from '@legendapp/state';
2
- import { internal, isArray, isFunction, isMap } from '@legendapp/state';
3
- import { FC, ReactElement, createElement, memo, useMemo, useRef } from 'react';
4
- import { observer } from './reactive-observer';
5
- import { useSelector } from './useSelector';
6
- const { findIDKey, getNode, optimized } = internal;
7
-
8
- const autoMemoCache = new Map<FC<any>, FC<any>>();
9
-
10
- type ForItemProps<T, TProps = {}> = {
11
- item$: Observable<T>;
12
- id?: string;
13
- } & TProps;
14
-
15
- export function For<T, TProps>({
16
- each,
17
- optimized: isOptimized,
18
- item,
19
- itemProps,
20
- sortValues,
21
- children,
22
- }: {
23
- each?: ObservableParam<T[] | Record<any, T> | Map<any, T>>;
24
- optimized?: boolean;
25
- item?: FC<ForItemProps<T, TProps>>;
26
- itemProps?: TProps;
27
- sortValues?: (A: T, B: T, AKey: string, BKey: string) => number;
28
- children?: (value: Observable<T>, id: string | undefined) => ReactElement;
29
- }): ReactElement | null {
30
- if (!each) return null;
31
-
32
- // Get the raw value with a shallow listener so this list only re-renders
33
- // when the array length changes
34
- const value = useSelector(() => each!.get(isOptimized ? optimized : true));
35
-
36
- // The child function gets wrapped in a memoized observer component
37
- if (!item && children) {
38
- // Update the ref so the generated component uses the latest function
39
- const refChildren = useRef<(value: Observable<T>, id: string | undefined) => ReactElement>();
40
- refChildren.current = children;
41
-
42
- item = useMemo(() => observer(({ item$, id }) => refChildren.current!(item$, id)), []);
43
- } else {
44
- // @ts-expect-error $$typeof is private
45
- if (item.$$typeof !== Symbol.for('react.memo')) {
46
- let memod = autoMemoCache.get(item!);
47
- if (!memod) {
48
- memod = memo(item!);
49
- autoMemoCache.set(item!, memod);
50
- }
51
- item = memod;
52
- }
53
- }
54
-
55
- // This early out needs to be after any hooks
56
- if (!value) return null;
57
-
58
- // Create the child elements
59
- const out: ReactElement[] = [];
60
-
61
- const isArr = isArray(value);
62
-
63
- if (isArr) {
64
- // Get the appropriate id field
65
- const v0 = value[0] as any;
66
- const node = getNode(each!);
67
- const length = (value as any[]).length;
68
-
69
- const idField =
70
- length > 0
71
- ? (node && findIDKey(v0, node)) ||
72
- (v0.id !== undefined ? 'id' : v0.key !== undefined ? 'key' : undefined)
73
- : undefined;
74
-
75
- const isIdFieldFunction = isFunction(idField);
76
-
77
- for (let i = 0; i < length; i++) {
78
- if (value[i]) {
79
- const val = value[i];
80
- const key = (isIdFieldFunction ? idField(val) : (val as Record<string, any>)[idField as string]) ?? i;
81
- const item$ = (each as Observable<any[]>)[i];
82
- // TODOV3 Remove item
83
- const props: ForItemProps<any> & { key: string; item: Observable<any> } = {
84
- key,
85
- id: key,
86
- item$,
87
- item: item$,
88
- };
89
-
90
- out.push(createElement(item as FC, itemProps ? Object.assign(props, itemProps) : props));
91
- }
92
- }
93
- } else {
94
- // Render the values of the object / Map
95
- const asMap = isMap(value);
96
- const keys = asMap ? Array.from(value.keys()) : Object.keys(value);
97
- if (sortValues) {
98
- keys.sort((A, B) => sortValues(asMap ? value.get(A)! : value[A], asMap ? value.get(B)! : value[B], A, B));
99
- }
100
- for (let i = 0; i < keys.length; i++) {
101
- const key = keys[i];
102
- if (asMap ? value.get(key) : value[key]) {
103
- const item$ = asMap ? each!.get(key) : (each as ObservableObject<Record<string, any>>)[key];
104
- const props: ForItemProps<any> & { key: string; item: Observable<any> } = {
105
- key,
106
- id: key,
107
- item$,
108
- item: item$,
109
- };
110
- out.push(createElement(item as FC, itemProps ? Object.assign(props, itemProps) : props));
111
- }
112
- }
113
- }
114
-
115
- return out as unknown as ReactElement;
116
- }
@@ -1,4 +0,0 @@
1
- import { memo } from 'react';
2
- import { Computed } from './Computed';
3
-
4
- export const Memo = memo(Computed, () => true);
@@ -1,53 +0,0 @@
1
- import { isEmpty, isFunction } from '@legendapp/state';
2
- import { ComponentClass, FC, createElement, forwardRef } from 'react';
3
- import { BindKeys } from './reactInterfaces';
4
- import { reactive } from './reactive-observer';
5
-
6
- const ReactiveFns = new Map<string, FC | ComponentClass>();
7
- const ReactiveFnBinders = new Map<string, BindKeys>();
8
-
9
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
10
- export interface IReactive {}
11
-
12
- export const Reactive: IReactive = new Proxy(
13
- {},
14
- {
15
- get(target: Record<string, FC>, p: string) {
16
- if (!target[p]) {
17
- const Component = ReactiveFns.get(p) || p;
18
-
19
- // Create a wrapper around createElement with the string so we can proxy it
20
- // eslint-disable-next-line react/display-name
21
- const render = forwardRef((props, ref) => {
22
- const propsOut = { ...props } as any;
23
- if (ref && (isFunction(ref) || !isEmpty(ref))) {
24
- propsOut.ref = ref;
25
- }
26
- return createElement(Component, propsOut);
27
- });
28
-
29
- target[p] = reactive(render, ReactiveFnBinders.get(p));
30
- }
31
- return target[p];
32
- },
33
- },
34
- ) as unknown as IReactive;
35
-
36
- export function configureReactive({
37
- components,
38
- binders,
39
- }: {
40
- components?: Record<string, FC | ComponentClass<any>>;
41
- binders?: Record<string, BindKeys>;
42
- }) {
43
- if (components) {
44
- for (const key in components) {
45
- ReactiveFns.set(key, components[key]);
46
- }
47
- }
48
- if (binders) {
49
- for (const key in binders) {
50
- ReactiveFnBinders.set(key, binders[key]);
51
- }
52
- }
53
- }
@@ -1,33 +0,0 @@
1
- import type { Selector } from '@legendapp/state';
2
- import { isFunction, isObservableValueReady } from '@legendapp/state';
3
- import { FC, ReactElement, ReactNode, createElement } from 'react';
4
- import { useSelector } from './useSelector';
5
-
6
- interface PropsIf<T> {
7
- if: Selector<T>;
8
- ifReady?: never;
9
- }
10
- interface PropsIfReady<T> {
11
- if?: never;
12
- ifReady: Selector<T>;
13
- }
14
-
15
- interface PropsBase<T> {
16
- else?: ReactNode | (() => ReactNode);
17
- wrap?: FC;
18
- children: ReactNode | ((value?: T) => ReactNode);
19
- }
20
-
21
- type Props<T> = PropsBase<T> & (PropsIf<T> | PropsIfReady<T>);
22
-
23
- export function Show<T>(props: Props<T>): ReactElement;
24
- export function Show<T>({ if: if_, ifReady, else: else_, wrap, children }: Props<T>): ReactElement {
25
- const value = useSelector(if_ ?? ifReady);
26
- const show = ifReady !== undefined ? isObservableValueReady(value) : value;
27
- const child = useSelector(
28
- show ? (isFunction(children) ? () => children(value) : (children as any)) : else_ ?? null,
29
- { skipCheck: true },
30
- );
31
-
32
- return wrap ? createElement(wrap, undefined, child) : child;
33
- }
@@ -1,43 +0,0 @@
1
- import type { Selector } from '@legendapp/state';
2
- import { ReactElement, ReactNode } from 'react';
3
- import { useSelector } from './useSelector';
4
-
5
- export function Switch<T extends object>({
6
- value,
7
- children,
8
- }: {
9
- value?: Selector<T>;
10
- children: Partial<Record<keyof T | 'null' | 'undefined' | 'default', () => ReactNode>>;
11
- }): ReactElement | null;
12
- export function Switch<T extends string | number | symbol>({
13
- value,
14
- children,
15
- }: {
16
- value?: Selector<T>;
17
- children: Partial<Record<T | 'null' | 'undefined' | 'default', () => ReactNode>>;
18
- }): ReactElement | null;
19
- export function Switch<T extends boolean>({
20
- value,
21
- children,
22
- }: {
23
- value?: Selector<T>;
24
- children: Partial<Record<'false' | 'true' | 'null' | 'undefined' | 'default', () => ReactNode>>;
25
- }): ReactElement | null;
26
- export function Switch<T>({
27
- value,
28
- children,
29
- }: {
30
- value?: Selector<T>;
31
- children: Partial<Record<'undefined' | 'default', () => ReactNode>>;
32
- }): ReactElement | null;
33
- export function Switch<T>({
34
- value,
35
- children,
36
- }: {
37
- value?: Selector<T>;
38
- children: Partial<Record<any, () => ReactNode>>;
39
- }): ReactNode {
40
- // Select from an object of cases
41
- const child = children[useSelector(value)!];
42
- return (child ? child() : children['default']?.()) ?? null;
43
- }
@@ -1,3 +0,0 @@
1
- export const reactGlobals = {
2
- inObserver: false,
3
- };
@@ -1,32 +0,0 @@
1
- import type { FC, LegacyRef, ReactNode } from 'react';
2
- import type { Observable } from '../observableTypes';
3
- import type { Selector } from '../observableInterfaces';
4
-
5
- export type ShapeWithNew$<T> = Partial<Omit<T, 'children'>> & {
6
- [K in keyof T as K extends `$${string & K}` ? K : `$${string & K}`]?: Selector<T[K]>;
7
- } & { children?: Selector<ReactNode> };
8
-
9
- export interface BindKey<P> {
10
- handler?: keyof P;
11
- getValue?: (e: any) => any;
12
- defaultValue?: any;
13
- selector?: (propsOut: Record<string, any>, p: Observable<any>) => any;
14
- }
15
-
16
- export type BindKeys<P = any> = Record<keyof P, BindKey<P>>;
17
-
18
- export type FCReactiveObject<T> = {
19
- [K in keyof T]: FC<ShapeWithNew$<T[K]>>;
20
- };
21
-
22
- export type FCReactive<P, P2> = P &
23
- FC<
24
- ShapeWithNew$<P2> & {
25
- ref?: LegacyRef<P> | undefined;
26
- }
27
- >;
28
-
29
- export interface UseSelectorOptions {
30
- suspense?: boolean;
31
- skipCheck?: boolean;
32
- }
@@ -1,210 +0,0 @@
1
- import { isFunction, isObservable, Selector } from '@legendapp/state';
2
- import { ChangeEvent, FC, forwardRef, memo, useCallback } from 'react';
3
- import { reactGlobals } from './react-globals';
4
- import type { BindKeys } from './reactInterfaces';
5
- import { useSelector } from './useSelector';
6
-
7
- export type ShapeWithPick$<T, T2 extends keyof T = keyof T> = Partial<T> & {
8
- [K in T2 as K extends `$${string & K}` ? K : `$${string & K}`]?: Selector<T[K]>;
9
- };
10
- export type ShapeWith$<T> = Partial<T> & {
11
- [K in keyof T as K extends `$${string & K}` ? K : `$${string & K}`]?: Selector<T[K]>;
12
- };
13
- export type ObjectShapeWith$<T> = {
14
- [K in keyof T]: T[K] extends FC<infer P> ? FC<ShapeWith$<P>> : T[K];
15
- };
16
- export type ExtractFCPropsType<T> = T extends FC<infer P> ? P : never;
17
-
18
- // Extracting the forwardRef inspired by https://github.com/mobxjs/mobx/blob/main/packages/mobx-react-lite/src/observer.ts
19
- export const hasSymbol = /* @__PURE__ */ typeof Symbol === 'function' && Symbol.for;
20
-
21
- let didWarnProps = false;
22
-
23
- // TODOV2: Change bindKeys to an options object, where one of the options is "convertChildren" so that behavior can be optional
24
- function createReactiveComponent<P = object>(
25
- component: FC<P>,
26
- observe: boolean,
27
- reactive?: boolean,
28
- bindKeys?: BindKeys<P>,
29
- ) {
30
- const ReactForwardRefSymbol = hasSymbol
31
- ? Symbol.for('react.forward_ref')
32
- : // eslint-disable-next-line react/display-name, @typescript-eslint/no-unused-vars
33
- typeof forwardRef === 'function' && forwardRef((props: any) => null)['$$typeof'];
34
-
35
- const ReactMemoSymbol = hasSymbol
36
- ? Symbol.for('react.memo')
37
- : // eslint-disable-next-line react/display-name, @typescript-eslint/no-unused-vars
38
- typeof forwardRef === 'function' && memo((props) => null)['$$typeof'];
39
-
40
- // If this component is already reactive bail out early
41
- // This can happen with Fast Refresh.
42
- if ((component as any)['__legend_proxied']) return component;
43
-
44
- let useForwardRef = false;
45
- let useMemo = false;
46
- let render = component;
47
-
48
- // Unwrap memo on the component
49
- if (ReactMemoSymbol && (render as any)['$$typeof'] === ReactMemoSymbol && (render as any)['type']) {
50
- useMemo = true;
51
- render = (render as any)['type'];
52
- }
53
- // Unwrap forwardRef on the component
54
- if (ReactForwardRefSymbol && (render as any)['$$typeof'] === ReactForwardRefSymbol) {
55
- useForwardRef = true;
56
- render = (render as any)['render'];
57
- if (process.env.NODE_ENV === 'development' && typeof render !== 'function') {
58
- throw new Error(`[legend-state] \`render\` property of ForwardRef was not a function`);
59
- }
60
- }
61
-
62
- const proxyHandler: ProxyHandler<any> = {
63
- apply(target, thisArg, argArray) {
64
- // If this is a reactive component, convert all props ending in $
65
- // to regular props and set up a useSelector listener
66
- if (reactive) {
67
- const props = argArray[0];
68
- const propsOut = {} as Record<string, any>;
69
- const keys = Object.keys(props);
70
- for (let i = 0; i < keys.length; i++) {
71
- const key = keys[i];
72
- const p = props[key];
73
-
74
- // Convert children if it's a function
75
- if (key === 'children' && (isFunction(p) || isObservable(p))) {
76
- props[key] = useSelector(p, { skipCheck: true });
77
- }
78
- // Convert reactive props
79
- else if (key.startsWith('$') || key.endsWith('$')) {
80
- // TODOV3 Add this warning
81
- // TODOV4 Remove the deprecated endsWith option
82
- if (process.env.NODE_ENV === 'development' && !didWarnProps && key.endsWith('$')) {
83
- didWarnProps = true;
84
- console.warn(
85
- `[legend-state] Reactive props were changed to start with $ instead of end with $ in version 2.0. So please change ${key} to $${key.replace(
86
- '$',
87
- '',
88
- )}. See https://legendapp.com/open-source/state/migrating for more details.`,
89
- );
90
- }
91
- const k = key.endsWith('$') ? key.slice(0, -1) : key.slice(1);
92
- // Return raw value and listen to the selector for changes
93
-
94
- const bind = bindKeys?.[k as keyof P];
95
- const shouldBind = bind && isObservable(p);
96
-
97
- propsOut[k] = shouldBind && bind?.selector ? bind.selector(propsOut, p) : useSelector(p);
98
-
99
- // If this key is one of the bind keys set up a two-way binding
100
- if (shouldBind) {
101
- // Use the bind's defaultValue if value is undefined
102
- if (bind.defaultValue !== undefined && propsOut[k] === undefined) {
103
- propsOut[k] = bind.defaultValue;
104
- }
105
-
106
- if (bind.handler && bind.getValue) {
107
- // Hook up the change lander
108
- const handlerFn = (e: ChangeEvent) => {
109
- p.set(bind.getValue!(e));
110
- props[bind.handler!]?.(e);
111
- };
112
-
113
- (propsOut[bind.handler as string] as any) =
114
- // If in development mode, don't memoize the handler. fix fast refresh bug
115
- process.env.NODE_ENV === 'development'
116
- ? handlerFn
117
- : useCallback(handlerFn, [props[bind.handler], bindKeys]);
118
- }
119
- }
120
-
121
- // Delete the reactive key
122
- delete propsOut[key];
123
- } else if (propsOut[key] === undefined) {
124
- propsOut[key] = p;
125
- }
126
- }
127
- argArray[0] = propsOut;
128
- }
129
-
130
- // If observing wrap the whole render in a useSelector to listen to it
131
- if (observe) {
132
- return useSelector(
133
- () => {
134
- reactGlobals.inObserver = true;
135
- try {
136
- return Reflect.apply(target, thisArg, argArray);
137
- } finally {
138
- reactGlobals.inObserver = false;
139
- }
140
- },
141
- { skipCheck: true },
142
- );
143
- } else {
144
- return Reflect.apply(target, thisArg, argArray);
145
- }
146
- },
147
- };
148
-
149
- const proxy = new Proxy(render, proxyHandler);
150
-
151
- let ret;
152
-
153
- if (useForwardRef) {
154
- ret = forwardRef(proxy);
155
- (ret as any)['__legend_proxied'] = true;
156
- } else {
157
- ret = proxy;
158
- }
159
-
160
- return observe || useMemo ? memo(ret) : ret;
161
- }
162
-
163
- export function observer<P extends FC<any>>(component: P): P {
164
- return createReactiveComponent(component, true);
165
- }
166
-
167
- export function reactive<T extends FC<any>>(
168
- component: T,
169
- bindKeys?: BindKeys<ExtractFCPropsType<T>>,
170
- ): T | FC<ShapeWith$<ExtractFCPropsType<T>>>;
171
- export function reactive<T extends FC<any>, T2 extends keyof ExtractFCPropsType<T>>(
172
- component: T,
173
- bindKeys?: BindKeys<ExtractFCPropsType<T>>,
174
- ): T | FC<ShapeWithPick$<ExtractFCPropsType<T>, T2>>;
175
- export function reactive<T extends FC<any>>(
176
- component: T,
177
- bindKeys?: BindKeys<ExtractFCPropsType<T>>,
178
- ): T | FC<ShapeWith$<ExtractFCPropsType<T>>> {
179
- return createReactiveComponent(component, false, true, bindKeys);
180
- }
181
-
182
- export function reactiveObserver<T extends FC<any>>(
183
- component: T,
184
- bindKeys?: BindKeys<ExtractFCPropsType<T>>,
185
- ): T | FC<ShapeWith$<ExtractFCPropsType<T>>>;
186
- export function reactiveObserver<T extends FC<any>, T2 extends keyof ExtractFCPropsType<T>>(
187
- component: T,
188
- bindKeys?: BindKeys<ExtractFCPropsType<T>>,
189
- ): T | FC<ShapeWithPick$<ExtractFCPropsType<T>, T2>>;
190
- export function reactiveObserver<T extends FC<any>>(
191
- component: T,
192
- bindKeys?: BindKeys<ExtractFCPropsType<T>>,
193
- ): T | FC<ShapeWith$<ExtractFCPropsType<T>>> {
194
- return createReactiveComponent(component, true, true, bindKeys);
195
- }
196
-
197
- export function reactiveComponents<P extends Record<string, FC>>(components: P): ObjectShapeWith$<P> {
198
- return new Proxy(
199
- {},
200
- {
201
- get(target: Record<string, any>, p: string) {
202
- if (!target[p] && components[p]) {
203
- target[p] = createReactiveComponent(components[p], false, true) as FC<ShapeWith$<P>>;
204
- }
205
-
206
- return target[p];
207
- },
208
- },
209
- ) as ObjectShapeWith$<P>;
210
- }
@@ -1,36 +0,0 @@
1
- import { computed, isArray, isFunction, Observable, ObservableParam } from '@legendapp/state';
2
- import { useMemo, useRef } from 'react';
3
-
4
- export function useComputed<T>(compute: () => T | Promise<T>): Observable<T>;
5
- export function useComputed<T>(compute: () => T | Promise<T>, deps: any[]): Observable<T>;
6
- export function useComputed<T, T2 = T>(
7
- compute: (() => T | Promise<T>) | ObservableParam<T>,
8
- set: (value: T2) => void,
9
- ): Observable<T>;
10
- export function useComputed<T, T2 = T>(
11
- compute: (() => T | Promise<T>) | ObservableParam<T>,
12
- set: (value: T2) => void,
13
- deps: any[],
14
- ): Observable<T>;
15
- export function useComputed<T, T2 = T>(
16
- compute: (() => T | Promise<T>) | ObservableParam<T>,
17
- set?: ((value: T2) => void) | any[],
18
- deps?: any[],
19
- ): Observable<T> {
20
- if (!deps && isArray(set)) {
21
- deps = set;
22
- set = undefined;
23
- }
24
- const ref = useRef<{ compute?: (() => T | Promise<T>) | ObservableParam<T>; set?: (value: T2) => void }>({});
25
- ref.current.compute = compute;
26
- ref.current.set = set as (value: T2) => void;
27
-
28
- return useMemo(
29
- () =>
30
- computed<T, T2>(
31
- () => (isFunction(ref.current.compute) ? ref.current.compute() : ref.current.compute) as any,
32
- (set ? (value) => ref.current.set!(value) : undefined) as (value: T2) => void,
33
- ),
34
- deps || [],
35
- );
36
- }