@legendapp/state 3.0.0-alpha.2 → 3.0.0-alpha.20
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/helpers/trackHistory.js +2 -2
- package/helpers/trackHistory.mjs +2 -2
- package/index.d.mts +45 -32
- package/index.d.ts +45 -32
- package/index.js +234 -156
- package/index.mjs +234 -156
- package/package.json +6 -1
- package/persist-plugins/async-storage.d.mts +2 -2
- package/persist-plugins/async-storage.d.ts +2 -2
- package/persist-plugins/indexeddb.js +1 -1
- package/persist-plugins/indexeddb.mjs +1 -1
- package/react.d.mts +17 -14
- package/react.d.ts +17 -14
- package/react.js +55 -30
- package/react.mjs +56 -31
- 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 +14 -23
- package/sync-plugins/crud.d.ts +14 -23
- package/sync-plugins/crud.js +194 -129
- package/sync-plugins/crud.mjs +195 -130
- package/sync-plugins/firebase.d.mts +26 -0
- package/sync-plugins/firebase.d.ts +26 -0
- package/sync-plugins/firebase.js +365 -0
- package/sync-plugins/firebase.mjs +360 -0
- package/sync-plugins/keel.d.mts +24 -8
- package/sync-plugins/keel.d.ts +24 -8
- package/sync-plugins/keel.js +32 -16
- package/sync-plugins/keel.mjs +32 -16
- package/sync-plugins/supabase.d.mts +1 -1
- package/sync-plugins/supabase.d.ts +1 -1
- package/sync-plugins/supabase.js +5 -4
- package/sync-plugins/supabase.mjs +6 -5
- 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 +38 -185
- package/sync.d.ts +38 -185
- package/sync.js +354 -296
- package/sync.mjs +356 -297
- 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, 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,209 @@ 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,
|
|
45
37
|
updatePartial,
|
|
38
|
+
subscribe: subscribeProp,
|
|
46
39
|
onSaved,
|
|
47
|
-
onSavedUpdate,
|
|
48
40
|
mode: modeParam,
|
|
49
41
|
changesSince,
|
|
50
42
|
generateId,
|
|
51
43
|
...rest
|
|
52
44
|
} = props;
|
|
45
|
+
const fieldId = fieldIdProp || "id";
|
|
53
46
|
let asType = props.as;
|
|
54
47
|
if (!asType) {
|
|
55
48
|
asType = getFn ? "value" : "object";
|
|
56
49
|
}
|
|
57
50
|
const asMap = asType === "Map";
|
|
58
51
|
const asArray = asType === "array";
|
|
59
|
-
const
|
|
52
|
+
const resultsToOutType = (results) => {
|
|
53
|
+
if (asType === "value") {
|
|
54
|
+
return results[0];
|
|
55
|
+
}
|
|
56
|
+
const out = asType === "array" ? [] : asMap ? /* @__PURE__ */ new Map() : {};
|
|
57
|
+
for (let i = 0; i < results.length; i++) {
|
|
58
|
+
let result = results[i];
|
|
59
|
+
const isObs = isObservable(result);
|
|
60
|
+
const value = isObs ? result.peek() : result;
|
|
61
|
+
if (value) {
|
|
62
|
+
result = !isObs && (result[fieldDeleted] || result.__deleted) ? internal.symbolDelete : result;
|
|
63
|
+
if (asArray) {
|
|
64
|
+
out.push(result);
|
|
65
|
+
} else if (asMap) {
|
|
66
|
+
out.set(value[fieldId], result);
|
|
67
|
+
} else {
|
|
68
|
+
out[value[fieldId]] = result;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return out;
|
|
73
|
+
};
|
|
74
|
+
const get = getFn || listFn ? (getParams) => {
|
|
60
75
|
const { updateLastSync, lastSync, value } = getParams;
|
|
61
76
|
if (listFn) {
|
|
62
77
|
const isLastSyncMode = changesSince === "last-sync";
|
|
63
78
|
if (isLastSyncMode && lastSync) {
|
|
64
79
|
getParams.mode = modeParam || (asType === "array" ? "append" : asType === "value" ? "set" : "assign");
|
|
65
80
|
}
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
81
|
+
const listPromise = listFn(getParams);
|
|
82
|
+
const toOut = (transformed) => {
|
|
83
|
+
var _a;
|
|
84
|
+
if (asType === "value") {
|
|
85
|
+
return transformed.length > 0 ? transformed[0] : (_a = (isLastSyncMode && lastSync || fieldDeleted) && value) != null ? _a : null;
|
|
86
|
+
} else {
|
|
87
|
+
return resultsToOutType(transformed);
|
|
72
88
|
}
|
|
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;
|
|
89
|
+
};
|
|
90
|
+
const processTransformed = (data) => {
|
|
91
|
+
data || (data = []);
|
|
92
|
+
if (fieldUpdatedAt) {
|
|
93
|
+
const newLastSync = computeLastSync(data, fieldUpdatedAt, fieldCreatedAt);
|
|
94
|
+
if (newLastSync && newLastSync !== lastSync) {
|
|
95
|
+
updateLastSync(newLastSync);
|
|
97
96
|
}
|
|
98
97
|
}
|
|
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
|
-
}
|
|
98
|
+
let transformed = data;
|
|
109
99
|
if (transform == null ? void 0 : transform.load) {
|
|
110
|
-
transformed =
|
|
100
|
+
transformed = Promise.all(data.map((value2) => transform.load(value2, "get")));
|
|
111
101
|
}
|
|
112
|
-
|
|
113
|
-
|
|
102
|
+
return isPromise(transformed) ? transformed.then(toOut) : toOut(transformed);
|
|
103
|
+
};
|
|
104
|
+
return isPromise(listPromise) ? listPromise.then(processTransformed) : processTransformed(listPromise);
|
|
105
|
+
} else if (getFn) {
|
|
106
|
+
const dataPromise = getFn(getParams);
|
|
107
|
+
const processData = (data) => {
|
|
108
|
+
let transformed = data;
|
|
109
|
+
if (data) {
|
|
110
|
+
const newLastSync = data[fieldUpdatedAt] || data[fieldCreatedAt];
|
|
111
|
+
if (newLastSync && newLastSync !== lastSync) {
|
|
112
|
+
updateLastSync(newLastSync);
|
|
113
|
+
}
|
|
114
|
+
if (transform == null ? void 0 : transform.load) {
|
|
115
|
+
transformed = transform.load(data, "get");
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return transformed;
|
|
119
|
+
};
|
|
120
|
+
return isPromise(dataPromise) ? dataPromise.then(processData) : processData(dataPromise);
|
|
114
121
|
}
|
|
115
122
|
} : void 0;
|
|
116
123
|
const set = createFn || updateFn || deleteFn ? async (params) => {
|
|
117
|
-
const { value, changes, update, retryAsCreate,
|
|
124
|
+
const { value, changes, update, retryAsCreate, node } = params;
|
|
118
125
|
const creates = /* @__PURE__ */ new Map();
|
|
119
126
|
const updates = /* @__PURE__ */ new Map();
|
|
120
127
|
const deletes = /* @__PURE__ */ new Set();
|
|
121
|
-
|
|
128
|
+
const getUpdateValue = (itemValue, prev) => {
|
|
129
|
+
return updatePartial ? Object.assign(
|
|
130
|
+
diffObjects(
|
|
131
|
+
prev,
|
|
132
|
+
itemValue,
|
|
133
|
+
/*deep*/
|
|
134
|
+
true
|
|
135
|
+
),
|
|
136
|
+
itemValue[fieldId] ? { [fieldId]: itemValue[fieldId] } : {}
|
|
137
|
+
) : itemValue;
|
|
138
|
+
};
|
|
139
|
+
changes.forEach((change) => {
|
|
140
|
+
const { path, prevAtPath, valueAtPath, pathTypes } = change;
|
|
122
141
|
if (asType === "value") {
|
|
123
142
|
if (value) {
|
|
124
|
-
let id = value == null ? void 0 : value
|
|
143
|
+
let id = value == null ? void 0 : value[fieldId];
|
|
125
144
|
const isCreate = fieldCreatedAt ? !value[fieldCreatedAt] : !prevAtPath;
|
|
126
145
|
if (!id && generateId) {
|
|
127
|
-
id = ensureId(value, generateId);
|
|
146
|
+
id = ensureId(value, fieldId, generateId);
|
|
128
147
|
}
|
|
129
148
|
if (id) {
|
|
130
149
|
if (isCreate || retryAsCreate) {
|
|
131
150
|
creates.set(id, value);
|
|
132
151
|
} else if (path.length === 0) {
|
|
133
152
|
if (valueAtPath) {
|
|
134
|
-
updates.set(id, valueAtPath);
|
|
153
|
+
updates.set(id, getUpdateValue(valueAtPath, prevAtPath));
|
|
135
154
|
} else if (prevAtPath) {
|
|
136
155
|
deletes.add(prevAtPath == null ? void 0 : prevAtPath.id);
|
|
137
156
|
}
|
|
138
|
-
} else {
|
|
139
|
-
|
|
157
|
+
} else if (!updates.has(id)) {
|
|
158
|
+
const previous = applyChanges(
|
|
159
|
+
clone(value),
|
|
160
|
+
changes,
|
|
161
|
+
/*applyPrevious*/
|
|
162
|
+
true
|
|
163
|
+
);
|
|
164
|
+
updates.set(id, getUpdateValue(value, previous));
|
|
140
165
|
}
|
|
141
166
|
} else {
|
|
142
167
|
console.error("[legend-state]: added synced item without an id");
|
|
143
168
|
}
|
|
144
169
|
} else if (path.length === 0) {
|
|
145
|
-
|
|
146
|
-
if (id) {
|
|
147
|
-
deletes.add(id);
|
|
148
|
-
}
|
|
170
|
+
deletes.add(prevAtPath);
|
|
149
171
|
}
|
|
150
172
|
} else {
|
|
151
|
-
let itemsChanged =
|
|
173
|
+
let itemsChanged = [];
|
|
152
174
|
if (path.length === 0) {
|
|
153
|
-
|
|
175
|
+
const changed = asMap ? Array.from(valueAtPath.entries()) : Object.entries(valueAtPath);
|
|
176
|
+
for (let i = 0; i < changed.length; i++) {
|
|
177
|
+
const [key, value2] = changed[i];
|
|
154
178
|
const prev = asMap ? prevAtPath.get(key) : prevAtPath[key];
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
179
|
+
if (isNullOrUndefined(value2) && !isNullOrUndefined(prev)) {
|
|
180
|
+
deletes.add(prev);
|
|
181
|
+
return false;
|
|
182
|
+
} else {
|
|
183
|
+
const isDiff = !prevAtPath || !deepEqual(value2, prev);
|
|
184
|
+
if (isDiff) {
|
|
185
|
+
itemsChanged.push([getUpdateValue(value2, prev), prev]);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
158
189
|
} else {
|
|
159
190
|
const itemKey = path[0];
|
|
160
191
|
const itemValue = asMap ? value.get(itemKey) : value[itemKey];
|
|
161
192
|
if (!itemValue) {
|
|
162
193
|
if (path.length === 1 && prevAtPath) {
|
|
163
|
-
deletes.add(
|
|
194
|
+
deletes.add(prevAtPath);
|
|
164
195
|
}
|
|
165
196
|
} else {
|
|
166
|
-
|
|
197
|
+
const previous = setAtPath(
|
|
198
|
+
clone(itemValue),
|
|
199
|
+
path.slice(1),
|
|
200
|
+
pathTypes.slice(1),
|
|
201
|
+
prevAtPath
|
|
202
|
+
);
|
|
203
|
+
itemsChanged = [[getUpdateValue(itemValue, previous), previous]];
|
|
167
204
|
}
|
|
168
205
|
}
|
|
169
|
-
itemsChanged == null ? void 0 : itemsChanged.forEach(([
|
|
170
|
-
|
|
171
|
-
|
|
206
|
+
itemsChanged == null ? void 0 : itemsChanged.forEach(([item, prev]) => {
|
|
207
|
+
const isCreate = fieldCreatedAt ? !item[fieldCreatedAt] && !(prev == null ? void 0 : prev[fieldCreatedAt]) : fieldUpdatedAt ? !item[fieldUpdatedAt] && !(prev == null ? void 0 : prev[fieldCreatedAt]) : isNullOrUndefined(prev);
|
|
208
|
+
if (isCreate) {
|
|
209
|
+
if (generateId) {
|
|
210
|
+
ensureId(item, fieldId, generateId);
|
|
211
|
+
}
|
|
212
|
+
if (!item.id) {
|
|
213
|
+
console.error("[legend-state]: added item without an id");
|
|
214
|
+
}
|
|
215
|
+
if (createFn) {
|
|
216
|
+
creates.set(item.id, item);
|
|
217
|
+
} else {
|
|
218
|
+
console.log("[legend-state] missing create function");
|
|
219
|
+
}
|
|
172
220
|
} 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
|
-
}
|
|
221
|
+
if (updateFn) {
|
|
222
|
+
updates.set(
|
|
223
|
+
item.id,
|
|
224
|
+
updates.has(item.id) ? Object.assign(updates.get(item.id), item) : item
|
|
225
|
+
);
|
|
187
226
|
} else {
|
|
188
|
-
|
|
189
|
-
updates.set(item.id, item);
|
|
190
|
-
} else {
|
|
191
|
-
console.log("[legend-state] missing update function");
|
|
192
|
-
}
|
|
227
|
+
console.log("[legend-state] missing update function");
|
|
193
228
|
}
|
|
194
229
|
}
|
|
195
230
|
});
|
|
196
231
|
}
|
|
197
232
|
});
|
|
198
233
|
const saveResult = async (itemKey, input, data, isCreate) => {
|
|
199
|
-
if (data
|
|
200
|
-
const saved = (transform == null ? void 0 : transform.load) ? transform.load(data, "set") : data;
|
|
234
|
+
if (data) {
|
|
235
|
+
const saved = (transform == null ? void 0 : transform.load) ? await transform.load(data, "set") : data;
|
|
201
236
|
const isChild = itemKey !== "undefined" && asType !== "value";
|
|
202
237
|
const currentPeeked = getNodeValue(node);
|
|
203
238
|
const currentValue = isChild ? currentPeeked == null ? void 0 : currentPeeked[itemKey] : currentPeeked;
|
|
@@ -208,17 +243,26 @@ function syncedCrud(props) {
|
|
|
208
243
|
isCreate,
|
|
209
244
|
props
|
|
210
245
|
};
|
|
211
|
-
let savedOut =
|
|
212
|
-
if (
|
|
213
|
-
savedOut =
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
246
|
+
let savedOut = saved;
|
|
247
|
+
if (savedOut && !isNullOrUndefined(currentValue)) {
|
|
248
|
+
savedOut = clone(savedOut);
|
|
249
|
+
Object.keys(savedOut).forEach((key) => {
|
|
250
|
+
const i = input[key];
|
|
251
|
+
const c = currentValue[key];
|
|
252
|
+
if (
|
|
253
|
+
// value is already the new value, can ignore
|
|
254
|
+
savedOut[key] === c || // user has changed local value
|
|
255
|
+
key !== "id" && i !== c
|
|
256
|
+
) {
|
|
257
|
+
delete savedOut[key];
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
if (onSaved) {
|
|
261
|
+
const ret = onSaved(dataOnSaved);
|
|
262
|
+
if (ret) {
|
|
263
|
+
savedOut = ret;
|
|
264
|
+
}
|
|
219
265
|
}
|
|
220
|
-
}
|
|
221
|
-
if (savedOut) {
|
|
222
266
|
const createdAt = fieldCreatedAt ? savedOut[fieldCreatedAt] : void 0;
|
|
223
267
|
const updatedAt = fieldUpdatedAt ? savedOut[fieldUpdatedAt] : void 0;
|
|
224
268
|
const value2 = itemKey !== "undefined" && asType !== "value" ? { [itemKey]: savedOut } : savedOut;
|
|
@@ -231,38 +275,59 @@ function syncedCrud(props) {
|
|
|
231
275
|
}
|
|
232
276
|
};
|
|
233
277
|
return Promise.all([
|
|
234
|
-
...Array.from(creates).map(([itemKey, itemValue]) => {
|
|
235
|
-
const createObj = transformOut(itemValue, transform == null ? void 0 : transform.save);
|
|
278
|
+
...Array.from(creates).map(async ([itemKey, itemValue]) => {
|
|
279
|
+
const createObj = await transformOut(itemValue, transform == null ? void 0 : transform.save);
|
|
236
280
|
return createFn(createObj, params).then(
|
|
237
281
|
(result) => saveResult(itemKey, createObj, result, true)
|
|
238
282
|
);
|
|
239
283
|
}),
|
|
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);
|
|
284
|
+
...Array.from(updates).map(async ([itemKey, itemValue]) => {
|
|
285
|
+
const toSave = itemValue;
|
|
286
|
+
const changed = await transformOut(toSave, transform == null ? void 0 : transform.save);
|
|
246
287
|
if (Object.keys(changed).length > 0) {
|
|
247
288
|
return updateFn(changed, params).then(
|
|
248
289
|
(result) => result && saveResult(itemKey, changed, result, false)
|
|
249
290
|
);
|
|
250
291
|
}
|
|
251
292
|
}),
|
|
252
|
-
...Array.from(deletes).map((
|
|
293
|
+
...Array.from(deletes).map((valuePrevious) => {
|
|
253
294
|
if (deleteFn) {
|
|
254
|
-
deleteFn(
|
|
295
|
+
deleteFn(valuePrevious, params);
|
|
255
296
|
} else if (fieldDeleted && updateFn) {
|
|
256
|
-
|
|
297
|
+
const valueId = valuePrevious[fieldId];
|
|
298
|
+
updateFn(
|
|
299
|
+
{ ...valueId ? { [fieldId]: valueId } : {}, [fieldDeleted]: true },
|
|
300
|
+
params
|
|
301
|
+
);
|
|
257
302
|
} else {
|
|
258
303
|
console.log("[legend-state] missing delete function");
|
|
259
304
|
}
|
|
260
305
|
})
|
|
261
306
|
]);
|
|
262
307
|
} : void 0;
|
|
308
|
+
const subscribe = subscribeProp ? (params) => subscribeProp({
|
|
309
|
+
...params,
|
|
310
|
+
update: async (paramsUpdate) => {
|
|
311
|
+
const paramsForUpdate = paramsUpdate;
|
|
312
|
+
const rows = paramsUpdate.value;
|
|
313
|
+
if (process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test") {
|
|
314
|
+
if (!isArray(rows)) {
|
|
315
|
+
console.error("[legend-state] subscribe:update expects an array of changed items");
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
const newLastSync = computeLastSync(rows, fieldUpdatedAt, fieldCreatedAt);
|
|
319
|
+
if (newLastSync) {
|
|
320
|
+
paramsForUpdate.lastSync = newLastSync;
|
|
321
|
+
}
|
|
322
|
+
const rowsTransformed = (transform == null ? void 0 : transform.load) ? await Promise.all(rows.map((row) => transform.load(row, "get"))) : rows;
|
|
323
|
+
paramsForUpdate.value = resultsToOutType(rowsTransformed);
|
|
324
|
+
params.update(paramsForUpdate);
|
|
325
|
+
}
|
|
326
|
+
}) : void 0;
|
|
263
327
|
return synced({
|
|
264
328
|
set,
|
|
265
329
|
get,
|
|
330
|
+
subscribe,
|
|
266
331
|
mode: modeParam,
|
|
267
332
|
...rest
|
|
268
333
|
});
|
|
@@ -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 };
|