@spooky-sync/core 0.0.1-canary.130 → 0.0.1-canary.131
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/index.js
CHANGED
|
@@ -1283,25 +1283,36 @@ var SurrealCacheEngine = class extends LocalDatabaseService {
|
|
|
1283
1283
|
}
|
|
1284
1284
|
return result;
|
|
1285
1285
|
}
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1286
|
+
/**
|
|
1287
|
+
* Coerce the contract's `Id` (a RecordId, a stable `table:id` string, or a
|
|
1288
|
+
* bare id + the verb's `table` param) to a real RecordId. SurrealDB binds
|
|
1289
|
+
* `$__id` verbatim: a plain string makes `FROM ONLY $__id` "select" the
|
|
1290
|
+
* string itself (a truthy non-row) and `UPSERT $__id` an InternalError, so
|
|
1291
|
+
* string ids silently broke every id-verb on this engine.
|
|
1292
|
+
*/
|
|
1293
|
+
toRecordId(table, id) {
|
|
1294
|
+
if (typeof id !== "string") return id;
|
|
1295
|
+
return new RecordId(table, id.startsWith(`${table}:`) ? id.slice(table.length + 1) : id);
|
|
1296
|
+
}
|
|
1297
|
+
async getById(table, id) {
|
|
1298
|
+
const [row] = await this.query("SELECT * FROM ONLY $__id;", { __id: this.toRecordId(table, id) });
|
|
1299
|
+
return row && typeof row === "object" ? row : null;
|
|
1289
1300
|
}
|
|
1290
|
-
async upsert(
|
|
1301
|
+
async upsert(table, id, data, mode) {
|
|
1291
1302
|
const sql = mode === "merge" ? surql.upsertMerge("__id", "__data") : surql.upsert("__id", "__data");
|
|
1292
1303
|
await this.query(surql.seal(sql), {
|
|
1293
|
-
__id: id,
|
|
1304
|
+
__id: this.toRecordId(table, id),
|
|
1294
1305
|
__data: data
|
|
1295
1306
|
});
|
|
1296
1307
|
}
|
|
1297
|
-
async patch(
|
|
1308
|
+
async patch(table, id, patches) {
|
|
1298
1309
|
await this.query(surql.seal("UPDATE ONLY $__id PATCH $__patches"), {
|
|
1299
|
-
__id: id,
|
|
1310
|
+
__id: this.toRecordId(table, id),
|
|
1300
1311
|
__patches: patches
|
|
1301
1312
|
});
|
|
1302
1313
|
}
|
|
1303
|
-
async delete(
|
|
1304
|
-
await this.query(surql.seal(surql.delete("__id")), { __id: id });
|
|
1314
|
+
async delete(table, id) {
|
|
1315
|
+
await this.query(surql.seal(surql.delete("__id")), { __id: this.toRecordId(table, id) });
|
|
1305
1316
|
}
|
|
1306
1317
|
/**
|
|
1307
1318
|
* Serialized (not strictly atomic) transaction: verbs run in order on the
|
|
@@ -2774,8 +2785,8 @@ var DataModule = class {
|
|
|
2774
2785
|
*/
|
|
2775
2786
|
async getPreloadMarker(hash) {
|
|
2776
2787
|
try {
|
|
2777
|
-
const row = await this.local.getById("_00_preload", hash);
|
|
2778
|
-
if (!row) return null;
|
|
2788
|
+
const row = await this.local.getById("_00_preload", new RecordId("_00_preload", hash));
|
|
2789
|
+
if (!row || typeof row !== "object") return null;
|
|
2779
2790
|
return {
|
|
2780
2791
|
fetchedAt: Number(row.fetchedAt) || 0,
|
|
2781
2792
|
rowCount: Number(row.rowCount) || 0
|
|
@@ -2796,7 +2807,7 @@ var DataModule = class {
|
|
|
2796
2807
|
}
|
|
2797
2808
|
/** Stamp the preload freshness marker after a successful snapshot fetch. */
|
|
2798
2809
|
async writePreloadMarker(hash, rowCount) {
|
|
2799
|
-
await this.local.upsert("_00_preload", hash, {
|
|
2810
|
+
await this.local.upsert("_00_preload", new RecordId("_00_preload", hash), {
|
|
2800
2811
|
fetchedAt: Date.now(),
|
|
2801
2812
|
rowCount
|
|
2802
2813
|
}, "replace");
|
|
@@ -5130,8 +5141,8 @@ function parseBackendInfo(raw) {
|
|
|
5130
5141
|
|
|
5131
5142
|
//#endregion
|
|
5132
5143
|
//#region src/modules/devtools/index.ts
|
|
5133
|
-
const CORE_VERSION = "0.0.1-canary.
|
|
5134
|
-
const WASM_VERSION = "0.0.1-canary.
|
|
5144
|
+
const CORE_VERSION = "0.0.1-canary.131";
|
|
5145
|
+
const WASM_VERSION = "0.0.1-canary.131";
|
|
5135
5146
|
const SURREAL_VERSION = "3.0.3";
|
|
5136
5147
|
var DevToolsService = class {
|
|
5137
5148
|
eventsHistory = [];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spooky-sync/core",
|
|
3
|
-
"version": "0.0.1-canary.
|
|
3
|
+
"version": "0.0.1-canary.131",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
}
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@spooky-sync/query-builder": "0.0.1-canary.
|
|
63
|
-
"@spooky-sync/ssp-wasm": "0.0.1-canary.
|
|
62
|
+
"@spooky-sync/query-builder": "0.0.1-canary.131",
|
|
63
|
+
"@spooky-sync/ssp-wasm": "0.0.1-canary.131",
|
|
64
64
|
"@sqlite.org/sqlite-wasm": "3.53.0-build1",
|
|
65
65
|
"@surrealdb/wasm": "^3.0.3",
|
|
66
66
|
"fast-json-patch": "^3.1.1",
|
|
@@ -876,8 +876,11 @@ export class DataModule<S extends SchemaStructure> {
|
|
|
876
876
|
hash: string
|
|
877
877
|
): Promise<{ fetchedAt: number; rowCount: number } | null> {
|
|
878
878
|
try {
|
|
879
|
-
|
|
880
|
-
|
|
879
|
+
// Pass a real RecordId: a bare string id hits the SurrealDB engine's
|
|
880
|
+
// `FROM ONLY $__id` as a plain string, which "selects" the string itself
|
|
881
|
+
// (a truthy non-row) instead of the record — misread as a warm marker.
|
|
882
|
+
const row = await this.local.getById('_00_preload', new RecordId('_00_preload', hash));
|
|
883
|
+
if (!row || typeof row !== 'object') return null;
|
|
881
884
|
return {
|
|
882
885
|
fetchedAt: Number((row as any).fetchedAt) || 0,
|
|
883
886
|
rowCount: Number((row as any).rowCount) || 0,
|
|
@@ -900,9 +903,12 @@ export class DataModule<S extends SchemaStructure> {
|
|
|
900
903
|
|
|
901
904
|
/** Stamp the preload freshness marker after a successful snapshot fetch. */
|
|
902
905
|
async writePreloadMarker(hash: string, rowCount: number): Promise<void> {
|
|
906
|
+
// RecordId, not a bare string: the SurrealDB engine binds the id verbatim,
|
|
907
|
+
// and `UPSERT <string>` is an InternalError — the marker silently never
|
|
908
|
+
// landed (the write is awaited inside preload's best-effort catch).
|
|
903
909
|
await this.local.upsert(
|
|
904
910
|
'_00_preload',
|
|
905
|
-
hash,
|
|
911
|
+
new RecordId('_00_preload', hash),
|
|
906
912
|
{ fetchedAt: Date.now(), rowCount },
|
|
907
913
|
'replace'
|
|
908
914
|
);
|
|
@@ -15,6 +15,7 @@ import type {
|
|
|
15
15
|
} from './cache-engine';
|
|
16
16
|
import { stableKey } from './relation-resolver';
|
|
17
17
|
import { surql } from '../../utils/surql';
|
|
18
|
+
import { RecordId } from 'surrealdb';
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* Default local cache backend: the in-browser SurrealDB-WASM store. Implemented
|
|
@@ -83,25 +84,41 @@ export class SurrealCacheEngine extends LocalDatabaseService implements LocalCac
|
|
|
83
84
|
return result;
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
/**
|
|
88
|
+
* Coerce the contract's `Id` (a RecordId, a stable `table:id` string, or a
|
|
89
|
+
* bare id + the verb's `table` param) to a real RecordId. SurrealDB binds
|
|
90
|
+
* `$__id` verbatim: a plain string makes `FROM ONLY $__id` "select" the
|
|
91
|
+
* string itself (a truthy non-row) and `UPSERT $__id` an InternalError, so
|
|
92
|
+
* string ids silently broke every id-verb on this engine.
|
|
93
|
+
*/
|
|
94
|
+
private toRecordId(table: string, id: Id): unknown {
|
|
95
|
+
if (typeof id !== 'string') return id;
|
|
96
|
+
const raw = id.startsWith(`${table}:`) ? id.slice(table.length + 1) : id;
|
|
97
|
+
return new RecordId(table, raw);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async getById(table: string, id: Id): Promise<Row | null> {
|
|
101
|
+
const [row] = await this.query<[Row | null]>('SELECT * FROM ONLY $__id;', {
|
|
102
|
+
__id: this.toRecordId(table, id),
|
|
103
|
+
});
|
|
104
|
+
// `FROM ONLY <non-record>` echoes the value back; only a real row counts.
|
|
105
|
+
return row && typeof row === 'object' ? row : null;
|
|
89
106
|
}
|
|
90
107
|
|
|
91
|
-
async upsert(
|
|
108
|
+
async upsert(table: string, id: Id, data: Row, mode: 'replace' | 'merge'): Promise<void> {
|
|
92
109
|
const sql = mode === 'merge' ? surql.upsertMerge('__id', '__data') : surql.upsert('__id', '__data');
|
|
93
|
-
await this.query(surql.seal(sql), { __id: id, __data: data });
|
|
110
|
+
await this.query(surql.seal(sql), { __id: this.toRecordId(table, id), __data: data });
|
|
94
111
|
}
|
|
95
112
|
|
|
96
|
-
async patch(
|
|
113
|
+
async patch(table: string, id: Id, patches: unknown[]): Promise<void> {
|
|
97
114
|
await this.query(surql.seal('UPDATE ONLY $__id PATCH $__patches'), {
|
|
98
|
-
__id: id,
|
|
115
|
+
__id: this.toRecordId(table, id),
|
|
99
116
|
__patches: patches,
|
|
100
117
|
});
|
|
101
118
|
}
|
|
102
119
|
|
|
103
|
-
async delete(
|
|
104
|
-
await this.query(surql.seal(surql.delete('__id')), { __id: id });
|
|
120
|
+
async delete(table: string, id: Id): Promise<void> {
|
|
121
|
+
await this.query(surql.seal(surql.delete('__id')), { __id: this.toRecordId(table, id) });
|
|
105
122
|
}
|
|
106
123
|
|
|
107
124
|
/**
|