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