@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,249 +0,0 @@
1
- import { Observable, computeSelector, isObject, observable, symbolDelete } from '@legendapp/state';
2
- import {
3
- SyncTransform,
4
- SyncedOptions,
5
- SyncedOptionsGlobal,
6
- combineTransforms,
7
- removeNullUndefined,
8
- transformStringifyDates,
9
- type SyncedGetParams,
10
- type SyncedSubscribeParams,
11
- } from '@legendapp/state/sync';
12
- import {
13
- CrudAsOption,
14
- SyncedCrudPropsBase,
15
- SyncedCrudPropsMany,
16
- SyncedCrudReturnType,
17
- syncedCrud,
18
- } from '@legendapp/state/sync-plugins/crud';
19
- import type { PostgrestFilterBuilder, PostgrestQueryBuilder } from '@supabase/postgrest-js';
20
- import type { SupabaseClient } from '@supabase/supabase-js';
21
- // Unused types but maybe useful in the future so keeping them for now
22
- // type DatabaseOf<Client extends SupabaseClient> = Client extends SupabaseClient<infer TDB> ? TDB : never;
23
- // type SchemaNameOf<Client extends SupabaseClient> = Client extends SupabaseClient<infer _, infer SchemaName>
24
- // ? SchemaName
25
- // : never;
26
-
27
- export type SupabaseSchemaOf<Client extends SupabaseClient> = Client extends SupabaseClient<
28
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
29
- infer _,
30
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
31
- infer __,
32
- infer Schema
33
- >
34
- ? Schema
35
- : never;
36
- export type SupabaseTableOf<Client extends SupabaseClient> = SupabaseSchemaOf<Client>['Tables'];
37
- export type SupabaseCollectionOf<Client extends SupabaseClient> = keyof SupabaseTableOf<Client>;
38
- export type SupabaseRowOf<
39
- Client extends SupabaseClient,
40
- Collection extends SupabaseCollectionOf<Client>,
41
- > = SupabaseTableOf<Client>[Collection]['Row'];
42
-
43
- export type SyncedSupabaseConfig<TRemote extends { id: string | number }, TLocal> = Omit<
44
- SyncedCrudPropsBase<TRemote, TLocal>,
45
- 'create' | 'update' | 'delete'
46
- >;
47
-
48
- export interface SyncedSupabaseConfiguration
49
- extends Omit<
50
- SyncedSupabaseConfig<{ id: string | number }, { id: string | number }>,
51
- 'persist' | keyof SyncedOptions
52
- > {
53
- persist?: SyncedOptionsGlobal;
54
- enabled?: Observable<boolean>;
55
- as?: Exclude<CrudAsOption, 'value'>;
56
- }
57
-
58
- interface SyncedSupabaseProps<
59
- Client extends SupabaseClient,
60
- Collection extends SupabaseCollectionOf<Client>,
61
- TOption extends CrudAsOption = 'object',
62
- TRemote extends SupabaseRowOf<Client, Collection> = SupabaseRowOf<Client, Collection>,
63
- TLocal = TRemote,
64
- > extends SyncedSupabaseConfig<TRemote, TLocal>,
65
- SyncedCrudPropsMany<TRemote, TRemote, TOption> {
66
- supabase: Client;
67
- collection: Collection;
68
- select?: (
69
- query: PostgrestQueryBuilder<SupabaseSchemaOf<Client>, SupabaseTableOf<Client>[Collection], Collection>,
70
- ) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
71
- filter?: (
72
- select: PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>,
73
- params: SyncedGetParams,
74
- ) => PostgrestFilterBuilder<SupabaseSchemaOf<Client>, TRemote, TRemote[], Collection, []>;
75
- actions?: ('create' | 'read' | 'update' | 'delete')[];
76
- realtime?: boolean | { schema?: string; filter?: string };
77
- stringifyDates?: boolean;
78
- }
79
-
80
- let channelNum = 1;
81
- const supabaseConfig: SyncedSupabaseConfiguration = {};
82
- const isEnabled$ = observable(true);
83
-
84
- export function getSyncedSupabaseConfiguration() {
85
- return supabaseConfig;
86
- }
87
- export function configureSyncedSupabase(config: SyncedSupabaseConfiguration) {
88
- const { enabled, ...rest } = config;
89
- if (enabled !== undefined) {
90
- isEnabled$.set(enabled);
91
- }
92
- Object.assign(supabaseConfig, removeNullUndefined(rest));
93
- }
94
-
95
- export function syncedSupabase<
96
- Client extends SupabaseClient,
97
- Collection extends SupabaseCollectionOf<Client> & string,
98
- AsOption extends CrudAsOption = 'object',
99
- TRemote extends SupabaseRowOf<Client, Collection> = SupabaseRowOf<Client, Collection>,
100
- TLocal = TRemote,
101
- >(props: SyncedSupabaseProps<Client, Collection, AsOption, TRemote, TLocal>): SyncedCrudReturnType<TLocal, AsOption> {
102
- props = { ...supabaseConfig, ...props } as any;
103
- const {
104
- supabase: client,
105
- collection,
106
- select: selectFn,
107
- filter,
108
- actions,
109
- fieldCreatedAt: fieldCreatedAtParam,
110
- fieldUpdatedAt: fieldUpdatedAtParam,
111
- fieldDeleted: fieldDeletedParam,
112
- realtime,
113
- changesSince,
114
- transform: transformParam,
115
- stringifyDates,
116
- waitFor,
117
- waitForSet,
118
- generateId,
119
- ...rest
120
- } = props;
121
-
122
- // If using last-sync mode then put it into soft delete mode
123
- const fieldCreatedAt = fieldCreatedAtParam || (changesSince === 'last-sync' ? 'created_at' : undefined);
124
- const fieldUpdatedAt = fieldUpdatedAtParam || (changesSince === 'last-sync' ? 'updated_at' : undefined);
125
- const fieldDeleted = fieldDeletedParam || (changesSince === 'last-sync' ? 'deleted' : undefined);
126
-
127
- const list =
128
- !actions || actions.includes('read')
129
- ? async (params: SyncedGetParams) => {
130
- const { lastSync } = params;
131
- const from = client.from(collection);
132
- let select = selectFn ? selectFn(from) : from.select();
133
-
134
- // in last-sync mode, filter for rows updated more recently than the last sync
135
- if (changesSince === 'last-sync' && lastSync) {
136
- const date = new Date(lastSync).toISOString();
137
- select = select.gt(fieldUpdatedAt!, date);
138
- }
139
- // filter with filter parameter
140
- if (filter) {
141
- select = filter(select, params);
142
- }
143
- const { data, error } = await select;
144
- if (error) {
145
- throw new Error(error?.message);
146
- }
147
- return (data! || []) as SupabaseRowOf<Client, Collection>[];
148
- }
149
- : undefined;
150
-
151
- const upsert = async (input: SupabaseRowOf<Client, Collection>) => {
152
- const res = await client.from(collection).upsert(input).select();
153
- const { data, error } = res;
154
- if (data) {
155
- const created = data[0];
156
- return created;
157
- } else {
158
- throw new Error(error?.message);
159
- }
160
- };
161
- const create = !actions || actions.includes('create') ? upsert : undefined;
162
- const update = !actions || actions.includes('update') ? upsert : undefined;
163
- const deleteFn =
164
- !fieldDeleted && (!actions || actions.includes('delete'))
165
- ? async (input: { id: SupabaseRowOf<Client, Collection>['id'] }) => {
166
- const id = input.id;
167
- const res = await client.from(collection).delete().eq('id', id).select();
168
- const { data, error } = res;
169
- if (data) {
170
- const created = data[0];
171
- return created;
172
- } else {
173
- throw new Error(error?.message);
174
- }
175
- }
176
- : undefined;
177
- const subscribe = realtime
178
- ? ({ node, value$, update }: SyncedSubscribeParams) => {
179
- const { filter, schema } = (isObject(realtime) ? realtime : {}) as { schema?: string; filter?: string };
180
- const channel = client
181
- .channel(`LS_${node.key || ''}${channelNum++}`)
182
- .on(
183
- 'postgres_changes',
184
- {
185
- event: '*',
186
- table: collection,
187
- schema: schema || 'public',
188
- filter: filter || undefined,
189
- },
190
- (payload) => {
191
- const { eventType, new: value, old } = payload;
192
- if (eventType === 'INSERT' || eventType === 'UPDATE') {
193
- const cur = value$.peek()?.[value.id];
194
- const curDateStr =
195
- cur &&
196
- ((fieldUpdatedAt && cur[fieldUpdatedAt]) ||
197
- fieldCreatedAt ||
198
- cur[fieldCreatedAt as any]);
199
- const valueDateStr =
200
- (fieldUpdatedAt && value[fieldUpdatedAt]) ||
201
- (fieldCreatedAt && value[fieldCreatedAt]);
202
- const valueDate = +new Date(valueDateStr);
203
- // Check if new or newer than last seen locally
204
- if (valueDateStr && (!curDateStr || valueDate > +new Date(curDateStr))) {
205
- // Update local with the new value
206
- update({
207
- value: { [value.id]: value },
208
- lastSync: valueDate,
209
- mode: 'merge',
210
- });
211
- }
212
- } else if (eventType === 'DELETE') {
213
- const { id } = old;
214
- update({
215
- value: { [id]: symbolDelete },
216
- });
217
- }
218
- },
219
- )
220
- .subscribe();
221
-
222
- return channel.unsubscribe;
223
- }
224
- : undefined;
225
-
226
- let transform = transformParam;
227
- if (stringifyDates) {
228
- const stringifier = transformStringifyDates() as SyncTransform<TLocal, TRemote>;
229
- transform = transform ? combineTransforms(stringifier, transform) : stringifier;
230
- }
231
-
232
- return syncedCrud<SupabaseRowOf<Client, Collection>, SupabaseRowOf<Client, Collection>, AsOption>({
233
- ...rest,
234
- list,
235
- create,
236
- update,
237
- delete: deleteFn,
238
- subscribe,
239
- fieldCreatedAt,
240
- fieldUpdatedAt,
241
- fieldDeleted,
242
- updatePartial: false,
243
- onSavedUpdate: 'createdUpdatedAt',
244
- transform,
245
- generateId,
246
- waitFor: () => isEnabled$.get() && (waitFor ? computeSelector(waitFor) : true),
247
- waitForSet,
248
- });
249
- }
@@ -1,113 +0,0 @@
1
- import { isFunction, observe } from '@legendapp/state';
2
- import { SyncedOptions, SyncedSetParams, SyncedSubscribeParams, synced } from '@legendapp/state/sync';
3
- import {
4
- DefaultError,
5
- DefaultedQueryObserverOptions,
6
- MutationObserver,
7
- MutationObserverOptions,
8
- QueryClient,
9
- QueryKey,
10
- QueryObserver,
11
- QueryObserverOptions,
12
- notifyManager,
13
- } from '@tanstack/query-core';
14
-
15
- export interface ObservableQueryOptions<TQueryFnData, TError, TData, TQueryKey extends QueryKey>
16
- extends Omit<QueryObserverOptions<TQueryFnData, TError, TData, TQueryKey>, 'queryKey'> {
17
- queryKey?: TQueryKey | (() => TQueryKey);
18
- }
19
-
20
- export interface SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey extends QueryKey>
21
- extends SyncedOptions<TData> {
22
- queryClient: QueryClient;
23
- query: ObservableQueryOptions<TQueryFnData, TError, TData, TQueryKey>;
24
- mutation?: MutationObserverOptions<TData, TError, void>;
25
- }
26
-
27
- export function syncedQuery<
28
- TQueryFnData = unknown,
29
- TError = DefaultError,
30
- TData = TQueryFnData,
31
- TQueryKey extends QueryKey = QueryKey,
32
- >(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>) {
33
- const { query: options, mutation: mutationOptions, queryClient } = params;
34
-
35
- const Observer = QueryObserver;
36
- const defaultedOptions = queryClient!.defaultQueryOptions(
37
- options as QueryObserverOptions<TQueryFnData, TError, TData, TQueryKey>,
38
- );
39
- let observer: QueryObserver<TQueryFnData, TError, TData, TQueryKey> | undefined = undefined;
40
- let latestOptions = defaultedOptions;
41
- let queryKeyFromFn: TQueryKey;
42
-
43
- const origQueryKey = options.queryKey!;
44
-
45
- // If the queryKey is a function, observe it and extract the raw value
46
- const isKeyFunction = isFunction(origQueryKey);
47
-
48
- const updateQueryOptions = (obj: DefaultedQueryObserverOptions<TQueryFnData, TError, TData, TQueryKey>) => {
49
- // Since legend-state mutates the query options, we need to clone it to make Query
50
- // see it as changed
51
- const options = Object.assign({}, obj);
52
-
53
- // Use the latest value from the observed queryKey function
54
- if (isKeyFunction) {
55
- options.queryKey = queryKeyFromFn;
56
- }
57
-
58
- latestOptions = options;
59
-
60
- // Update the Query options
61
- if (observer) {
62
- observer.setOptions(options, { listeners: false });
63
- }
64
- };
65
-
66
- if (isKeyFunction) {
67
- observe(() => {
68
- queryKeyFromFn = origQueryKey();
69
- updateQueryOptions(latestOptions);
70
- });
71
- }
72
-
73
- // Create the observer
74
- observer = new Observer!<TQueryFnData, TError, TData, TQueryKey>(queryClient!, latestOptions);
75
-
76
- const get = () => {
77
- // Get the initial optimistic results if it's already cached
78
- const result = observer!.getOptimisticResult(latestOptions);
79
-
80
- return result.data!;
81
- };
82
-
83
- const subscribe = ({ update }: SyncedSubscribeParams<TData>) => {
84
- // Subscribe to Query's observer and update the observable
85
- const unsubscribe = observer!.subscribe(
86
- notifyManager.batchCalls((result) => {
87
- if (result.status === 'success') {
88
- update({ value: result.data });
89
- }
90
- }),
91
- );
92
-
93
- // Update result to make sure we did not miss any query updates
94
- // between creating the observer and subscribing to it.
95
- observer.updateResult();
96
-
97
- return unsubscribe;
98
- };
99
-
100
- let set: undefined | (({ value }: SyncedSetParams<TData>) => Promise<TData>) = undefined;
101
- if (mutationOptions) {
102
- const mutator = new MutationObserver(queryClient!, mutationOptions);
103
- set = ({ value }: SyncedSetParams<TData>) => {
104
- return mutator.mutate(value as any);
105
- };
106
- }
107
-
108
- return synced({
109
- get,
110
- set,
111
- subscribe,
112
- });
113
- }
@@ -1,12 +0,0 @@
1
- import { useObservable } from '@legendapp/state/react';
2
- import { SyncedQueryParams, syncedQuery } from '@legendapp/state/sync-plugins/tanstack-query';
3
- import { DefaultError, QueryKey } from '@tanstack/query-core';
4
-
5
- export function useObservableSyncedQuery<
6
- TQueryFnData = unknown,
7
- TError = DefaultError,
8
- TData = TQueryFnData,
9
- TQueryKey extends QueryKey = QueryKey,
10
- >(params: SyncedQueryParams<TQueryFnData, TError, TData, TQueryKey>) {
11
- return useObservable(syncedQuery(params));
12
- }
@@ -1,11 +0,0 @@
1
- import type { NodeValue } from '@legendapp/state';
2
-
3
- export function getNodePath(node: NodeValue) {
4
- const arr: (string | number)[] = [];
5
- let n = node;
6
- while (n?.key !== undefined) {
7
- arr.splice(0, 0, n.key);
8
- n = n.parent;
9
- }
10
- return arr.join('.');
11
- }
@@ -1,34 +0,0 @@
1
- import { NodeValue, internal, TrackingNode } from '@legendapp/state';
2
- import { getNodePath } from './traceHelpers';
3
- const { optimized, tracking } = internal;
4
-
5
- export function useTraceListeners(this: any, name?: string) {
6
- if (process.env.NODE_ENV === 'development' && tracking.current) {
7
- tracking.current.traceListeners = traceNodes.bind(this, name);
8
- }
9
- }
10
-
11
- function traceNodes(name: string | undefined, nodes: Map<NodeValue, TrackingNode>) {
12
- if (process.env.NODE_ENV === 'development' && tracking.current) {
13
- tracking.current.traceListeners = undefined;
14
- const arr: string[] = [];
15
- if (nodes) {
16
- for (const tracked of nodes.values()) {
17
- const { node, track } = tracked;
18
- const shallow = track === true;
19
- const isOptimized = track === optimized;
20
- arr.push(
21
- `${arr.length + 1}: ${getNodePath(node)}${shallow ? ' (shallow)' : ''}${
22
- isOptimized ? ' (optimized)' : ''
23
- }`,
24
- );
25
- }
26
- }
27
-
28
- console.log(
29
- `[legend-state] ${name ? name + ' ' : ''}tracking ${arr.length} observable${
30
- arr.length !== 1 ? 's' : ''
31
- }:\n${arr.join('\n')}`,
32
- );
33
- }
34
- }
@@ -1,24 +0,0 @@
1
- import { ListenerParams, internal } from '@legendapp/state';
2
- const { tracking } = internal;
3
-
4
- export function useTraceUpdates(name?: string) {
5
- if (process.env.NODE_ENV === 'development' && tracking.current) {
6
- tracking.current.traceUpdates = replaceUpdateFn.bind(undefined, name);
7
- }
8
- }
9
-
10
- function replaceUpdateFn(name: string | undefined, updateFn: Function) {
11
- return onChange.bind(undefined, name, updateFn);
12
- }
13
-
14
- function onChange(name: string | undefined, updateFn: Function, params: ListenerParams<any>) {
15
- const { changes } = params;
16
- if (process.env.NODE_ENV === 'development') {
17
- changes.forEach(({ path, valueAtPath, prevAtPath }) => {
18
- console.log(`[legend-state] Rendering ${name ? name + ' ' : ''}because "${path}" changed:
19
- from: ${JSON.stringify(prevAtPath)}
20
- to: ${JSON.stringify(valueAtPath)}`);
21
- });
22
- return updateFn();
23
- }
24
- }
@@ -1,33 +0,0 @@
1
- import { internal, NodeValue, TrackingNode } from '@legendapp/state';
2
- import { getNodePath } from './traceHelpers';
3
- const { optimized, tracking } = internal;
4
-
5
- export function useVerifyNotTracking(this: any, name?: string) {
6
- if (process.env.NODE_ENV === 'development') {
7
- tracking.current!.traceListeners = traceNodes.bind(this, name);
8
- }
9
- }
10
-
11
- function traceNodes(name: string | undefined, nodes: Map<NodeValue, TrackingNode>) {
12
- if (process.env.NODE_ENV === 'development') {
13
- tracking.current!.traceListeners = undefined;
14
- const arr: string[] = [];
15
- if (nodes) {
16
- for (const tracked of nodes.values()) {
17
- const { node, track } = tracked;
18
- const shallow = track === true;
19
- const isOptimized = track === optimized;
20
- arr.push(
21
- `${arr.length + 1}: ${getNodePath(node)}${shallow ? ' (shallow)' : ''}${
22
- isOptimized ? ' (optimized)' : ''
23
- }`,
24
- );
25
- }
26
- console.error(
27
- `[legend-state] ${name ? name + ' ' : ''}tracking ${arr.length} observable${
28
- arr.length !== 1 ? 's' : ''
29
- } when it should not be:\n${arr.join('\n')}`,
30
- );
31
- }
32
- }
33
- }
@@ -1,10 +0,0 @@
1
- import { useRef } from 'react';
2
-
3
- export function useVerifyOneRender(name?: string) {
4
- if (process.env.NODE_ENV === 'development') {
5
- const numRenders = ++useRef(0).current;
6
- if (numRenders > 1) {
7
- console.error(`[legend-state] ${name ? name + ' ' : ''}Component rendered more than once`);
8
- }
9
- }
10
- }
@@ -1,52 +0,0 @@
1
- import { computeSelector } from './helpers';
2
- import type { ListenerParams, ObserveEvent, Selector } from './observableInterfaces';
3
- import type { ObserveOptions } from './observe';
4
- import { setupTracking } from './setupTracking';
5
- import { beginTracking, endTracking, tracking } from './tracking';
6
-
7
- export function trackSelector<T>(
8
- selector: Selector<T>,
9
- update: (params: ListenerParams) => void,
10
- observeEvent?: ObserveEvent<T>,
11
- observeOptions?: ObserveOptions,
12
- createResubscribe?: boolean,
13
- ) {
14
- let dispose: undefined | (() => void);
15
- let resubscribe: (() => () => void) | undefined;
16
- let updateFn = update;
17
-
18
- beginTracking();
19
- const value = selector ? computeSelector(selector, observeEvent, observeOptions?.fromComputed) : selector;
20
- const tracker = tracking.current;
21
- const nodes = tracker!.nodes;
22
- endTracking();
23
-
24
- if ((process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') && tracker && nodes) {
25
- tracker.traceListeners?.(nodes);
26
- if (tracker.traceUpdates) {
27
- updateFn = tracker.traceUpdates(update) as () => void;
28
- }
29
- // Clear tracing so it doesn't leak to other components
30
- tracker.traceListeners = undefined;
31
- tracker.traceUpdates = undefined;
32
- }
33
-
34
- if (!observeEvent?.cancel) {
35
- // Do tracing if it was requested
36
-
37
- // useSyncExternalStore doesn't subscribe until after the component mount.
38
- // We want to subscribe immediately so we don't miss any updates
39
- dispose = setupTracking(nodes, updateFn, false, observeOptions?.immediate);
40
- if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
41
- resubscribe = createResubscribe
42
- ? () => {
43
- dispose?.();
44
- dispose = setupTracking(nodes, updateFn);
45
- return dispose;
46
- }
47
- : undefined;
48
- }
49
- }
50
-
51
- return { nodes, value, dispose, resubscribe };
52
- }
package/src/tracking.ts DELETED
@@ -1,43 +0,0 @@
1
- import type { NodeValue, TrackingState, TrackingType } from './observableInterfaces';
2
-
3
- let trackCount = 0;
4
- const trackingQueue: (TrackingState | undefined)[] = [];
5
-
6
- export const tracking = {
7
- current: undefined as TrackingState | undefined,
8
- };
9
-
10
- export function beginTracking() {
11
- // Keep a copy of the previous tracking context so it can be restored
12
- // when this context is complete
13
- trackingQueue.push(tracking.current);
14
- trackCount++;
15
- tracking.current = {};
16
- }
17
- export function endTracking() {
18
- // Restore the previous tracking context
19
- trackCount--;
20
- if (trackCount < 0) {
21
- trackCount = 0;
22
- }
23
- tracking.current = trackingQueue.pop();
24
- }
25
-
26
- export function updateTracking(node: NodeValue, track?: TrackingType) {
27
- if (trackCount) {
28
- const tracker = tracking.current;
29
- if (tracker) {
30
- if (!tracker.nodes) {
31
- tracker.nodes = new Map();
32
- }
33
-
34
- const existing = tracker.nodes.get(node);
35
- if (existing) {
36
- existing.track = existing.track || track;
37
- existing.num++;
38
- } else {
39
- tracker.nodes.set(node, { node, track, num: 1 });
40
- }
41
- }
42
- }
43
- }
@@ -1,12 +0,0 @@
1
- import type { ObservableParam } from '@legendapp/state';
2
- import { ReactNode } from 'react';
3
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
4
- import type { Computed, Memo } from '@legendapp/state/react';
5
- declare module '@legendapp/state/react' {
6
- export declare const Computed: (props: {
7
- children: ObservableParam | (() => ReactNode) | ReactNode;
8
- }) => React.ReactElement;
9
- export declare const Memo: (props: {
10
- children: ObservableParam | (() => ReactNode) | ReactNode;
11
- }) => React.ReactElement;
12
- }
package/src/when.ts DELETED
@@ -1,75 +0,0 @@
1
- import { computeSelector, isObservableValueReady } from './helpers';
2
- import { isPromise } from './is';
3
- import type { ObserveEvent, Selector } from './observableInterfaces';
4
- import { observe } from './observe';
5
-
6
- function _when<T, T2>(predicate: Selector<T>, effect?: (value: T) => T2, checkReady?: boolean): any {
7
- // If predicate is a regular Promise skip all the observable stuff
8
- if (isPromise<T>(predicate)) {
9
- return effect ? predicate.then(effect) : (predicate as any);
10
- }
11
-
12
- let value: T | undefined;
13
- let effectValue: T2 | undefined;
14
-
15
- // Create a wrapping fn that calls the effect if predicate returns true
16
- function run(e: ObserveEvent<T>) {
17
- const ret = computeSelector(predicate);
18
-
19
- if (isPromise(ret)) {
20
- value = ret as any;
21
- // We want value to be the Promise but return undefined
22
- // so it doesn't run the effect with the Promise as the value
23
- return undefined;
24
- } else if (!isPromise(ret) && (checkReady ? isObservableValueReady(ret) : ret)) {
25
- value = ret;
26
-
27
- // Set cancel so that observe does not track anymore
28
- e.cancel = true;
29
- }
30
-
31
- return value;
32
- }
33
- function doEffect() {
34
- // If value is truthy then run the effect
35
- effectValue = effect?.(value!);
36
- }
37
- // Run in an observe
38
- observe(run, doEffect);
39
-
40
- // If first run resulted in a truthy value just return it.
41
- // It will have set e.cancel so no need to dispose
42
- if (isPromise<T>(value)) {
43
- return effect ? value.then(effect) : (value as any);
44
- } else if (value !== undefined) {
45
- return effect ? effectValue : Promise.resolve(value);
46
- } else {
47
- // Wrap it in a promise
48
- const promise = new Promise<T2>((resolve) => {
49
- if (effect) {
50
- const originalEffect = effect;
51
- effect = ((value: T) => {
52
- const effectValue = originalEffect(value);
53
- resolve(isPromise(effectValue) ? effectValue.then((value) => value as T2) : effectValue);
54
- }) as any;
55
- } else {
56
- effect = resolve as any;
57
- }
58
- });
59
-
60
- return promise;
61
- }
62
- }
63
-
64
- export function when<T, T2>(predicate: Promise<T>, effect: (value: T) => T2): Promise<T2>;
65
- export function when<T, T2>(predicate: Selector<T>, effect: (value: T) => T2): Promise<T2>;
66
- export function when<T>(predicate: Selector<T>): Promise<T>;
67
- export function when<T, T2>(predicate: Selector<T>, effect?: (value: T) => T2): Promise<T | T2> {
68
- return _when<T, T2>(predicate, effect, false);
69
- }
70
- export function whenReady<T, T2>(predicate: Promise<T>, effect: (value: T) => T2): Promise<T2>;
71
- export function whenReady<T, T2>(predicate: Selector<T>, effect: (value: T) => T2): Promise<T2>;
72
- export function whenReady<T>(predicate: Selector<T>): Promise<T>;
73
- export function whenReady<T, T2>(predicate: Selector<T>, effect?: (value: T) => T2): Promise<T | T2> {
74
- return _when<T, T2>(predicate, effect, true);
75
- }