@foretag/tanstack-db-surrealdb 0.3.2 → 0.3.3
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 +6 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +28 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +28 -23
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -20,15 +20,18 @@ bun install @foretag/tanstack-db-surrealdb
|
|
|
20
20
|
## Usage
|
|
21
21
|
```ts
|
|
22
22
|
// db.ts
|
|
23
|
+
import { QueryClient } from '@tanstack/svelte-query'; // Can also use '@tanstack/react-query' etc.
|
|
23
24
|
import { Surreal } from 'surrealdb';
|
|
24
25
|
|
|
25
26
|
export const db = new Surreal();
|
|
26
27
|
await db.connect('ws://localhost:8000/rpc');
|
|
27
28
|
await db.use({ ns: 'ns', db: 'db' });
|
|
28
29
|
|
|
30
|
+
export const queryClient = new QueryClient();
|
|
31
|
+
|
|
29
32
|
// collections/products.ts
|
|
30
33
|
import { eq } from 'surrealdb';
|
|
31
|
-
import { db } from '../db';
|
|
34
|
+
import { db, queryClient } from '../db';
|
|
32
35
|
import { createCollection } from '@tanstack/db';
|
|
33
36
|
import { surrealCollectionOptions } from '@foretag/tanstack-db-surrealdb';
|
|
34
37
|
|
|
@@ -42,6 +45,8 @@ type Product = {
|
|
|
42
45
|
export const products = createCollection(
|
|
43
46
|
surrealCollection<Product>({
|
|
44
47
|
db,
|
|
48
|
+
queryKey: ['products'],
|
|
49
|
+
queryClient,
|
|
45
50
|
useLoro: true, // Optional if you need CRDTs
|
|
46
51
|
table: {
|
|
47
52
|
name: 'products',
|
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -113,21 +113,14 @@ function manageTable(db, useLoro, { name, ...args }) {
|
|
|
113
113
|
function toCleanup(res) {
|
|
114
114
|
if (!res) return () => {
|
|
115
115
|
};
|
|
116
|
-
if (typeof res === "function")
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if (typeof res === "object" && res !== null) {
|
|
120
|
-
const r = res;
|
|
121
|
-
const cleanup = r["cleanup"];
|
|
122
|
-
if (typeof cleanup === "function") return cleanup;
|
|
123
|
-
const unsubscribe = r["unsubscribe"];
|
|
124
|
-
if (typeof unsubscribe === "function") return unsubscribe;
|
|
125
|
-
const dispose = r["dispose"];
|
|
126
|
-
if (typeof dispose === "function") return dispose;
|
|
127
|
-
}
|
|
128
|
-
return () => {
|
|
116
|
+
if (typeof res === "function") return res;
|
|
117
|
+
const cleanup = res.cleanup ?? res.unsubscribe ?? res.dispose;
|
|
118
|
+
return typeof cleanup === "function" ? cleanup : () => {
|
|
129
119
|
};
|
|
130
120
|
}
|
|
121
|
+
function hasLoadSubset(res) {
|
|
122
|
+
return typeof res === "object" && res !== null && "loadSubset" in res;
|
|
123
|
+
}
|
|
131
124
|
function surrealCollectionOptions({
|
|
132
125
|
id,
|
|
133
126
|
useLoro = false,
|
|
@@ -169,8 +162,7 @@ function surrealCollectionOptions({
|
|
|
169
162
|
out.push(s);
|
|
170
163
|
continue;
|
|
171
164
|
}
|
|
172
|
-
|
|
173
|
-
if (lDeleted) continue;
|
|
165
|
+
if ((l.sync_deleted ?? false) === true) continue;
|
|
174
166
|
out.push(l);
|
|
175
167
|
}
|
|
176
168
|
return out;
|
|
@@ -239,22 +231,35 @@ function surrealCollectionOptions({
|
|
|
239
231
|
const baseSync = base.sync?.sync;
|
|
240
232
|
const sync = baseSync ? {
|
|
241
233
|
sync: (ctx) => {
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
|
|
234
|
+
const baseRes = baseSync(ctx);
|
|
235
|
+
const baseCleanup = toCleanup(baseRes);
|
|
236
|
+
if (!db.isFeatureSupported(surrealdb.Features.LiveQueries)) {
|
|
237
|
+
return baseRes;
|
|
238
|
+
}
|
|
245
239
|
const offLive = table.subscribe((evt) => {
|
|
246
240
|
if (useLoro) {
|
|
247
|
-
if (evt.type === "delete")
|
|
241
|
+
if (evt.type === "delete") {
|
|
248
242
|
loroRemove(getKey(evt.row));
|
|
249
|
-
else
|
|
243
|
+
} else {
|
|
244
|
+
loroPut(evt.row);
|
|
245
|
+
}
|
|
250
246
|
}
|
|
251
247
|
void queryClient.invalidateQueries({ queryKey, exact: false }).catch((e) => onError?.(e));
|
|
252
248
|
});
|
|
253
|
-
|
|
254
|
-
|
|
249
|
+
if (hasLoadSubset(baseRes)) {
|
|
250
|
+
const resObj = baseRes;
|
|
251
|
+
return {
|
|
252
|
+
...resObj,
|
|
253
|
+
cleanup: () => {
|
|
254
|
+
offLive();
|
|
255
|
+
baseCleanup();
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
return (() => {
|
|
255
260
|
offLive();
|
|
256
261
|
baseCleanup();
|
|
257
|
-
};
|
|
262
|
+
});
|
|
258
263
|
}
|
|
259
264
|
} : void 0;
|
|
260
265
|
return {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/table.ts","../src/index.ts"],"names":["eq","and","Table","Features","LoroDoc","queryCollectionOptions","RecordId"],"mappings":"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","file":"index.js","sourcesContent":["import {\n\tand,\n\ttype ExprLike,\n\teq,\n\tFeatures,\n\ttype LiveMessage,\n\ttype LiveSubscription,\n\ttype RecordId,\n\ttype Surreal,\n\tTable,\n} from 'surrealdb';\n\nimport type {\n\tFieldList,\n\tSurrealField,\n\tSurrealSubset,\n\tTableOptions,\n} from './types';\n\nconst normalizeFields = <T>(\n\traw: FieldList<T> | undefined,\n): ReadonlyArray<SurrealField<T>> => {\n\tif (!raw || raw === '*') return ['*' as SurrealField<T>];\n\treturn raw;\n};\n\nconst joinOrderBy = (\n\to: string | readonly string[] | undefined,\n): string | undefined => {\n\tif (!o) return undefined;\n\treturn typeof o === 'string' ? o : o.join(', ');\n};\n\ntype QueryResult<T> = T[] | null;\n\nexport function manageTable<T extends { id: string | RecordId }>(\n\tdb: Surreal,\n\tuseLoro: boolean,\n\t{ name, ...args }: TableOptions<T>,\n) {\n\tconst fields = normalizeFields<T>(args.fields);\n\n\tconst baseWhere = (): ExprLike | undefined => {\n\t\tif (!useLoro) return args.where;\n\t\tconst alive = eq('sync_deleted', false);\n\t\treturn args.where ? and(args.where, alive) : alive;\n\t};\n\n\tconst listAll = async (): Promise<T[]> => {\n\t\tconst where = baseWhere();\n\t\tconst whereSql = where ? ' WHERE $where' : '';\n\t\tconst sql = `SELECT ${fields.join(', ')} FROM type::table($table)${whereSql};`;\n\t\tconst [res] = await db.query<[QueryResult<T>]>(sql, {\n\t\t\ttable: name,\n\t\t\twhere,\n\t\t});\n\t\treturn res ?? [];\n\t};\n\n\tconst loadSubset = async (subset?: SurrealSubset): Promise<T[]> => {\n\t\tconst b = baseWhere();\n\t\tconst w = subset?.where;\n\t\tconst where = b && w ? and(b, w) : (b ?? w);\n\n\t\tconst whereSql = where ? ' WHERE $where' : '';\n\t\tconst order = joinOrderBy(subset?.orderBy);\n\t\tconst orderSql = order ? ` ORDER BY ${order}` : '';\n\t\tconst limitSql =\n\t\t\ttypeof subset?.limit === 'number' ? ' LIMIT $limit' : '';\n\t\tconst startSql =\n\t\t\ttypeof subset?.offset === 'number' ? ' START $offset' : '';\n\n\t\tconst sql = `SELECT ${fields.join(', ')} FROM type::table($table)${whereSql}${orderSql}${limitSql}${startSql};`;\n\n\t\tconst [res] = await db.query<[QueryResult<T>]>(sql, {\n\t\t\ttable: name,\n\t\t\twhere,\n\t\t\tlimit: subset?.limit,\n\t\t\toffset: subset?.offset,\n\t\t});\n\n\t\treturn res ?? [];\n\t};\n\n\tconst create = async (data: T | Partial<T>) => {\n\t\tawait db.create(new Table(name)).content(data);\n\t};\n\n\tconst update = async (id: RecordId, data: T | Partial<T>) => {\n\t\tif (!useLoro) {\n\t\t\tawait db.update(id).merge(data);\n\t\t\treturn;\n\t\t}\n\t\tawait db.update(id).merge({\n\t\t\t...data,\n\t\t\tsync_deleted: false,\n\t\t\tupdated_at: Date.now(),\n\t\t});\n\t};\n\n\tconst remove = async (id: RecordId) => {\n\t\tawait db.delete(id);\n\t};\n\n\tconst softDelete = async (id: RecordId) => {\n\t\tif (!useLoro) {\n\t\t\tawait db.delete(id);\n\t\t\treturn;\n\t\t}\n\t\tawait db.upsert(id).merge({\n\t\t\tsync_deleted: true,\n\t\t\tupdated_at: Date.now(),\n\t\t});\n\t};\n\n\tconst subscribe = (\n\t\tcb: (e: { type: 'insert' | 'update' | 'delete'; row: T }) => void,\n\t) => {\n\t\tlet killed = false;\n\t\tlet live: LiveSubscription | undefined;\n\n\t\tconst on = (msg: LiveMessage) => {\n\t\t\tconst { action, value } = msg as unknown as {\n\t\t\t\taction: 'CREATE' | 'UPDATE' | 'DELETE' | 'KILLED';\n\t\t\t\tvalue: T & { id: string | RecordId };\n\t\t\t};\n\n\t\t\tif (action === 'KILLED') return;\n\n\t\t\tif (action === 'CREATE') cb({ type: 'insert', row: value });\n\t\t\telse if (action === 'UPDATE') cb({ type: 'update', row: value });\n\t\t\telse if (action === 'DELETE')\n\t\t\t\tcb({ type: 'delete', row: { id: value.id } as T });\n\t\t};\n\n\t\tconst start = async () => {\n\t\t\tif (!db.isFeatureSupported(Features.LiveQueries)) return;\n\t\t\tlive = await db.live(new Table(name)).where(args.where);\n\t\t\tlive.subscribe(on);\n\t\t};\n\n\t\tvoid start();\n\n\t\treturn () => {\n\t\t\tif (killed) return;\n\t\t\tkilled = true;\n\t\t\tif (live) void live.kill();\n\t\t};\n\t};\n\n\treturn {\n\t\tlistAll,\n\t\tloadSubset,\n\t\tcreate,\n\t\tupdate,\n\t\tremove,\n\t\tsoftDelete,\n\t\tsubscribe,\n\t};\n}\n","import type {\n\tCollectionConfig,\n\tDeleteMutationFn,\n\tDeleteMutationFnParams,\n\tInsertMutationFn,\n\tInsertMutationFnParams,\n\tStandardSchema,\n\tUpdateMutationFn,\n\tUpdateMutationFnParams,\n\tUtilsRecord,\n} from '@tanstack/db';\nimport { queryCollectionOptions } from '@tanstack/query-db-collection';\nimport { type Container, LoroDoc } from 'loro-crdt';\nimport { Features, RecordId } from 'surrealdb';\n\nimport { manageTable } from './table';\nimport type {\n\tSurrealCollectionConfig,\n\tSurrealSubset,\n\tSyncedTable,\n} from './types';\n\ntype Cleanup = () => void;\n\nexport { SurrealSubset } from './types';\n\nfunction toCleanup(res: unknown): Cleanup {\n\tif (!res) return () => {};\n\n\tif (typeof res === 'function') {\n\t\treturn res as Cleanup;\n\t}\n\n\tif (typeof res === 'object' && res !== null) {\n\t\tconst r = res as Record<string, unknown>;\n\n\t\tconst cleanup = r['cleanup'];\n\t\tif (typeof cleanup === 'function') return cleanup as Cleanup;\n\n\t\tconst unsubscribe = r['unsubscribe'];\n\t\tif (typeof unsubscribe === 'function') return unsubscribe as Cleanup;\n\n\t\tconst dispose = r['dispose'];\n\t\tif (typeof dispose === 'function') return dispose as Cleanup;\n\t}\n\n\treturn () => {};\n}\n\nexport function surrealCollectionOptions<\n\tT extends SyncedTable<object>,\n\tS extends Record<string, Container> = { [k: string]: never },\n>({\n\tid,\n\tuseLoro = false,\n\tonError,\n\tdb,\n\tqueryClient,\n\tqueryKey,\n\tsyncMode = 'eager',\n\t...config\n}: SurrealCollectionConfig<T>): CollectionConfig<\n\tT,\n\tstring | number,\n\tnever,\n\tUtilsRecord\n> {\n\tlet loro: { doc: LoroDoc<S>; key?: string } | undefined;\n\tif (useLoro) loro = { doc: new LoroDoc(), key: id };\n\n\tconst table = manageTable<T>(db, useLoro, config.table);\n\n\tconst keyOf = (rid: RecordId | string): string =>\n\t\ttypeof rid === 'string' ? rid : rid.toString();\n\tconst getKey = (row: { id: string | RecordId }) => keyOf(row.id);\n\n\tconst loroKey = loro?.key ?? id ?? 'surreal';\n\tconst loroMap = useLoro ? (loro?.doc?.getMap?.(loroKey) ?? null) : null;\n\n\tconst loroPut = (row: T) => {\n\t\tif (!loroMap) return;\n\t\tloroMap.set(getKey(row), row as unknown);\n\t\tloro?.doc?.commit?.();\n\t};\n\n\tconst loroRemove = (idStr: string) => {\n\t\tif (!loroMap) return;\n\t\tloroMap.delete(idStr);\n\t\tloro?.doc?.commit?.();\n\t};\n\n\tconst mergeLocalOverServer = (serverRows: T[]): T[] => {\n\t\tif (!useLoro || !loroMap) return serverRows;\n\n\t\tconst localJson = loroMap.toJSON?.() ?? {};\n\t\tconst localById = new Map<string, T>(\n\t\t\tObject.values(localJson).map((r) => [getKey(r as T), r as T]),\n\t\t);\n\n\t\t// Overlay local on top of server when same id exists, and respect local tombstones.\n\t\tconst out: T[] = [];\n\t\tfor (const s of serverRows) {\n\t\t\tconst idStr = getKey(s);\n\t\t\tconst l = localById.get(idStr);\n\n\t\t\tif (!l) {\n\t\t\t\tout.push(s);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst lDeleted = (l.sync_deleted ?? false) === true;\n\t\t\tif (lDeleted) continue;\n\n\t\t\tout.push(l);\n\t\t}\n\n\t\treturn out;\n\t};\n\n\tconst base = queryCollectionOptions<T>({\n\t\tgetKey: (row) => getKey(row),\n\n\t\tqueryKey,\n\t\tqueryClient,\n\n\t\tsyncMode,\n\n\t\tqueryFn: async ({ meta }) => {\n\t\t\ttry {\n\t\t\t\tconst subset =\n\t\t\t\t\tsyncMode === 'on-demand'\n\t\t\t\t\t\t? (meta['surrealSubset'] as SurrealSubset | undefined)\n\t\t\t\t\t\t: undefined;\n\n\t\t\t\tconst rows =\n\t\t\t\t\tsyncMode === 'eager'\n\t\t\t\t\t\t? await table.listAll()\n\t\t\t\t\t\t: await table.loadSubset(subset);\n\n\t\t\t\treturn mergeLocalOverServer(rows);\n\t\t\t} catch (e) {\n\t\t\t\tonError?.(e);\n\t\t\t\treturn [];\n\t\t\t}\n\t\t},\n\n\t\tonInsert: (async (p: InsertMutationFnParams<T>) => {\n\t\t\tconst now = () => new Date();\n\n\t\t\tconst resultRows: T[] = [];\n\t\t\tfor (const m of p.transaction.mutations) {\n\t\t\t\tif (m.type !== 'insert') continue;\n\t\t\t\tconst baseRow = { ...m.modified } as T;\n\n\t\t\t\tconst row = useLoro\n\t\t\t\t\t? ({\n\t\t\t\t\t\t\t...baseRow,\n\t\t\t\t\t\t\tupdated_at: now(),\n\t\t\t\t\t\t\tsync_deleted: false,\n\t\t\t\t\t\t} as T)\n\t\t\t\t\t: baseRow;\n\n\t\t\t\tif (useLoro) loroPut(row);\n\t\t\t\tawait table.create(row);\n\t\t\t\tresultRows.push(row);\n\t\t\t}\n\n\t\t\treturn resultRows as unknown as StandardSchema<T>;\n\t\t}) as InsertMutationFn<T, string, UtilsRecord, StandardSchema<T>>,\n\n\t\tonUpdate: (async (p: UpdateMutationFnParams<T>) => {\n\t\t\tconst now = () => new Date();\n\n\t\t\tconst resultRows: T[] = [];\n\t\t\tfor (const m of p.transaction.mutations) {\n\t\t\t\tif (m.type !== 'update') continue;\n\n\t\t\t\tconst idKey = m.key as RecordId;\n\t\t\t\tconst baseRow = { ...(m.modified as T), id: idKey } as T;\n\n\t\t\t\tconst row = useLoro\n\t\t\t\t\t? ({ ...baseRow, updated_at: now() } as T)\n\t\t\t\t\t: baseRow;\n\n\t\t\t\tif (useLoro) loroPut(row);\n\t\t\t\tawait table.update(\n\t\t\t\t\tnew RecordId(config.table.name, keyOf(idKey)),\n\t\t\t\t\trow,\n\t\t\t\t);\n\t\t\t\tresultRows.push(row);\n\t\t\t}\n\n\t\t\treturn resultRows as unknown as StandardSchema<T>;\n\t\t}) as UpdateMutationFn<T, string, UtilsRecord, StandardSchema<T>>,\n\n\t\tonDelete: (async (p: DeleteMutationFnParams<T>) => {\n\t\t\tfor (const m of p.transaction.mutations) {\n\t\t\t\tif (m.type !== 'delete') continue;\n\n\t\t\t\tconst idKey = m.key as RecordId;\n\t\t\t\tif (useLoro) loroRemove(keyOf(idKey));\n\n\t\t\t\tawait table.softDelete(\n\t\t\t\t\tnew RecordId(config.table.name, keyOf(idKey)),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn [] as unknown as StandardSchema<T>;\n\t\t}) as DeleteMutationFn<T, string, UtilsRecord, StandardSchema<T>>,\n\t});\n\n\t// LIVE updates -> invalidate all subsets under base queryKey\n\tconst baseSync = base.sync?.sync;\n\n\tconst sync = baseSync\n\t\t? {\n\t\t\t\tsync: (ctx: Parameters<NonNullable<typeof baseSync>>[0]) => {\n\t\t\t\t\tconst offBase = baseSync(ctx);\n\n\t\t\t\t\tif (!db.isFeatureSupported(Features.LiveQueries))\n\t\t\t\t\t\treturn offBase;\n\n\t\t\t\t\tconst offLive = table.subscribe((evt) => {\n\t\t\t\t\t\t// Keep Loro in sync with server pushes\n\t\t\t\t\t\tif (useLoro) {\n\t\t\t\t\t\t\tif (evt.type === 'delete')\n\t\t\t\t\t\t\t\tloroRemove(getKey(evt.row));\n\t\t\t\t\t\t\telse loroPut(evt.row);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvoid queryClient\n\t\t\t\t\t\t\t.invalidateQueries({ queryKey, exact: false })\n\t\t\t\t\t\t\t.catch((e) => onError?.(e));\n\t\t\t\t\t});\n\n\t\t\t\t\tconst baseCleanup = toCleanup(baseSync(ctx));\n\n\t\t\t\t\treturn () => {\n\t\t\t\t\t\toffLive();\n\t\t\t\t\t\tbaseCleanup();\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t}\n\t\t: undefined;\n\n\treturn {\n\t\t...base,\n\t\tsync: sync ?? base.sync,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/table.ts","../src/index.ts"],"names":["eq","and","Table","Features","LoroDoc","queryCollectionOptions","RecordId"],"mappings":"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","file":"index.js","sourcesContent":["import {\n\tand,\n\ttype ExprLike,\n\teq,\n\tFeatures,\n\ttype LiveMessage,\n\ttype LiveSubscription,\n\ttype RecordId,\n\ttype Surreal,\n\tTable,\n} from 'surrealdb';\n\nimport type {\n\tFieldList,\n\tSurrealField,\n\tSurrealSubset,\n\tTableOptions,\n} from './types';\n\nconst normalizeFields = <T>(\n\traw: FieldList<T> | undefined,\n): ReadonlyArray<SurrealField<T>> => {\n\tif (!raw || raw === '*') return ['*' as SurrealField<T>];\n\treturn raw;\n};\n\nconst joinOrderBy = (\n\to: string | readonly string[] | undefined,\n): string | undefined => {\n\tif (!o) return undefined;\n\treturn typeof o === 'string' ? o : o.join(', ');\n};\n\ntype QueryResult<T> = T[] | null;\n\nexport function manageTable<T extends { id: string | RecordId }>(\n\tdb: Surreal,\n\tuseLoro: boolean,\n\t{ name, ...args }: TableOptions<T>,\n) {\n\tconst fields = normalizeFields<T>(args.fields);\n\n\tconst baseWhere = (): ExprLike | undefined => {\n\t\tif (!useLoro) return args.where;\n\t\tconst alive = eq('sync_deleted', false);\n\t\treturn args.where ? and(args.where, alive) : alive;\n\t};\n\n\tconst listAll = async (): Promise<T[]> => {\n\t\tconst where = baseWhere();\n\t\tconst whereSql = where ? ' WHERE $where' : '';\n\t\tconst sql = `SELECT ${fields.join(', ')} FROM type::table($table)${whereSql};`;\n\t\tconst [res] = await db.query<[QueryResult<T>]>(sql, {\n\t\t\ttable: name,\n\t\t\twhere,\n\t\t});\n\t\treturn res ?? [];\n\t};\n\n\tconst loadSubset = async (subset?: SurrealSubset): Promise<T[]> => {\n\t\tconst b = baseWhere();\n\t\tconst w = subset?.where;\n\t\tconst where = b && w ? and(b, w) : (b ?? w);\n\n\t\tconst whereSql = where ? ' WHERE $where' : '';\n\t\tconst order = joinOrderBy(subset?.orderBy);\n\t\tconst orderSql = order ? ` ORDER BY ${order}` : '';\n\t\tconst limitSql =\n\t\t\ttypeof subset?.limit === 'number' ? ' LIMIT $limit' : '';\n\t\tconst startSql =\n\t\t\ttypeof subset?.offset === 'number' ? ' START $offset' : '';\n\n\t\tconst sql = `SELECT ${fields.join(', ')} FROM type::table($table)${whereSql}${orderSql}${limitSql}${startSql};`;\n\n\t\tconst [res] = await db.query<[QueryResult<T>]>(sql, {\n\t\t\ttable: name,\n\t\t\twhere,\n\t\t\tlimit: subset?.limit,\n\t\t\toffset: subset?.offset,\n\t\t});\n\n\t\treturn res ?? [];\n\t};\n\n\tconst create = async (data: T | Partial<T>) => {\n\t\tawait db.create(new Table(name)).content(data);\n\t};\n\n\tconst update = async (id: RecordId, data: T | Partial<T>) => {\n\t\tif (!useLoro) {\n\t\t\tawait db.update(id).merge(data);\n\t\t\treturn;\n\t\t}\n\t\tawait db.update(id).merge({\n\t\t\t...data,\n\t\t\tsync_deleted: false,\n\t\t\tupdated_at: Date.now(),\n\t\t});\n\t};\n\n\tconst remove = async (id: RecordId) => {\n\t\tawait db.delete(id);\n\t};\n\n\tconst softDelete = async (id: RecordId) => {\n\t\tif (!useLoro) {\n\t\t\tawait db.delete(id);\n\t\t\treturn;\n\t\t}\n\t\tawait db.upsert(id).merge({\n\t\t\tsync_deleted: true,\n\t\t\tupdated_at: Date.now(),\n\t\t});\n\t};\n\n\tconst subscribe = (\n\t\tcb: (e: { type: 'insert' | 'update' | 'delete'; row: T }) => void,\n\t) => {\n\t\tlet killed = false;\n\t\tlet live: LiveSubscription | undefined;\n\n\t\tconst on = (msg: LiveMessage) => {\n\t\t\tconst { action, value } = msg as unknown as {\n\t\t\t\taction: 'CREATE' | 'UPDATE' | 'DELETE' | 'KILLED';\n\t\t\t\tvalue: T & { id: string | RecordId };\n\t\t\t};\n\n\t\t\tif (action === 'KILLED') return;\n\n\t\t\tif (action === 'CREATE') cb({ type: 'insert', row: value });\n\t\t\telse if (action === 'UPDATE') cb({ type: 'update', row: value });\n\t\t\telse if (action === 'DELETE')\n\t\t\t\tcb({ type: 'delete', row: { id: value.id } as T });\n\t\t};\n\n\t\tconst start = async () => {\n\t\t\tif (!db.isFeatureSupported(Features.LiveQueries)) return;\n\t\t\tlive = await db.live(new Table(name)).where(args.where);\n\t\t\tlive.subscribe(on);\n\t\t};\n\n\t\tvoid start();\n\n\t\treturn () => {\n\t\t\tif (killed) return;\n\t\t\tkilled = true;\n\t\t\tif (live) void live.kill();\n\t\t};\n\t};\n\n\treturn {\n\t\tlistAll,\n\t\tloadSubset,\n\t\tcreate,\n\t\tupdate,\n\t\tremove,\n\t\tsoftDelete,\n\t\tsubscribe,\n\t};\n}\n","import type {\n\tCollectionConfig,\n\tDeleteMutationFn,\n\tDeleteMutationFnParams,\n\tInsertMutationFn,\n\tInsertMutationFnParams,\n\tStandardSchema,\n\tUpdateMutationFn,\n\tUpdateMutationFnParams,\n\tUtilsRecord,\n} from '@tanstack/db';\nimport { queryCollectionOptions } from '@tanstack/query-db-collection';\nimport { type Container, LoroDoc } from 'loro-crdt';\nimport { Features, RecordId } from 'surrealdb';\n\nimport { manageTable } from './table';\nimport type {\n\tSurrealCollectionConfig,\n\tSurrealSubset,\n\tSyncedTable,\n} from './types';\n\ntype Cleanup = () => void;\n\nexport { SurrealSubset } from './types';\n\ntype SyncReturn =\n\t| void\n\t| Cleanup\n\t| {\n\t\t\tcleanup?: Cleanup;\n\t\t\tunsubscribe?: Cleanup;\n\t\t\tdispose?: Cleanup;\n\t\t\tloadSubset?: unknown; // keep unknown; Only pass through\n\t };\n\nfunction toCleanup(res: SyncReturn): Cleanup {\n\tif (!res) return () => {};\n\tif (typeof res === 'function') return res;\n\n\tconst cleanup = res.cleanup ?? res.unsubscribe ?? res.dispose;\n\n\treturn typeof cleanup === 'function' ? cleanup : () => {};\n}\n\nfunction hasLoadSubset(\n\tres: SyncReturn,\n): res is { loadSubset: unknown } & Record<string, unknown> {\n\treturn typeof res === 'object' && res !== null && 'loadSubset' in res;\n}\n\nexport function surrealCollectionOptions<\n\tT extends SyncedTable<object>,\n\tS extends Record<string, Container> = { [k: string]: never },\n>({\n\tid,\n\tuseLoro = false,\n\tonError,\n\tdb,\n\tqueryClient,\n\tqueryKey,\n\tsyncMode = 'eager',\n\t...config\n}: SurrealCollectionConfig<T>): CollectionConfig<\n\tT,\n\tstring | number,\n\tnever,\n\tUtilsRecord\n> {\n\tlet loro: { doc: LoroDoc<S>; key?: string } | undefined;\n\tif (useLoro) loro = { doc: new LoroDoc(), key: id };\n\n\tconst table = manageTable<T>(db, useLoro, config.table);\n\n\tconst keyOf = (rid: RecordId | string): string =>\n\t\ttypeof rid === 'string' ? rid : rid.toString();\n\n\tconst getKey = (row: { id: string | RecordId }) => keyOf(row.id);\n\n\tconst loroKey = loro?.key ?? id ?? 'surreal';\n\tconst loroMap = useLoro ? (loro?.doc?.getMap?.(loroKey) ?? null) : null;\n\n\tconst loroPut = (row: T) => {\n\t\tif (!loroMap) return;\n\t\tloroMap.set(getKey(row), row as unknown);\n\t\tloro?.doc?.commit?.();\n\t};\n\n\tconst loroRemove = (idStr: string) => {\n\t\tif (!loroMap) return;\n\t\tloroMap.delete(idStr);\n\t\tloro?.doc?.commit?.();\n\t};\n\n\tconst mergeLocalOverServer = (serverRows: T[]): T[] => {\n\t\tif (!useLoro || !loroMap) return serverRows;\n\n\t\tconst localJson = loroMap.toJSON?.() ?? {};\n\t\tconst localById = new Map<string, T>(\n\t\t\tObject.values(localJson).map((r) => [getKey(r as T), r as T]),\n\t\t);\n\n\t\tconst out: T[] = [];\n\t\tfor (const s of serverRows) {\n\t\t\tconst idStr = getKey(s);\n\t\t\tconst l = localById.get(idStr);\n\n\t\t\tif (!l) {\n\t\t\t\tout.push(s);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ((l.sync_deleted ?? false) === true) continue;\n\t\t\tout.push(l);\n\t\t}\n\n\t\treturn out;\n\t};\n\n\tconst base = queryCollectionOptions<T>({\n\t\tgetKey: (row) => getKey(row),\n\n\t\tqueryKey,\n\t\tqueryClient,\n\n\t\tsyncMode,\n\n\t\tqueryFn: async ({ meta }) => {\n\t\t\ttry {\n\t\t\t\tconst subset =\n\t\t\t\t\tsyncMode === 'on-demand'\n\t\t\t\t\t\t? (meta['surrealSubset'] as SurrealSubset | undefined)\n\t\t\t\t\t\t: undefined;\n\n\t\t\t\tconst rows =\n\t\t\t\t\tsyncMode === 'eager'\n\t\t\t\t\t\t? await table.listAll()\n\t\t\t\t\t\t: await table.loadSubset(subset);\n\n\t\t\t\treturn mergeLocalOverServer(rows);\n\t\t\t} catch (e) {\n\t\t\t\tonError?.(e);\n\t\t\t\treturn [];\n\t\t\t}\n\t\t},\n\n\t\tonInsert: (async (p: InsertMutationFnParams<T>) => {\n\t\t\tconst now = () => new Date();\n\n\t\t\tconst resultRows: T[] = [];\n\t\t\tfor (const m of p.transaction.mutations) {\n\t\t\t\tif (m.type !== 'insert') continue;\n\n\t\t\t\tconst baseRow = { ...m.modified } as T;\n\n\t\t\t\tconst row = useLoro\n\t\t\t\t\t? ({\n\t\t\t\t\t\t\t...baseRow,\n\t\t\t\t\t\t\tupdated_at: now(),\n\t\t\t\t\t\t\tsync_deleted: false,\n\t\t\t\t\t\t} as T)\n\t\t\t\t\t: baseRow;\n\n\t\t\t\tif (useLoro) loroPut(row);\n\t\t\t\tawait table.create(row);\n\t\t\t\tresultRows.push(row);\n\t\t\t}\n\n\t\t\treturn resultRows as unknown as StandardSchema<T>;\n\t\t}) as InsertMutationFn<T, string, UtilsRecord, StandardSchema<T>>,\n\n\t\tonUpdate: (async (p: UpdateMutationFnParams<T>) => {\n\t\t\tconst now = () => new Date();\n\n\t\t\tconst resultRows: T[] = [];\n\t\t\tfor (const m of p.transaction.mutations) {\n\t\t\t\tif (m.type !== 'update') continue;\n\n\t\t\t\tconst idKey = m.key as RecordId;\n\t\t\t\tconst baseRow = { ...(m.modified as T), id: idKey } as T;\n\n\t\t\t\tconst row = useLoro\n\t\t\t\t\t? ({ ...baseRow, updated_at: now() } as T)\n\t\t\t\t\t: baseRow;\n\n\t\t\t\tif (useLoro) loroPut(row);\n\n\t\t\t\tawait table.update(\n\t\t\t\t\tnew RecordId(config.table.name, keyOf(idKey)),\n\t\t\t\t\trow,\n\t\t\t\t);\n\n\t\t\t\tresultRows.push(row);\n\t\t\t}\n\n\t\t\treturn resultRows as unknown as StandardSchema<T>;\n\t\t}) as UpdateMutationFn<T, string, UtilsRecord, StandardSchema<T>>,\n\n\t\tonDelete: (async (p: DeleteMutationFnParams<T>) => {\n\t\t\tfor (const m of p.transaction.mutations) {\n\t\t\t\tif (m.type !== 'delete') continue;\n\n\t\t\t\tconst idKey = m.key as RecordId;\n\t\t\t\tif (useLoro) loroRemove(keyOf(idKey));\n\n\t\t\t\tawait table.softDelete(\n\t\t\t\t\tnew RecordId(config.table.name, keyOf(idKey)),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn [] as unknown as StandardSchema<T>;\n\t\t}) as DeleteMutationFn<T, string, UtilsRecord, StandardSchema<T>>,\n\t});\n\n\t// LIVE updates -> invalidate all subsets under base queryKey\n\tconst baseSync = base.sync?.sync;\n\n\tconst sync = baseSync\n\t\t? {\n\t\t\t\tsync: (ctx: Parameters<NonNullable<typeof baseSync>>[0]) => {\n\t\t\t\t\t// IMPORTANT: call baseSync exactly once\n\t\t\t\t\tconst baseRes = baseSync(ctx) as SyncReturn;\n\t\t\t\t\tconst baseCleanup = toCleanup(baseRes);\n\n\t\t\t\t\t// If live queries aren't supported, return the base result untouched\n\t\t\t\t\tif (!db.isFeatureSupported(Features.LiveQueries)) {\n\t\t\t\t\t\treturn baseRes as unknown as ReturnType<\n\t\t\t\t\t\t\tNonNullable<typeof baseSync>\n\t\t\t\t\t\t>;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst offLive = table.subscribe((evt) => {\n\t\t\t\t\t\tif (useLoro) {\n\t\t\t\t\t\t\tif (evt.type === 'delete') {\n\t\t\t\t\t\t\t\tloroRemove(getKey(evt.row));\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tloroPut(evt.row);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvoid queryClient\n\t\t\t\t\t\t\t.invalidateQueries({ queryKey, exact: false })\n\t\t\t\t\t\t\t.catch((e) => onError?.(e));\n\t\t\t\t\t});\n\n\t\t\t\t\t// Preserve base return shape, just wrap cleanup\n\t\t\t\t\tif (hasLoadSubset(baseRes)) {\n\t\t\t\t\t\t// on-demand mode relies on this being present\n\t\t\t\t\t\tconst resObj = baseRes as Record<string, unknown>;\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...resObj,\n\t\t\t\t\t\t\tcleanup: () => {\n\t\t\t\t\t\t\t\toffLive();\n\t\t\t\t\t\t\t\tbaseCleanup();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t} as unknown as ReturnType<\n\t\t\t\t\t\t\tNonNullable<typeof baseSync>\n\t\t\t\t\t\t>;\n\t\t\t\t\t}\n\n\t\t\t\t\t// eager mode usually returns a cleanup function\n\t\t\t\t\treturn (() => {\n\t\t\t\t\t\toffLive();\n\t\t\t\t\t\tbaseCleanup();\n\t\t\t\t\t}) as unknown as ReturnType<NonNullable<typeof baseSync>>;\n\t\t\t\t},\n\t\t\t}\n\t\t: undefined;\n\n\treturn {\n\t\t...base,\n\t\tsync: sync ?? base.sync,\n\t};\n}\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -111,21 +111,14 @@ function manageTable(db, useLoro, { name, ...args }) {
|
|
|
111
111
|
function toCleanup(res) {
|
|
112
112
|
if (!res) return () => {
|
|
113
113
|
};
|
|
114
|
-
if (typeof res === "function")
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
if (typeof res === "object" && res !== null) {
|
|
118
|
-
const r = res;
|
|
119
|
-
const cleanup = r["cleanup"];
|
|
120
|
-
if (typeof cleanup === "function") return cleanup;
|
|
121
|
-
const unsubscribe = r["unsubscribe"];
|
|
122
|
-
if (typeof unsubscribe === "function") return unsubscribe;
|
|
123
|
-
const dispose = r["dispose"];
|
|
124
|
-
if (typeof dispose === "function") return dispose;
|
|
125
|
-
}
|
|
126
|
-
return () => {
|
|
114
|
+
if (typeof res === "function") return res;
|
|
115
|
+
const cleanup = res.cleanup ?? res.unsubscribe ?? res.dispose;
|
|
116
|
+
return typeof cleanup === "function" ? cleanup : () => {
|
|
127
117
|
};
|
|
128
118
|
}
|
|
119
|
+
function hasLoadSubset(res) {
|
|
120
|
+
return typeof res === "object" && res !== null && "loadSubset" in res;
|
|
121
|
+
}
|
|
129
122
|
function surrealCollectionOptions({
|
|
130
123
|
id,
|
|
131
124
|
useLoro = false,
|
|
@@ -167,8 +160,7 @@ function surrealCollectionOptions({
|
|
|
167
160
|
out.push(s);
|
|
168
161
|
continue;
|
|
169
162
|
}
|
|
170
|
-
|
|
171
|
-
if (lDeleted) continue;
|
|
163
|
+
if ((l.sync_deleted ?? false) === true) continue;
|
|
172
164
|
out.push(l);
|
|
173
165
|
}
|
|
174
166
|
return out;
|
|
@@ -237,22 +229,35 @@ function surrealCollectionOptions({
|
|
|
237
229
|
const baseSync = base.sync?.sync;
|
|
238
230
|
const sync = baseSync ? {
|
|
239
231
|
sync: (ctx) => {
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
232
|
+
const baseRes = baseSync(ctx);
|
|
233
|
+
const baseCleanup = toCleanup(baseRes);
|
|
234
|
+
if (!db.isFeatureSupported(Features.LiveQueries)) {
|
|
235
|
+
return baseRes;
|
|
236
|
+
}
|
|
243
237
|
const offLive = table.subscribe((evt) => {
|
|
244
238
|
if (useLoro) {
|
|
245
|
-
if (evt.type === "delete")
|
|
239
|
+
if (evt.type === "delete") {
|
|
246
240
|
loroRemove(getKey(evt.row));
|
|
247
|
-
else
|
|
241
|
+
} else {
|
|
242
|
+
loroPut(evt.row);
|
|
243
|
+
}
|
|
248
244
|
}
|
|
249
245
|
void queryClient.invalidateQueries({ queryKey, exact: false }).catch((e) => onError?.(e));
|
|
250
246
|
});
|
|
251
|
-
|
|
252
|
-
|
|
247
|
+
if (hasLoadSubset(baseRes)) {
|
|
248
|
+
const resObj = baseRes;
|
|
249
|
+
return {
|
|
250
|
+
...resObj,
|
|
251
|
+
cleanup: () => {
|
|
252
|
+
offLive();
|
|
253
|
+
baseCleanup();
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
return (() => {
|
|
253
258
|
offLive();
|
|
254
259
|
baseCleanup();
|
|
255
|
-
};
|
|
260
|
+
});
|
|
256
261
|
}
|
|
257
262
|
} : void 0;
|
|
258
263
|
return {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/table.ts","../src/index.ts"],"names":["Features"],"mappings":"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","file":"index.mjs","sourcesContent":["import {\n\tand,\n\ttype ExprLike,\n\teq,\n\tFeatures,\n\ttype LiveMessage,\n\ttype LiveSubscription,\n\ttype RecordId,\n\ttype Surreal,\n\tTable,\n} from 'surrealdb';\n\nimport type {\n\tFieldList,\n\tSurrealField,\n\tSurrealSubset,\n\tTableOptions,\n} from './types';\n\nconst normalizeFields = <T>(\n\traw: FieldList<T> | undefined,\n): ReadonlyArray<SurrealField<T>> => {\n\tif (!raw || raw === '*') return ['*' as SurrealField<T>];\n\treturn raw;\n};\n\nconst joinOrderBy = (\n\to: string | readonly string[] | undefined,\n): string | undefined => {\n\tif (!o) return undefined;\n\treturn typeof o === 'string' ? o : o.join(', ');\n};\n\ntype QueryResult<T> = T[] | null;\n\nexport function manageTable<T extends { id: string | RecordId }>(\n\tdb: Surreal,\n\tuseLoro: boolean,\n\t{ name, ...args }: TableOptions<T>,\n) {\n\tconst fields = normalizeFields<T>(args.fields);\n\n\tconst baseWhere = (): ExprLike | undefined => {\n\t\tif (!useLoro) return args.where;\n\t\tconst alive = eq('sync_deleted', false);\n\t\treturn args.where ? and(args.where, alive) : alive;\n\t};\n\n\tconst listAll = async (): Promise<T[]> => {\n\t\tconst where = baseWhere();\n\t\tconst whereSql = where ? ' WHERE $where' : '';\n\t\tconst sql = `SELECT ${fields.join(', ')} FROM type::table($table)${whereSql};`;\n\t\tconst [res] = await db.query<[QueryResult<T>]>(sql, {\n\t\t\ttable: name,\n\t\t\twhere,\n\t\t});\n\t\treturn res ?? [];\n\t};\n\n\tconst loadSubset = async (subset?: SurrealSubset): Promise<T[]> => {\n\t\tconst b = baseWhere();\n\t\tconst w = subset?.where;\n\t\tconst where = b && w ? and(b, w) : (b ?? w);\n\n\t\tconst whereSql = where ? ' WHERE $where' : '';\n\t\tconst order = joinOrderBy(subset?.orderBy);\n\t\tconst orderSql = order ? ` ORDER BY ${order}` : '';\n\t\tconst limitSql =\n\t\t\ttypeof subset?.limit === 'number' ? ' LIMIT $limit' : '';\n\t\tconst startSql =\n\t\t\ttypeof subset?.offset === 'number' ? ' START $offset' : '';\n\n\t\tconst sql = `SELECT ${fields.join(', ')} FROM type::table($table)${whereSql}${orderSql}${limitSql}${startSql};`;\n\n\t\tconst [res] = await db.query<[QueryResult<T>]>(sql, {\n\t\t\ttable: name,\n\t\t\twhere,\n\t\t\tlimit: subset?.limit,\n\t\t\toffset: subset?.offset,\n\t\t});\n\n\t\treturn res ?? [];\n\t};\n\n\tconst create = async (data: T | Partial<T>) => {\n\t\tawait db.create(new Table(name)).content(data);\n\t};\n\n\tconst update = async (id: RecordId, data: T | Partial<T>) => {\n\t\tif (!useLoro) {\n\t\t\tawait db.update(id).merge(data);\n\t\t\treturn;\n\t\t}\n\t\tawait db.update(id).merge({\n\t\t\t...data,\n\t\t\tsync_deleted: false,\n\t\t\tupdated_at: Date.now(),\n\t\t});\n\t};\n\n\tconst remove = async (id: RecordId) => {\n\t\tawait db.delete(id);\n\t};\n\n\tconst softDelete = async (id: RecordId) => {\n\t\tif (!useLoro) {\n\t\t\tawait db.delete(id);\n\t\t\treturn;\n\t\t}\n\t\tawait db.upsert(id).merge({\n\t\t\tsync_deleted: true,\n\t\t\tupdated_at: Date.now(),\n\t\t});\n\t};\n\n\tconst subscribe = (\n\t\tcb: (e: { type: 'insert' | 'update' | 'delete'; row: T }) => void,\n\t) => {\n\t\tlet killed = false;\n\t\tlet live: LiveSubscription | undefined;\n\n\t\tconst on = (msg: LiveMessage) => {\n\t\t\tconst { action, value } = msg as unknown as {\n\t\t\t\taction: 'CREATE' | 'UPDATE' | 'DELETE' | 'KILLED';\n\t\t\t\tvalue: T & { id: string | RecordId };\n\t\t\t};\n\n\t\t\tif (action === 'KILLED') return;\n\n\t\t\tif (action === 'CREATE') cb({ type: 'insert', row: value });\n\t\t\telse if (action === 'UPDATE') cb({ type: 'update', row: value });\n\t\t\telse if (action === 'DELETE')\n\t\t\t\tcb({ type: 'delete', row: { id: value.id } as T });\n\t\t};\n\n\t\tconst start = async () => {\n\t\t\tif (!db.isFeatureSupported(Features.LiveQueries)) return;\n\t\t\tlive = await db.live(new Table(name)).where(args.where);\n\t\t\tlive.subscribe(on);\n\t\t};\n\n\t\tvoid start();\n\n\t\treturn () => {\n\t\t\tif (killed) return;\n\t\t\tkilled = true;\n\t\t\tif (live) void live.kill();\n\t\t};\n\t};\n\n\treturn {\n\t\tlistAll,\n\t\tloadSubset,\n\t\tcreate,\n\t\tupdate,\n\t\tremove,\n\t\tsoftDelete,\n\t\tsubscribe,\n\t};\n}\n","import type {\n\tCollectionConfig,\n\tDeleteMutationFn,\n\tDeleteMutationFnParams,\n\tInsertMutationFn,\n\tInsertMutationFnParams,\n\tStandardSchema,\n\tUpdateMutationFn,\n\tUpdateMutationFnParams,\n\tUtilsRecord,\n} from '@tanstack/db';\nimport { queryCollectionOptions } from '@tanstack/query-db-collection';\nimport { type Container, LoroDoc } from 'loro-crdt';\nimport { Features, RecordId } from 'surrealdb';\n\nimport { manageTable } from './table';\nimport type {\n\tSurrealCollectionConfig,\n\tSurrealSubset,\n\tSyncedTable,\n} from './types';\n\ntype Cleanup = () => void;\n\nexport { SurrealSubset } from './types';\n\nfunction toCleanup(res: unknown): Cleanup {\n\tif (!res) return () => {};\n\n\tif (typeof res === 'function') {\n\t\treturn res as Cleanup;\n\t}\n\n\tif (typeof res === 'object' && res !== null) {\n\t\tconst r = res as Record<string, unknown>;\n\n\t\tconst cleanup = r['cleanup'];\n\t\tif (typeof cleanup === 'function') return cleanup as Cleanup;\n\n\t\tconst unsubscribe = r['unsubscribe'];\n\t\tif (typeof unsubscribe === 'function') return unsubscribe as Cleanup;\n\n\t\tconst dispose = r['dispose'];\n\t\tif (typeof dispose === 'function') return dispose as Cleanup;\n\t}\n\n\treturn () => {};\n}\n\nexport function surrealCollectionOptions<\n\tT extends SyncedTable<object>,\n\tS extends Record<string, Container> = { [k: string]: never },\n>({\n\tid,\n\tuseLoro = false,\n\tonError,\n\tdb,\n\tqueryClient,\n\tqueryKey,\n\tsyncMode = 'eager',\n\t...config\n}: SurrealCollectionConfig<T>): CollectionConfig<\n\tT,\n\tstring | number,\n\tnever,\n\tUtilsRecord\n> {\n\tlet loro: { doc: LoroDoc<S>; key?: string } | undefined;\n\tif (useLoro) loro = { doc: new LoroDoc(), key: id };\n\n\tconst table = manageTable<T>(db, useLoro, config.table);\n\n\tconst keyOf = (rid: RecordId | string): string =>\n\t\ttypeof rid === 'string' ? rid : rid.toString();\n\tconst getKey = (row: { id: string | RecordId }) => keyOf(row.id);\n\n\tconst loroKey = loro?.key ?? id ?? 'surreal';\n\tconst loroMap = useLoro ? (loro?.doc?.getMap?.(loroKey) ?? null) : null;\n\n\tconst loroPut = (row: T) => {\n\t\tif (!loroMap) return;\n\t\tloroMap.set(getKey(row), row as unknown);\n\t\tloro?.doc?.commit?.();\n\t};\n\n\tconst loroRemove = (idStr: string) => {\n\t\tif (!loroMap) return;\n\t\tloroMap.delete(idStr);\n\t\tloro?.doc?.commit?.();\n\t};\n\n\tconst mergeLocalOverServer = (serverRows: T[]): T[] => {\n\t\tif (!useLoro || !loroMap) return serverRows;\n\n\t\tconst localJson = loroMap.toJSON?.() ?? {};\n\t\tconst localById = new Map<string, T>(\n\t\t\tObject.values(localJson).map((r) => [getKey(r as T), r as T]),\n\t\t);\n\n\t\t// Overlay local on top of server when same id exists, and respect local tombstones.\n\t\tconst out: T[] = [];\n\t\tfor (const s of serverRows) {\n\t\t\tconst idStr = getKey(s);\n\t\t\tconst l = localById.get(idStr);\n\n\t\t\tif (!l) {\n\t\t\t\tout.push(s);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst lDeleted = (l.sync_deleted ?? false) === true;\n\t\t\tif (lDeleted) continue;\n\n\t\t\tout.push(l);\n\t\t}\n\n\t\treturn out;\n\t};\n\n\tconst base = queryCollectionOptions<T>({\n\t\tgetKey: (row) => getKey(row),\n\n\t\tqueryKey,\n\t\tqueryClient,\n\n\t\tsyncMode,\n\n\t\tqueryFn: async ({ meta }) => {\n\t\t\ttry {\n\t\t\t\tconst subset =\n\t\t\t\t\tsyncMode === 'on-demand'\n\t\t\t\t\t\t? (meta['surrealSubset'] as SurrealSubset | undefined)\n\t\t\t\t\t\t: undefined;\n\n\t\t\t\tconst rows =\n\t\t\t\t\tsyncMode === 'eager'\n\t\t\t\t\t\t? await table.listAll()\n\t\t\t\t\t\t: await table.loadSubset(subset);\n\n\t\t\t\treturn mergeLocalOverServer(rows);\n\t\t\t} catch (e) {\n\t\t\t\tonError?.(e);\n\t\t\t\treturn [];\n\t\t\t}\n\t\t},\n\n\t\tonInsert: (async (p: InsertMutationFnParams<T>) => {\n\t\t\tconst now = () => new Date();\n\n\t\t\tconst resultRows: T[] = [];\n\t\t\tfor (const m of p.transaction.mutations) {\n\t\t\t\tif (m.type !== 'insert') continue;\n\t\t\t\tconst baseRow = { ...m.modified } as T;\n\n\t\t\t\tconst row = useLoro\n\t\t\t\t\t? ({\n\t\t\t\t\t\t\t...baseRow,\n\t\t\t\t\t\t\tupdated_at: now(),\n\t\t\t\t\t\t\tsync_deleted: false,\n\t\t\t\t\t\t} as T)\n\t\t\t\t\t: baseRow;\n\n\t\t\t\tif (useLoro) loroPut(row);\n\t\t\t\tawait table.create(row);\n\t\t\t\tresultRows.push(row);\n\t\t\t}\n\n\t\t\treturn resultRows as unknown as StandardSchema<T>;\n\t\t}) as InsertMutationFn<T, string, UtilsRecord, StandardSchema<T>>,\n\n\t\tonUpdate: (async (p: UpdateMutationFnParams<T>) => {\n\t\t\tconst now = () => new Date();\n\n\t\t\tconst resultRows: T[] = [];\n\t\t\tfor (const m of p.transaction.mutations) {\n\t\t\t\tif (m.type !== 'update') continue;\n\n\t\t\t\tconst idKey = m.key as RecordId;\n\t\t\t\tconst baseRow = { ...(m.modified as T), id: idKey } as T;\n\n\t\t\t\tconst row = useLoro\n\t\t\t\t\t? ({ ...baseRow, updated_at: now() } as T)\n\t\t\t\t\t: baseRow;\n\n\t\t\t\tif (useLoro) loroPut(row);\n\t\t\t\tawait table.update(\n\t\t\t\t\tnew RecordId(config.table.name, keyOf(idKey)),\n\t\t\t\t\trow,\n\t\t\t\t);\n\t\t\t\tresultRows.push(row);\n\t\t\t}\n\n\t\t\treturn resultRows as unknown as StandardSchema<T>;\n\t\t}) as UpdateMutationFn<T, string, UtilsRecord, StandardSchema<T>>,\n\n\t\tonDelete: (async (p: DeleteMutationFnParams<T>) => {\n\t\t\tfor (const m of p.transaction.mutations) {\n\t\t\t\tif (m.type !== 'delete') continue;\n\n\t\t\t\tconst idKey = m.key as RecordId;\n\t\t\t\tif (useLoro) loroRemove(keyOf(idKey));\n\n\t\t\t\tawait table.softDelete(\n\t\t\t\t\tnew RecordId(config.table.name, keyOf(idKey)),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn [] as unknown as StandardSchema<T>;\n\t\t}) as DeleteMutationFn<T, string, UtilsRecord, StandardSchema<T>>,\n\t});\n\n\t// LIVE updates -> invalidate all subsets under base queryKey\n\tconst baseSync = base.sync?.sync;\n\n\tconst sync = baseSync\n\t\t? {\n\t\t\t\tsync: (ctx: Parameters<NonNullable<typeof baseSync>>[0]) => {\n\t\t\t\t\tconst offBase = baseSync(ctx);\n\n\t\t\t\t\tif (!db.isFeatureSupported(Features.LiveQueries))\n\t\t\t\t\t\treturn offBase;\n\n\t\t\t\t\tconst offLive = table.subscribe((evt) => {\n\t\t\t\t\t\t// Keep Loro in sync with server pushes\n\t\t\t\t\t\tif (useLoro) {\n\t\t\t\t\t\t\tif (evt.type === 'delete')\n\t\t\t\t\t\t\t\tloroRemove(getKey(evt.row));\n\t\t\t\t\t\t\telse loroPut(evt.row);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvoid queryClient\n\t\t\t\t\t\t\t.invalidateQueries({ queryKey, exact: false })\n\t\t\t\t\t\t\t.catch((e) => onError?.(e));\n\t\t\t\t\t});\n\n\t\t\t\t\tconst baseCleanup = toCleanup(baseSync(ctx));\n\n\t\t\t\t\treturn () => {\n\t\t\t\t\t\toffLive();\n\t\t\t\t\t\tbaseCleanup();\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t}\n\t\t: undefined;\n\n\treturn {\n\t\t...base,\n\t\tsync: sync ?? base.sync,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/table.ts","../src/index.ts"],"names":["Features"],"mappings":"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","file":"index.mjs","sourcesContent":["import {\n\tand,\n\ttype ExprLike,\n\teq,\n\tFeatures,\n\ttype LiveMessage,\n\ttype LiveSubscription,\n\ttype RecordId,\n\ttype Surreal,\n\tTable,\n} from 'surrealdb';\n\nimport type {\n\tFieldList,\n\tSurrealField,\n\tSurrealSubset,\n\tTableOptions,\n} from './types';\n\nconst normalizeFields = <T>(\n\traw: FieldList<T> | undefined,\n): ReadonlyArray<SurrealField<T>> => {\n\tif (!raw || raw === '*') return ['*' as SurrealField<T>];\n\treturn raw;\n};\n\nconst joinOrderBy = (\n\to: string | readonly string[] | undefined,\n): string | undefined => {\n\tif (!o) return undefined;\n\treturn typeof o === 'string' ? o : o.join(', ');\n};\n\ntype QueryResult<T> = T[] | null;\n\nexport function manageTable<T extends { id: string | RecordId }>(\n\tdb: Surreal,\n\tuseLoro: boolean,\n\t{ name, ...args }: TableOptions<T>,\n) {\n\tconst fields = normalizeFields<T>(args.fields);\n\n\tconst baseWhere = (): ExprLike | undefined => {\n\t\tif (!useLoro) return args.where;\n\t\tconst alive = eq('sync_deleted', false);\n\t\treturn args.where ? and(args.where, alive) : alive;\n\t};\n\n\tconst listAll = async (): Promise<T[]> => {\n\t\tconst where = baseWhere();\n\t\tconst whereSql = where ? ' WHERE $where' : '';\n\t\tconst sql = `SELECT ${fields.join(', ')} FROM type::table($table)${whereSql};`;\n\t\tconst [res] = await db.query<[QueryResult<T>]>(sql, {\n\t\t\ttable: name,\n\t\t\twhere,\n\t\t});\n\t\treturn res ?? [];\n\t};\n\n\tconst loadSubset = async (subset?: SurrealSubset): Promise<T[]> => {\n\t\tconst b = baseWhere();\n\t\tconst w = subset?.where;\n\t\tconst where = b && w ? and(b, w) : (b ?? w);\n\n\t\tconst whereSql = where ? ' WHERE $where' : '';\n\t\tconst order = joinOrderBy(subset?.orderBy);\n\t\tconst orderSql = order ? ` ORDER BY ${order}` : '';\n\t\tconst limitSql =\n\t\t\ttypeof subset?.limit === 'number' ? ' LIMIT $limit' : '';\n\t\tconst startSql =\n\t\t\ttypeof subset?.offset === 'number' ? ' START $offset' : '';\n\n\t\tconst sql = `SELECT ${fields.join(', ')} FROM type::table($table)${whereSql}${orderSql}${limitSql}${startSql};`;\n\n\t\tconst [res] = await db.query<[QueryResult<T>]>(sql, {\n\t\t\ttable: name,\n\t\t\twhere,\n\t\t\tlimit: subset?.limit,\n\t\t\toffset: subset?.offset,\n\t\t});\n\n\t\treturn res ?? [];\n\t};\n\n\tconst create = async (data: T | Partial<T>) => {\n\t\tawait db.create(new Table(name)).content(data);\n\t};\n\n\tconst update = async (id: RecordId, data: T | Partial<T>) => {\n\t\tif (!useLoro) {\n\t\t\tawait db.update(id).merge(data);\n\t\t\treturn;\n\t\t}\n\t\tawait db.update(id).merge({\n\t\t\t...data,\n\t\t\tsync_deleted: false,\n\t\t\tupdated_at: Date.now(),\n\t\t});\n\t};\n\n\tconst remove = async (id: RecordId) => {\n\t\tawait db.delete(id);\n\t};\n\n\tconst softDelete = async (id: RecordId) => {\n\t\tif (!useLoro) {\n\t\t\tawait db.delete(id);\n\t\t\treturn;\n\t\t}\n\t\tawait db.upsert(id).merge({\n\t\t\tsync_deleted: true,\n\t\t\tupdated_at: Date.now(),\n\t\t});\n\t};\n\n\tconst subscribe = (\n\t\tcb: (e: { type: 'insert' | 'update' | 'delete'; row: T }) => void,\n\t) => {\n\t\tlet killed = false;\n\t\tlet live: LiveSubscription | undefined;\n\n\t\tconst on = (msg: LiveMessage) => {\n\t\t\tconst { action, value } = msg as unknown as {\n\t\t\t\taction: 'CREATE' | 'UPDATE' | 'DELETE' | 'KILLED';\n\t\t\t\tvalue: T & { id: string | RecordId };\n\t\t\t};\n\n\t\t\tif (action === 'KILLED') return;\n\n\t\t\tif (action === 'CREATE') cb({ type: 'insert', row: value });\n\t\t\telse if (action === 'UPDATE') cb({ type: 'update', row: value });\n\t\t\telse if (action === 'DELETE')\n\t\t\t\tcb({ type: 'delete', row: { id: value.id } as T });\n\t\t};\n\n\t\tconst start = async () => {\n\t\t\tif (!db.isFeatureSupported(Features.LiveQueries)) return;\n\t\t\tlive = await db.live(new Table(name)).where(args.where);\n\t\t\tlive.subscribe(on);\n\t\t};\n\n\t\tvoid start();\n\n\t\treturn () => {\n\t\t\tif (killed) return;\n\t\t\tkilled = true;\n\t\t\tif (live) void live.kill();\n\t\t};\n\t};\n\n\treturn {\n\t\tlistAll,\n\t\tloadSubset,\n\t\tcreate,\n\t\tupdate,\n\t\tremove,\n\t\tsoftDelete,\n\t\tsubscribe,\n\t};\n}\n","import type {\n\tCollectionConfig,\n\tDeleteMutationFn,\n\tDeleteMutationFnParams,\n\tInsertMutationFn,\n\tInsertMutationFnParams,\n\tStandardSchema,\n\tUpdateMutationFn,\n\tUpdateMutationFnParams,\n\tUtilsRecord,\n} from '@tanstack/db';\nimport { queryCollectionOptions } from '@tanstack/query-db-collection';\nimport { type Container, LoroDoc } from 'loro-crdt';\nimport { Features, RecordId } from 'surrealdb';\n\nimport { manageTable } from './table';\nimport type {\n\tSurrealCollectionConfig,\n\tSurrealSubset,\n\tSyncedTable,\n} from './types';\n\ntype Cleanup = () => void;\n\nexport { SurrealSubset } from './types';\n\ntype SyncReturn =\n\t| void\n\t| Cleanup\n\t| {\n\t\t\tcleanup?: Cleanup;\n\t\t\tunsubscribe?: Cleanup;\n\t\t\tdispose?: Cleanup;\n\t\t\tloadSubset?: unknown; // keep unknown; Only pass through\n\t };\n\nfunction toCleanup(res: SyncReturn): Cleanup {\n\tif (!res) return () => {};\n\tif (typeof res === 'function') return res;\n\n\tconst cleanup = res.cleanup ?? res.unsubscribe ?? res.dispose;\n\n\treturn typeof cleanup === 'function' ? cleanup : () => {};\n}\n\nfunction hasLoadSubset(\n\tres: SyncReturn,\n): res is { loadSubset: unknown } & Record<string, unknown> {\n\treturn typeof res === 'object' && res !== null && 'loadSubset' in res;\n}\n\nexport function surrealCollectionOptions<\n\tT extends SyncedTable<object>,\n\tS extends Record<string, Container> = { [k: string]: never },\n>({\n\tid,\n\tuseLoro = false,\n\tonError,\n\tdb,\n\tqueryClient,\n\tqueryKey,\n\tsyncMode = 'eager',\n\t...config\n}: SurrealCollectionConfig<T>): CollectionConfig<\n\tT,\n\tstring | number,\n\tnever,\n\tUtilsRecord\n> {\n\tlet loro: { doc: LoroDoc<S>; key?: string } | undefined;\n\tif (useLoro) loro = { doc: new LoroDoc(), key: id };\n\n\tconst table = manageTable<T>(db, useLoro, config.table);\n\n\tconst keyOf = (rid: RecordId | string): string =>\n\t\ttypeof rid === 'string' ? rid : rid.toString();\n\n\tconst getKey = (row: { id: string | RecordId }) => keyOf(row.id);\n\n\tconst loroKey = loro?.key ?? id ?? 'surreal';\n\tconst loroMap = useLoro ? (loro?.doc?.getMap?.(loroKey) ?? null) : null;\n\n\tconst loroPut = (row: T) => {\n\t\tif (!loroMap) return;\n\t\tloroMap.set(getKey(row), row as unknown);\n\t\tloro?.doc?.commit?.();\n\t};\n\n\tconst loroRemove = (idStr: string) => {\n\t\tif (!loroMap) return;\n\t\tloroMap.delete(idStr);\n\t\tloro?.doc?.commit?.();\n\t};\n\n\tconst mergeLocalOverServer = (serverRows: T[]): T[] => {\n\t\tif (!useLoro || !loroMap) return serverRows;\n\n\t\tconst localJson = loroMap.toJSON?.() ?? {};\n\t\tconst localById = new Map<string, T>(\n\t\t\tObject.values(localJson).map((r) => [getKey(r as T), r as T]),\n\t\t);\n\n\t\tconst out: T[] = [];\n\t\tfor (const s of serverRows) {\n\t\t\tconst idStr = getKey(s);\n\t\t\tconst l = localById.get(idStr);\n\n\t\t\tif (!l) {\n\t\t\t\tout.push(s);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ((l.sync_deleted ?? false) === true) continue;\n\t\t\tout.push(l);\n\t\t}\n\n\t\treturn out;\n\t};\n\n\tconst base = queryCollectionOptions<T>({\n\t\tgetKey: (row) => getKey(row),\n\n\t\tqueryKey,\n\t\tqueryClient,\n\n\t\tsyncMode,\n\n\t\tqueryFn: async ({ meta }) => {\n\t\t\ttry {\n\t\t\t\tconst subset =\n\t\t\t\t\tsyncMode === 'on-demand'\n\t\t\t\t\t\t? (meta['surrealSubset'] as SurrealSubset | undefined)\n\t\t\t\t\t\t: undefined;\n\n\t\t\t\tconst rows =\n\t\t\t\t\tsyncMode === 'eager'\n\t\t\t\t\t\t? await table.listAll()\n\t\t\t\t\t\t: await table.loadSubset(subset);\n\n\t\t\t\treturn mergeLocalOverServer(rows);\n\t\t\t} catch (e) {\n\t\t\t\tonError?.(e);\n\t\t\t\treturn [];\n\t\t\t}\n\t\t},\n\n\t\tonInsert: (async (p: InsertMutationFnParams<T>) => {\n\t\t\tconst now = () => new Date();\n\n\t\t\tconst resultRows: T[] = [];\n\t\t\tfor (const m of p.transaction.mutations) {\n\t\t\t\tif (m.type !== 'insert') continue;\n\n\t\t\t\tconst baseRow = { ...m.modified } as T;\n\n\t\t\t\tconst row = useLoro\n\t\t\t\t\t? ({\n\t\t\t\t\t\t\t...baseRow,\n\t\t\t\t\t\t\tupdated_at: now(),\n\t\t\t\t\t\t\tsync_deleted: false,\n\t\t\t\t\t\t} as T)\n\t\t\t\t\t: baseRow;\n\n\t\t\t\tif (useLoro) loroPut(row);\n\t\t\t\tawait table.create(row);\n\t\t\t\tresultRows.push(row);\n\t\t\t}\n\n\t\t\treturn resultRows as unknown as StandardSchema<T>;\n\t\t}) as InsertMutationFn<T, string, UtilsRecord, StandardSchema<T>>,\n\n\t\tonUpdate: (async (p: UpdateMutationFnParams<T>) => {\n\t\t\tconst now = () => new Date();\n\n\t\t\tconst resultRows: T[] = [];\n\t\t\tfor (const m of p.transaction.mutations) {\n\t\t\t\tif (m.type !== 'update') continue;\n\n\t\t\t\tconst idKey = m.key as RecordId;\n\t\t\t\tconst baseRow = { ...(m.modified as T), id: idKey } as T;\n\n\t\t\t\tconst row = useLoro\n\t\t\t\t\t? ({ ...baseRow, updated_at: now() } as T)\n\t\t\t\t\t: baseRow;\n\n\t\t\t\tif (useLoro) loroPut(row);\n\n\t\t\t\tawait table.update(\n\t\t\t\t\tnew RecordId(config.table.name, keyOf(idKey)),\n\t\t\t\t\trow,\n\t\t\t\t);\n\n\t\t\t\tresultRows.push(row);\n\t\t\t}\n\n\t\t\treturn resultRows as unknown as StandardSchema<T>;\n\t\t}) as UpdateMutationFn<T, string, UtilsRecord, StandardSchema<T>>,\n\n\t\tonDelete: (async (p: DeleteMutationFnParams<T>) => {\n\t\t\tfor (const m of p.transaction.mutations) {\n\t\t\t\tif (m.type !== 'delete') continue;\n\n\t\t\t\tconst idKey = m.key as RecordId;\n\t\t\t\tif (useLoro) loroRemove(keyOf(idKey));\n\n\t\t\t\tawait table.softDelete(\n\t\t\t\t\tnew RecordId(config.table.name, keyOf(idKey)),\n\t\t\t\t);\n\t\t\t}\n\n\t\t\treturn [] as unknown as StandardSchema<T>;\n\t\t}) as DeleteMutationFn<T, string, UtilsRecord, StandardSchema<T>>,\n\t});\n\n\t// LIVE updates -> invalidate all subsets under base queryKey\n\tconst baseSync = base.sync?.sync;\n\n\tconst sync = baseSync\n\t\t? {\n\t\t\t\tsync: (ctx: Parameters<NonNullable<typeof baseSync>>[0]) => {\n\t\t\t\t\t// IMPORTANT: call baseSync exactly once\n\t\t\t\t\tconst baseRes = baseSync(ctx) as SyncReturn;\n\t\t\t\t\tconst baseCleanup = toCleanup(baseRes);\n\n\t\t\t\t\t// If live queries aren't supported, return the base result untouched\n\t\t\t\t\tif (!db.isFeatureSupported(Features.LiveQueries)) {\n\t\t\t\t\t\treturn baseRes as unknown as ReturnType<\n\t\t\t\t\t\t\tNonNullable<typeof baseSync>\n\t\t\t\t\t\t>;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst offLive = table.subscribe((evt) => {\n\t\t\t\t\t\tif (useLoro) {\n\t\t\t\t\t\t\tif (evt.type === 'delete') {\n\t\t\t\t\t\t\t\tloroRemove(getKey(evt.row));\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tloroPut(evt.row);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvoid queryClient\n\t\t\t\t\t\t\t.invalidateQueries({ queryKey, exact: false })\n\t\t\t\t\t\t\t.catch((e) => onError?.(e));\n\t\t\t\t\t});\n\n\t\t\t\t\t// Preserve base return shape, just wrap cleanup\n\t\t\t\t\tif (hasLoadSubset(baseRes)) {\n\t\t\t\t\t\t// on-demand mode relies on this being present\n\t\t\t\t\t\tconst resObj = baseRes as Record<string, unknown>;\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...resObj,\n\t\t\t\t\t\t\tcleanup: () => {\n\t\t\t\t\t\t\t\toffLive();\n\t\t\t\t\t\t\t\tbaseCleanup();\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t} as unknown as ReturnType<\n\t\t\t\t\t\t\tNonNullable<typeof baseSync>\n\t\t\t\t\t\t>;\n\t\t\t\t\t}\n\n\t\t\t\t\t// eager mode usually returns a cleanup function\n\t\t\t\t\treturn (() => {\n\t\t\t\t\t\toffLive();\n\t\t\t\t\t\tbaseCleanup();\n\t\t\t\t\t}) as unknown as ReturnType<NonNullable<typeof baseSync>>;\n\t\t\t\t},\n\t\t\t}\n\t\t: undefined;\n\n\treturn {\n\t\t...base,\n\t\tsync: sync ?? base.sync,\n\t};\n}\n"]}
|
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.3.
|
|
4
|
+
"version": "0.3.3",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
7
7
|
],
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"@biomejs/biome": "^2.3.11",
|
|
51
51
|
"@tanstack/query-db-collection": "^1.0.14",
|
|
52
52
|
"@tanstack/svelte-db": "^0.1.61",
|
|
53
|
+
"@tanstack/svelte-query": "^6.0.14",
|
|
53
54
|
"surrealdb": "2.0.0-alpha.16",
|
|
54
55
|
"tsup": "^8.5.1"
|
|
55
56
|
}
|