@farm.js/sync 0.1.0-beta.3 → 0.1.0-beta.5

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/dist/client.d.ts CHANGED
@@ -100,7 +100,12 @@ type SyncPersistence = {
100
100
  };
101
101
  /** Replace the default browser store, for example with an IndexedDB one. */
102
102
  export declare function setSyncPersistence(store: SyncPersistence | null): void;
103
- /** Remove every persisted row. Call on logout so a shared device stays clean. */
103
+ /**
104
+ * Forget every synced row, on disk and in memory. Call it when the session
105
+ * changes (sign out, sign in as someone else, switch organization) so the next
106
+ * account never sees the previous one's rows. Each model reloads in full on its
107
+ * next use, scoped to the session current at that point.
108
+ */
104
109
  export declare function clearSyncedRows(): void;
105
110
  export declare function hydrateModel(model: string): void;
106
111
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js CHANGED
@@ -30,11 +30,31 @@ function requireRuntime() {
30
30
  }
31
31
  throw new Error("The sync runtime is not started. Add `sync({ ... })` to the plugins in farm.config.ts.");
32
32
  }
33
+ const scheduledReloads = new Set();
34
+ /**
35
+ * A store cleared by clearSyncedRows() reloads on its next use, under whichever
36
+ * session is current by then. Deferred so the reload's status change never
37
+ * fires while a component is rendering, and so loadModel's own lookup of the
38
+ * store does not schedule it again.
39
+ */
40
+ function scheduleReload(model, store) {
41
+ if (scheduledReloads.has(model))
42
+ return;
43
+ scheduledReloads.add(model);
44
+ queueMicrotask(() => {
45
+ if (store.status === "idle")
46
+ void loadModel(model);
47
+ scheduledReloads.delete(model);
48
+ });
49
+ }
33
50
  export function getSyncStore(model) {
34
51
  const state = requireRuntime();
35
52
  let store = state.stores.get(model);
36
- if (store)
53
+ if (store) {
54
+ if (store.status === "idle" && isBrowser())
55
+ scheduleReload(model, store);
37
56
  return store;
57
+ }
38
58
  const descriptor = state.config.models[model];
39
59
  if (!descriptor) {
40
60
  if (!isBrowser())
@@ -68,10 +88,13 @@ async function request(body) {
68
88
  /** Fetch rows for a model, incrementally when the schema supports a cursor. */
69
89
  export async function loadModel(model) {
70
90
  const store = getSyncStore(model);
91
+ const generation = store.generation;
71
92
  if (store.status === "idle")
72
93
  store.setStatus("loading");
73
94
  try {
74
95
  const result = await request({ model, operation: "list", since: store.cursor });
96
+ if (store.generation !== generation)
97
+ return;
75
98
  store.applyServerRows(result.rows ?? [], {
76
99
  full: result.full !== false,
77
100
  cursor: result.cursor ?? null,
@@ -80,6 +103,8 @@ export async function loadModel(model) {
80
103
  persistModel(model);
81
104
  }
82
105
  catch (cause) {
106
+ if (store.generation !== generation)
107
+ return;
83
108
  store.setStatus("error", cause instanceof Error ? cause : new Error(String(cause)));
84
109
  }
85
110
  }
@@ -147,18 +172,24 @@ function runMutation(model, operation, input, optimistic) {
147
172
  : { type: "upsert", key: optimistic.key, row: optimistic.row };
148
173
  store.addLayer(layer);
149
174
  store.trackPending(1);
175
+ const generation = store.generation;
150
176
  let handleState = "pending";
151
177
  const isPersisted = (async () => {
152
178
  try {
153
179
  const result = await dispatchWrite(store, { model, operation, input }, state.options);
154
- store.commitLayer(layer, operation === "delete" ? null : result);
155
180
  handleState = "completed";
181
+ // The store was cleared for a new session while this was in flight.
182
+ if (store.generation !== generation)
183
+ return result;
184
+ store.commitLayer(layer, operation === "delete" ? null : result);
156
185
  persistModel(model);
157
186
  return result;
158
187
  }
159
188
  catch (error) {
160
- store.removeLayer(layer);
161
189
  handleState = "failed";
190
+ if (store.generation !== generation)
191
+ throw error;
192
+ store.removeLayer(layer);
162
193
  store.recordFailure({
163
194
  operation,
164
195
  input,
@@ -217,6 +248,7 @@ export function runSyncAction(model, action, invoke, input, explicitPatch) {
217
248
  if (layer)
218
249
  store.addLayer(layer);
219
250
  store.trackPending(1);
251
+ const generation = store.generation;
220
252
  let handleState = "pending";
221
253
  const isPersisted = (async () => {
222
254
  try {
@@ -231,6 +263,10 @@ export function runSyncAction(model, action, invoke, input, explicitPatch) {
231
263
  }
232
264
  const result = await invoke(input);
233
265
  const rows = Array.isArray(result) ? result : [result];
266
+ if (store.generation !== generation) {
267
+ handleState = "completed";
268
+ return (rows[0] ?? null);
269
+ }
234
270
  let committed = false;
235
271
  for (const row of rows) {
236
272
  if (row && typeof row === "object" && row[keyField] !== undefined) {
@@ -254,9 +290,11 @@ export function runSyncAction(model, action, invoke, input, explicitPatch) {
254
290
  return (rows[0] ?? null);
255
291
  }
256
292
  catch (error) {
293
+ handleState = "failed";
294
+ if (store.generation !== generation)
295
+ throw error;
257
296
  if (layer)
258
297
  store.removeLayer(layer);
259
- handleState = "failed";
260
298
  store.recordFailure({
261
299
  operation: action,
262
300
  input,
@@ -406,9 +444,16 @@ function getPersistence() {
406
444
  export function setSyncPersistence(store) {
407
445
  persistence = store;
408
446
  }
409
- /** Remove every persisted row. Call on logout so a shared device stays clean. */
447
+ /**
448
+ * Forget every synced row, on disk and in memory. Call it when the session
449
+ * changes (sign out, sign in as someone else, switch organization) so the next
450
+ * account never sees the previous one's rows. Each model reloads in full on its
451
+ * next use, scoped to the session current at that point.
452
+ */
410
453
  export function clearSyncedRows() {
411
454
  getPersistence()?.clear();
455
+ for (const store of runtime?.stores.values() ?? [])
456
+ store.reset();
412
457
  }
413
458
  function persistModel(model) {
414
459
  const store = runtime?.stores.get(model);
package/dist/store.d.ts CHANGED
@@ -54,6 +54,12 @@ export declare class SyncModelStore {
54
54
  /** Rolled-back writes awaiting the user. Replaced, never mutated, so a
55
55
  * useSyncExternalStore snapshot of it stays referentially stable. */
56
56
  failures: readonly SyncWriteFailure[];
57
+ /**
58
+ * Bumped by reset(). A load or write that started before a reset compares
59
+ * against it and drops its result, so a response for the previous session
60
+ * cannot land in the store after it was cleared.
61
+ */
62
+ generation: number;
57
63
  private nextFailureId;
58
64
  constructor(name: string, descriptor: SyncModelDescriptor);
59
65
  subscribe(listener: () => void): () => void;
@@ -71,6 +77,12 @@ export declare class SyncModelStore {
71
77
  /** Fold a confirmed server row in and drop the layer that predicted it. */
72
78
  commitLayer(layer: OptimisticLayer, confirmed: SyncRow | null): void;
73
79
  mergeRow(key: unknown, changes: SyncRow): SyncRow;
80
+ /**
81
+ * Forget everything this store holds for a session change: confirmed rows,
82
+ * optimistic layers, recorded failures, and the incremental cursor. The next
83
+ * load is a full one, scoped to whoever is signed in by then.
84
+ */
85
+ reset(): void;
74
86
  /** Rows worth persisting: confirmed only, never optimistic guesses. */
75
87
  confirmedRows(): SyncRow[];
76
88
  hydrate(rows: SyncRow[], cursor: string | null): void;
@@ -1 +1 @@
1
- {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
package/dist/store.js CHANGED
@@ -19,6 +19,12 @@ export class SyncModelStore {
19
19
  /** Rolled-back writes awaiting the user. Replaced, never mutated, so a
20
20
  * useSyncExternalStore snapshot of it stays referentially stable. */
21
21
  failures = [];
22
+ /**
23
+ * Bumped by reset(). A load or write that started before a reset compares
24
+ * against it and drops its result, so a response for the previous session
25
+ * cannot land in the store after it was cleared.
26
+ */
27
+ generation = 0;
22
28
  nextFailureId = 1;
23
29
  constructor(name, descriptor) {
24
30
  this.name = name;
@@ -98,6 +104,21 @@ export class SyncModelStore {
98
104
  const current = this.get(key) ?? { [this.descriptor.key]: key };
99
105
  return { ...current, ...changes };
100
106
  }
107
+ /**
108
+ * Forget everything this store holds for a session change: confirmed rows,
109
+ * optimistic layers, recorded failures, and the incremental cursor. The next
110
+ * load is a full one, scoped to whoever is signed in by then.
111
+ */
112
+ reset() {
113
+ this.generation += 1;
114
+ this.confirmed.clear();
115
+ this.layers = [];
116
+ this.failures = [];
117
+ this.cursor = null;
118
+ this.status = "idle";
119
+ this.error = null;
120
+ this.invalidate();
121
+ }
101
122
  /** Rows worth persisting: confirmed only, never optimistic guesses. */
102
123
  confirmedRows() {
103
124
  return Array.from(this.confirmed.values());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farm.js/sync",
3
- "version": "0.1.0-beta.3",
3
+ "version": "0.1.0-beta.5",
4
4
  "description": "Local-first collections for Farm.js: schema-driven reads, optimistic writes, offline queueing",
5
5
  "keywords": [
6
6
  "farm.js",
@@ -40,7 +40,7 @@
40
40
  "access": "public"
41
41
  },
42
42
  "dependencies": {
43
- "@farm.js/core": "0.1.0-beta.105"
43
+ "@farm.js/core": "0.1.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@farming-labs/orm": "0.0.62",