@legendapp/state 2.2.0-next.8 → 2.2.0-next.80
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.
- package/README.md +4 -2
- package/babel.js.map +1 -1
- package/config/enable$get.d.ts +8 -0
- package/config/enable$get.js +24 -0
- package/config/enable$get.js.map +1 -0
- package/config/enable$get.mjs +21 -0
- package/config/enable$get.mjs.map +1 -0
- package/config/enableReactComponents.js.map +1 -1
- package/config/enableReactComponents.mjs.map +1 -1
- package/config/enableReactNativeComponents.js.map +1 -1
- package/config/enableReactNativeComponents.mjs.map +1 -1
- package/config/enableReactTracking.d.ts +0 -9
- package/config/enableReactTracking.js +34 -32
- package/config/enableReactTracking.js.map +1 -1
- package/config/enableReactTracking.mjs +35 -33
- package/config/enableReactTracking.mjs.map +1 -1
- package/config/enableReactUse.d.ts +1 -1
- package/config/enableReactUse.js +9 -1
- package/config/enableReactUse.js.map +1 -1
- package/config/enableReactUse.mjs +9 -1
- package/config/enableReactUse.mjs.map +1 -1
- package/config/enable_peek.d.ts +8 -0
- package/config/{enableDirectPeek.js → enable_peek.js} +6 -3
- package/config/enable_peek.js.map +1 -0
- package/config/{enableDirectPeek.mjs → enable_peek.mjs} +5 -3
- package/config/enable_peek.mjs.map +1 -0
- package/helpers/fetch.d.ts +4 -3
- package/helpers/fetch.js.map +1 -1
- package/helpers/fetch.mjs.map +1 -1
- package/helpers/pageHash.js.map +1 -1
- package/helpers/pageHash.mjs.map +1 -1
- package/helpers/pageHashParams.js.map +1 -1
- package/helpers/pageHashParams.mjs.map +1 -1
- package/helpers/time.d.ts +2 -2
- package/helpers/time.js.map +1 -1
- package/helpers/time.mjs.map +1 -1
- package/history.js +2 -2
- package/history.js.map +1 -1
- package/history.mjs +3 -3
- package/history.mjs.map +1 -1
- package/index.d.ts +29 -9
- package/index.js +964 -671
- package/index.js.map +1 -1
- package/index.mjs +959 -668
- package/index.mjs.map +1 -1
- package/package.json +37 -25
- package/persist-plugins/async-storage.d.ts +4 -3
- package/persist-plugins/async-storage.js +8 -7
- package/persist-plugins/async-storage.js.map +1 -1
- package/persist-plugins/async-storage.mjs +9 -8
- package/persist-plugins/async-storage.mjs.map +1 -1
- package/persist-plugins/fetch.d.ts +1 -1
- package/persist-plugins/fetch.js.map +1 -1
- package/persist-plugins/fetch.mjs.map +1 -1
- package/persist-plugins/firebase.d.ts +2 -2
- package/persist-plugins/firebase.js +12 -11
- package/persist-plugins/firebase.js.map +1 -1
- package/persist-plugins/firebase.mjs +13 -12
- package/persist-plugins/firebase.mjs.map +1 -1
- package/persist-plugins/indexeddb.d.ts +11 -10
- package/persist-plugins/indexeddb.js +2 -2
- package/persist-plugins/indexeddb.js.map +1 -1
- package/persist-plugins/indexeddb.mjs +2 -2
- package/persist-plugins/indexeddb.mjs.map +1 -1
- package/persist-plugins/local-storage.d.ts +4 -4
- package/persist-plugins/local-storage.js +19 -7
- package/persist-plugins/local-storage.js.map +1 -1
- package/persist-plugins/local-storage.mjs +20 -9
- package/persist-plugins/local-storage.mjs.map +1 -1
- package/persist-plugins/mmkv.d.ts +9 -8
- package/persist-plugins/mmkv.js +5 -4
- package/persist-plugins/mmkv.js.map +1 -1
- package/persist-plugins/mmkv.mjs +6 -5
- package/persist-plugins/mmkv.mjs.map +1 -1
- package/persist-plugins/query.d.ts +1 -1
- package/persist-plugins/query.js.map +1 -1
- package/persist-plugins/query.mjs.map +1 -1
- package/persist.d.ts +2 -14
- package/persist.js +1270 -269
- package/persist.js.map +1 -1
- package/persist.mjs +1270 -270
- package/persist.mjs.map +1 -1
- package/react-hooks/createObservableHook.js +1 -1
- package/react-hooks/createObservableHook.js.map +1 -1
- package/react-hooks/createObservableHook.mjs +1 -1
- package/react-hooks/createObservableHook.mjs.map +1 -1
- package/react-hooks/useFetch.d.ts +4 -3
- package/react-hooks/useFetch.js.map +1 -1
- package/react-hooks/useFetch.mjs.map +1 -1
- package/react-hooks/useHover.js.map +1 -1
- package/react-hooks/useHover.mjs.map +1 -1
- package/react-hooks/useMeasure.js.map +1 -1
- package/react-hooks/useMeasure.mjs.map +1 -1
- package/react-hooks/useObservableNextRouter.js.map +1 -1
- package/react-hooks/useObservableNextRouter.mjs.map +1 -1
- package/react-hooks/useObservableQuery.js.map +1 -1
- package/react-hooks/useObservableQuery.mjs.map +1 -1
- package/react-hooks/usePersistedObservable.d.ts +6 -3
- package/react-hooks/usePersistedObservable.js +5 -2
- package/react-hooks/usePersistedObservable.js.map +1 -1
- package/react-hooks/usePersistedObservable.mjs +5 -2
- package/react-hooks/usePersistedObservable.mjs.map +1 -1
- package/react.js +73 -93
- package/react.js.map +1 -1
- package/react.mjs +73 -93
- package/react.mjs.map +1 -1
- package/src/ObservableObject.ts +1217 -0
- package/src/ObservablePrimitive.ts +62 -0
- package/src/babel/index.ts +70 -0
- package/src/batching.ts +378 -0
- package/src/computed.ts +18 -0
- package/src/config/enable$get.ts +30 -0
- package/src/config/enableReactComponents.ts +26 -0
- package/src/config/enableReactNativeComponents.ts +102 -0
- package/src/config/enableReactTracking.ts +62 -0
- package/src/config/enableReactUse.ts +32 -0
- package/src/config/enable_peek.ts +31 -0
- package/src/config.ts +47 -0
- package/src/createObservable.ts +46 -0
- package/src/event.ts +26 -0
- package/src/globals.ts +234 -0
- package/src/helpers/fetch.ts +26 -0
- package/src/helpers/pageHash.ts +41 -0
- package/src/helpers/pageHashParams.ts +55 -0
- package/src/helpers/time.ts +30 -0
- package/src/helpers.ts +224 -0
- package/src/history/trackHistory.ts +29 -0
- package/src/history/undoRedo.ts +111 -0
- package/src/is.ts +63 -0
- package/src/linked.ts +6 -0
- package/src/observable.ts +32 -0
- package/src/observableInterfaces.ts +148 -0
- package/src/observableTypes.ts +226 -0
- package/src/observe.ts +89 -0
- package/src/onChange.ts +136 -0
- package/src/persist/configureObservablePersistence.ts +7 -0
- package/src/persist/fieldTransformer.ts +149 -0
- package/src/persist/observablePersistRemoteFunctionsAdapter.ts +39 -0
- package/src/persist/persistObservable.ts +1031 -0
- package/src/persist-plugins/async-storage.ts +102 -0
- package/src/persist-plugins/fetch.ts +34 -0
- package/src/persist-plugins/firebase.ts +1052 -0
- package/src/persist-plugins/indexeddb.ts +432 -0
- package/src/persist-plugins/local-storage.ts +91 -0
- package/src/persist-plugins/mmkv.ts +91 -0
- package/src/persist-plugins/query.ts +129 -0
- package/src/proxy.ts +28 -0
- package/src/react/Computed.tsx +7 -0
- package/src/react/For.tsx +116 -0
- package/src/react/Memo.tsx +4 -0
- package/src/react/Reactive.tsx +53 -0
- package/src/react/Show.tsx +33 -0
- package/src/react/Switch.tsx +43 -0
- package/src/react/react-globals.ts +3 -0
- package/src/react/{reactInterfaces.d.ts → reactInterfaces.ts} +15 -7
- package/src/react/reactive-observer.tsx +210 -0
- package/src/react/useComputed.ts +36 -0
- package/src/react/useEffectOnce.ts +41 -0
- package/src/react/useIsMounted.ts +16 -0
- package/src/react/useMount.ts +15 -0
- package/src/react/useObservable.ts +24 -0
- package/src/react/useObservableReducer.ts +52 -0
- package/src/react/useObservableState.ts +30 -0
- package/src/react/useObserve.ts +54 -0
- package/src/react/useObserveEffect.ts +40 -0
- package/src/react/usePauseProvider.tsx +13 -0
- package/src/react/useSelector.ts +167 -0
- package/src/react/useUnmount.ts +8 -0
- package/src/react/useWhen.ts +9 -0
- package/src/react-hooks/createObservableHook.ts +53 -0
- package/src/react-hooks/useFetch.ts +16 -0
- package/src/react-hooks/useHover.ts +40 -0
- package/src/react-hooks/useMeasure.ts +48 -0
- package/src/react-hooks/useObservableNextRouter.ts +137 -0
- package/src/react-hooks/useObservableQuery.ts +205 -0
- package/src/react-hooks/usePersistedObservable.ts +25 -0
- package/src/retry.ts +71 -0
- package/src/setupTracking.ts +26 -0
- package/src/sync/activateSyncedNode.ts +128 -0
- package/src/sync/configureObservableSync.ts +7 -0
- package/src/sync/persistTypes.ts +226 -0
- package/src/sync/syncHelpers.ts +56 -0
- package/src/sync/syncObservable.ts +1040 -0
- package/src/sync/syncObservableAdapter.ts +31 -0
- package/src/sync/syncTypes.ts +188 -0
- package/src/sync/synced.ts +20 -0
- package/src/sync-plugins/crud.ts +404 -0
- package/src/sync-plugins/fetch.ts +72 -0
- package/src/sync-plugins/keel.ts +452 -0
- package/src/sync-plugins/supabase.ts +261 -0
- package/src/trace/traceHelpers.ts +11 -0
- package/src/trace/useTraceListeners.ts +34 -0
- package/src/trace/useTraceUpdates.ts +24 -0
- package/src/trace/useVerifyNotTracking.ts +33 -0
- package/src/trace/useVerifyOneRender.ts +10 -0
- package/src/trackSelector.ts +52 -0
- package/src/tracking.ts +43 -0
- package/src/types/babel.d.ts +12 -0
- package/src/when.ts +75 -0
- package/sync-plugins/crud.d.ts +41 -0
- package/sync-plugins/crud.js +290 -0
- package/sync-plugins/crud.js.map +1 -0
- package/sync-plugins/crud.mjs +286 -0
- package/sync-plugins/crud.mjs.map +1 -0
- package/sync-plugins/fetch.d.ts +13 -0
- package/sync-plugins/fetch.js +46 -0
- package/sync-plugins/fetch.js.map +1 -0
- package/sync-plugins/fetch.mjs +44 -0
- package/sync-plugins/fetch.mjs.map +1 -0
- package/sync-plugins/keel.d.ts +91 -0
- package/sync-plugins/keel.js +277 -0
- package/sync-plugins/keel.js.map +1 -0
- package/sync-plugins/keel.mjs +273 -0
- package/sync-plugins/keel.mjs.map +1 -0
- package/sync-plugins/supabase.d.ts +36 -0
- package/sync-plugins/supabase.js +152 -0
- package/sync-plugins/supabase.js.map +1 -0
- package/sync-plugins/supabase.mjs +149 -0
- package/sync-plugins/supabase.mjs.map +1 -0
- package/sync.d.ts +11 -0
- package/sync.js +976 -0
- package/sync.js.map +1 -0
- package/sync.mjs +966 -0
- package/sync.mjs.map +1 -0
- package/trace.js +13 -10
- package/trace.js.map +1 -1
- package/trace.mjs +11 -8
- package/trace.mjs.map +1 -1
- package/types/babel.d.ts +3 -3
- package/config/enableDirectAccess.d.ts +0 -7
- package/config/enableDirectAccess.js +0 -25
- package/config/enableDirectAccess.js.map +0 -1
- package/config/enableDirectAccess.mjs +0 -23
- package/config/enableDirectAccess.mjs.map +0 -1
- package/config/enableDirectPeek.d.ts +0 -7
- package/config/enableDirectPeek.js.map +0 -1
- package/config/enableDirectPeek.mjs.map +0 -1
- package/config/enableReactDirectRender.d.ts +0 -2
- package/config/enableReactDirectRender.js +0 -78
- package/config/enableReactDirectRender.js.map +0 -1
- package/config/enableReactDirectRender.mjs +0 -75
- package/config/enableReactDirectRender.mjs.map +0 -1
- package/src/ObservableObject.d.ts +0 -14
- package/src/ObservablePrimitive.d.ts +0 -7
- package/src/babel/index.d.ts +0 -17
- package/src/batching.d.ts +0 -6
- package/src/computed.d.ts +0 -4
- package/src/config/enableDirectAccess.d.ts +0 -7
- package/src/config/enableDirectPeek.d.ts +0 -7
- package/src/config/enableReactComponents.d.ts +0 -7
- package/src/config/enableReactDirectRender.d.ts +0 -2
- package/src/config/enableReactNativeComponents.d.ts +0 -20
- package/src/config/enableReactTracking.d.ts +0 -15
- package/src/config/enableReactUse.d.ts +0 -7
- package/src/config.d.ts +0 -8
- package/src/createObservable.d.ts +0 -2
- package/src/event.d.ts +0 -2
- package/src/globals.d.ts +0 -32
- package/src/helpers/fetch.d.ts +0 -6
- package/src/helpers/pageHash.d.ts +0 -7
- package/src/helpers/pageHashParams.d.ts +0 -7
- package/src/helpers/time.d.ts +0 -3
- package/src/helpers.d.ts +0 -13
- package/src/history/trackHistory.d.ts +0 -4
- package/src/is.d.ts +0 -10
- package/src/observable.d.ts +0 -16
- package/src/observableInterfaces.d.ts +0 -458
- package/src/observe.d.ts +0 -6
- package/src/onChange.d.ts +0 -7
- package/src/persist/configureObservablePersistence.d.ts +0 -3
- package/src/persist/fieldTransformer.d.ts +0 -8
- package/src/persist/observablePersistRemoteFunctionsAdapter.d.ts +0 -2
- package/src/persist/persistActivateNode.d.ts +0 -1
- package/src/persist/persistHelpers.d.ts +0 -1
- package/src/persist/persistObservable.d.ts +0 -25
- package/src/persist-plugins/async-storage.d.ts +0 -14
- package/src/persist-plugins/fetch.d.ts +0 -10
- package/src/persist-plugins/firebase.d.ts +0 -51
- package/src/persist-plugins/indexeddb.d.ts +0 -25
- package/src/persist-plugins/local-storage.d.ts +0 -21
- package/src/persist-plugins/mmkv.d.ts +0 -14
- package/src/persist-plugins/query.d.ts +0 -18
- package/src/proxy.d.ts +0 -5
- package/src/react/Computed.d.ts +0 -5
- package/src/react/For.d.ts +0 -15
- package/src/react/Memo.d.ts +0 -3
- package/src/react/Reactive.d.ts +0 -9
- package/src/react/Show.d.ts +0 -18
- package/src/react/Switch.d.ts +0 -14
- package/src/react/react-globals.d.ts +0 -3
- package/src/react/reactive-observer.d.ts +0 -14
- package/src/react/useComputed.d.ts +0 -5
- package/src/react/useEffectOnce.d.ts +0 -1
- package/src/react/useIsMounted.d.ts +0 -2
- package/src/react/useMount.d.ts +0 -2
- package/src/react/useObservable.d.ts +0 -9
- package/src/react/useObservableReducer.d.ts +0 -7
- package/src/react/useObservableState.d.ts +0 -2
- package/src/react/useObserve.d.ts +0 -4
- package/src/react/useObserveEffect.d.ts +0 -4
- package/src/react/usePauseProvider.d.ts +0 -8
- package/src/react/useSelector.d.ts +0 -3
- package/src/react/useUnmount.d.ts +0 -2
- package/src/react/useWhen.d.ts +0 -3
- package/src/react-hooks/createObservableHook.d.ts +0 -2
- package/src/react-hooks/useFetch.d.ts +0 -6
- package/src/react-hooks/useHover.d.ts +0 -3
- package/src/react-hooks/useMeasure.d.ts +0 -6
- package/src/react-hooks/useObservableNextRouter.d.ts +0 -33
- package/src/react-hooks/useObservableQuery.d.ts +0 -6
- package/src/react-hooks/usePersistedObservable.d.ts +0 -11
- package/src/retry.d.ts +0 -9
- package/src/setupTracking.d.ts +0 -2
- package/src/trace/traceHelpers.d.ts +0 -2
- package/src/trace/useTraceListeners.d.ts +0 -1
- package/src/trace/useTraceUpdates.d.ts +0 -1
- package/src/trace/useVerifyNotTracking.d.ts +0 -1
- package/src/trace/useVerifyOneRender.d.ts +0 -1
- package/src/trackSelector.d.ts +0 -7
- package/src/tracking.d.ts +0 -13
- package/src/when.d.ts +0 -3
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Observable,
|
|
3
|
+
computeSelector,
|
|
4
|
+
getNodeValue,
|
|
5
|
+
mergeIntoObservable,
|
|
6
|
+
observable,
|
|
7
|
+
symbolDelete,
|
|
8
|
+
} from '@legendapp/state';
|
|
9
|
+
import {
|
|
10
|
+
SyncedOptions,
|
|
11
|
+
SyncedOptionsGlobal,
|
|
12
|
+
removeNullUndefined,
|
|
13
|
+
type SyncedGetParams,
|
|
14
|
+
type SyncedSubscribeParams,
|
|
15
|
+
} from '@legendapp/state/sync';
|
|
16
|
+
import {
|
|
17
|
+
CrudAsOption,
|
|
18
|
+
SyncedCrudPropsBase,
|
|
19
|
+
SyncedCrudPropsMany,
|
|
20
|
+
SyncedCrudReturnType,
|
|
21
|
+
syncedCrud,
|
|
22
|
+
} from '@legendapp/state/sync-plugins/crud';
|
|
23
|
+
import type { PostgrestFilterBuilder, PostgrestQueryBuilder } from '@supabase/postgrest-js';
|
|
24
|
+
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
25
|
+
|
|
26
|
+
// Unused types but maybe useful in the future so keeping them for now
|
|
27
|
+
// type DatabaseOf<Client extends SupabaseClient> = Client extends SupabaseClient<infer TDB> ? TDB : never;
|
|
28
|
+
// type SchemaNameOf<Client extends SupabaseClient> = Client extends SupabaseClient<infer _, infer SchemaName>
|
|
29
|
+
// ? SchemaName
|
|
30
|
+
// : never;
|
|
31
|
+
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
33
|
+
type SchemaOf<Client extends SupabaseClient> = Client extends SupabaseClient<infer _, infer __, infer Schema>
|
|
34
|
+
? Schema
|
|
35
|
+
: never;
|
|
36
|
+
type TableOf<Client extends SupabaseClient> = SchemaOf<Client>['Tables'];
|
|
37
|
+
type CollectionOf<Client extends SupabaseClient> = keyof TableOf<Client>;
|
|
38
|
+
type RowOf<Client extends SupabaseClient, Collection extends CollectionOf<Client>> = TableOf<Client>[Collection]['Row'];
|
|
39
|
+
|
|
40
|
+
export type SyncedSupabaseConfig<T extends { id: string }> = Omit<
|
|
41
|
+
SyncedCrudPropsBase<T>,
|
|
42
|
+
'create' | 'update' | 'delete' | 'onSaved' | 'transform' | 'updatePartial' | 'subscribe'
|
|
43
|
+
>;
|
|
44
|
+
|
|
45
|
+
export interface SyncedSupabaseGlobalConfig
|
|
46
|
+
extends Omit<SyncedSupabaseConfig<{ id: string }>, 'persist' | keyof SyncedOptions> {
|
|
47
|
+
persist?: SyncedOptionsGlobal;
|
|
48
|
+
enabled?: Observable<boolean>;
|
|
49
|
+
as?: Exclude<CrudAsOption, 'first'>;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
interface SyncedSupabaseProps<
|
|
53
|
+
Client extends SupabaseClient,
|
|
54
|
+
Collection extends CollectionOf<Client>,
|
|
55
|
+
TOption extends CrudAsOption = 'object',
|
|
56
|
+
> extends SyncedSupabaseConfig<RowOf<Client, Collection>>,
|
|
57
|
+
SyncedCrudPropsMany<RowOf<Client, Collection>, RowOf<Client, Collection>, TOption> {
|
|
58
|
+
supabase: Client;
|
|
59
|
+
collection: Collection;
|
|
60
|
+
select?: (
|
|
61
|
+
query: PostgrestQueryBuilder<SchemaOf<Client>, TableOf<Client>[Collection], Collection>,
|
|
62
|
+
) => PostgrestFilterBuilder<
|
|
63
|
+
SchemaOf<Client>,
|
|
64
|
+
RowOf<Client, Collection>,
|
|
65
|
+
RowOf<Client, Collection>[],
|
|
66
|
+
Collection,
|
|
67
|
+
[]
|
|
68
|
+
>;
|
|
69
|
+
filter?: (
|
|
70
|
+
select: PostgrestFilterBuilder<
|
|
71
|
+
SchemaOf<Client>,
|
|
72
|
+
RowOf<Client, Collection>,
|
|
73
|
+
RowOf<Client, Collection>[],
|
|
74
|
+
Collection,
|
|
75
|
+
[]
|
|
76
|
+
>,
|
|
77
|
+
params: SyncedGetParams,
|
|
78
|
+
) => PostgrestFilterBuilder<
|
|
79
|
+
SchemaOf<Client>,
|
|
80
|
+
RowOf<Client, Collection>,
|
|
81
|
+
RowOf<Client, Collection>[],
|
|
82
|
+
Collection,
|
|
83
|
+
[]
|
|
84
|
+
>;
|
|
85
|
+
actions?: ('create' | 'read' | 'update' | 'delete')[];
|
|
86
|
+
realtime?: { schema?: string; filter?: string };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
let channelNum = 1;
|
|
90
|
+
const supabaseConfig: SyncedSupabaseGlobalConfig = {};
|
|
91
|
+
const isEnabled$ = observable(true);
|
|
92
|
+
|
|
93
|
+
export function configureSyncedSupabase(config: SyncedSupabaseGlobalConfig) {
|
|
94
|
+
const { enabled, ...rest } = config;
|
|
95
|
+
if (enabled !== undefined) {
|
|
96
|
+
isEnabled$.set(enabled);
|
|
97
|
+
}
|
|
98
|
+
Object.assign(supabaseConfig, removeNullUndefined(rest));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function syncedSupabase<
|
|
102
|
+
Client extends SupabaseClient,
|
|
103
|
+
Collection extends CollectionOf<Client> & string,
|
|
104
|
+
AsOption extends CrudAsOption = 'object',
|
|
105
|
+
>(props: SyncedSupabaseProps<Client, Collection, AsOption>): SyncedCrudReturnType<RowOf<Client, Collection>, AsOption> {
|
|
106
|
+
mergeIntoObservable(props, supabaseConfig);
|
|
107
|
+
const {
|
|
108
|
+
supabase: client,
|
|
109
|
+
collection,
|
|
110
|
+
select: selectFn,
|
|
111
|
+
filter,
|
|
112
|
+
actions,
|
|
113
|
+
fieldCreatedAt,
|
|
114
|
+
fieldUpdatedAt,
|
|
115
|
+
realtime,
|
|
116
|
+
changesSince,
|
|
117
|
+
waitFor,
|
|
118
|
+
waitForSet,
|
|
119
|
+
generateId: generateIdParam,
|
|
120
|
+
...rest
|
|
121
|
+
} = props;
|
|
122
|
+
|
|
123
|
+
const generateId = generateIdParam || supabaseConfig.generateId;
|
|
124
|
+
|
|
125
|
+
const list =
|
|
126
|
+
!actions || actions.includes('read')
|
|
127
|
+
? async (params: SyncedGetParams) => {
|
|
128
|
+
const { lastSync } = params;
|
|
129
|
+
const from = client.from(collection);
|
|
130
|
+
let select = selectFn ? selectFn(from) : from.select();
|
|
131
|
+
if (changesSince === 'last-sync') {
|
|
132
|
+
select = select.neq('deleted', true);
|
|
133
|
+
if (lastSync) {
|
|
134
|
+
const date = new Date(lastSync).toISOString();
|
|
135
|
+
select = select.or(
|
|
136
|
+
[
|
|
137
|
+
fieldCreatedAt && `${fieldCreatedAt}.gt.${date}`,
|
|
138
|
+
fieldUpdatedAt && `${fieldUpdatedAt}.gt.${date}`,
|
|
139
|
+
].join(','),
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (filter) {
|
|
144
|
+
select = filter(select, params);
|
|
145
|
+
}
|
|
146
|
+
const { data, error } = await select;
|
|
147
|
+
if (error) {
|
|
148
|
+
throw new Error(error?.message);
|
|
149
|
+
}
|
|
150
|
+
return (data! || []) as RowOf<Client, Collection>[];
|
|
151
|
+
}
|
|
152
|
+
: undefined;
|
|
153
|
+
|
|
154
|
+
const upsert = async (input: RowOf<Client, Collection>) => {
|
|
155
|
+
const res = await client.from(collection).upsert(input).select();
|
|
156
|
+
const { data, error } = res;
|
|
157
|
+
if (data) {
|
|
158
|
+
const created = data[0];
|
|
159
|
+
return created;
|
|
160
|
+
} else {
|
|
161
|
+
throw new Error(error?.message);
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
const create = !actions || actions.includes('create') ? upsert : undefined;
|
|
165
|
+
const update = !actions || actions.includes('update') ? upsert : undefined;
|
|
166
|
+
const deleteFn =
|
|
167
|
+
!actions || actions.includes('delete')
|
|
168
|
+
? async (input: RowOf<Client, Collection>) => {
|
|
169
|
+
const id = input.id;
|
|
170
|
+
const from = client.from(collection);
|
|
171
|
+
const res = await (changesSince === 'last-sync' ? from.update({ deleted: true }) : from.delete())
|
|
172
|
+
.eq('id', id)
|
|
173
|
+
.select();
|
|
174
|
+
const { data, error } = res;
|
|
175
|
+
if (data) {
|
|
176
|
+
const created = data[0];
|
|
177
|
+
return created;
|
|
178
|
+
} else {
|
|
179
|
+
throw new Error(error?.message);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
: undefined;
|
|
183
|
+
const subscribe = realtime
|
|
184
|
+
? ({ node, update }: SyncedSubscribeParams) => {
|
|
185
|
+
const { filter, schema } = realtime;
|
|
186
|
+
const channel = client
|
|
187
|
+
.channel(`LS_${node.key || ''}${channelNum++}`)
|
|
188
|
+
.on(
|
|
189
|
+
'postgres_changes',
|
|
190
|
+
{
|
|
191
|
+
event: '*',
|
|
192
|
+
table: collection,
|
|
193
|
+
schema: schema || 'public',
|
|
194
|
+
filter: filter || undefined,
|
|
195
|
+
},
|
|
196
|
+
(payload) => {
|
|
197
|
+
const { eventType, new: value, old } = payload;
|
|
198
|
+
if (eventType === 'INSERT' || eventType === 'UPDATE') {
|
|
199
|
+
const cur = getNodeValue(node)?.[value.id];
|
|
200
|
+
const curDateStr =
|
|
201
|
+
cur &&
|
|
202
|
+
((fieldUpdatedAt && cur[fieldUpdatedAt]) ||
|
|
203
|
+
fieldCreatedAt ||
|
|
204
|
+
cur[fieldCreatedAt as any]);
|
|
205
|
+
const valueDateStr =
|
|
206
|
+
(fieldUpdatedAt && value[fieldUpdatedAt]) ||
|
|
207
|
+
(fieldCreatedAt && value[fieldCreatedAt]);
|
|
208
|
+
const valueDate = +new Date(valueDateStr);
|
|
209
|
+
// Check if new or newer than last seen locally
|
|
210
|
+
if (valueDateStr && (!curDateStr || valueDate > +new Date(curDateStr))) {
|
|
211
|
+
// Update local with the new value
|
|
212
|
+
update({
|
|
213
|
+
value: { [value.id]: value },
|
|
214
|
+
lastSync: valueDate,
|
|
215
|
+
mode: 'merge',
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
} else if (eventType === 'DELETE') {
|
|
219
|
+
const { id } = old;
|
|
220
|
+
update({
|
|
221
|
+
value: { [id]: symbolDelete },
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
)
|
|
226
|
+
.subscribe();
|
|
227
|
+
|
|
228
|
+
return channel.unsubscribe;
|
|
229
|
+
}
|
|
230
|
+
: undefined;
|
|
231
|
+
|
|
232
|
+
return syncedCrud<RowOf<Client, Collection>, RowOf<Client, Collection>, AsOption>({
|
|
233
|
+
...rest,
|
|
234
|
+
list,
|
|
235
|
+
create,
|
|
236
|
+
update,
|
|
237
|
+
delete: deleteFn,
|
|
238
|
+
onSaved: (saved) => {
|
|
239
|
+
// Update the local timestamps with server response
|
|
240
|
+
if (fieldCreatedAt || fieldUpdatedAt) {
|
|
241
|
+
const ret: any = {
|
|
242
|
+
id: saved.id,
|
|
243
|
+
};
|
|
244
|
+
if (fieldCreatedAt) {
|
|
245
|
+
ret[fieldCreatedAt] = fieldCreatedAt;
|
|
246
|
+
}
|
|
247
|
+
if (fieldUpdatedAt) {
|
|
248
|
+
ret[fieldUpdatedAt] = fieldUpdatedAt;
|
|
249
|
+
}
|
|
250
|
+
return ret;
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
subscribe,
|
|
254
|
+
fieldCreatedAt,
|
|
255
|
+
fieldUpdatedAt,
|
|
256
|
+
updatePartial: true,
|
|
257
|
+
generateId,
|
|
258
|
+
waitFor: () => isEnabled$.get() && (waitFor ? computeSelector(waitFor) : true),
|
|
259
|
+
waitForSet: () => isEnabled$.get() && (waitForSet ? computeSelector(waitForSet) : true),
|
|
260
|
+
});
|
|
261
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
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
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
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
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { SyncTransform, SyncedGetParams, SyncedOptions, SyncedSetParams } from '@legendapp/state/sync';
|
|
2
|
+
export type CrudAsOption = 'Map' | 'object' | 'first';
|
|
3
|
+
export type CrudResult<T> = T;
|
|
4
|
+
export interface SyncedCrudPropsSingle<TRemote, TLocal> {
|
|
5
|
+
get?: (params: SyncedGetParams) => Promise<CrudResult<TRemote | null>> | CrudResult<TRemote | null>;
|
|
6
|
+
initial?: InitialValue<TLocal, 'first'>;
|
|
7
|
+
as?: never | 'first';
|
|
8
|
+
}
|
|
9
|
+
export interface SyncedCrudPropsMany<TRemote, TLocal, TAsOption extends CrudAsOption> {
|
|
10
|
+
list?: (params: SyncedGetParams) => Promise<CrudResult<TRemote[] | null>> | CrudResult<TRemote[] | null>;
|
|
11
|
+
as?: TAsOption;
|
|
12
|
+
initial?: InitialValue<TLocal, TAsOption>;
|
|
13
|
+
}
|
|
14
|
+
export interface SyncedCrudPropsBase<TRemote extends {
|
|
15
|
+
id: string | number;
|
|
16
|
+
}, TLocal = TRemote> extends Omit<SyncedOptions<TLocal>, 'get' | 'set' | 'transform' | 'initial'> {
|
|
17
|
+
create?(input: TRemote, params: SyncedSetParams<TRemote>): Promise<CrudResult<TRemote> | null | undefined>;
|
|
18
|
+
update?(input: Partial<TRemote>, params: SyncedSetParams<TRemote>): Promise<CrudResult<Partial<TRemote> | null | undefined>>;
|
|
19
|
+
delete?(input: TRemote, params: SyncedSetParams<TRemote>): Promise<CrudResult<any>>;
|
|
20
|
+
onSaved?(saved: TLocal, input: TRemote, isCreate: boolean): Partial<TLocal> | void;
|
|
21
|
+
transform?: SyncTransform<TLocal, TRemote>;
|
|
22
|
+
fieldUpdatedAt?: string;
|
|
23
|
+
fieldCreatedAt?: string;
|
|
24
|
+
updatePartial?: boolean;
|
|
25
|
+
changesSince?: 'all' | 'last-sync';
|
|
26
|
+
generateId?: () => string | number;
|
|
27
|
+
}
|
|
28
|
+
type InitialValue<T, TAsOption extends CrudAsOption> = TAsOption extends 'Map' ? Map<string, T> : TAsOption extends 'object' ? Record<string, T> : TAsOption extends 'first' ? T : T[];
|
|
29
|
+
export type SyncedCrudReturnType<TLocal, TAsOption extends CrudAsOption> = TAsOption extends 'Map' ? Map<string, TLocal> : TAsOption extends 'object' ? Record<string, TLocal> : TAsOption extends 'first' ? TLocal : TLocal[];
|
|
30
|
+
export declare function createTransform<T extends Record<string, any>, T2 extends Record<string, any>>(...keys: (keyof T | {
|
|
31
|
+
from: keyof T;
|
|
32
|
+
to: keyof T2;
|
|
33
|
+
})[]): SyncTransform<T2, T>;
|
|
34
|
+
export declare function combineTransforms<T, T2>(transform1: SyncTransform<T2, T>, ...transforms: Partial<SyncTransform<T2, T>>[]): SyncTransform<T2, T>;
|
|
35
|
+
export declare function syncedCrud<TRemote extends {
|
|
36
|
+
id: string | number;
|
|
37
|
+
}, TLocal = TRemote>(props: SyncedCrudPropsBase<TRemote, TLocal> & SyncedCrudPropsSingle<TRemote, TLocal>): SyncedCrudReturnType<TLocal, 'first'>;
|
|
38
|
+
export declare function syncedCrud<TRemote extends {
|
|
39
|
+
id: string | number;
|
|
40
|
+
}, TLocal = TRemote, TAsOption extends CrudAsOption = 'object'>(props: SyncedCrudPropsBase<TRemote, TLocal> & SyncedCrudPropsMany<TRemote, TLocal, TAsOption>): SyncedCrudReturnType<TLocal, Exclude<TAsOption, 'first'>>;
|
|
41
|
+
export {};
|