@foretag/tanstack-db-surrealdb 0.1.13 → 0.1.15

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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Note: Please note this Software is Pre-release pending testing and not yet recommended for production use.
4
4
 
5
- Add Offline / Local First Caching & Syncing to your SurrealDB app with TanstackDB and Loro (CRDTs). For SurrealDB v3 and SurrealDB JS SDK v2.
5
+ Add Offline / Local First Caching & Syncing to your SurrealDB app with TanstackDB and Loro (CRDTs). For SurrealDB v3.alpha-13 and SurrealDB JS SDK v2 (and above).
6
6
 
7
7
  - Local / Offline first applications with TanstackDB and Loro
8
8
  - High performance with Low resource consumption
package/dist/index.js CHANGED
@@ -27,29 +27,43 @@ var import_surrealdb2 = require("surrealdb");
27
27
 
28
28
  // src/table.ts
29
29
  var import_surrealdb = require("surrealdb");
30
- function manageTable(db, { name, ...args }) {
30
+ function manageTable(db, useLoro, { name, ...args }) {
31
31
  const fields = args.fields ?? "*";
32
32
  const listAll = async () => {
33
33
  return await db.select(new import_surrealdb.Table(name)).where(args.where).fields(...fields);
34
34
  };
35
35
  const listActive = async () => {
36
+ if (!useLoro) return listAll();
36
37
  return await db.select(new import_surrealdb.Table(name)).where((0, import_surrealdb.and)(args.where, (0, import_surrealdb.eq)("sync_deleted", false))).fields(...fields);
37
38
  };
38
- const upsert = async (id, data) => {
39
- await db.upsert(id).merge({
40
- ...data,
41
- sync_deleted: false,
42
- updated_at: Date.now()
43
- });
39
+ const create = async (data) => {
40
+ await db.create(new import_surrealdb.Table(name)).content(data);
41
+ };
42
+ const update = async (id, data) => {
43
+ if (useLoro) {
44
+ await db.update(id).merge({
45
+ ...data,
46
+ sync_deleted: false,
47
+ updated_at: Date.now()
48
+ });
49
+ } else {
50
+ await db.update(id).merge({
51
+ ...data
52
+ });
53
+ }
44
54
  };
45
55
  const remove = async (id) => {
46
56
  await db.delete(id);
47
57
  };
48
58
  const softDelete = async (id) => {
49
- await db.upsert(id).merge({
50
- sync_deleted: true,
51
- updated_at: Date.now()
52
- });
59
+ if (useLoro) {
60
+ await db.update(id).merge({
61
+ sync_deleted: true,
62
+ updated_at: Date.now()
63
+ });
64
+ } else {
65
+ await db.delete(id);
66
+ }
53
67
  };
54
68
  const subscribe = (cb) => {
55
69
  let killed = false;
@@ -79,7 +93,8 @@ function manageTable(db, { name, ...args }) {
79
93
  return {
80
94
  listAll,
81
95
  listActive,
82
- upsert,
96
+ create,
97
+ update,
83
98
  remove,
84
99
  softDelete,
85
100
  subscribe
@@ -115,32 +130,44 @@ function surrealCollectionOptions({
115
130
  loroMap.delete(id2);
116
131
  loro?.doc?.commit?.();
117
132
  };
133
+ const pushQueue = [];
134
+ const enqueuePush = (op) => {
135
+ if (!useLoro) return;
136
+ pushQueue.push(op);
137
+ };
118
138
  const flushPushQueue = async () => {
139
+ if (!useLoro) return;
119
140
  const ops = pushQueue.splice(0, pushQueue.length);
120
141
  for (const op of ops) {
121
- if (op.kind === "upsert") {
142
+ if (op.kind === "create") {
143
+ await table.create(op.row);
144
+ }
145
+ if (op.kind === "update") {
122
146
  const rid = new import_surrealdb2.RecordId(
123
147
  config.table.name,
124
148
  op.row.id.toString()
125
149
  );
126
- await table.upsert(rid, op.row);
127
- } else {
150
+ await table.update(rid, op.row);
151
+ }
152
+ if (op.kind === "delete") {
128
153
  const rid = new import_surrealdb2.RecordId(config.table.name, op.id.toString());
129
154
  await table.softDelete(rid);
130
155
  }
131
156
  }
132
157
  };
133
- const pushQueue = [];
134
- const enqueuePush = (op) => pushQueue.push(op);
135
158
  const newer = (a, b) => (a?.getTime() ?? -1) > (b?.getTime() ?? -1);
136
159
  const reconcileBoot = (serverRows, write) => {
137
- const localRows = useLoro ? loroToArray() : [];
160
+ if (!useLoro) {
161
+ diffAndEmit(serverRows, write);
162
+ return;
163
+ }
164
+ const localRows = loroToArray();
138
165
  const serverById = new Map(serverRows.map((r) => [getKey(r), r]));
139
166
  const localById = new Map(localRows.map((r) => [getKey(r), r]));
140
167
  const ids = /* @__PURE__ */ new Set([...serverById.keys(), ...localById.keys()]);
141
168
  const current = [];
142
169
  const applyLocal = (row) => {
143
- if (!useLoro || !row) return;
170
+ if (!row) return;
144
171
  if (row.sync_deleted) loroRemove(getKey(row));
145
172
  else loroPut(row);
146
173
  };
@@ -148,18 +175,22 @@ function surrealCollectionOptions({
148
175
  const s = serverById.get(id2);
149
176
  const l = localById.get(id2);
150
177
  if (s && l) {
151
- if (s.sync_deleted && l.sync_deleted) {
178
+ const sDeleted = s.sync_deleted ?? false;
179
+ const lDeleted = l.sync_deleted ?? false;
180
+ const sUpdated = s.updated_at;
181
+ const lUpdated = l.updated_at;
182
+ if (sDeleted && lDeleted) {
152
183
  applyLocal(s);
153
184
  current.push(s);
154
- } else if (s.sync_deleted && !l.sync_deleted) {
185
+ } else if (sDeleted && !lDeleted) {
155
186
  applyLocal(s);
156
187
  current.push(s);
157
- } else if (!s.sync_deleted && l.sync_deleted) {
158
- if (newer(l.updated_at, s.updated_at)) {
188
+ } else if (!sDeleted && lDeleted) {
189
+ if (newer(lUpdated, sUpdated)) {
159
190
  enqueuePush({
160
191
  kind: "delete",
161
192
  id: id2,
162
- updated_at: l.updated_at
193
+ updated_at: lUpdated ?? /* @__PURE__ */ new Date()
163
194
  });
164
195
  applyLocal(l);
165
196
  current.push(l);
@@ -168,8 +199,8 @@ function surrealCollectionOptions({
168
199
  current.push(s);
169
200
  }
170
201
  } else {
171
- if (newer(l.updated_at, s.updated_at)) {
172
- enqueuePush({ kind: "upsert", row: l });
202
+ if (newer(lUpdated, sUpdated)) {
203
+ enqueuePush({ kind: "update", row: l });
173
204
  applyLocal(l);
174
205
  current.push(l);
175
206
  } else {
@@ -181,16 +212,18 @@ function surrealCollectionOptions({
181
212
  applyLocal(s);
182
213
  current.push(s);
183
214
  } else if (!s && l) {
184
- if (l.sync_deleted) {
215
+ const lDeleted = l.sync_deleted ?? false;
216
+ const lUpdated = l.updated_at;
217
+ if (lDeleted) {
185
218
  enqueuePush({
186
219
  kind: "delete",
187
220
  id: id2,
188
- updated_at: l.updated_at
221
+ updated_at: lUpdated ?? /* @__PURE__ */ new Date()
189
222
  });
190
223
  applyLocal(l);
191
224
  current.push(l);
192
225
  } else {
193
- enqueuePush({ kind: "upsert", row: l });
226
+ enqueuePush({ kind: "create", row: l });
194
227
  applyLocal(l);
195
228
  current.push(l);
196
229
  }
@@ -200,15 +233,24 @@ function surrealCollectionOptions({
200
233
  };
201
234
  let prevById = /* @__PURE__ */ new Map();
202
235
  const buildMap = (rows) => new Map(rows.map((r) => [getKey(r), r]));
203
- const same = (a, b) => a.sync_deleted === b.sync_deleted && a.updated_at.getTime() === b.updated_at.getTime() && JSON.stringify({
204
- ...a,
205
- updated_at: void 0,
206
- sync_deleted: void 0
207
- }) === JSON.stringify({
208
- ...b,
209
- updated_at: void 0,
210
- sync_deleted: void 0
211
- });
236
+ const same = (a, b) => {
237
+ if (useLoro) {
238
+ const aUpdated = a.updated_at;
239
+ const bUpdated = b.updated_at;
240
+ const aDeleted = a.sync_deleted ?? false;
241
+ const bDeleted = b.sync_deleted ?? false;
242
+ return aDeleted === bDeleted && (aUpdated?.getTime() ?? 0) === (bUpdated?.getTime() ?? 0) && JSON.stringify({
243
+ ...a,
244
+ updated_at: void 0,
245
+ sync_deleted: void 0
246
+ }) === JSON.stringify({
247
+ ...b,
248
+ updated_at: void 0,
249
+ sync_deleted: void 0
250
+ });
251
+ }
252
+ return JSON.stringify(a) === JSON.stringify(b);
253
+ };
212
254
  const diffAndEmit = (currentRows, write) => {
213
255
  const currById = buildMap(currentRows);
214
256
  for (const [id2, row] of currById) {
@@ -226,7 +268,8 @@ function surrealCollectionOptions({
226
268
  }
227
269
  prevById = currById;
228
270
  };
229
- const table = manageTable(db, config.table);
271
+ const table = manageTable(db, useLoro, config.table);
272
+ const now = () => /* @__PURE__ */ new Date();
230
273
  const sync = ({
231
274
  begin,
232
275
  write,
@@ -236,15 +279,18 @@ function surrealCollectionOptions({
236
279
  let offLive = null;
237
280
  const makeTombstone = (id2) => ({
238
281
  id: new import_surrealdb2.RecordId(config.table.name, id2).toString(),
239
- updated_at: /* @__PURE__ */ new Date(),
282
+ updated_at: now(),
240
283
  sync_deleted: true
241
284
  });
242
285
  const start = async () => {
243
286
  try {
244
287
  const serverRows = await table.listAll();
245
288
  begin();
246
- if (useLoro) reconcileBoot(serverRows, write);
247
- else diffAndEmit(serverRows, write);
289
+ if (useLoro) {
290
+ reconcileBoot(serverRows, write);
291
+ } else {
292
+ diffAndEmit(serverRows, write);
293
+ }
248
294
  commit();
249
295
  markReady();
250
296
  await flushPushQueue();
@@ -253,7 +299,8 @@ function surrealCollectionOptions({
253
299
  try {
254
300
  if (evt.type === "insert" || evt.type === "update") {
255
301
  const row = evt.row;
256
- if (row.sync_deleted) {
302
+ const deleted = useLoro ? row.sync_deleted ?? false : false;
303
+ if (deleted) {
257
304
  if (useLoro) loroRemove(getKey(row));
258
305
  const prev = prevById.get(getKey(row)) ?? makeTombstone(getKey(row));
259
306
  write({ type: "delete", value: prev });
@@ -288,19 +335,18 @@ function surrealCollectionOptions({
288
335
  if (offLive) offLive();
289
336
  };
290
337
  };
291
- const now = () => /* @__PURE__ */ new Date();
292
338
  const onInsert = async (p) => {
293
339
  const resultRows = [];
294
340
  for (const m of p.transaction.mutations) {
295
341
  if (m.type !== "insert") continue;
296
- const row = {
297
- ...m.modified,
342
+ const base = { ...m.modified };
343
+ const row = useLoro ? {
344
+ ...base,
298
345
  updated_at: now(),
299
- deleted: false
300
- };
346
+ sync_deleted: false
347
+ } : base;
301
348
  if (useLoro) loroPut(row);
302
- const rid = new import_surrealdb2.RecordId(config.table.name, getKey(row));
303
- await table.upsert(rid, row);
349
+ await table.create(row);
304
350
  resultRows.push(row);
305
351
  }
306
352
  return resultRows;
@@ -310,10 +356,14 @@ function surrealCollectionOptions({
310
356
  for (const m of p.transaction.mutations) {
311
357
  if (m.type !== "update") continue;
312
358
  const id2 = m.key;
313
- const merged = { ...m.modified, id: id2, updated_at: now() };
359
+ const base = { ...m.modified, id: id2 };
360
+ const merged = useLoro ? {
361
+ ...base,
362
+ updated_at: now()
363
+ } : base;
314
364
  if (useLoro) loroPut(merged);
315
365
  const rid = new import_surrealdb2.RecordId(config.table.name, keyOf(id2));
316
- await table.upsert(rid, merged);
366
+ await table.update(rid, merged);
317
367
  resultRows.push(merged);
318
368
  }
319
369
  return resultRows;
@@ -323,7 +373,9 @@ function surrealCollectionOptions({
323
373
  for (const m of p.transaction.mutations) {
324
374
  if (m.type !== "delete") continue;
325
375
  const id2 = m.key;
326
- if (useLoro) loroRemove(keyOf(id2));
376
+ if (useLoro) {
377
+ loroRemove(keyOf(id2));
378
+ }
327
379
  await table.softDelete(new import_surrealdb2.RecordId(config.table.name, keyOf(id2)));
328
380
  }
329
381
  return resultRows;
package/dist/index.mjs CHANGED
@@ -9,29 +9,43 @@ import {
9
9
  Features,
10
10
  Table
11
11
  } from "surrealdb";
12
- function manageTable(db, { name, ...args }) {
12
+ function manageTable(db, useLoro, { name, ...args }) {
13
13
  const fields = args.fields ?? "*";
14
14
  const listAll = async () => {
15
15
  return await db.select(new Table(name)).where(args.where).fields(...fields);
16
16
  };
17
17
  const listActive = async () => {
18
+ if (!useLoro) return listAll();
18
19
  return await db.select(new Table(name)).where(and(args.where, eq("sync_deleted", false))).fields(...fields);
19
20
  };
20
- const upsert = async (id, data) => {
21
- await db.upsert(id).merge({
22
- ...data,
23
- sync_deleted: false,
24
- updated_at: Date.now()
25
- });
21
+ const create = async (data) => {
22
+ await db.create(new Table(name)).content(data);
23
+ };
24
+ const update = async (id, data) => {
25
+ if (useLoro) {
26
+ await db.update(id).merge({
27
+ ...data,
28
+ sync_deleted: false,
29
+ updated_at: Date.now()
30
+ });
31
+ } else {
32
+ await db.update(id).merge({
33
+ ...data
34
+ });
35
+ }
26
36
  };
27
37
  const remove = async (id) => {
28
38
  await db.delete(id);
29
39
  };
30
40
  const softDelete = async (id) => {
31
- await db.upsert(id).merge({
32
- sync_deleted: true,
33
- updated_at: Date.now()
34
- });
41
+ if (useLoro) {
42
+ await db.update(id).merge({
43
+ sync_deleted: true,
44
+ updated_at: Date.now()
45
+ });
46
+ } else {
47
+ await db.delete(id);
48
+ }
35
49
  };
36
50
  const subscribe = (cb) => {
37
51
  let killed = false;
@@ -61,7 +75,8 @@ function manageTable(db, { name, ...args }) {
61
75
  return {
62
76
  listAll,
63
77
  listActive,
64
- upsert,
78
+ create,
79
+ update,
65
80
  remove,
66
81
  softDelete,
67
82
  subscribe
@@ -97,32 +112,44 @@ function surrealCollectionOptions({
97
112
  loroMap.delete(id2);
98
113
  loro?.doc?.commit?.();
99
114
  };
115
+ const pushQueue = [];
116
+ const enqueuePush = (op) => {
117
+ if (!useLoro) return;
118
+ pushQueue.push(op);
119
+ };
100
120
  const flushPushQueue = async () => {
121
+ if (!useLoro) return;
101
122
  const ops = pushQueue.splice(0, pushQueue.length);
102
123
  for (const op of ops) {
103
- if (op.kind === "upsert") {
124
+ if (op.kind === "create") {
125
+ await table.create(op.row);
126
+ }
127
+ if (op.kind === "update") {
104
128
  const rid = new RecordId(
105
129
  config.table.name,
106
130
  op.row.id.toString()
107
131
  );
108
- await table.upsert(rid, op.row);
109
- } else {
132
+ await table.update(rid, op.row);
133
+ }
134
+ if (op.kind === "delete") {
110
135
  const rid = new RecordId(config.table.name, op.id.toString());
111
136
  await table.softDelete(rid);
112
137
  }
113
138
  }
114
139
  };
115
- const pushQueue = [];
116
- const enqueuePush = (op) => pushQueue.push(op);
117
140
  const newer = (a, b) => (a?.getTime() ?? -1) > (b?.getTime() ?? -1);
118
141
  const reconcileBoot = (serverRows, write) => {
119
- const localRows = useLoro ? loroToArray() : [];
142
+ if (!useLoro) {
143
+ diffAndEmit(serverRows, write);
144
+ return;
145
+ }
146
+ const localRows = loroToArray();
120
147
  const serverById = new Map(serverRows.map((r) => [getKey(r), r]));
121
148
  const localById = new Map(localRows.map((r) => [getKey(r), r]));
122
149
  const ids = /* @__PURE__ */ new Set([...serverById.keys(), ...localById.keys()]);
123
150
  const current = [];
124
151
  const applyLocal = (row) => {
125
- if (!useLoro || !row) return;
152
+ if (!row) return;
126
153
  if (row.sync_deleted) loroRemove(getKey(row));
127
154
  else loroPut(row);
128
155
  };
@@ -130,18 +157,22 @@ function surrealCollectionOptions({
130
157
  const s = serverById.get(id2);
131
158
  const l = localById.get(id2);
132
159
  if (s && l) {
133
- if (s.sync_deleted && l.sync_deleted) {
160
+ const sDeleted = s.sync_deleted ?? false;
161
+ const lDeleted = l.sync_deleted ?? false;
162
+ const sUpdated = s.updated_at;
163
+ const lUpdated = l.updated_at;
164
+ if (sDeleted && lDeleted) {
134
165
  applyLocal(s);
135
166
  current.push(s);
136
- } else if (s.sync_deleted && !l.sync_deleted) {
167
+ } else if (sDeleted && !lDeleted) {
137
168
  applyLocal(s);
138
169
  current.push(s);
139
- } else if (!s.sync_deleted && l.sync_deleted) {
140
- if (newer(l.updated_at, s.updated_at)) {
170
+ } else if (!sDeleted && lDeleted) {
171
+ if (newer(lUpdated, sUpdated)) {
141
172
  enqueuePush({
142
173
  kind: "delete",
143
174
  id: id2,
144
- updated_at: l.updated_at
175
+ updated_at: lUpdated ?? /* @__PURE__ */ new Date()
145
176
  });
146
177
  applyLocal(l);
147
178
  current.push(l);
@@ -150,8 +181,8 @@ function surrealCollectionOptions({
150
181
  current.push(s);
151
182
  }
152
183
  } else {
153
- if (newer(l.updated_at, s.updated_at)) {
154
- enqueuePush({ kind: "upsert", row: l });
184
+ if (newer(lUpdated, sUpdated)) {
185
+ enqueuePush({ kind: "update", row: l });
155
186
  applyLocal(l);
156
187
  current.push(l);
157
188
  } else {
@@ -163,16 +194,18 @@ function surrealCollectionOptions({
163
194
  applyLocal(s);
164
195
  current.push(s);
165
196
  } else if (!s && l) {
166
- if (l.sync_deleted) {
197
+ const lDeleted = l.sync_deleted ?? false;
198
+ const lUpdated = l.updated_at;
199
+ if (lDeleted) {
167
200
  enqueuePush({
168
201
  kind: "delete",
169
202
  id: id2,
170
- updated_at: l.updated_at
203
+ updated_at: lUpdated ?? /* @__PURE__ */ new Date()
171
204
  });
172
205
  applyLocal(l);
173
206
  current.push(l);
174
207
  } else {
175
- enqueuePush({ kind: "upsert", row: l });
208
+ enqueuePush({ kind: "create", row: l });
176
209
  applyLocal(l);
177
210
  current.push(l);
178
211
  }
@@ -182,15 +215,24 @@ function surrealCollectionOptions({
182
215
  };
183
216
  let prevById = /* @__PURE__ */ new Map();
184
217
  const buildMap = (rows) => new Map(rows.map((r) => [getKey(r), r]));
185
- const same = (a, b) => a.sync_deleted === b.sync_deleted && a.updated_at.getTime() === b.updated_at.getTime() && JSON.stringify({
186
- ...a,
187
- updated_at: void 0,
188
- sync_deleted: void 0
189
- }) === JSON.stringify({
190
- ...b,
191
- updated_at: void 0,
192
- sync_deleted: void 0
193
- });
218
+ const same = (a, b) => {
219
+ if (useLoro) {
220
+ const aUpdated = a.updated_at;
221
+ const bUpdated = b.updated_at;
222
+ const aDeleted = a.sync_deleted ?? false;
223
+ const bDeleted = b.sync_deleted ?? false;
224
+ return aDeleted === bDeleted && (aUpdated?.getTime() ?? 0) === (bUpdated?.getTime() ?? 0) && JSON.stringify({
225
+ ...a,
226
+ updated_at: void 0,
227
+ sync_deleted: void 0
228
+ }) === JSON.stringify({
229
+ ...b,
230
+ updated_at: void 0,
231
+ sync_deleted: void 0
232
+ });
233
+ }
234
+ return JSON.stringify(a) === JSON.stringify(b);
235
+ };
194
236
  const diffAndEmit = (currentRows, write) => {
195
237
  const currById = buildMap(currentRows);
196
238
  for (const [id2, row] of currById) {
@@ -208,7 +250,8 @@ function surrealCollectionOptions({
208
250
  }
209
251
  prevById = currById;
210
252
  };
211
- const table = manageTable(db, config.table);
253
+ const table = manageTable(db, useLoro, config.table);
254
+ const now = () => /* @__PURE__ */ new Date();
212
255
  const sync = ({
213
256
  begin,
214
257
  write,
@@ -218,15 +261,18 @@ function surrealCollectionOptions({
218
261
  let offLive = null;
219
262
  const makeTombstone = (id2) => ({
220
263
  id: new RecordId(config.table.name, id2).toString(),
221
- updated_at: /* @__PURE__ */ new Date(),
264
+ updated_at: now(),
222
265
  sync_deleted: true
223
266
  });
224
267
  const start = async () => {
225
268
  try {
226
269
  const serverRows = await table.listAll();
227
270
  begin();
228
- if (useLoro) reconcileBoot(serverRows, write);
229
- else diffAndEmit(serverRows, write);
271
+ if (useLoro) {
272
+ reconcileBoot(serverRows, write);
273
+ } else {
274
+ diffAndEmit(serverRows, write);
275
+ }
230
276
  commit();
231
277
  markReady();
232
278
  await flushPushQueue();
@@ -235,7 +281,8 @@ function surrealCollectionOptions({
235
281
  try {
236
282
  if (evt.type === "insert" || evt.type === "update") {
237
283
  const row = evt.row;
238
- if (row.sync_deleted) {
284
+ const deleted = useLoro ? row.sync_deleted ?? false : false;
285
+ if (deleted) {
239
286
  if (useLoro) loroRemove(getKey(row));
240
287
  const prev = prevById.get(getKey(row)) ?? makeTombstone(getKey(row));
241
288
  write({ type: "delete", value: prev });
@@ -270,19 +317,18 @@ function surrealCollectionOptions({
270
317
  if (offLive) offLive();
271
318
  };
272
319
  };
273
- const now = () => /* @__PURE__ */ new Date();
274
320
  const onInsert = async (p) => {
275
321
  const resultRows = [];
276
322
  for (const m of p.transaction.mutations) {
277
323
  if (m.type !== "insert") continue;
278
- const row = {
279
- ...m.modified,
324
+ const base = { ...m.modified };
325
+ const row = useLoro ? {
326
+ ...base,
280
327
  updated_at: now(),
281
- deleted: false
282
- };
328
+ sync_deleted: false
329
+ } : base;
283
330
  if (useLoro) loroPut(row);
284
- const rid = new RecordId(config.table.name, getKey(row));
285
- await table.upsert(rid, row);
331
+ await table.create(row);
286
332
  resultRows.push(row);
287
333
  }
288
334
  return resultRows;
@@ -292,10 +338,14 @@ function surrealCollectionOptions({
292
338
  for (const m of p.transaction.mutations) {
293
339
  if (m.type !== "update") continue;
294
340
  const id2 = m.key;
295
- const merged = { ...m.modified, id: id2, updated_at: now() };
341
+ const base = { ...m.modified, id: id2 };
342
+ const merged = useLoro ? {
343
+ ...base,
344
+ updated_at: now()
345
+ } : base;
296
346
  if (useLoro) loroPut(merged);
297
347
  const rid = new RecordId(config.table.name, keyOf(id2));
298
- await table.upsert(rid, merged);
348
+ await table.update(rid, merged);
299
349
  resultRows.push(merged);
300
350
  }
301
351
  return resultRows;
@@ -305,7 +355,9 @@ function surrealCollectionOptions({
305
355
  for (const m of p.transaction.mutations) {
306
356
  if (m.type !== "delete") continue;
307
357
  const id2 = m.key;
308
- if (useLoro) loroRemove(keyOf(id2));
358
+ if (useLoro) {
359
+ loroRemove(keyOf(id2));
360
+ }
309
361
  await table.softDelete(new RecordId(config.table.name, keyOf(id2)));
310
362
  }
311
363
  return resultRows;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@foretag/tanstack-db-surrealdb",
3
3
  "description": "Add Offline / Local First Caching & Syncing to your SurrealDB app with TanstackDB and Loro (CRDTs)",
4
- "version": "0.1.13",
4
+ "version": "0.1.15",
5
5
  "files": [
6
6
  "dist"
7
7
  ],
@@ -43,8 +43,8 @@
43
43
  "loro-crdt": "^1.9.0"
44
44
  },
45
45
  "peerDependencies": {
46
- "@tanstack/db": "*",
47
- "@tanstack/query-db-collection": "*",
46
+ "@tanstack/db": "^0.5.0",
47
+ "@tanstack/query-db-collection": "^1.0.0",
48
48
  "surrealdb": "2.0.0-alpha.13"
49
49
  },
50
50
  "devDependencies": {