@legendapp/state 3.0.0-beta.4 → 3.0.0-beta.40

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.
Files changed (79) hide show
  1. package/.DS_Store +0 -0
  2. package/README.md +2 -2
  3. package/config/enableReactComponents.js +3 -1
  4. package/config/enableReactComponents.mjs +3 -1
  5. package/config/enableReactTracking.d.mts +2 -1
  6. package/config/enableReactTracking.d.ts +2 -1
  7. package/config/enableReactTracking.js +32 -13
  8. package/config/enableReactTracking.mjs +32 -13
  9. package/index.d.mts +46 -8
  10. package/index.d.ts +46 -8
  11. package/index.js +267 -75
  12. package/index.mjs +267 -75
  13. package/package.json +35 -1
  14. package/persist-plugins/async-storage.js +17 -9
  15. package/persist-plugins/async-storage.mjs +17 -9
  16. package/persist-plugins/expo-sqlite.d.mts +19 -0
  17. package/persist-plugins/expo-sqlite.d.ts +19 -0
  18. package/persist-plugins/expo-sqlite.js +72 -0
  19. package/persist-plugins/expo-sqlite.mjs +69 -0
  20. package/persist-plugins/indexeddb.js +13 -3
  21. package/persist-plugins/indexeddb.mjs +13 -3
  22. package/react-native.d.mts +4 -0
  23. package/react-native.d.ts +4 -0
  24. package/react-native.js +53 -0
  25. package/react-native.mjs +40 -0
  26. package/react-reactive/Components.d.mts +19 -0
  27. package/react-reactive/Components.d.ts +19 -0
  28. package/react-reactive/Components.js +53 -0
  29. package/react-reactive/Components.mjs +40 -0
  30. package/react-reactive/enableReactComponents.d.mts +3 -2
  31. package/react-reactive/enableReactComponents.d.ts +3 -2
  32. package/react-reactive/enableReactComponents.js +10 -3
  33. package/react-reactive/enableReactComponents.mjs +10 -3
  34. package/react-reactive/enableReactNativeComponents.d.mts +3 -20
  35. package/react-reactive/enableReactNativeComponents.d.ts +3 -20
  36. package/react-reactive/enableReactNativeComponents.js +8 -3
  37. package/react-reactive/enableReactNativeComponents.mjs +8 -3
  38. package/react-reactive/enableReactive.js +10 -3
  39. package/react-reactive/enableReactive.mjs +10 -3
  40. package/react-reactive/enableReactive.native.js +8 -3
  41. package/react-reactive/enableReactive.native.mjs +8 -3
  42. package/react-reactive/enableReactive.web.js +8 -3
  43. package/react-reactive/enableReactive.web.mjs +8 -3
  44. package/react-web.d.mts +7 -0
  45. package/react-web.d.ts +7 -0
  46. package/react-web.js +39 -0
  47. package/react-web.mjs +37 -0
  48. package/react.d.mts +59 -26
  49. package/react.d.ts +59 -26
  50. package/react.js +136 -87
  51. package/react.mjs +135 -89
  52. package/sync-plugins/crud.d.mts +24 -9
  53. package/sync-plugins/crud.d.ts +24 -9
  54. package/sync-plugins/crud.js +267 -123
  55. package/sync-plugins/crud.mjs +268 -124
  56. package/sync-plugins/firebase.d.mts +7 -3
  57. package/sync-plugins/firebase.d.ts +7 -3
  58. package/sync-plugins/firebase.js +214 -64
  59. package/sync-plugins/firebase.mjs +215 -65
  60. package/sync-plugins/keel.d.mts +12 -13
  61. package/sync-plugins/keel.d.ts +12 -13
  62. package/sync-plugins/keel.js +60 -52
  63. package/sync-plugins/keel.mjs +61 -48
  64. package/sync-plugins/supabase.d.mts +10 -5
  65. package/sync-plugins/supabase.d.ts +10 -5
  66. package/sync-plugins/supabase.js +90 -33
  67. package/sync-plugins/supabase.mjs +91 -34
  68. package/sync-plugins/tanstack-query.d.mts +3 -3
  69. package/sync-plugins/tanstack-query.d.ts +3 -3
  70. package/sync-plugins/tanstack-query.js +1 -1
  71. package/sync-plugins/tanstack-query.mjs +1 -1
  72. package/sync.d.mts +17 -8
  73. package/sync.d.ts +17 -8
  74. package/sync.js +448 -307
  75. package/sync.mjs +446 -307
  76. package/trace.js +5 -6
  77. package/trace.mjs +5 -6
  78. package/types/reactive-native.d.ts +19 -0
  79. package/types/reactive-web.d.ts +7 -0
@@ -4,16 +4,18 @@ var state = require('@legendapp/state');
4
4
  var sync = require('@legendapp/state/sync');
5
5
 
6
6
  // src/sync-plugins/crud.ts
7
- var { clone } = state.internal;
8
- var { waitForSet } = sync.internal;
7
+ var { clone, getKeys, setNodeValue, getChildNode } = state.internal;
8
+ var { waitForSet, runWithRetry } = sync.internal;
9
9
  function transformOut(data, transform) {
10
10
  return transform ? transform(clone(data)) : data;
11
11
  }
12
- function ensureId(obj, fieldId, generateId) {
12
+ function ensureId(obj, fieldId, generateId, node) {
13
13
  if (!obj[fieldId]) {
14
14
  obj[fieldId] = generateId();
15
+ if (node) {
16
+ setNodeValue(node, obj);
17
+ }
15
18
  }
16
- return obj[fieldId];
17
19
  }
18
20
  function computeLastSync(data, fieldUpdatedAt, fieldCreatedAt) {
19
21
  let newLastSync = 0;
@@ -25,6 +27,47 @@ function computeLastSync(data, fieldUpdatedAt, fieldCreatedAt) {
25
27
  }
26
28
  return newLastSync;
27
29
  }
30
+ function arrayToRecord(arr, keyField) {
31
+ const record = {};
32
+ if (arr == null ? void 0 : arr.length) {
33
+ for (let i = 0; i < arr.length; i++) {
34
+ const v = arr[i];
35
+ const key = v[keyField];
36
+ record[key] = v;
37
+ }
38
+ }
39
+ return record;
40
+ }
41
+ function retrySet(params, retry, action, itemKey, itemValue, change, queuedRetries, itemValueFull, actionFn, saveResult) {
42
+ if (action === "delete") {
43
+ if (queuedRetries.create.has(itemKey)) {
44
+ queuedRetries.create.delete(itemKey);
45
+ }
46
+ if (queuedRetries.update.has(itemKey)) {
47
+ queuedRetries.update.delete(itemKey);
48
+ }
49
+ } else {
50
+ if (queuedRetries.delete.has(itemKey)) {
51
+ queuedRetries.delete.delete(itemKey);
52
+ }
53
+ }
54
+ const queuedRetry = queuedRetries[action].get(itemKey);
55
+ if (queuedRetry) {
56
+ itemValue = Object.assign(queuedRetry, itemValue);
57
+ }
58
+ queuedRetries[action].set(itemKey, itemValue);
59
+ const clonedValue = clone(itemValueFull);
60
+ const paramsWithChanges = { ...params, changes: [change] };
61
+ return runWithRetry(
62
+ paramsWithChanges,
63
+ retry,
64
+ "create_" + itemKey,
65
+ () => actionFn(itemValue, paramsWithChanges).then((result) => {
66
+ queuedRetries[action].delete(itemKey);
67
+ return saveResult(itemKey, clonedValue, result, true, change);
68
+ })
69
+ );
70
+ }
28
71
  function syncedCrud(props) {
29
72
  const {
30
73
  get: getFn,
@@ -45,10 +88,16 @@ function syncedCrud(props) {
45
88
  changesSince,
46
89
  generateId,
47
90
  waitForSet: waitForSetParam,
91
+ retry,
48
92
  ...rest
49
93
  } = props;
50
94
  const fieldId = fieldIdProp || "id";
51
95
  const pendingCreates = /* @__PURE__ */ new Set();
96
+ const queuedRetries = {
97
+ create: /* @__PURE__ */ new Map(),
98
+ update: /* @__PURE__ */ new Map(),
99
+ delete: /* @__PURE__ */ new Map()
100
+ };
52
101
  let asType = props.as;
53
102
  if (!asType) {
54
103
  asType = getFn ? "value" : "object";
@@ -77,69 +126,76 @@ function syncedCrud(props) {
77
126
  return out;
78
127
  };
79
128
  const transformRows = (data) => {
80
- return Promise.all(
129
+ return data.length ? Promise.all(
81
130
  data.map(
82
131
  (value) => (
83
132
  // Skip transforming any children with symbolDelete or fieldDeleted because they'll get deleted by resultsToOutType
84
133
  value[state.symbolDelete] || fieldDeleted && value[fieldDeleted] || fieldDeletedList && value[fieldDeletedList] ? value : transform.load(value, "get")
85
134
  )
86
135
  )
87
- );
136
+ ) : [];
88
137
  };
89
138
  const get = getFn || listFn ? (getParams) => {
90
- const { updateLastSync, lastSync, value } = getParams;
91
- if (listFn) {
92
- const isLastSyncMode = changesSince === "last-sync";
93
- if (isLastSyncMode && lastSync) {
94
- getParams.mode = modeParam || (asType === "array" ? "append" : asType === "value" ? "set" : "assign");
95
- }
96
- const listPromise = listFn(getParams);
97
- const toOut = (transformed) => {
98
- var _a;
99
- if (asType === "value") {
100
- return transformed.length > 0 ? transformed[0] : (_a = (isLastSyncMode && lastSync || fieldDeleted) && value) != null ? _a : null;
101
- } else {
102
- return resultsToOutType(transformed);
139
+ return runWithRetry(getParams, retry, getFn || listFn, () => {
140
+ const { updateLastSync, lastSync, value } = getParams;
141
+ if (listFn) {
142
+ const isLastSyncMode = changesSince === "last-sync";
143
+ if (isLastSyncMode && lastSync) {
144
+ getParams.mode = modeParam || (asType === "array" ? "append" : asType === "value" ? "set" : "assign");
103
145
  }
104
- };
105
- const processResults = (data) => {
106
- data || (data = []);
107
- if (fieldUpdatedAt) {
108
- const newLastSync = computeLastSync(data, fieldUpdatedAt, fieldCreatedAt);
109
- if (newLastSync && newLastSync !== lastSync) {
110
- updateLastSync(newLastSync);
146
+ const listPromise = listFn(getParams);
147
+ const toOut = (transformed) => {
148
+ if (asType === "value") {
149
+ if (transformed.length > 0) {
150
+ return transformed[0];
151
+ } else {
152
+ return value ? void 0 : null;
153
+ }
154
+ } else {
155
+ return resultsToOutType(transformed);
111
156
  }
112
- }
113
- let transformed = data;
114
- if (transform == null ? void 0 : transform.load) {
115
- transformed = transformRows(data);
116
- }
117
- return state.isPromise(transformed) ? transformed.then(toOut) : toOut(transformed);
118
- };
119
- return state.isPromise(listPromise) ? listPromise.then(processResults) : processResults(listPromise);
120
- } else if (getFn) {
121
- const dataPromise = getFn(getParams);
122
- const processData = (data) => {
123
- let transformed = data;
124
- if (data) {
125
- const newLastSync = data[fieldUpdatedAt] || data[fieldCreatedAt];
126
- if (newLastSync && newLastSync !== lastSync) {
127
- updateLastSync(newLastSync);
157
+ };
158
+ const processResults = (data) => {
159
+ data || (data = []);
160
+ if (fieldUpdatedAt) {
161
+ const newLastSync = computeLastSync(data, fieldUpdatedAt, fieldCreatedAt);
162
+ if (newLastSync && newLastSync !== lastSync) {
163
+ updateLastSync(newLastSync);
164
+ }
128
165
  }
166
+ let transformed = data;
129
167
  if (transform == null ? void 0 : transform.load) {
130
- transformed = transform.load(data, "get");
168
+ transformed = transformRows(data);
131
169
  }
132
- }
133
- return transformed;
134
- };
135
- return state.isPromise(dataPromise) ? dataPromise.then(processData) : processData(dataPromise);
136
- }
170
+ return state.isPromise(transformed) ? transformed.then(toOut) : toOut(transformed);
171
+ };
172
+ return state.isPromise(listPromise) ? listPromise.then(processResults) : processResults(listPromise);
173
+ } else if (getFn) {
174
+ const dataPromise = getFn(getParams);
175
+ const processData = (data) => {
176
+ let transformed = data;
177
+ if (data) {
178
+ const newLastSync = data[fieldUpdatedAt] || data[fieldCreatedAt];
179
+ if (newLastSync && newLastSync !== lastSync) {
180
+ updateLastSync(newLastSync);
181
+ }
182
+ if (transform == null ? void 0 : transform.load) {
183
+ transformed = transform.load(data, "get");
184
+ }
185
+ }
186
+ return transformed;
187
+ };
188
+ return state.isPromise(dataPromise) ? dataPromise.then(processData) : processData(dataPromise);
189
+ }
190
+ });
137
191
  } : void 0;
138
192
  const set = createFn || updateFn || deleteFn ? async (params) => {
139
193
  const { value, changes, update, retryAsCreate, node } = params;
140
194
  const creates = /* @__PURE__ */ new Map();
141
195
  const updates = /* @__PURE__ */ new Map();
196
+ const updateFullValues = /* @__PURE__ */ new Map();
142
197
  const deletes = /* @__PURE__ */ new Set();
198
+ const changesById = /* @__PURE__ */ new Map();
143
199
  const getUpdateValue = (itemValue, prev) => {
144
200
  return updatePartial ? Object.assign(
145
201
  sync.diffObjects(
@@ -148,19 +204,21 @@ function syncedCrud(props) {
148
204
  /*deep*/
149
205
  true
150
206
  ),
151
- itemValue[fieldId] ? { [fieldId]: itemValue[fieldId] } : {}
207
+ !state.isNullOrUndefined(itemValue[fieldId]) ? { [fieldId]: itemValue[fieldId] } : {}
152
208
  ) : itemValue;
153
209
  };
154
210
  changes.forEach((change) => {
211
+ var _a, _b;
155
212
  const { path, prevAtPath, valueAtPath, pathTypes } = change;
156
213
  if (asType === "value") {
157
214
  if (value) {
158
- let id = value == null ? void 0 : value[fieldId];
159
215
  let isCreate = fieldCreatedAt ? !value[fieldCreatedAt] : !prevAtPath;
160
- if (!id && generateId) {
161
- id = ensureId(value, fieldId, generateId);
216
+ if (state.isNullOrUndefined(value[fieldId]) && generateId) {
217
+ ensureId(value, fieldId, generateId, node);
162
218
  }
163
- if (id) {
219
+ const id = value[fieldId];
220
+ if (!state.isNullOrUndefined(id)) {
221
+ changesById.set(id, change);
164
222
  if (pendingCreates.has(id)) {
165
223
  isCreate = false;
166
224
  }
@@ -173,6 +231,7 @@ function syncedCrud(props) {
173
231
  } else if (path.length === 0) {
174
232
  if (valueAtPath) {
175
233
  updates.set(id, getUpdateValue(valueAtPath, prevAtPath));
234
+ updateFullValues.set(id, valueAtPath);
176
235
  } else if (prevAtPath) {
177
236
  deletes.add(prevAtPath);
178
237
  }
@@ -184,27 +243,50 @@ function syncedCrud(props) {
184
243
  true
185
244
  );
186
245
  updates.set(id, getUpdateValue(value, previous));
246
+ updateFullValues.set(id, value);
187
247
  }
188
248
  } else {
189
249
  console.error("[legend-state]: added synced item without an id");
190
250
  }
191
251
  } else if (path.length === 0) {
192
252
  deletes.add(prevAtPath);
253
+ changesById.set(prevAtPath[fieldId], change);
193
254
  }
194
255
  } else {
195
256
  let itemsChanged = [];
196
257
  if (path.length === 0) {
197
- const changed = asMap ? Array.from(valueAtPath.entries()) : Object.entries(valueAtPath);
198
- for (let i = 0; i < changed.length; i++) {
199
- const [key, value2] = changed[i];
200
- const prev = asMap ? prevAtPath.get(key) : prevAtPath[key];
258
+ if (asArray && generateId) {
259
+ for (let i = 0; i < valueAtPath.length; i++) {
260
+ const value2 = valueAtPath[i];
261
+ if (value2 && !value2[fieldId]) {
262
+ ensureId(value2, fieldId, generateId, getChildNode(node, i + ""));
263
+ }
264
+ }
265
+ }
266
+ const valueAsObject = asArray ? arrayToRecord(valueAtPath, fieldId) : valueAtPath;
267
+ const prevAsObject = asArray ? arrayToRecord(prevAtPath, fieldId) : prevAtPath;
268
+ const keys = getKeys(valueAsObject, false, asMap, false);
269
+ const keysPrev = getKeys(prevAsObject, false, asMap, false);
270
+ const keysSet = new Set(keys);
271
+ const length = ((_a = keys || valueAsObject) == null ? void 0 : _a.length) || 0;
272
+ const lengthPrev = ((_b = keysPrev || prevAsObject) == null ? void 0 : _b.length) || 0;
273
+ for (let i = 0; i < lengthPrev; i++) {
274
+ const key = keysPrev[i];
275
+ if (!keysSet.has(key)) {
276
+ deletes.add(prevAsObject[key]);
277
+ }
278
+ }
279
+ for (let i = 0; i < length; i++) {
280
+ const key = keys[i];
281
+ const value2 = asMap ? valueAsObject.get(key) : valueAsObject[key];
282
+ const prev = prevAsObject ? asMap ? prevAsObject.get(key) : prevAsObject[key] : void 0;
201
283
  if (state.isNullOrUndefined(value2) && !state.isNullOrUndefined(prev)) {
202
284
  deletes.add(prev);
203
285
  return false;
204
286
  } else {
205
- const isDiff = !prevAtPath || !sync.deepEqual(value2, prev);
287
+ const isDiff = !prevAsObject || !sync.deepEqual(value2, prev);
206
288
  if (isDiff) {
207
- itemsChanged.push([getUpdateValue(value2, prev), prev]);
289
+ itemsChanged.push([getUpdateValue(value2, prev), prev, value2]);
208
290
  }
209
291
  }
210
292
  }
@@ -214,37 +296,43 @@ function syncedCrud(props) {
214
296
  if (!itemValue) {
215
297
  if (path.length === 1 && prevAtPath) {
216
298
  deletes.add(prevAtPath);
299
+ changesById.set(prevAtPath[fieldId], change);
217
300
  }
218
301
  } else {
302
+ if (generateId) {
303
+ ensureId(itemValue, fieldId, generateId, getChildNode(node, itemKey + ""));
304
+ }
219
305
  const previous = state.setAtPath(
220
306
  clone(itemValue),
221
307
  path.slice(1),
222
308
  pathTypes.slice(1),
223
309
  prevAtPath
224
310
  );
225
- itemsChanged = [[getUpdateValue(itemValue, previous), previous]];
311
+ itemsChanged = [[getUpdateValue(itemValue, previous), previous, itemValue]];
226
312
  }
227
313
  }
228
- itemsChanged == null ? void 0 : itemsChanged.forEach(([item, prev]) => {
314
+ itemsChanged == null ? void 0 : itemsChanged.forEach(([item, prev, fullValue]) => {
229
315
  const isCreate = !pendingCreates.has(item[fieldId]) && (fieldCreatedAt ? !item[fieldCreatedAt] && !(prev == null ? void 0 : prev[fieldCreatedAt]) : fieldUpdatedAt ? !item[fieldUpdatedAt] && !(prev == null ? void 0 : prev[fieldCreatedAt]) : state.isNullOrUndefined(prev));
230
316
  if (isCreate) {
231
- if (generateId) {
232
- ensureId(item, fieldId, generateId);
233
- }
234
317
  if (!item[fieldId]) {
235
318
  console.error("[legend-state]: added item without an id");
236
319
  }
237
320
  if (createFn) {
238
- pendingCreates.add(item[fieldId]);
239
- creates.set(item[fieldId], item);
321
+ const id = item[fieldId];
322
+ changesById.set(id, change);
323
+ pendingCreates.add(id);
324
+ creates.set(id, item);
240
325
  } else {
241
326
  console.warn("[legend-state] missing create function");
242
327
  }
243
328
  } else {
244
329
  if (updateFn) {
245
- updates.set(
246
- item[fieldId],
247
- updates.has(item[fieldId]) ? Object.assign(updates.get(item[fieldId]), item) : item
330
+ const id = item[fieldId];
331
+ changesById.set(id, change);
332
+ updates.set(id, updates.has(id) ? Object.assign(updates.get(id), item) : item);
333
+ updateFullValues.set(
334
+ id,
335
+ updateFullValues.has(id) ? Object.assign(updateFullValues.get(id), fullValue) : fullValue
248
336
  );
249
337
  } else {
250
338
  console.warn("[legend-state] missing update function");
@@ -253,93 +341,149 @@ function syncedCrud(props) {
253
341
  });
254
342
  }
255
343
  });
256
- const saveResult = async (itemKey, input, data, isCreate) => {
344
+ const saveResult = async (itemKey, input, data, isCreate, change) => {
257
345
  var _a;
258
346
  if (data) {
259
- const saved = (transform == null ? void 0 : transform.load) ? await transform.load(data, "set") : data;
347
+ let saved = (transform == null ? void 0 : transform.load) ? await transform.load(data, "set") : data;
260
348
  const isChild = itemKey !== "undefined" && asType !== "value";
261
349
  const currentPeeked = state.getNodeValue(node);
262
- const currentValue = isChild ? (_a = asType === "array" && state.isArray(currentPeeked) ? currentPeeked.find((v) => v[fieldId] === itemKey) : void 0) != null ? _a : currentPeeked[itemKey] : currentPeeked;
263
- const dataOnSaved = {
264
- saved,
265
- input,
266
- currentValue,
267
- isCreate,
268
- props
269
- };
270
- let savedOut = saved;
271
- if (savedOut && !state.isNullOrUndefined(currentValue)) {
272
- savedOut = clone(savedOut);
273
- Object.keys(savedOut).forEach((key) => {
350
+ const currentValue = isChild ? (_a = asType === "array" && state.isArray(currentPeeked) ? currentPeeked.find((v) => v[fieldId] === itemKey) : void 0) != null ? _a : asType === "Map" ? currentPeeked.get(itemKey) : currentPeeked[itemKey] : currentPeeked;
351
+ if (saved && !state.isNullOrUndefined(currentValue)) {
352
+ if (onSaved) {
353
+ const ret = onSaved({
354
+ saved,
355
+ input,
356
+ currentValue,
357
+ isCreate,
358
+ props
359
+ });
360
+ if (ret) {
361
+ saved = ret;
362
+ }
363
+ }
364
+ saved = clone(saved);
365
+ Object.keys(saved).forEach((key) => {
274
366
  const i = input[key];
275
367
  const c = currentValue[key];
276
368
  if (
277
369
  // value is already the new value, can ignore
278
- savedOut[key] === c || // user has changed local value
279
- key !== "id" && i !== c
370
+ saved[key] === c || // user has changed local value
371
+ key !== fieldId && i !== void 0 && i !== c
280
372
  ) {
281
- delete savedOut[key];
373
+ delete saved[key];
282
374
  }
283
375
  });
284
- if (onSaved) {
285
- const ret = onSaved(dataOnSaved);
286
- if (ret) {
287
- savedOut = ret;
376
+ let value2;
377
+ if (asType === "array") {
378
+ const index = currentPeeked.findIndex(
379
+ (cur) => cur[fieldId] === itemKey
380
+ );
381
+ if (index < 0) {
382
+ console.warn("[legend-state] Item saved that does not exist in array", saved);
383
+ } else {
384
+ value2 = { [index < 0 ? 0 : index]: saved };
288
385
  }
386
+ } else {
387
+ value2 = itemKey !== "undefined" && asType !== "value" ? { [itemKey]: saved } : saved;
388
+ }
389
+ if (value2 !== void 0) {
390
+ update({
391
+ value: value2,
392
+ mode: "merge",
393
+ changes: [change]
394
+ });
289
395
  }
290
- const createdAt = fieldCreatedAt ? savedOut[fieldCreatedAt] : void 0;
291
- const updatedAt = fieldUpdatedAt ? savedOut[fieldUpdatedAt] : void 0;
292
- const value2 = itemKey !== "undefined" && asType !== "value" ? { [itemKey]: savedOut } : savedOut;
293
- update({
294
- value: value2,
295
- lastSync: updatedAt || createdAt ? +new Date(updatedAt || createdAt) : void 0,
296
- mode: "merge"
297
- });
298
396
  }
299
397
  }
300
398
  };
301
399
  return Promise.all([
400
+ // Handle creates
302
401
  ...Array.from(creates).map(async ([itemKey, itemValue]) => {
303
402
  if (waitForSetParam) {
304
403
  await waitForSet(waitForSetParam, changes, itemValue, { type: "create" });
305
404
  }
306
405
  const createObj = await transformOut(itemValue, transform == null ? void 0 : transform.save);
307
- return createFn(createObj, params).then((result) => {
308
- return saveResult(itemKey, createObj, result, true);
309
- }).finally(() => {
406
+ return retrySet(
407
+ params,
408
+ retry,
409
+ "create",
410
+ itemKey,
411
+ createObj,
412
+ changesById.get(itemKey),
413
+ queuedRetries,
414
+ createObj,
415
+ createFn,
416
+ saveResult
417
+ ).then(() => {
310
418
  pendingCreates.delete(itemKey);
311
419
  });
312
420
  }),
421
+ // Handle updates
313
422
  ...Array.from(updates).map(async ([itemKey, itemValue]) => {
423
+ const fullValue = updateFullValues.get(itemKey);
314
424
  if (waitForSetParam) {
315
- await waitForSet(waitForSetParam, changes, itemValue, { type: "update" });
425
+ await waitForSet(waitForSetParam, changes, fullValue, { type: "update" });
316
426
  }
317
- const toSave = itemValue;
318
- const changed = await transformOut(toSave, transform == null ? void 0 : transform.save);
427
+ const changed = await transformOut(itemValue, transform == null ? void 0 : transform.save);
428
+ const fullValueTransformed = await transformOut(
429
+ fullValue,
430
+ transform == null ? void 0 : transform.save
431
+ );
319
432
  if (Object.keys(changed).length > 0) {
320
- return updateFn(changed, params).then(
321
- (result) => result && saveResult(itemKey, changed, result, false)
433
+ return retrySet(
434
+ params,
435
+ retry,
436
+ "update",
437
+ itemKey,
438
+ changed,
439
+ changesById.get(itemKey),
440
+ queuedRetries,
441
+ fullValueTransformed,
442
+ updateFn,
443
+ saveResult
322
444
  );
323
445
  }
324
446
  }),
325
- ...Array.from(deletes).map(async (valuePrevious) => {
326
- if (valuePrevious !== state.symbolDelete) {
327
- if (waitForSetParam) {
328
- await waitForSet(waitForSetParam, changes, valuePrevious, { type: "delete" });
329
- }
330
- if (deleteFn) {
331
- deleteFn(valuePrevious, params);
332
- } else if (fieldDeleted && updateFn) {
333
- const valueId = valuePrevious[fieldId];
334
- if (valueId) {
335
- updateFn({ ...{ [fieldId]: valueId }, [fieldDeleted]: true }, params);
336
- } else {
337
- console.error("[legend-state]: deleting item without an id");
338
- }
339
- } else {
340
- console.warn("[legend-state] missing delete function");
341
- }
447
+ // Handle deletes
448
+ ...Array.from(deletes).filter((val) => val !== state.symbolDelete).map(async (valuePrevious) => {
449
+ if (waitForSetParam) {
450
+ await waitForSet(waitForSetParam, changes, valuePrevious, { type: "delete" });
451
+ }
452
+ const itemKey = valuePrevious[fieldId];
453
+ if (!itemKey) {
454
+ console.error("[legend-state]: deleting item without an id");
455
+ return;
456
+ }
457
+ if (deleteFn) {
458
+ return retrySet(
459
+ params,
460
+ retry,
461
+ "delete",
462
+ itemKey,
463
+ valuePrevious,
464
+ changesById.get(itemKey),
465
+ queuedRetries,
466
+ valuePrevious,
467
+ deleteFn,
468
+ saveResult
469
+ );
470
+ }
471
+ if (fieldDeleted && updateFn) {
472
+ const value2 = { [fieldId]: itemKey, [fieldDeleted]: true };
473
+ return retrySet(
474
+ params,
475
+ retry,
476
+ "delete",
477
+ itemKey,
478
+ value2,
479
+ changesById.get(itemKey),
480
+ queuedRetries,
481
+ value2,
482
+ updateFn,
483
+ saveResult
484
+ );
342
485
  }
486
+ console.warn("[legend-state] missing delete function");
343
487
  })
344
488
  ]);
345
489
  } : void 0;