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