@legendapp/state 3.0.0-alpha.8 → 3.0.0-alpha.9

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/index.d.mts CHANGED
@@ -96,7 +96,7 @@ type RecursiveValueOrFunction<T> = T extends Function ? T : T extends object ? (
96
96
 
97
97
  declare const symbolOpaque: unique symbol;
98
98
  declare function getPathType(value: any): TypeAtPath;
99
- declare function safeStringify(value: any): string;
99
+ declare function safeStringify(value: any): any;
100
100
  declare function safeParse(value: any): any;
101
101
  declare function clone<T>(value: T): any;
102
102
  declare function isObservable(value$: any): value$ is Observable;
package/index.d.ts CHANGED
@@ -96,7 +96,7 @@ type RecursiveValueOrFunction<T> = T extends Function ? T : T extends object ? (
96
96
 
97
97
  declare const symbolOpaque: unique symbol;
98
98
  declare function getPathType(value: any): TypeAtPath;
99
- declare function safeStringify(value: any): string;
99
+ declare function safeStringify(value: any): any;
100
100
  declare function safeParse(value: any): any;
101
101
  declare function clone<T>(value: T): any;
102
102
  declare function isObservable(value$: any): value$ is Observable;
package/index.js CHANGED
@@ -118,10 +118,10 @@ function reviver(key, value) {
118
118
  return value;
119
119
  }
120
120
  function safeStringify(value) {
121
- return JSON.stringify(value, replacer);
121
+ return value ? JSON.stringify(value, replacer) : value;
122
122
  }
123
123
  function safeParse(value) {
124
- return JSON.parse(value, reviver);
124
+ return value ? JSON.parse(value, reviver) : value;
125
125
  }
126
126
  function clone(value) {
127
127
  return safeParse(safeStringify(value));
package/index.mjs CHANGED
@@ -116,10 +116,10 @@ function reviver(key, value) {
116
116
  return value;
117
117
  }
118
118
  function safeStringify(value) {
119
- return JSON.stringify(value, replacer);
119
+ return value ? JSON.stringify(value, replacer) : value;
120
120
  }
121
121
  function safeParse(value) {
122
- return JSON.parse(value, reviver);
122
+ return value ? JSON.parse(value, reviver) : value;
123
123
  }
124
124
  function clone(value) {
125
125
  return safeParse(safeStringify(value));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/state",
3
- "version": "3.0.0-alpha.8",
3
+ "version": "3.0.0-alpha.9",
4
4
  "description": "legend-state",
5
5
  "sideEffects": false,
6
6
  "private": false,
@@ -30,7 +30,6 @@ interface SyncedCrudPropsBase<TRemote extends {
30
30
  id: TRemote['id'];
31
31
  }, params: SyncedSetParams<TRemote>): Promise<CrudResult<any>>;
32
32
  onSaved?(params: SyncedCrudOnSavedParams<TRemote, TLocal>): Partial<TLocal> | void;
33
- onSavedUpdate?: 'createdUpdatedAt';
34
33
  fieldUpdatedAt?: string;
35
34
  fieldCreatedAt?: string;
36
35
  fieldDeleted?: string;
@@ -30,7 +30,6 @@ interface SyncedCrudPropsBase<TRemote extends {
30
30
  id: TRemote['id'];
31
31
  }, params: SyncedSetParams<TRemote>): Promise<CrudResult<any>>;
32
32
  onSaved?(params: SyncedCrudOnSavedParams<TRemote, TLocal>): Partial<TLocal> | void;
33
- onSavedUpdate?: 'createdUpdatedAt';
34
33
  fieldUpdatedAt?: string;
35
34
  fieldCreatedAt?: string;
36
35
  fieldDeleted?: string;
@@ -14,25 +14,6 @@ function ensureId(obj, generateId) {
14
14
  }
15
15
  return obj.id;
16
16
  }
17
- function onSavedCreatedUpdatedAt(mode, { saved, currentValue, isCreate, props }) {
18
- const savedOut = {};
19
- if (isCreate) {
20
- Object.keys(saved).forEach((key) => {
21
- if (state.isNullOrUndefined(currentValue[key])) {
22
- savedOut[key] = saved[key];
23
- }
24
- });
25
- } else if (mode === "createdUpdatedAt") {
26
- Object.keys(saved).forEach((key) => {
27
- const k = key;
28
- const keyLower = key.toLowerCase();
29
- if ((key === props.fieldCreatedAt || key === props.fieldUpdatedAt || keyLower.endsWith("createdat") || keyLower.endsWith("updatedat") || keyLower.endsWith("created_at") || keyLower.endsWith("updated_at")) && saved[k] instanceof Date) {
30
- savedOut[k] = saved[k];
31
- }
32
- });
33
- }
34
- return savedOut;
35
- }
36
17
  function syncedCrud(props) {
37
18
  const {
38
19
  get: getFn,
@@ -46,7 +27,6 @@ function syncedCrud(props) {
46
27
  fieldDeleted,
47
28
  updatePartial,
48
29
  onSaved,
49
- onSavedUpdate,
50
30
  mode: modeParam,
51
31
  changesSince,
52
32
  generateId,
@@ -198,7 +178,7 @@ function syncedCrud(props) {
198
178
  }
199
179
  });
200
180
  const saveResult = async (itemKey, input, data, isCreate) => {
201
- if (data && (onSaved || onSavedUpdate)) {
181
+ if (data) {
202
182
  const saved = (transform == null ? void 0 : transform.load) ? transform.load(data, "set") : data;
203
183
  const isChild = itemKey !== "undefined" && asType !== "value";
204
184
  const currentPeeked = state.getNodeValue(node);
@@ -210,17 +190,26 @@ function syncedCrud(props) {
210
190
  isCreate,
211
191
  props
212
192
  };
213
- let savedOut = void 0;
214
- if (onSavedUpdate) {
215
- savedOut = onSavedCreatedUpdatedAt(onSavedUpdate, dataOnSaved);
216
- }
217
- if (onSaved) {
218
- const ret = onSaved(dataOnSaved);
219
- if (ret) {
220
- savedOut = ret;
221
- }
222
- }
193
+ let savedOut = saved;
223
194
  if (savedOut) {
195
+ savedOut = clone(savedOut);
196
+ Object.keys(savedOut).forEach((key) => {
197
+ const i = input[key];
198
+ const c = currentValue[key];
199
+ if (
200
+ // value is already the new value, can ignore
201
+ savedOut[key] === c || // user has changed local value
202
+ key !== "id" && i !== c
203
+ ) {
204
+ delete savedOut[key];
205
+ }
206
+ });
207
+ if (onSaved) {
208
+ const ret = onSaved(dataOnSaved);
209
+ if (ret) {
210
+ savedOut = ret;
211
+ }
212
+ }
224
213
  const createdAt = fieldCreatedAt ? savedOut[fieldCreatedAt] : void 0;
225
214
  const updatedAt = fieldUpdatedAt ? savedOut[fieldUpdatedAt] : void 0;
226
215
  const value2 = itemKey !== "undefined" && asType !== "value" ? { [itemKey]: savedOut } : savedOut;
@@ -12,25 +12,6 @@ function ensureId(obj, generateId) {
12
12
  }
13
13
  return obj.id;
14
14
  }
15
- function onSavedCreatedUpdatedAt(mode, { saved, currentValue, isCreate, props }) {
16
- const savedOut = {};
17
- if (isCreate) {
18
- Object.keys(saved).forEach((key) => {
19
- if (isNullOrUndefined(currentValue[key])) {
20
- savedOut[key] = saved[key];
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
- });
31
- }
32
- return savedOut;
33
- }
34
15
  function syncedCrud(props) {
35
16
  const {
36
17
  get: getFn,
@@ -44,7 +25,6 @@ function syncedCrud(props) {
44
25
  fieldDeleted,
45
26
  updatePartial,
46
27
  onSaved,
47
- onSavedUpdate,
48
28
  mode: modeParam,
49
29
  changesSince,
50
30
  generateId,
@@ -196,7 +176,7 @@ function syncedCrud(props) {
196
176
  }
197
177
  });
198
178
  const saveResult = async (itemKey, input, data, isCreate) => {
199
- if (data && (onSaved || onSavedUpdate)) {
179
+ if (data) {
200
180
  const saved = (transform == null ? void 0 : transform.load) ? transform.load(data, "set") : data;
201
181
  const isChild = itemKey !== "undefined" && asType !== "value";
202
182
  const currentPeeked = getNodeValue(node);
@@ -208,17 +188,26 @@ function syncedCrud(props) {
208
188
  isCreate,
209
189
  props
210
190
  };
211
- let savedOut = void 0;
212
- if (onSavedUpdate) {
213
- savedOut = onSavedCreatedUpdatedAt(onSavedUpdate, dataOnSaved);
214
- }
215
- if (onSaved) {
216
- const ret = onSaved(dataOnSaved);
217
- if (ret) {
218
- savedOut = ret;
219
- }
220
- }
191
+ let savedOut = saved;
221
192
  if (savedOut) {
193
+ savedOut = clone(savedOut);
194
+ Object.keys(savedOut).forEach((key) => {
195
+ const i = input[key];
196
+ const c = currentValue[key];
197
+ if (
198
+ // value is already the new value, can ignore
199
+ savedOut[key] === c || // user has changed local value
200
+ key !== "id" && i !== c
201
+ ) {
202
+ delete savedOut[key];
203
+ }
204
+ });
205
+ if (onSaved) {
206
+ const ret = onSaved(dataOnSaved);
207
+ if (ret) {
208
+ savedOut = ret;
209
+ }
210
+ }
222
211
  const createdAt = fieldCreatedAt ? savedOut[fieldCreatedAt] : void 0;
223
212
  const updatedAt = fieldUpdatedAt ? savedOut[fieldUpdatedAt] : void 0;
224
213
  const value2 = itemKey !== "undefined" && asType !== "value" ? { [itemKey]: savedOut } : savedOut;
@@ -244,7 +244,6 @@ function syncedKeel(props) {
244
244
  delete: deleteFn,
245
245
  waitFor: () => isEnabled$.get() && (waitFor ? state.computeSelector(waitFor) : true),
246
246
  onSaved,
247
- onSavedUpdate: "createdUpdatedAt",
248
247
  fieldCreatedAt,
249
248
  fieldUpdatedAt,
250
249
  fieldDeleted: fieldDeleted || "deleted",
@@ -238,7 +238,6 @@ function syncedKeel(props) {
238
238
  delete: deleteFn,
239
239
  waitFor: () => isEnabled$.get() && (waitFor ? computeSelector(waitFor) : true),
240
240
  onSaved,
241
- onSavedUpdate: "createdUpdatedAt",
242
241
  fieldCreatedAt,
243
242
  fieldUpdatedAt,
244
243
  fieldDeleted: fieldDeleted || "deleted",
@@ -132,7 +132,6 @@ function syncedSupabase(props) {
132
132
  fieldUpdatedAt,
133
133
  fieldDeleted,
134
134
  updatePartial: false,
135
- onSavedUpdate: "createdUpdatedAt",
136
135
  transform,
137
136
  generateId,
138
137
  waitFor: () => isEnabled$.get() && (waitFor ? state.computeSelector(waitFor) : true),
@@ -130,7 +130,6 @@ function syncedSupabase(props) {
130
130
  fieldUpdatedAt,
131
131
  fieldDeleted,
132
132
  updatePartial: false,
133
- onSavedUpdate: "createdUpdatedAt",
134
133
  transform,
135
134
  generateId,
136
135
  waitFor: () => isEnabled$.get() && (waitFor ? computeSelector(waitFor) : true),
package/sync.js CHANGED
@@ -525,13 +525,12 @@ async function doChangeRemote(changeInfo) {
525
525
  await state.when(waitFor);
526
526
  }
527
527
  }
528
- let value = obs.peek();
528
+ let value = clone(obs.peek());
529
529
  const transformSave = (_a = syncOptions == null ? void 0 : syncOptions.transform) == null ? void 0 : _a.save;
530
530
  if (transformSave) {
531
- value = transformSave(clone(value));
531
+ value = transformSave(value);
532
532
  }
533
533
  onBeforeSet == null ? void 0 : onBeforeSet();
534
- localState.numSavesOutstanding = (localState.numSavesOutstanding || 0) + 1;
535
534
  let savedPromise = pluginSync.set({
536
535
  value$: obs,
537
536
  syncState,
@@ -544,7 +543,6 @@ async function doChangeRemote(changeInfo) {
544
543
  savedPromise = savedPromise.catch((err) => onSetError == null ? void 0 : onSetError(err));
545
544
  }
546
545
  const saved = await savedPromise;
547
- localState.numSavesOutstanding--;
548
546
  if (saved !== void 0) {
549
547
  const pathStrs = Array.from(new Set(changesRemote.map((change) => change.pathStr)));
550
548
  const { changes, lastSync } = saved;
@@ -571,29 +569,16 @@ async function doChangeRemote(changeInfo) {
571
569
  if (changes && !state.isEmpty(changes)) {
572
570
  transformedChanges = transformLoadData(changes, syncOptions, false, "set");
573
571
  }
574
- if (localState.numSavesOutstanding > 0) {
575
- if (transformedChanges) {
576
- if (!localState.pendingSaveResults) {
577
- localState.pendingSaveResults = [];
578
- }
579
- localState.pendingSaveResults.push(transformedChanges);
580
- }
581
- } else {
582
- let allChanges = [...localState.pendingSaveResults || [], transformedChanges].filter(
583
- (v) => v !== void 0
584
- );
585
- if (allChanges.length > 0) {
586
- if (allChanges.some((change) => state.isPromise(change))) {
587
- allChanges = await Promise.all(allChanges);
588
- }
589
- onChangeRemote(() => state.mergeIntoObservable(obs, ...allChanges));
572
+ if (transformedChanges !== void 0) {
573
+ if (state.isPromise(transformedChanges)) {
574
+ transformedChanges = await transformedChanges;
590
575
  }
591
- if (saveLocal) {
592
- if (shouldSaveMetadata && !state.isEmpty(metadata)) {
593
- updateMetadata(obs, localState, syncState, syncOptions, metadata);
594
- }
576
+ onChangeRemote(() => state.mergeIntoObservable(obs, transformedChanges));
577
+ }
578
+ if (saveLocal) {
579
+ if (shouldSaveMetadata && !state.isEmpty(metadata)) {
580
+ updateMetadata(obs, localState, syncState, syncOptions, metadata);
595
581
  }
596
- localState.pendingSaveResults = [];
597
582
  }
598
583
  onAfterSet == null ? void 0 : onAfterSet();
599
584
  }
package/sync.mjs CHANGED
@@ -523,13 +523,12 @@ async function doChangeRemote(changeInfo) {
523
523
  await when(waitFor);
524
524
  }
525
525
  }
526
- let value = obs.peek();
526
+ let value = clone(obs.peek());
527
527
  const transformSave = (_a = syncOptions == null ? void 0 : syncOptions.transform) == null ? void 0 : _a.save;
528
528
  if (transformSave) {
529
- value = transformSave(clone(value));
529
+ value = transformSave(value);
530
530
  }
531
531
  onBeforeSet == null ? void 0 : onBeforeSet();
532
- localState.numSavesOutstanding = (localState.numSavesOutstanding || 0) + 1;
533
532
  let savedPromise = pluginSync.set({
534
533
  value$: obs,
535
534
  syncState,
@@ -542,7 +541,6 @@ async function doChangeRemote(changeInfo) {
542
541
  savedPromise = savedPromise.catch((err) => onSetError == null ? void 0 : onSetError(err));
543
542
  }
544
543
  const saved = await savedPromise;
545
- localState.numSavesOutstanding--;
546
544
  if (saved !== void 0) {
547
545
  const pathStrs = Array.from(new Set(changesRemote.map((change) => change.pathStr)));
548
546
  const { changes, lastSync } = saved;
@@ -569,29 +567,16 @@ async function doChangeRemote(changeInfo) {
569
567
  if (changes && !isEmpty(changes)) {
570
568
  transformedChanges = transformLoadData(changes, syncOptions, false, "set");
571
569
  }
572
- if (localState.numSavesOutstanding > 0) {
573
- if (transformedChanges) {
574
- if (!localState.pendingSaveResults) {
575
- localState.pendingSaveResults = [];
576
- }
577
- localState.pendingSaveResults.push(transformedChanges);
578
- }
579
- } else {
580
- let allChanges = [...localState.pendingSaveResults || [], transformedChanges].filter(
581
- (v) => v !== void 0
582
- );
583
- if (allChanges.length > 0) {
584
- if (allChanges.some((change) => isPromise(change))) {
585
- allChanges = await Promise.all(allChanges);
586
- }
587
- onChangeRemote(() => mergeIntoObservable(obs, ...allChanges));
570
+ if (transformedChanges !== void 0) {
571
+ if (isPromise(transformedChanges)) {
572
+ transformedChanges = await transformedChanges;
588
573
  }
589
- if (saveLocal) {
590
- if (shouldSaveMetadata && !isEmpty(metadata)) {
591
- updateMetadata(obs, localState, syncState, syncOptions, metadata);
592
- }
574
+ onChangeRemote(() => mergeIntoObservable(obs, transformedChanges));
575
+ }
576
+ if (saveLocal) {
577
+ if (shouldSaveMetadata && !isEmpty(metadata)) {
578
+ updateMetadata(obs, localState, syncState, syncOptions, metadata);
593
579
  }
594
- localState.pendingSaveResults = [];
595
580
  }
596
581
  onAfterSet == null ? void 0 : onAfterSet();
597
582
  }