@legendapp/state 3.0.0-alpha.3 → 3.0.0-alpha.30
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/CHANGELOG.md +831 -1
- package/LICENSE +21 -1
- package/README.md +141 -1
- package/babel.js +0 -2
- package/babel.mjs +0 -2
- package/config/enable$GetSet.js +2 -1
- package/config/enable$GetSet.mjs +2 -1
- package/config/enableReactTracking.js +2 -1
- package/config/enableReactTracking.mjs +2 -1
- package/config/enableReactUse.js +2 -1
- package/config/enableReactUse.mjs +2 -1
- package/config/enable_PeekAssign.js +2 -1
- package/config/enable_PeekAssign.mjs +2 -1
- package/config.d.mts +13 -0
- package/config.d.ts +13 -0
- package/config.js +2052 -0
- package/config.mjs +2050 -0
- package/helpers/trackHistory.js +2 -2
- package/helpers/trackHistory.mjs +2 -2
- package/index.d.mts +21 -302
- package/index.d.ts +21 -302
- package/index.js +274 -318
- package/index.mjs +275 -317
- package/observableInterfaces-Dilj6F92.d.mts +282 -0
- package/observableInterfaces-Dilj6F92.d.ts +282 -0
- package/package.json +11 -1
- package/persist-plugins/async-storage.d.mts +6 -3
- package/persist-plugins/async-storage.d.ts +6 -3
- package/persist-plugins/async-storage.js +12 -4
- package/persist-plugins/async-storage.mjs +12 -5
- package/persist-plugins/indexeddb.d.mts +6 -4
- package/persist-plugins/indexeddb.d.ts +6 -4
- package/persist-plugins/indexeddb.js +16 -6
- package/persist-plugins/indexeddb.mjs +16 -7
- package/persist-plugins/mmkv.d.mts +5 -1
- package/persist-plugins/mmkv.d.ts +5 -1
- package/persist-plugins/mmkv.js +14 -5
- package/persist-plugins/mmkv.mjs +14 -6
- package/react.d.mts +18 -14
- package/react.d.ts +18 -14
- package/react.js +57 -32
- package/react.mjs +58 -33
- package/sync-plugins/_transformObjectFields.d.mts +31 -0
- package/sync-plugins/_transformObjectFields.d.ts +31 -0
- package/sync-plugins/_transformObjectFields.js +114 -0
- package/sync-plugins/_transformObjectFields.mjs +110 -0
- package/sync-plugins/crud.d.mts +15 -23
- package/sync-plugins/crud.d.ts +15 -23
- package/sync-plugins/crud.js +213 -134
- package/sync-plugins/crud.mjs +214 -135
- package/sync-plugins/fetch.js +12 -8
- package/sync-plugins/fetch.mjs +13 -9
- package/sync-plugins/firebase.d.mts +26 -0
- package/sync-plugins/firebase.d.ts +26 -0
- package/sync-plugins/firebase.js +373 -0
- package/sync-plugins/firebase.mjs +368 -0
- package/sync-plugins/keel.d.mts +27 -10
- package/sync-plugins/keel.d.ts +27 -10
- package/sync-plugins/keel.js +40 -21
- package/sync-plugins/keel.mjs +40 -21
- package/sync-plugins/supabase.d.mts +12 -7
- package/sync-plugins/supabase.d.ts +12 -7
- package/sync-plugins/supabase.js +24 -13
- package/sync-plugins/supabase.mjs +25 -14
- package/sync-plugins/tanstack-query.d.mts +2 -2
- package/sync-plugins/tanstack-query.d.ts +2 -2
- package/sync-plugins/tanstack-query.js +3 -2
- package/sync-plugins/tanstack-query.mjs +3 -2
- package/sync-plugins/tanstack-react-query.d.mts +1 -1
- package/sync-plugins/tanstack-react-query.d.ts +1 -1
- package/sync.d.mts +68 -197
- package/sync.d.ts +68 -197
- package/sync.js +448 -283
- package/sync.mjs +454 -289
- package/types/babel.d.ts +12 -1
- package/.DS_Store +0 -0
- /package/config/{enable_GetSet.d.mts → enable$GetSet.d.mts} +0 -0
- /package/config/{enable_GetSet.d.ts → enable$GetSet.d.ts} +0 -0
package/sync-plugins/crud.d.mts
CHANGED
|
@@ -1,42 +1,38 @@
|
|
|
1
|
-
import { SyncedGetParams, SyncedOptions, SyncedSetParams } from '@legendapp/state/sync';
|
|
1
|
+
import { SyncedGetParams, SyncedOptions, SyncedSetParams, SyncedSubscribeParams } from '@legendapp/state/sync';
|
|
2
2
|
|
|
3
3
|
type CrudAsOption = 'Map' | 'object' | 'value' | 'array';
|
|
4
4
|
type CrudResult<T> = T;
|
|
5
|
-
interface SyncedCrudPropsSingle<TRemote, TLocal> {
|
|
6
|
-
get?: (params: SyncedGetParams) => Promise<CrudResult<TRemote | null>> | CrudResult<TRemote | null>;
|
|
5
|
+
interface SyncedCrudPropsSingle<TRemote extends object, TLocal> {
|
|
6
|
+
get?: (params: SyncedGetParams<TRemote>) => Promise<CrudResult<TRemote | null>> | CrudResult<TRemote | null>;
|
|
7
7
|
initial?: InitialValue<TLocal, 'value'>;
|
|
8
8
|
as?: never | 'value';
|
|
9
9
|
}
|
|
10
|
-
interface SyncedCrudPropsMany<TRemote, TLocal, TAsOption extends CrudAsOption> {
|
|
11
|
-
list?: (params: SyncedGetParams) => Promise<CrudResult<TRemote[] | null>> | CrudResult<TRemote[] | null>;
|
|
10
|
+
interface SyncedCrudPropsMany<TRemote extends object, TLocal, TAsOption extends CrudAsOption> {
|
|
11
|
+
list?: (params: SyncedGetParams<TRemote>) => Promise<CrudResult<TRemote[] | null>> | CrudResult<TRemote[] | null>;
|
|
12
12
|
as?: TAsOption;
|
|
13
13
|
initial?: InitialValue<TLocal, TAsOption>;
|
|
14
14
|
}
|
|
15
|
-
interface SyncedCrudOnSavedParams<TRemote extends {
|
|
16
|
-
id: string | number;
|
|
17
|
-
}, TLocal> {
|
|
15
|
+
interface SyncedCrudOnSavedParams<TRemote extends object, TLocal> {
|
|
18
16
|
saved: TLocal;
|
|
19
17
|
input: TRemote;
|
|
20
18
|
currentValue: TLocal;
|
|
21
19
|
isCreate: boolean;
|
|
22
20
|
props: SyncedCrudPropsBase<TRemote, TLocal>;
|
|
23
21
|
}
|
|
24
|
-
interface SyncedCrudPropsBase<TRemote extends {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
update?(input: Partial<TRemote>, params: SyncedSetParams<TRemote>): Promise<CrudResult<Partial<TRemote> | null | undefined>>;
|
|
29
|
-
delete?(input: {
|
|
30
|
-
id: TRemote['id'];
|
|
31
|
-
}, params: SyncedSetParams<TRemote>): Promise<CrudResult<any>>;
|
|
22
|
+
interface SyncedCrudPropsBase<TRemote extends object, TLocal = TRemote> extends Omit<SyncedOptions<TRemote, TLocal>, 'get' | 'set' | 'initial' | 'subscribe'> {
|
|
23
|
+
create?(input: TRemote, params: SyncedSetParams<TRemote>): Promise<CrudResult<TRemote> | null | undefined | void>;
|
|
24
|
+
update?(input: Partial<TRemote>, params: SyncedSetParams<TRemote>): Promise<CrudResult<Partial<TRemote> | null | undefined | void>>;
|
|
25
|
+
delete?(input: TRemote, params: SyncedSetParams<TRemote>): Promise<any>;
|
|
32
26
|
onSaved?(params: SyncedCrudOnSavedParams<TRemote, TLocal>): Partial<TLocal> | void;
|
|
33
|
-
|
|
27
|
+
fieldId?: string;
|
|
34
28
|
fieldUpdatedAt?: string;
|
|
35
29
|
fieldCreatedAt?: string;
|
|
36
30
|
fieldDeleted?: string;
|
|
31
|
+
fieldDeletedList?: string;
|
|
37
32
|
updatePartial?: boolean;
|
|
38
33
|
changesSince?: 'all' | 'last-sync';
|
|
39
34
|
generateId?: () => string | number;
|
|
35
|
+
subscribe?: (params: SyncedSubscribeParams<TRemote[]>) => (() => void) | void;
|
|
40
36
|
}
|
|
41
37
|
type InitialValue<TLocal, TAsOption extends CrudAsOption> = TAsOption extends 'Map' ? Map<string | number, TLocal> : TAsOption extends 'object' ? Record<string | number, TLocal> : TAsOption extends 'value' ? TLocal : TLocal[];
|
|
42
38
|
type SyncedCrudReturnType<TLocal, TAsOption extends CrudAsOption> = TAsOption extends 'Map' ? Map<TLocal extends {
|
|
@@ -44,11 +40,7 @@ type SyncedCrudReturnType<TLocal, TAsOption extends CrudAsOption> = TAsOption ex
|
|
|
44
40
|
} ? number : string, TLocal> : TAsOption extends 'object' ? Record<TLocal extends {
|
|
45
41
|
id: number;
|
|
46
42
|
} ? number : string, TLocal> : TAsOption extends 'value' ? TLocal : TLocal[];
|
|
47
|
-
declare function syncedCrud<TRemote extends
|
|
48
|
-
|
|
49
|
-
}, TLocal = TRemote>(props: SyncedCrudPropsBase<TRemote, TLocal> & SyncedCrudPropsSingle<TRemote, TLocal>): SyncedCrudReturnType<TLocal, 'value'>;
|
|
50
|
-
declare function syncedCrud<TRemote extends {
|
|
51
|
-
id: string | number;
|
|
52
|
-
}, TLocal = TRemote, TAsOption extends CrudAsOption = 'object'>(props: SyncedCrudPropsBase<TRemote, TLocal> & SyncedCrudPropsMany<TRemote, TLocal, TAsOption>): SyncedCrudReturnType<TLocal, Exclude<TAsOption, 'value'>>;
|
|
43
|
+
declare function syncedCrud<TRemote extends object, TLocal = TRemote>(props: SyncedCrudPropsBase<TRemote, TLocal> & SyncedCrudPropsSingle<TRemote, TLocal>): SyncedCrudReturnType<TLocal, 'value'>;
|
|
44
|
+
declare function syncedCrud<TRemote extends object, TLocal = TRemote, TAsOption extends CrudAsOption = 'object'>(props: SyncedCrudPropsBase<TRemote, TLocal> & SyncedCrudPropsMany<TRemote, TLocal, TAsOption>): SyncedCrudReturnType<TLocal, Exclude<TAsOption, 'value'>>;
|
|
53
45
|
|
|
54
46
|
export { type CrudAsOption, type CrudResult, type SyncedCrudOnSavedParams, type SyncedCrudPropsBase, type SyncedCrudPropsMany, type SyncedCrudPropsSingle, type SyncedCrudReturnType, syncedCrud };
|
package/sync-plugins/crud.d.ts
CHANGED
|
@@ -1,42 +1,38 @@
|
|
|
1
|
-
import { SyncedGetParams, SyncedOptions, SyncedSetParams } from '@legendapp/state/sync';
|
|
1
|
+
import { SyncedGetParams, SyncedOptions, SyncedSetParams, SyncedSubscribeParams } from '@legendapp/state/sync';
|
|
2
2
|
|
|
3
3
|
type CrudAsOption = 'Map' | 'object' | 'value' | 'array';
|
|
4
4
|
type CrudResult<T> = T;
|
|
5
|
-
interface SyncedCrudPropsSingle<TRemote, TLocal> {
|
|
6
|
-
get?: (params: SyncedGetParams) => Promise<CrudResult<TRemote | null>> | CrudResult<TRemote | null>;
|
|
5
|
+
interface SyncedCrudPropsSingle<TRemote extends object, TLocal> {
|
|
6
|
+
get?: (params: SyncedGetParams<TRemote>) => Promise<CrudResult<TRemote | null>> | CrudResult<TRemote | null>;
|
|
7
7
|
initial?: InitialValue<TLocal, 'value'>;
|
|
8
8
|
as?: never | 'value';
|
|
9
9
|
}
|
|
10
|
-
interface SyncedCrudPropsMany<TRemote, TLocal, TAsOption extends CrudAsOption> {
|
|
11
|
-
list?: (params: SyncedGetParams) => Promise<CrudResult<TRemote[] | null>> | CrudResult<TRemote[] | null>;
|
|
10
|
+
interface SyncedCrudPropsMany<TRemote extends object, TLocal, TAsOption extends CrudAsOption> {
|
|
11
|
+
list?: (params: SyncedGetParams<TRemote>) => Promise<CrudResult<TRemote[] | null>> | CrudResult<TRemote[] | null>;
|
|
12
12
|
as?: TAsOption;
|
|
13
13
|
initial?: InitialValue<TLocal, TAsOption>;
|
|
14
14
|
}
|
|
15
|
-
interface SyncedCrudOnSavedParams<TRemote extends {
|
|
16
|
-
id: string | number;
|
|
17
|
-
}, TLocal> {
|
|
15
|
+
interface SyncedCrudOnSavedParams<TRemote extends object, TLocal> {
|
|
18
16
|
saved: TLocal;
|
|
19
17
|
input: TRemote;
|
|
20
18
|
currentValue: TLocal;
|
|
21
19
|
isCreate: boolean;
|
|
22
20
|
props: SyncedCrudPropsBase<TRemote, TLocal>;
|
|
23
21
|
}
|
|
24
|
-
interface SyncedCrudPropsBase<TRemote extends {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
update?(input: Partial<TRemote>, params: SyncedSetParams<TRemote>): Promise<CrudResult<Partial<TRemote> | null | undefined>>;
|
|
29
|
-
delete?(input: {
|
|
30
|
-
id: TRemote['id'];
|
|
31
|
-
}, params: SyncedSetParams<TRemote>): Promise<CrudResult<any>>;
|
|
22
|
+
interface SyncedCrudPropsBase<TRemote extends object, TLocal = TRemote> extends Omit<SyncedOptions<TRemote, TLocal>, 'get' | 'set' | 'initial' | 'subscribe'> {
|
|
23
|
+
create?(input: TRemote, params: SyncedSetParams<TRemote>): Promise<CrudResult<TRemote> | null | undefined | void>;
|
|
24
|
+
update?(input: Partial<TRemote>, params: SyncedSetParams<TRemote>): Promise<CrudResult<Partial<TRemote> | null | undefined | void>>;
|
|
25
|
+
delete?(input: TRemote, params: SyncedSetParams<TRemote>): Promise<any>;
|
|
32
26
|
onSaved?(params: SyncedCrudOnSavedParams<TRemote, TLocal>): Partial<TLocal> | void;
|
|
33
|
-
|
|
27
|
+
fieldId?: string;
|
|
34
28
|
fieldUpdatedAt?: string;
|
|
35
29
|
fieldCreatedAt?: string;
|
|
36
30
|
fieldDeleted?: string;
|
|
31
|
+
fieldDeletedList?: string;
|
|
37
32
|
updatePartial?: boolean;
|
|
38
33
|
changesSince?: 'all' | 'last-sync';
|
|
39
34
|
generateId?: () => string | number;
|
|
35
|
+
subscribe?: (params: SyncedSubscribeParams<TRemote[]>) => (() => void) | void;
|
|
40
36
|
}
|
|
41
37
|
type InitialValue<TLocal, TAsOption extends CrudAsOption> = TAsOption extends 'Map' ? Map<string | number, TLocal> : TAsOption extends 'object' ? Record<string | number, TLocal> : TAsOption extends 'value' ? TLocal : TLocal[];
|
|
42
38
|
type SyncedCrudReturnType<TLocal, TAsOption extends CrudAsOption> = TAsOption extends 'Map' ? Map<TLocal extends {
|
|
@@ -44,11 +40,7 @@ type SyncedCrudReturnType<TLocal, TAsOption extends CrudAsOption> = TAsOption ex
|
|
|
44
40
|
} ? number : string, TLocal> : TAsOption extends 'object' ? Record<TLocal extends {
|
|
45
41
|
id: number;
|
|
46
42
|
} ? number : string, TLocal> : TAsOption extends 'value' ? TLocal : TLocal[];
|
|
47
|
-
declare function syncedCrud<TRemote extends
|
|
48
|
-
|
|
49
|
-
}, TLocal = TRemote>(props: SyncedCrudPropsBase<TRemote, TLocal> & SyncedCrudPropsSingle<TRemote, TLocal>): SyncedCrudReturnType<TLocal, 'value'>;
|
|
50
|
-
declare function syncedCrud<TRemote extends {
|
|
51
|
-
id: string | number;
|
|
52
|
-
}, TLocal = TRemote, TAsOption extends CrudAsOption = 'object'>(props: SyncedCrudPropsBase<TRemote, TLocal> & SyncedCrudPropsMany<TRemote, TLocal, TAsOption>): SyncedCrudReturnType<TLocal, Exclude<TAsOption, 'value'>>;
|
|
43
|
+
declare function syncedCrud<TRemote extends object, TLocal = TRemote>(props: SyncedCrudPropsBase<TRemote, TLocal> & SyncedCrudPropsSingle<TRemote, TLocal>): SyncedCrudReturnType<TLocal, 'value'>;
|
|
44
|
+
declare function syncedCrud<TRemote extends object, TLocal = TRemote, TAsOption extends CrudAsOption = 'object'>(props: SyncedCrudPropsBase<TRemote, TLocal> & SyncedCrudPropsMany<TRemote, TLocal, TAsOption>): SyncedCrudReturnType<TLocal, Exclude<TAsOption, 'value'>>;
|
|
53
45
|
|
|
54
46
|
export { type CrudAsOption, type CrudResult, type SyncedCrudOnSavedParams, type SyncedCrudPropsBase, type SyncedCrudPropsMany, type SyncedCrudPropsSingle, type SyncedCrudReturnType, syncedCrud };
|
package/sync-plugins/crud.js
CHANGED
|
@@ -8,30 +8,21 @@ var { clone } = state.internal;
|
|
|
8
8
|
function transformOut(data, transform) {
|
|
9
9
|
return transform ? transform(clone(data)) : data;
|
|
10
10
|
}
|
|
11
|
-
function ensureId(obj, generateId) {
|
|
12
|
-
if (!obj
|
|
13
|
-
obj
|
|
11
|
+
function ensureId(obj, fieldId, generateId) {
|
|
12
|
+
if (!obj[fieldId]) {
|
|
13
|
+
obj[fieldId] = generateId();
|
|
14
14
|
}
|
|
15
|
-
return obj
|
|
15
|
+
return obj[fieldId];
|
|
16
16
|
}
|
|
17
|
-
function
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
});
|
|
25
|
-
} else if (mode === "createdUpdatedAt") {
|
|
26
|
-
Object.keys(saved).forEach((key) => {
|
|
27
|
-
const k = key;
|
|
28
|
-
const keyLower = key.toLowerCase();
|
|
29
|
-
if ((key === props.fieldCreatedAt || key === props.fieldUpdatedAt || keyLower.endsWith("createdat") || keyLower.endsWith("updatedat") || keyLower.endsWith("created_at") || keyLower.endsWith("updated_at")) && saved[k] instanceof Date) {
|
|
30
|
-
savedOut[k] = saved[k];
|
|
31
|
-
}
|
|
32
|
-
});
|
|
17
|
+
function computeLastSync(data, fieldUpdatedAt, fieldCreatedAt) {
|
|
18
|
+
let newLastSync = 0;
|
|
19
|
+
for (let i = 0; i < data.length; i++) {
|
|
20
|
+
const updated = (fieldUpdatedAt ? data[i][fieldUpdatedAt] : 0) || (fieldCreatedAt ? data[i][fieldCreatedAt] : 0);
|
|
21
|
+
if (updated) {
|
|
22
|
+
newLastSync = Math.max(newLastSync, +new Date(updated));
|
|
23
|
+
}
|
|
33
24
|
}
|
|
34
|
-
return
|
|
25
|
+
return newLastSync;
|
|
35
26
|
}
|
|
36
27
|
function syncedCrud(props) {
|
|
37
28
|
const {
|
|
@@ -41,165 +32,220 @@ function syncedCrud(props) {
|
|
|
41
32
|
update: updateFn,
|
|
42
33
|
delete: deleteFn,
|
|
43
34
|
transform,
|
|
35
|
+
fieldId: fieldIdProp,
|
|
44
36
|
fieldCreatedAt,
|
|
45
37
|
fieldUpdatedAt,
|
|
46
38
|
fieldDeleted,
|
|
39
|
+
fieldDeletedList,
|
|
47
40
|
updatePartial,
|
|
41
|
+
subscribe: subscribeProp,
|
|
48
42
|
onSaved,
|
|
49
|
-
onSavedUpdate,
|
|
50
43
|
mode: modeParam,
|
|
51
44
|
changesSince,
|
|
52
45
|
generateId,
|
|
53
46
|
...rest
|
|
54
47
|
} = props;
|
|
48
|
+
const fieldId = fieldIdProp || "id";
|
|
55
49
|
let asType = props.as;
|
|
56
50
|
if (!asType) {
|
|
57
51
|
asType = getFn ? "value" : "object";
|
|
58
52
|
}
|
|
59
53
|
const asMap = asType === "Map";
|
|
60
54
|
const asArray = asType === "array";
|
|
61
|
-
const
|
|
55
|
+
const resultsToOutType = (results) => {
|
|
56
|
+
if (asType === "value") {
|
|
57
|
+
return results[0];
|
|
58
|
+
}
|
|
59
|
+
const out = asType === "array" ? [] : asMap ? /* @__PURE__ */ new Map() : {};
|
|
60
|
+
for (let i = 0; i < results.length; i++) {
|
|
61
|
+
let result = results[i];
|
|
62
|
+
const isObs = state.isObservable(result);
|
|
63
|
+
const value = isObs ? result.peek() : result;
|
|
64
|
+
if (value) {
|
|
65
|
+
result = !isObs && (fieldDeleted && result[fieldDeleted] || fieldDeletedList && result[fieldDeletedList] || result[state.symbolDelete]) ? state.internal.symbolDelete : result;
|
|
66
|
+
if (asArray) {
|
|
67
|
+
out.push(result);
|
|
68
|
+
} else if (asMap) {
|
|
69
|
+
out.set(value[fieldId], result);
|
|
70
|
+
} else {
|
|
71
|
+
out[value[fieldId]] = result;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return out;
|
|
76
|
+
};
|
|
77
|
+
const transformRows = (data) => {
|
|
78
|
+
return Promise.all(
|
|
79
|
+
data.map(
|
|
80
|
+
(value) => (
|
|
81
|
+
// Skip transforming any children with symbolDelete or fieldDeleted because they'll get deleted by resultsToOutType
|
|
82
|
+
value[state.symbolDelete] || fieldDeleted && value[fieldDeleted] || fieldDeletedList && value[fieldDeletedList] ? value : transform.load(value, "get")
|
|
83
|
+
)
|
|
84
|
+
)
|
|
85
|
+
);
|
|
86
|
+
};
|
|
87
|
+
const get = getFn || listFn ? (getParams) => {
|
|
62
88
|
const { updateLastSync, lastSync, value } = getParams;
|
|
63
89
|
if (listFn) {
|
|
64
90
|
const isLastSyncMode = changesSince === "last-sync";
|
|
65
91
|
if (isLastSyncMode && lastSync) {
|
|
66
92
|
getParams.mode = modeParam || (asType === "array" ? "append" : asType === "value" ? "set" : "assign");
|
|
67
93
|
}
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
94
|
+
const listPromise = listFn(getParams);
|
|
95
|
+
const toOut = (transformed) => {
|
|
96
|
+
var _a;
|
|
97
|
+
if (asType === "value") {
|
|
98
|
+
return transformed.length > 0 ? transformed[0] : (_a = (isLastSyncMode && lastSync || fieldDeleted) && value) != null ? _a : null;
|
|
99
|
+
} else {
|
|
100
|
+
return resultsToOutType(transformed);
|
|
74
101
|
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
}
|
|
83
|
-
if (asType === "value") {
|
|
84
|
-
return transformed.length > 0 ? transformed[0] : isLastSyncMode && lastSync && value || null;
|
|
85
|
-
} else {
|
|
86
|
-
const results = transformed.map(
|
|
87
|
-
(result) => result[fieldDeleted] || result.__deleted ? state.internal.symbolDelete : result
|
|
88
|
-
);
|
|
89
|
-
const out = asType === "array" ? [] : asMap ? /* @__PURE__ */ new Map() : {};
|
|
90
|
-
for (let i = 0; i < results.length; i++) {
|
|
91
|
-
let result = results[i];
|
|
92
|
-
result = result[fieldDeleted] || result.__deleted ? state.internal.symbolDelete : result;
|
|
93
|
-
if (asArray) {
|
|
94
|
-
out.push(result);
|
|
95
|
-
} else if (asMap) {
|
|
96
|
-
out.set(result.id, result);
|
|
97
|
-
} else {
|
|
98
|
-
out[result.id] = result;
|
|
102
|
+
};
|
|
103
|
+
const processResults = (data) => {
|
|
104
|
+
data || (data = []);
|
|
105
|
+
if (fieldUpdatedAt) {
|
|
106
|
+
const newLastSync = computeLastSync(data, fieldUpdatedAt, fieldCreatedAt);
|
|
107
|
+
if (newLastSync && newLastSync !== lastSync) {
|
|
108
|
+
updateLastSync(newLastSync);
|
|
99
109
|
}
|
|
100
110
|
}
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
} else if (getFn) {
|
|
104
|
-
const data = await getFn(getParams);
|
|
105
|
-
let transformed = data;
|
|
106
|
-
if (data) {
|
|
107
|
-
const newLastSync = data[fieldUpdatedAt] || data[fieldCreatedAt];
|
|
108
|
-
if (newLastSync && newLastSync !== lastSync) {
|
|
109
|
-
updateLastSync(newLastSync);
|
|
110
|
-
}
|
|
111
|
+
let transformed = data;
|
|
111
112
|
if (transform == null ? void 0 : transform.load) {
|
|
112
|
-
transformed =
|
|
113
|
+
transformed = transformRows(data);
|
|
113
114
|
}
|
|
114
|
-
|
|
115
|
-
|
|
115
|
+
return state.isPromise(transformed) ? transformed.then(toOut) : toOut(transformed);
|
|
116
|
+
};
|
|
117
|
+
return state.isPromise(listPromise) ? listPromise.then(processResults) : processResults(listPromise);
|
|
118
|
+
} else if (getFn) {
|
|
119
|
+
const dataPromise = getFn(getParams);
|
|
120
|
+
const processData = (data) => {
|
|
121
|
+
let transformed = data;
|
|
122
|
+
if (data) {
|
|
123
|
+
const newLastSync = data[fieldUpdatedAt] || data[fieldCreatedAt];
|
|
124
|
+
if (newLastSync && newLastSync !== lastSync) {
|
|
125
|
+
updateLastSync(newLastSync);
|
|
126
|
+
}
|
|
127
|
+
if (transform == null ? void 0 : transform.load) {
|
|
128
|
+
transformed = transform.load(data, "get");
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return transformed;
|
|
132
|
+
};
|
|
133
|
+
return state.isPromise(dataPromise) ? dataPromise.then(processData) : processData(dataPromise);
|
|
116
134
|
}
|
|
117
135
|
} : void 0;
|
|
118
136
|
const set = createFn || updateFn || deleteFn ? async (params) => {
|
|
119
|
-
const { value, changes, update, retryAsCreate,
|
|
137
|
+
const { value, changes, update, retryAsCreate, node } = params;
|
|
120
138
|
const creates = /* @__PURE__ */ new Map();
|
|
121
139
|
const updates = /* @__PURE__ */ new Map();
|
|
122
140
|
const deletes = /* @__PURE__ */ new Set();
|
|
123
|
-
|
|
141
|
+
const getUpdateValue = (itemValue, prev) => {
|
|
142
|
+
return updatePartial ? Object.assign(
|
|
143
|
+
sync.diffObjects(
|
|
144
|
+
prev,
|
|
145
|
+
itemValue,
|
|
146
|
+
/*deep*/
|
|
147
|
+
true
|
|
148
|
+
),
|
|
149
|
+
itemValue[fieldId] ? { [fieldId]: itemValue[fieldId] } : {}
|
|
150
|
+
) : itemValue;
|
|
151
|
+
};
|
|
152
|
+
changes.forEach((change) => {
|
|
153
|
+
const { path, prevAtPath, valueAtPath, pathTypes } = change;
|
|
124
154
|
if (asType === "value") {
|
|
125
155
|
if (value) {
|
|
126
|
-
let id = value == null ? void 0 : value
|
|
156
|
+
let id = value == null ? void 0 : value[fieldId];
|
|
127
157
|
const isCreate = fieldCreatedAt ? !value[fieldCreatedAt] : !prevAtPath;
|
|
128
158
|
if (!id && generateId) {
|
|
129
|
-
id = ensureId(value, generateId);
|
|
159
|
+
id = ensureId(value, fieldId, generateId);
|
|
130
160
|
}
|
|
131
161
|
if (id) {
|
|
132
162
|
if (isCreate || retryAsCreate) {
|
|
133
163
|
creates.set(id, value);
|
|
134
164
|
} else if (path.length === 0) {
|
|
135
165
|
if (valueAtPath) {
|
|
136
|
-
updates.set(id, valueAtPath);
|
|
166
|
+
updates.set(id, getUpdateValue(valueAtPath, prevAtPath));
|
|
137
167
|
} else if (prevAtPath) {
|
|
138
|
-
deletes.add(prevAtPath
|
|
168
|
+
deletes.add(prevAtPath);
|
|
139
169
|
}
|
|
140
|
-
} else {
|
|
141
|
-
|
|
170
|
+
} else if (!updates.has(id)) {
|
|
171
|
+
const previous = state.applyChanges(
|
|
172
|
+
clone(value),
|
|
173
|
+
changes,
|
|
174
|
+
/*applyPrevious*/
|
|
175
|
+
true
|
|
176
|
+
);
|
|
177
|
+
updates.set(id, getUpdateValue(value, previous));
|
|
142
178
|
}
|
|
143
179
|
} else {
|
|
144
180
|
console.error("[legend-state]: added synced item without an id");
|
|
145
181
|
}
|
|
146
182
|
} else if (path.length === 0) {
|
|
147
|
-
|
|
148
|
-
if (id) {
|
|
149
|
-
deletes.add(id);
|
|
150
|
-
}
|
|
183
|
+
deletes.add(prevAtPath);
|
|
151
184
|
}
|
|
152
185
|
} else {
|
|
153
|
-
let itemsChanged =
|
|
186
|
+
let itemsChanged = [];
|
|
154
187
|
if (path.length === 0) {
|
|
155
|
-
|
|
188
|
+
const changed = asMap ? Array.from(valueAtPath.entries()) : Object.entries(valueAtPath);
|
|
189
|
+
for (let i = 0; i < changed.length; i++) {
|
|
190
|
+
const [key, value2] = changed[i];
|
|
156
191
|
const prev = asMap ? prevAtPath.get(key) : prevAtPath[key];
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
192
|
+
if (state.isNullOrUndefined(value2) && !state.isNullOrUndefined(prev)) {
|
|
193
|
+
deletes.add(prev);
|
|
194
|
+
return false;
|
|
195
|
+
} else {
|
|
196
|
+
const isDiff = !prevAtPath || !sync.deepEqual(value2, prev);
|
|
197
|
+
if (isDiff) {
|
|
198
|
+
itemsChanged.push([getUpdateValue(value2, prev), prev]);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
160
202
|
} else {
|
|
161
203
|
const itemKey = path[0];
|
|
162
204
|
const itemValue = asMap ? value.get(itemKey) : value[itemKey];
|
|
163
205
|
if (!itemValue) {
|
|
164
206
|
if (path.length === 1 && prevAtPath) {
|
|
165
|
-
deletes.add(
|
|
207
|
+
deletes.add(prevAtPath);
|
|
166
208
|
}
|
|
167
209
|
} else {
|
|
168
|
-
|
|
210
|
+
const previous = state.setAtPath(
|
|
211
|
+
clone(itemValue),
|
|
212
|
+
path.slice(1),
|
|
213
|
+
pathTypes.slice(1),
|
|
214
|
+
prevAtPath
|
|
215
|
+
);
|
|
216
|
+
itemsChanged = [[getUpdateValue(itemValue, previous), previous]];
|
|
169
217
|
}
|
|
170
218
|
}
|
|
171
|
-
itemsChanged == null ? void 0 : itemsChanged.forEach(([
|
|
172
|
-
|
|
173
|
-
|
|
219
|
+
itemsChanged == null ? void 0 : itemsChanged.forEach(([item, prev]) => {
|
|
220
|
+
const isCreate = fieldCreatedAt ? !item[fieldCreatedAt] && !(prev == null ? void 0 : prev[fieldCreatedAt]) : fieldUpdatedAt ? !item[fieldUpdatedAt] && !(prev == null ? void 0 : prev[fieldCreatedAt]) : state.isNullOrUndefined(prev);
|
|
221
|
+
if (isCreate) {
|
|
222
|
+
if (generateId) {
|
|
223
|
+
ensureId(item, fieldId, generateId);
|
|
224
|
+
}
|
|
225
|
+
if (!item.id) {
|
|
226
|
+
console.error("[legend-state]: added item without an id");
|
|
227
|
+
}
|
|
228
|
+
if (createFn) {
|
|
229
|
+
creates.set(item.id, item);
|
|
230
|
+
} else {
|
|
231
|
+
console.log("[legend-state] missing create function");
|
|
232
|
+
}
|
|
174
233
|
} else {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
if (!item.id) {
|
|
182
|
-
console.error("[legend-state]: added item without an id");
|
|
183
|
-
}
|
|
184
|
-
if (createFn) {
|
|
185
|
-
creates.set(item.id, item);
|
|
186
|
-
} else {
|
|
187
|
-
console.log("[legend-state] missing create function");
|
|
188
|
-
}
|
|
234
|
+
if (updateFn) {
|
|
235
|
+
updates.set(
|
|
236
|
+
item.id,
|
|
237
|
+
updates.has(item.id) ? Object.assign(updates.get(item.id), item) : item
|
|
238
|
+
);
|
|
189
239
|
} else {
|
|
190
|
-
|
|
191
|
-
updates.set(item.id, item);
|
|
192
|
-
} else {
|
|
193
|
-
console.log("[legend-state] missing update function");
|
|
194
|
-
}
|
|
240
|
+
console.log("[legend-state] missing update function");
|
|
195
241
|
}
|
|
196
242
|
}
|
|
197
243
|
});
|
|
198
244
|
}
|
|
199
245
|
});
|
|
200
246
|
const saveResult = async (itemKey, input, data, isCreate) => {
|
|
201
|
-
if (data
|
|
202
|
-
const saved = (transform == null ? void 0 : transform.load) ? transform.load(data, "set") : data;
|
|
247
|
+
if (data) {
|
|
248
|
+
const saved = (transform == null ? void 0 : transform.load) ? await transform.load(data, "set") : data;
|
|
203
249
|
const isChild = itemKey !== "undefined" && asType !== "value";
|
|
204
250
|
const currentPeeked = state.getNodeValue(node);
|
|
205
251
|
const currentValue = isChild ? currentPeeked == null ? void 0 : currentPeeked[itemKey] : currentPeeked;
|
|
@@ -210,17 +256,26 @@ function syncedCrud(props) {
|
|
|
210
256
|
isCreate,
|
|
211
257
|
props
|
|
212
258
|
};
|
|
213
|
-
let savedOut =
|
|
214
|
-
if (
|
|
215
|
-
savedOut =
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
259
|
+
let savedOut = saved;
|
|
260
|
+
if (savedOut && !state.isNullOrUndefined(currentValue)) {
|
|
261
|
+
savedOut = clone(savedOut);
|
|
262
|
+
Object.keys(savedOut).forEach((key) => {
|
|
263
|
+
const i = input[key];
|
|
264
|
+
const c = currentValue[key];
|
|
265
|
+
if (
|
|
266
|
+
// value is already the new value, can ignore
|
|
267
|
+
savedOut[key] === c || // user has changed local value
|
|
268
|
+
key !== "id" && i !== c
|
|
269
|
+
) {
|
|
270
|
+
delete savedOut[key];
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
if (onSaved) {
|
|
274
|
+
const ret = onSaved(dataOnSaved);
|
|
275
|
+
if (ret) {
|
|
276
|
+
savedOut = ret;
|
|
277
|
+
}
|
|
221
278
|
}
|
|
222
|
-
}
|
|
223
|
-
if (savedOut) {
|
|
224
279
|
const createdAt = fieldCreatedAt ? savedOut[fieldCreatedAt] : void 0;
|
|
225
280
|
const updatedAt = fieldUpdatedAt ? savedOut[fieldUpdatedAt] : void 0;
|
|
226
281
|
const value2 = itemKey !== "undefined" && asType !== "value" ? { [itemKey]: savedOut } : savedOut;
|
|
@@ -233,38 +288,62 @@ function syncedCrud(props) {
|
|
|
233
288
|
}
|
|
234
289
|
};
|
|
235
290
|
return Promise.all([
|
|
236
|
-
...Array.from(creates).map(([itemKey, itemValue]) => {
|
|
237
|
-
const createObj = transformOut(itemValue, transform == null ? void 0 : transform.save);
|
|
291
|
+
...Array.from(creates).map(async ([itemKey, itemValue]) => {
|
|
292
|
+
const createObj = await transformOut(itemValue, transform == null ? void 0 : transform.save);
|
|
238
293
|
return createFn(createObj, params).then(
|
|
239
294
|
(result) => saveResult(itemKey, createObj, result, true)
|
|
240
295
|
);
|
|
241
296
|
}),
|
|
242
|
-
...Array.from(updates).map(([itemKey, itemValue]) => {
|
|
243
|
-
const toSave =
|
|
244
|
-
|
|
245
|
-
{ id: itemValue.id }
|
|
246
|
-
) : itemValue;
|
|
247
|
-
const changed = transformOut(toSave, transform == null ? void 0 : transform.save);
|
|
297
|
+
...Array.from(updates).map(async ([itemKey, itemValue]) => {
|
|
298
|
+
const toSave = itemValue;
|
|
299
|
+
const changed = await transformOut(toSave, transform == null ? void 0 : transform.save);
|
|
248
300
|
if (Object.keys(changed).length > 0) {
|
|
249
301
|
return updateFn(changed, params).then(
|
|
250
302
|
(result) => result && saveResult(itemKey, changed, result, false)
|
|
251
303
|
);
|
|
252
304
|
}
|
|
253
305
|
}),
|
|
254
|
-
...Array.from(deletes).map((
|
|
255
|
-
if (
|
|
256
|
-
deleteFn
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
306
|
+
...Array.from(deletes).map((valuePrevious) => {
|
|
307
|
+
if (valuePrevious !== state.symbolDelete) {
|
|
308
|
+
if (deleteFn) {
|
|
309
|
+
deleteFn(valuePrevious, params);
|
|
310
|
+
} else if (fieldDeleted && updateFn) {
|
|
311
|
+
const valueId = valuePrevious[fieldId];
|
|
312
|
+
if (valueId) {
|
|
313
|
+
updateFn({ ...{ [fieldId]: valueId }, [fieldDeleted]: true }, params);
|
|
314
|
+
} else {
|
|
315
|
+
console.error("[legend-state]: deleting item without an id");
|
|
316
|
+
}
|
|
317
|
+
} else {
|
|
318
|
+
console.log("[legend-state] missing delete function");
|
|
319
|
+
}
|
|
261
320
|
}
|
|
262
321
|
})
|
|
263
322
|
]);
|
|
264
323
|
} : void 0;
|
|
324
|
+
const subscribe = subscribeProp ? (params) => subscribeProp({
|
|
325
|
+
...params,
|
|
326
|
+
update: async (paramsUpdate) => {
|
|
327
|
+
const paramsForUpdate = paramsUpdate;
|
|
328
|
+
const rows = paramsUpdate.value;
|
|
329
|
+
if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") {
|
|
330
|
+
if (!state.isArray(rows)) {
|
|
331
|
+
console.error("[legend-state] subscribe:update expects an array of changed items");
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
const newLastSync = computeLastSync(rows, fieldUpdatedAt, fieldCreatedAt);
|
|
335
|
+
if (newLastSync) {
|
|
336
|
+
paramsForUpdate.lastSync = newLastSync;
|
|
337
|
+
}
|
|
338
|
+
const rowsTransformed = (transform == null ? void 0 : transform.load) ? await transformRows(rows) : rows;
|
|
339
|
+
paramsForUpdate.value = resultsToOutType(rowsTransformed);
|
|
340
|
+
params.update(paramsForUpdate);
|
|
341
|
+
}
|
|
342
|
+
}) : void 0;
|
|
265
343
|
return sync.synced({
|
|
266
344
|
set,
|
|
267
345
|
get,
|
|
346
|
+
subscribe,
|
|
268
347
|
mode: modeParam,
|
|
269
348
|
...rest
|
|
270
349
|
});
|