@vielzeug/vault 3.0.0 → 3.0.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/dist/adapter-core.cjs +1 -1
- package/dist/adapter-core.cjs.map +1 -1
- package/dist/adapter-core.d.ts +5 -34
- package/dist/adapter-core.d.ts.map +1 -1
- package/dist/adapter-core.js +1 -282
- package/dist/adapter-core.js.map +1 -1
- package/dist/adapters/indexeddb.cjs +1 -1
- package/dist/adapters/indexeddb.cjs.map +1 -1
- package/dist/adapters/indexeddb.d.ts +5 -35
- package/dist/adapters/indexeddb.d.ts.map +1 -1
- package/dist/adapters/indexeddb.js +1 -365
- package/dist/adapters/indexeddb.js.map +1 -1
- package/dist/adapters/memory.cjs +1 -1
- package/dist/adapters/memory.cjs.map +1 -1
- package/dist/adapters/memory.d.ts +8 -3
- package/dist/adapters/memory.d.ts.map +1 -1
- package/dist/adapters/memory.js +1 -60
- package/dist/adapters/memory.js.map +1 -1
- package/dist/adapters/sqlite.cjs +14 -32
- package/dist/adapters/sqlite.cjs.map +1 -1
- package/dist/adapters/sqlite.d.ts.map +1 -1
- package/dist/adapters/sqlite.js +14 -409
- package/dist/adapters/sqlite.js.map +1 -1
- package/dist/adapters/webstorage.cjs +1 -1
- package/dist/adapters/webstorage.cjs.map +1 -1
- package/dist/adapters/webstorage.d.ts +0 -6
- package/dist/adapters/webstorage.d.ts.map +1 -1
- package/dist/adapters/webstorage.js +1 -160
- package/dist/adapters/webstorage.js.map +1 -1
- package/dist/codec.cjs +1 -1
- package/dist/codec.cjs.map +1 -1
- package/dist/codec.js +1 -5
- package/dist/codec.js.map +1 -1
- package/dist/errors.cjs +1 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.ts +0 -5
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +1 -21
- package/dist/errors.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -5
- package/dist/indexeddb.cjs +1 -1
- package/dist/indexeddb.d.ts +2 -2
- package/dist/indexeddb.d.ts.map +1 -1
- package/dist/indexeddb.js +1 -2
- package/dist/internal.cjs +1 -1
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.js +1 -72
- package/dist/internal.js.map +1 -1
- package/dist/local-storage.js +1 -2
- package/dist/memory.js +1 -2
- package/dist/session-storage.js +1 -2
- package/dist/sqlite.js +1 -2
- package/dist/ttl.cjs +1 -1
- package/dist/ttl.cjs.map +1 -1
- package/dist/ttl.js +1 -24
- package/dist/ttl.js.map +1 -1
- package/dist/types.cjs +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.ts +0 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -27
- package/dist/types.js.map +1 -1
- package/dist/vault.cjs +1 -1
- package/dist/vault.cjs.map +1 -1
- package/dist/vault.iife.js +1 -1
- package/dist/vault.iife.js.map +1 -1
- package/dist/vault.js +1 -1
- package/dist/vault.js.map +1 -1
- package/package.json +6 -6
- package/dist/query.cjs +0 -2
- package/dist/query.cjs.map +0 -1
- package/dist/query.d.ts +0 -23
- package/dist/query.d.ts.map +0 -1
- package/dist/query.js +0 -54
- package/dist/query.js.map +0 -1
package/dist/adapters/memory.js
CHANGED
|
@@ -1,61 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { isExpired as n, parseStored as r } from "../ttl.js";
|
|
3
|
-
import { buildKeyValueStore as i } from "../adapter-core.js";
|
|
4
|
-
//#region src/adapters/memory.ts
|
|
5
|
-
function a(a) {
|
|
6
|
-
let { schema: o } = a, s = new Map(Object.keys(o).map((e) => [e, /* @__PURE__ */ new Map()])), c = (e) => s.get(e);
|
|
7
|
-
return i(o, {
|
|
8
|
-
async clear(e) {
|
|
9
|
-
c(e).clear();
|
|
10
|
-
},
|
|
11
|
-
async delete(t, i) {
|
|
12
|
-
let a = c(t), o = e(i), s = r(a.get(o));
|
|
13
|
-
return a.delete(o), s !== void 0 && !n(s.expiresAt);
|
|
14
|
-
},
|
|
15
|
-
async get(t, i) {
|
|
16
|
-
let a = c(t), o = e(i), s = r(a.get(o));
|
|
17
|
-
if (!s || n(s.expiresAt)) {
|
|
18
|
-
a.delete(o);
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
return s.value;
|
|
22
|
-
},
|
|
23
|
-
async getAll(e) {
|
|
24
|
-
let t = c(e), i = [];
|
|
25
|
-
for (let [e, a] of t) {
|
|
26
|
-
let o = r(a);
|
|
27
|
-
!o || n(o.expiresAt) ? t.delete(e) : i.push(o.value);
|
|
28
|
-
}
|
|
29
|
-
return i;
|
|
30
|
-
},
|
|
31
|
-
async pruneExpiredInTable(e) {
|
|
32
|
-
let t = c(e), i = 0;
|
|
33
|
-
for (let [e, a] of t) {
|
|
34
|
-
let o = r(a);
|
|
35
|
-
(!o || n(o.expiresAt)) && (t.delete(e), i += 1);
|
|
36
|
-
}
|
|
37
|
-
return i;
|
|
38
|
-
},
|
|
39
|
-
async put(n, r, i) {
|
|
40
|
-
let a = e(t(o, n, r)), s = i === void 0 ? { value: r } : {
|
|
41
|
-
expiresAt: Date.now() + i,
|
|
42
|
-
value: r
|
|
43
|
-
};
|
|
44
|
-
c(n).set(a, s);
|
|
45
|
-
},
|
|
46
|
-
async putAll(n, r, i) {
|
|
47
|
-
let a = i === void 0 ? void 0 : Date.now() + i;
|
|
48
|
-
for (let i of r) {
|
|
49
|
-
let r = e(t(o, n, i)), s = a === void 0 ? { value: i } : {
|
|
50
|
-
expiresAt: a,
|
|
51
|
-
value: i
|
|
52
|
-
};
|
|
53
|
-
c(n).set(r, s);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}, a);
|
|
57
|
-
}
|
|
58
|
-
//#endregion
|
|
59
|
-
export { a as createMemory };
|
|
60
|
-
|
|
1
|
+
import{isExpired as e,parseStored as t}from"../ttl.js";import{encodeVaultKey as n,getRecordKey as r}from"../internal.js";import{assertBatchTables as i,batchScopeGuard as a,buildDocumentStore as o,buildOperations as s}from"../adapter-core.js";function createMemory(c){let{schema:l}=c,u=new Map(Object.keys(l).map(e=>[e,new Map])),getTable=e=>u.get(e),d={async clear(e){getTable(e).clear()},async delete(r,i){let a=getTable(r),o=n(i),s=t(a.get(o));return a.delete(o),s!==void 0&&!e(s.expiresAt)},async get(r,i){let a=getTable(r),o=n(i),s=t(a.get(o));if(!s||e(s.expiresAt)){a.delete(o);return}return s.value},async getAll(n){let r=getTable(n),i=[];for(let[n,a]of r){let o=t(a);!o||e(o.expiresAt)?r.delete(n):i.push(o.value)}return i},async pruneExpiredInTable(n){let r=getTable(n),i=0;for(let[n,a]of r){let o=t(a);(!o||e(o.expiresAt))&&(r.delete(n),i+=1)}return i},async put(e,t,i){let a=n(r(l,e,t)),o=i===void 0?{value:t}:{expiresAt:Date.now()+i,value:t};getTable(e).set(a,o)},async putAll(e,t,i){let a=i===void 0?void 0:Date.now()+i;for(let i of t){let t=n(r(l,e,i)),o=a===void 0?{value:i}:{expiresAt:a,value:i};getTable(e).set(t,o)}}};return o(l,d,{...c,createBatch:e=>async(t,n)=>{i(t);let r=new Map(t.map(e=>[e,new Map(getTable(e))])),o=new Set,c=s(l,d,e=>{o.add(e)},e.validate,a(t));try{let t=await n(c);for(let t of o)e.notifyMutation(t);return t}catch(e){for(let[e,t]of r)u.set(e,t);throw e}}})}export{createMemory};
|
|
61
2
|
//# sourceMappingURL=memory.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.js","names":[],"sources":["../../src/adapters/memory.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"memory.js","names":[],"sources":["../../src/adapters/memory.ts"],"sourcesContent":["import {\n assertBatchTables,\n batchScopeGuard,\n buildDocumentStore,\n buildOperations,\n type StorageBackend,\n} from '../adapter-core';\nimport { encodeVaultKey, getRecordKey } from '../internal';\nimport { isExpired, parseStored, type StoredRecord } from '../ttl';\nimport type { AnySchema, DocumentVaultStore, MemoryStoreOptions, RecordOf } from '../types';\n\n/**\n * Creates an in-memory document store. Memory uses tagged Map keys so numeric and string\n * primary keys never collide. `batch()` snapshots the declared tables and restores them when\n * the callback throws; because memory writes never await real I/O, the rollback is exact as\n * long as the callback does not interleave external writes between its `await`s.\n */\nexport function createMemory<S extends AnySchema>(options: MemoryStoreOptions<S>): DocumentVaultStore<S> {\n const { schema } = options;\n const tables = new Map(Object.keys(schema).map((table) => [table, new Map<string, StoredRecord<unknown>>()]));\n const getTable = (table: string): Map<string, StoredRecord<unknown>> => tables.get(table)!;\n\n const core: StorageBackend<S> = {\n async clear(table) {\n getTable(table).clear();\n },\n async delete(table, key) {\n const store = getTable(table);\n const encodedKey = encodeVaultKey(key);\n const record = parseStored(store.get(encodedKey));\n\n store.delete(encodedKey);\n\n return record !== undefined && !isExpired(record.expiresAt);\n },\n async get(table, key) {\n const store = getTable(table);\n const encodedKey = encodeVaultKey(key);\n const record = parseStored<RecordOf<S, typeof table>>(store.get(encodedKey));\n\n if (!record || isExpired(record.expiresAt)) {\n store.delete(encodedKey);\n\n return undefined;\n }\n\n return record.value;\n },\n async getAll(table) {\n const store = getTable(table);\n const values: RecordOf<S, typeof table>[] = [];\n\n for (const [key, stored] of store) {\n const record = parseStored<RecordOf<S, typeof table>>(stored);\n\n if (!record || isExpired(record.expiresAt)) store.delete(key);\n else values.push(record.value);\n }\n\n return values;\n },\n async pruneExpiredInTable(table) {\n const store = getTable(table);\n let pruned = 0;\n\n for (const [key, stored] of store) {\n const record = parseStored(stored);\n\n if (!record || isExpired(record.expiresAt)) {\n store.delete(key);\n pruned += 1;\n }\n }\n\n return pruned;\n },\n async put(table, value, ttl) {\n const key = encodeVaultKey(getRecordKey(schema, table, value));\n const stored: StoredRecord<unknown> = ttl === undefined ? { value } : { expiresAt: Date.now() + ttl, value };\n\n getTable(table).set(key, stored);\n },\n async putAll(table, values, ttl) {\n const expiresAt = ttl === undefined ? undefined : Date.now() + ttl;\n\n for (const value of values) {\n const key = encodeVaultKey(getRecordKey(schema, table, value));\n const stored: StoredRecord<unknown> = expiresAt === undefined ? { value } : { expiresAt, value };\n\n getTable(table).set(key, stored);\n }\n },\n };\n\n return buildDocumentStore(schema, core, {\n ...options,\n createBatch: (deps) => async (declaredTables, fn) => {\n assertBatchTables(declaredTables);\n\n const snapshots = new Map(declaredTables.map((tableName) => [tableName, new Map(getTable(tableName))]));\n const dirty = new Set<keyof S & string>();\n const tx = buildOperations(\n schema,\n core,\n (table) => {\n // Record the dirty table; observers are notified once at commit, not per operation.\n dirty.add(table);\n },\n deps.validate,\n batchScopeGuard(declaredTables),\n );\n\n try {\n const result = await fn(tx);\n\n for (const table of dirty) deps.notifyMutation(table);\n\n return result;\n } catch (error) {\n for (const [tableName, snapshot] of snapshots) tables.set(tableName, snapshot);\n\n throw error;\n }\n },\n });\n}\n"],"mappings":"kPAiBA,SAAgB,aAAkC,EAAuD,CACvG,GAAM,CAAE,UAAW,EACb,EAAS,IAAI,IAAI,OAAO,KAAK,CAAM,CAAC,CAAC,IAAK,GAAU,CAAC,EAAO,IAAI,GAAoC,CAAC,CAAC,EACtG,SAAY,GAAsD,EAAO,IAAI,CAAK,EAElF,EAA0B,CAC9B,MAAM,MAAM,EAAO,CACjB,SAAS,CAAK,CAAC,CAAC,MAAM,CACxB,EACA,MAAM,OAAO,EAAO,EAAK,CACvB,IAAM,EAAQ,SAAS,CAAK,EACtB,EAAa,EAAe,CAAG,EAC/B,EAAS,EAAY,EAAM,IAAI,CAAU,CAAC,EAIhD,OAFA,EAAM,OAAO,CAAU,EAEhB,IAAW,IAAA,IAAa,CAAC,EAAU,EAAO,SAAS,CAC5D,EACA,MAAM,IAAI,EAAO,EAAK,CACpB,IAAM,EAAQ,SAAS,CAAK,EACtB,EAAa,EAAe,CAAG,EAC/B,EAAS,EAAuC,EAAM,IAAI,CAAU,CAAC,EAE3E,GAAI,CAAC,GAAU,EAAU,EAAO,SAAS,EAAG,CAC1C,EAAM,OAAO,CAAU,EAEvB,MACF,CAEA,OAAO,EAAO,KAChB,EACA,MAAM,OAAO,EAAO,CAClB,IAAM,EAAQ,SAAS,CAAK,EACtB,EAAsC,CAAC,EAE7C,IAAK,GAAM,CAAC,EAAK,KAAW,EAAO,CACjC,IAAM,EAAS,EAAuC,CAAM,EAExD,CAAC,GAAU,EAAU,EAAO,SAAS,EAAG,EAAM,OAAO,CAAG,EACvD,EAAO,KAAK,EAAO,KAAK,CAC/B,CAEA,OAAO,CACT,EACA,MAAM,oBAAoB,EAAO,CAC/B,IAAM,EAAQ,SAAS,CAAK,EACxB,EAAS,EAEb,IAAK,GAAM,CAAC,EAAK,KAAW,EAAO,CACjC,IAAM,EAAS,EAAY,CAAM,GAE7B,CAAC,GAAU,EAAU,EAAO,SAAS,KACvC,EAAM,OAAO,CAAG,EAChB,GAAU,EAEd,CAEA,OAAO,CACT,EACA,MAAM,IAAI,EAAO,EAAO,EAAK,CAC3B,IAAM,EAAM,EAAe,EAAa,EAAQ,EAAO,CAAK,CAAC,EACvD,EAAgC,IAAQ,IAAA,GAAY,CAAE,OAAM,EAAI,CAAE,UAAW,KAAK,IAAI,EAAI,EAAK,OAAM,EAE3G,SAAS,CAAK,CAAC,CAAC,IAAI,EAAK,CAAM,CACjC,EACA,MAAM,OAAO,EAAO,EAAQ,EAAK,CAC/B,IAAM,EAAY,IAAQ,IAAA,GAAY,IAAA,GAAY,KAAK,IAAI,EAAI,EAE/D,IAAK,IAAM,KAAS,EAAQ,CAC1B,IAAM,EAAM,EAAe,EAAa,EAAQ,EAAO,CAAK,CAAC,EACvD,EAAgC,IAAc,IAAA,GAAY,CAAE,OAAM,EAAI,CAAE,YAAW,OAAM,EAE/F,SAAS,CAAK,CAAC,CAAC,IAAI,EAAK,CAAM,CACjC,CACF,CACF,EAEA,OAAO,EAAmB,EAAQ,EAAM,CACtC,GAAG,EACH,YAAc,GAAS,MAAO,EAAgB,IAAO,CACnD,EAAkB,CAAc,EAEhC,IAAM,EAAY,IAAI,IAAI,EAAe,IAAK,GAAc,CAAC,EAAW,IAAI,IAAI,SAAS,CAAS,CAAC,CAAC,CAAC,CAAC,EAChG,EAAQ,IAAI,IACZ,EAAK,EACT,EACA,EACC,GAAU,CAET,EAAM,IAAI,CAAK,CACjB,EACA,EAAK,SACL,EAAgB,CAAc,CAChC,EAEA,GAAI,CACF,IAAM,EAAS,MAAM,EAAG,CAAE,EAE1B,IAAK,IAAM,KAAS,EAAO,EAAK,eAAe,CAAK,EAEpD,OAAO,CACT,OAAS,EAAO,CACd,IAAK,GAAM,CAAC,EAAW,KAAa,EAAW,EAAO,IAAI,EAAW,CAAQ,EAE7E,MAAM,CACR,CACF,CACF,CAAC,CACH"}
|
package/dist/adapters/sqlite.cjs
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
const e=require("../
|
|
1
|
+
const e=require("../errors.cjs"),t=require("../ttl.cjs"),n=require("../codec.cjs"),r=require("../internal.cjs"),i=require("../adapter-core.cjs");var a=new WeakMap,o=`"__vielzeug_vault_records"`,s=`"__vielzeug_vault_metadata"`,c=2,l=100,u=`INSERT INTO ${o}
|
|
2
|
+
(namespace, table_name, key_tag, value_json, expires_at)
|
|
3
|
+
VALUES (?, ?, ?, ?, ?)
|
|
4
|
+
ON CONFLICT(namespace, table_name, key_tag) DO UPDATE SET
|
|
5
|
+
value_json = excluded.value_json,
|
|
6
|
+
expires_at = excluded.expires_at`,ConnectionExecutor=class{tail=Promise.resolve();async acquire(){let e,t=this.tail;return this.tail=new Promise(t=>{e=t}),await t,()=>e?.()}async run(e){let t=await this.acquire();try{return await e()}finally{t()}}};function getConnectionState(e){let t=a.get(e);if(t)return t;let n=new ConnectionExecutor,r={batchActive:!1,executor:n,initialized:n.run(()=>initializeDatabase(e)),listeners:new Set};return a.set(e,r),r}function initializeDatabase(e){e.exec(`
|
|
2
7
|
CREATE TABLE IF NOT EXISTS ${s} (
|
|
3
8
|
namespace TEXT PRIMARY KEY,
|
|
4
9
|
format_version INTEGER NOT NULL
|
|
@@ -7,48 +12,25 @@ const e=require("../codec.cjs"),t=require("../errors.cjs"),n=require("../interna
|
|
|
7
12
|
namespace TEXT NOT NULL,
|
|
8
13
|
table_name TEXT NOT NULL,
|
|
9
14
|
key_tag TEXT NOT NULL,
|
|
10
|
-
key_kind TEXT NOT NULL,
|
|
11
|
-
key_number REAL,
|
|
12
|
-
key_string TEXT,
|
|
13
15
|
value_json TEXT NOT NULL,
|
|
14
16
|
expires_at INTEGER,
|
|
15
17
|
PRIMARY KEY (namespace, table_name, key_tag)
|
|
16
18
|
);
|
|
17
19
|
CREATE INDEX IF NOT EXISTS "__vielzeug_vault_records_expiration"
|
|
18
20
|
ON ${o} (namespace, table_name, expires_at);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
CREATE INDEX IF NOT EXISTS "__vielzeug_vault_records_string_key"
|
|
22
|
-
ON ${o} (namespace, table_name, key_kind, key_string);
|
|
23
|
-
`)}function p(e,n){let r=S(e,`SELECT format_version FROM ${s} WHERE namespace = ?`,[n]);if(r===void 0){x(e,`INSERT INTO ${s} (namespace, format_version) VALUES (?, ?)`,[n,c]);return}if(r.format_version!==c)throw new t.VaultError(`SQLite storage format for "${n}" is not supported`)}function m(e){if(e.length===0)throw new t.VaultError(`createSQLite: name must not be empty`)}function h(e,n,r){if(e===null||typeof e==`boolean`||typeof e==`string`)return;if(typeof e==`number`){if(Number.isFinite(e))return;throw new t.VaultError(`SQLite serialization failed at ${r}: numbers must be finite`)}if(typeof e!=`object`)throw new t.VaultError(`SQLite serialization failed at ${r}: expected a JSON-compatible value`);if(n.has(e))throw new t.VaultError(`SQLite serialization failed at ${r}: circular references are not supported`);if(Array.isArray(e)){n.add(e);for(let t=0;t<e.length;t+=1)h(e[t],n,`${r}[${String(t)}]`);n.delete(e);return}let i=Object.getPrototypeOf(e);if(i!==null&&i!==Object.prototype)throw new t.VaultError(`SQLite serialization failed at ${r}: expected a plain object`);n.add(e);for(let[t,i]of Object.entries(e))h(i,n,`${r}.${t}`);n.delete(e)}function g(e){return h(e,new Set,`record`),JSON.stringify(e)}function _(e){try{return JSON.parse(e)}catch(e){throw e instanceof t.VaultError?e:new t.VaultError(`stored record contains invalid JSON`,{cause:e})}}function v(e){let t=n.encodeVaultKey(e);return typeof e==`number`?{encoded:t,kind:`number`,number:e,string:null}:{encoded:t,kind:`string`,number:null,string:e}}function y(e){let n=e.value_json,r=e.expires_at,i=e.row_id;if(typeof n!=`string`||typeof i!=`number`||!Number.isInteger(i))throw new t.VaultError(`SQLite storage contains a malformed record`);if(r!==null&&(typeof r!=`number`||!Number.isFinite(r)))throw new t.VaultError(`SQLite storage contains a malformed expiration timestamp`);return{expiresAt:typeof r==`number`?r:void 0,json:n,rowId:i}}function b(e,t,n){let r=e.prepare(t);try{return n(r)}finally{r.finalize?.()}}function x(e,t,n=[]){return b(e,t,e=>e.run(...n))}function S(e,t,n=[]){return b(e,t,e=>e.get(...n)??void 0)}function C(e,t,n=[]){return b(e,t,e=>e.all(...n))}function w(e,t,n){x(e,`DELETE FROM ${o}
|
|
24
|
-
WHERE namespace = ? AND table_name = ? AND expires_at IS NOT NULL AND expires_at <= ?`,[t,n,Date.now()])}function T(i,a,s,c,l=!1){let u=(n,s)=>{let l=v(s),u=S(i,`SELECT rowid AS row_id, expires_at, value_json
|
|
21
|
+
`)}function initializeNamespace(t,n){let r=get(t,`SELECT format_version FROM ${s} WHERE namespace = ?`,[n]);if(r===void 0){run(t,`INSERT INTO ${s} (namespace, format_version) VALUES (?, ?)`,[n,c]);return}if(r.format_version!==c)throw new e.VaultError(`SQLite storage format for "${n}" is not supported`)}function assertName(t){if(t.length===0)throw new e.VaultError(`createSQLite: name must not be empty`)}function assertJsonValue(t,n,r){if(t===null||typeof t==`boolean`||typeof t==`string`)return;if(typeof t==`number`){if(Number.isFinite(t))return;throw new e.VaultError(`SQLite serialization failed at ${r}: numbers must be finite`)}if(typeof t!=`object`)throw new e.VaultError(`SQLite serialization failed at ${r}: expected a JSON-compatible value`);if(n.has(t))throw new e.VaultError(`SQLite serialization failed at ${r}: circular references are not supported`);if(Array.isArray(t)){n.add(t);for(let e=0;e<t.length;e+=1)assertJsonValue(t[e],n,`${r}[${String(e)}]`);n.delete(t);return}let i=Object.getPrototypeOf(t);if(i!==null&&i!==Object.prototype)throw new e.VaultError(`SQLite serialization failed at ${r}: expected a plain object`);n.add(t);for(let[e,i]of Object.entries(t))assertJsonValue(i,n,`${r}.${e}`);n.delete(t)}function encodeJson(e){return assertJsonValue(e,new Set,`record`),JSON.stringify(e)}function decodeJson(e){try{return JSON.parse(e)}catch{return}}function getStoredRow(t){let n=t.value_json,r=t.expires_at,i=t.row_id;if(typeof n!=`string`||typeof i!=`number`||!Number.isInteger(i))throw new e.VaultError(`SQLite storage contains a malformed record`);if(r!==null&&(typeof r!=`number`||!Number.isFinite(r)))throw new e.VaultError(`SQLite storage contains a malformed expiration timestamp`);return{expiresAt:typeof r==`number`?r:void 0,json:n,rowId:i}}function withStatement(e,t,n){let r=e.prepare(t);try{return n(r)}finally{r.finalize?.()}}function run(e,t,n=[]){return withStatement(e,t,e=>e.run(...n))}function get(e,t,n=[]){return withStatement(e,t,e=>e.get(...n)??void 0)}function all(e,t,n=[]){return withStatement(e,t,e=>e.all(...n))}function decodeRow(r,i,a,s){let c=t.isExpired(s.expiresAt)?void 0:decodeJson(s.json);if(c===void 0){run(r,`DELETE FROM ${o} WHERE rowid = ?`,[s.rowId]);return}try{return n.decodeRecord(a,c)}catch(t){throw t instanceof e.VaultError?t:new e.VaultError(`validation failed for table "${String(i)}"`,{cause:t})}}function deleteExpired(e,t,n){return run(e,`DELETE FROM ${o}
|
|
22
|
+
WHERE namespace = ? AND table_name = ? AND expires_at IS NOT NULL AND expires_at <= ?`,[t,n,Date.now()])?.changes??0}function createDirectCore(t,i,a,s,c=!1){let getRecord=(e,n)=>{let a=get(t,`SELECT rowid AS row_id, expires_at, value_json
|
|
25
23
|
FROM ${o}
|
|
26
|
-
WHERE namespace = ? AND table_name = ? AND key_tag = ?`,[
|
|
24
|
+
WHERE namespace = ? AND table_name = ? AND key_tag = ?`,[i,e,r.encodeVaultKey(n)]);if(a!==void 0)return decodeRow(t,e,s[e],getStoredRow(a))},l={async clear(e){run(t,`DELETE FROM ${o} WHERE namespace = ? AND table_name = ?`,[i,e])},async delete(e,n){return(run(t,`DELETE FROM ${o}
|
|
27
25
|
WHERE namespace = ? AND table_name = ? AND key_tag = ?
|
|
28
|
-
AND (expires_at IS NULL OR expires_at > ?)`,[
|
|
29
|
-
WHERE namespace = ? AND table_name = ? AND key_tag IN (${
|
|
30
|
-
AND (expires_at IS NULL OR expires_at > ?)`,[
|
|
26
|
+
AND (expires_at IS NULL OR expires_at > ?)`,[i,e,r.encodeVaultKey(n),Date.now()])?.changes??0)>0},async deleteMany(e,n){let a=0,s=n.map(e=>r.encodeVaultKey(e));for(let n=0;n<s.length;n+=996){let r=s.slice(n,n+996),c=run(t,`DELETE FROM ${o}
|
|
27
|
+
WHERE namespace = ? AND table_name = ? AND key_tag IN (${r.map(()=>`?`).join(`, `)})
|
|
28
|
+
AND (expires_at IS NULL OR expires_at > ?)`,[i,e,...r,Date.now()]);a+=c?.changes??0}return a},async get(e,t){return getRecord(e,t)},async getAll(e){return deleteExpired(t,i,e),all(t,`SELECT rowid AS row_id, expires_at, value_json
|
|
31
29
|
FROM ${o}
|
|
32
30
|
WHERE namespace = ? AND table_name = ?
|
|
33
|
-
ORDER BY rowid`,[
|
|
34
|
-
(namespace, table_name, key_tag, key_kind, key_number, key_string, value_json, expires_at)
|
|
35
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
36
|
-
ON CONFLICT(namespace, table_name, key_tag) DO UPDATE SET
|
|
37
|
-
key_kind = excluded.key_kind,
|
|
38
|
-
key_number = excluded.key_number,
|
|
39
|
-
key_string = excluded.key_string,
|
|
40
|
-
value_json = excluded.value_json,
|
|
41
|
-
expires_at = excluded.expires_at`,[a,t,u.encoded,u.kind,u.number,u.string,g(f),d])},async putAll(r,u,d){if(u.length===0)return;let f=d===void 0?null:Date.now()+d,p=u.map(t=>g(e.encodeRecord(c[r],t))),m=u.map(e=>v(n.getRecordKey(s,r,e))),h=()=>{for(let e=0;e<u.length;e++){let t=m[e];x(i,`INSERT INTO ${o}
|
|
42
|
-
(namespace, table_name, key_tag, key_kind, key_number, key_string, value_json, expires_at)
|
|
43
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
44
|
-
ON CONFLICT(namespace, table_name, key_tag) DO UPDATE SET
|
|
45
|
-
key_kind = excluded.key_kind,
|
|
46
|
-
key_number = excluded.key_number,
|
|
47
|
-
key_string = excluded.key_string,
|
|
48
|
-
value_json = excluded.value_json,
|
|
49
|
-
expires_at = excluded.expires_at`,[a,r,t.encoded,t.kind,t.number,t.string,p[e],f])}};if(l){h();return}i.exec(`BEGIN`);try{h(),i.exec(`COMMIT`)}catch(e){try{i.exec(`ROLLBACK`)}catch(e){throw new t.VaultError(`SQLite putAll rollback failed`,{cause:e})}throw e}}};return d}function E(n){let{closeOnDispose:a=!1,database:s,name:c,schema:u,codecs:f}=n;if(m(c),!f)throw new t.VaultError(`createSQLite: codecs are required for durable persistence`);let h=d(s),g=h.executor.run(async()=>{await h.initialized,p(s,c)}),v,b=T(s,c,u,f),S=e=>h.executor.run(async()=>(await h.initialized,await g,e())),w=Object.fromEntries(Object.entries(b).map(([e,n])=>[e,(...e)=>{if(h.batchActive)throw new t.VaultError(`cannot call a SQLite store sharing this connection from batch(); use the transaction context instead`);return S(()=>n(...e))}])),E,D=i.buildDocumentStore(u,w,{codecs:f,onCrossTabMessage(e){let t=(t,n)=>{t===c&&Object.hasOwn(u,n)&&e(n)};return v=t,h.listeners.add(t),()=>{h.listeners.delete(t),v===t&&(v=void 0)}},onMutation(e){for(let t of h.listeners)t!==v&&t(c,e)},onTransactions:e=>{E=async(n,r)=>{if(i.assertBatchTables(n),h.batchActive)throw new t.VaultError(`cannot call a SQLite store sharing this connection from batch(); use the transaction context instead`);return h.executor.run(async()=>{await h.initialized,await g;let a=new Set,o=T(s,c,u,f,!0),l=!0,d=i.buildTxContext(u,o,e=>a.add(e),e.validate,new Set(n),()=>l),p=!1,m=!1;h.batchActive=!0;try{s.exec(`BEGIN IMMEDIATE`),p=!0;let t=await r(d);s.exec(`COMMIT`),m=!0;for(let t of a)e.notifyMutation(t);return t}catch(e){if(p&&!m)try{s.exec(`ROLLBACK`)}catch(e){throw new t.VaultError(`SQLite batch rollback failed`,{cause:e})}throw e}finally{l=!1,h.batchActive=!1}})}},schema:u});if(!E)throw new t.VaultError(`SQLite transaction capability was not initialized`);let O=i.withBatch(D,E,u),k=Object.assign(O,{iterate(n){if(D.disposed)throw new t.VaultDisposedError(`"${c}" is disposed`);return{[Symbol.asyncIterator](){let i=!1,a=0,u=[],d=0,p=async()=>{let i=await h.executor.run(async()=>{await h.initialized,await g;let i=C(s,`SELECT rowid AS row_id, expires_at, value_json
|
|
31
|
+
ORDER BY rowid`,[i,e]).flatMap(n=>{let r=decodeRow(t,e,s[e],getStoredRow(n));return r===void 0?[]:[r]})},async getMany(e,t){return t.map(t=>getRecord(e,t))},async pruneAllExpired(){let e={};for(let t of Object.keys(a))e[t]=await l.pruneExpiredInTable(t);return e},async pruneExpiredInTable(e){return deleteExpired(t,i,e)},async put(e,o,c){let l=r.getRecordKey(a,e,o),d=c===void 0?null:Date.now()+c,f=n.encodeRecord(s[e],o);run(t,u,[i,e,r.encodeVaultKey(l),encodeJson(f),d])},async putAll(o,l,d){if(l.length===0)return;let f=d===void 0?null:Date.now()+d,p=l.map(e=>encodeJson(n.encodeRecord(s[o],e))),m=l.map(e=>r.encodeVaultKey(r.getRecordKey(a,o,e))),writeAll=()=>{for(let e=0;e<l.length;e++)run(t,u,[i,o,m[e],p[e],f])};if(c){writeAll();return}t.exec(`BEGIN`);try{writeAll(),t.exec(`COMMIT`)}catch(n){try{t.exec(`ROLLBACK`)}catch(t){throw new e.VaultError(`SQLite putAll rollback failed`,{cause:t})}throw n}}};return l}function createSQLite(t){let{closeOnDispose:n=!1,database:r,name:a,schema:s,codecs:c}=t;if(assertName(a),!c)throw new e.VaultError(`createSQLite: codecs are required for durable persistence`);let u=getConnectionState(r),d=u.executor.run(async()=>{await u.initialized,initializeNamespace(r,a)}),f,p=createDirectCore(r,a,s,c),withConnection=e=>u.executor.run(async()=>(await u.initialized,await d,e())),guard=t=>(...n)=>{if(u.batchActive)throw new e.VaultError(`cannot call a SQLite store sharing this connection from batch(); use the transaction context instead`);return withConnection(()=>t(...n))},m={clear:guard(e=>p.clear(e)),delete:guard((e,t)=>p.delete(e,t)),deleteMany:guard((e,t)=>p.deleteMany(e,t)),get:guard((e,t)=>p.get(e,t)),getAll:guard(e=>p.getAll(e)),getMany:guard((e,t)=>p.getMany(e,t)),pruneAllExpired:guard(()=>p.pruneAllExpired()),pruneExpiredInTable:guard(e=>p.pruneExpiredInTable(e)),put:guard((e,t,n)=>p.put(e,t,n)),putAll:guard((e,t,n)=>p.putAll(e,t,n))},h=i.buildDocumentStore(s,m,{codecs:c,createBatch:t=>async(n,o)=>{if(i.assertBatchTables(n),u.batchActive)throw new e.VaultError(`cannot call a SQLite store sharing this connection from batch(); use the transaction context instead`);return u.executor.run(async()=>{await u.initialized,await d;let l=new Set,f=createDirectCore(r,a,s,c,!0),p=!0,m=i.buildOperations(s,f,e=>l.add(e),t.validate,i.batchScopeGuard(n,()=>p)),h=!1;u.batchActive=!0;try{r.exec(`BEGIN IMMEDIATE`),h=!0;let e=await o(m);r.exec(`COMMIT`);for(let e of l)t.notifyMutation(e);return e}catch(t){if(h)try{r.exec(`ROLLBACK`)}catch(t){throw new e.VaultError(`SQLite batch rollback failed`,{cause:t})}throw t}finally{p=!1,u.batchActive=!1}})},onCrossTabMessage(e){let listener=(t,n)=>{t===a&&Object.hasOwn(s,n)&&e(n)};return f=listener,u.listeners.add(listener),()=>{u.listeners.delete(listener),f===listener&&(f=void 0)}},onMutation(e){for(let t of u.listeners)t!==f&&t(a,e)},schema:s}),g=Object.assign(h,{iterate(t){if(h.disposed)throw new e.VaultDisposedError(`"${a}" is disposed`);return{[Symbol.asyncIterator](){let n=!1,i=0,s=[],f=0,loadNextPage=async()=>{let e=await u.executor.run(async()=>{await u.initialized,await d;let e=all(r,`SELECT rowid AS row_id, expires_at, value_json
|
|
50
32
|
FROM ${o}
|
|
51
33
|
WHERE namespace = ? AND table_name = ? AND rowid > ?
|
|
52
34
|
ORDER BY rowid
|
|
53
|
-
LIMIT ?`,[
|
|
35
|
+
LIMIT ?`,[a,t,i,l]),n=[];for(let a of e){let e=getStoredRow(a);i=e.rowId;let o=decodeRow(r,t,c[t],e);o!==void 0&&n.push(o)}return{done:e.length===0,values:n}});return s=e.values,f=0,e.done};return{async next(){if(n)return{done:!0,value:void 0};if(h.disposed)throw new e.VaultDisposedError(`"${a}" is disposed`);if(u.batchActive)throw new e.VaultError(`cannot call a SQLite store sharing this connection from batch(); use the transaction context instead`);try{for(;f>=s.length;)if(await loadNextPage())return n=!0,{done:!0,value:void 0};return{done:!1,value:s[f++]}}catch(e){throw n=!0,e}},async return(e){return n=!0,{done:!0,value:e}},async throw(e){throw n=!0,e}}}}}});if(n){let e=g.dispose.bind(g),t;g.dispose=async()=>{await e(),t??=u.executor.run(()=>r.close?.()),await t},g[Symbol.asyncDispose]=async()=>{await g.dispose()}}return g}exports.createSQLite=createSQLite;
|
|
54
36
|
//# sourceMappingURL=sqlite.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.cjs","names":[],"sources":["../../src/adapters/sqlite.ts"],"sourcesContent":["import {\n assertBatchTables,\n type BatchImpl,\n buildDocumentStore,\n buildTxContext,\n type StorageBackend,\n withBatch,\n} from '../adapter-core';\nimport { decodeRecord, encodeRecord } from '../codec';\nimport { VaultDisposedError, VaultError } from '../errors';\nimport { encodeVaultKey, getRecordKey } from '../internal';\nimport { isExpired } from '../ttl';\nimport type { AnySchema, DocumentVaultStore, DurableStoreOptions, KeyOf, RecordOf, TransactionContext } from '../types';\n\nexport type { TransactionContext };\n\nexport type SQLiteParameter = null | number | string;\ntype SQLiteRow = Record<string, unknown>;\n\n/**\n * A synchronous SQLite statement with positional parameter binding.\n *\n * Adapters for drivers whose native statement API differs can implement this\n * structural protocol without adding a runtime dependency to Vault.\n */\nexport interface SQLiteStatement {\n all(...parameters: SQLiteParameter[]): readonly SQLiteRow[];\n finalize?(): void;\n get(...parameters: SQLiteParameter[]): SQLiteRow | null | undefined;\n run(...parameters: SQLiteParameter[]): unknown;\n}\n\n/**\n * A runtime-neutral synchronous SQLite connection.\n *\n * Node's `DatabaseSync`, Bun's `Database`, and Deno's `@db/sqlite` `Database`\n * satisfy this protocol directly.\n */\nexport interface SQLiteDatabase {\n close?(): void;\n exec(sql: string): void;\n prepare(sql: string): SQLiteStatement;\n}\n\nexport type SQLiteVaultOptions<S extends AnySchema> = DurableStoreOptions<S> & {\n /** Closes the caller-provided connection during store disposal when true. */\n closeOnDispose?: boolean;\n database: SQLiteDatabase;\n /** Namespace that isolates this store's records in the shared connection. */\n name: string;\n};\n\ntype ConnectionState = {\n batchActive: boolean;\n executor: ConnectionExecutor;\n initialized: Promise<void>;\n listeners: Set<ConnectionListener>;\n};\ntype ConnectionListener = (name: string, table: string) => void;\ntype KeyColumns = { encoded: string; kind: 'number' | 'string'; number: number | null; string: string | null };\ntype StoredRow = { expiresAt: number | undefined; json: string; rowId: number };\n\nconst connectionStates = new WeakMap<SQLiteDatabase, ConnectionState>();\nconst RECORDS_TABLE = '\"__vielzeug_vault_records\"';\nconst METADATA_TABLE = '\"__vielzeug_vault_metadata\"';\nconst STORAGE_FORMAT_VERSION = 1;\nconst ITERATION_PAGE_SIZE = 100;\n\nclass ConnectionExecutor {\n private tail: Promise<void> = Promise.resolve();\n\n async acquire(): Promise<() => void> {\n let release: (() => void) | undefined;\n const previous = this.tail;\n\n this.tail = new Promise<void>((resolve) => {\n release = resolve;\n });\n await previous;\n\n return () => release?.();\n }\n\n async run<T>(work: () => T | Promise<T>): Promise<T> {\n const release = await this.acquire();\n\n try {\n return await work();\n } finally {\n release();\n }\n }\n}\n\nfunction getConnectionState(database: SQLiteDatabase): ConnectionState {\n const current = connectionStates.get(database);\n\n if (current) return current;\n\n const executor = new ConnectionExecutor();\n const state: ConnectionState = {\n batchActive: false,\n executor,\n initialized: executor.run(() => initializeDatabase(database)),\n listeners: new Set(),\n };\n\n connectionStates.set(database, state);\n\n return state;\n}\n\nfunction initializeDatabase(database: SQLiteDatabase): void {\n database.exec(\n `\n CREATE TABLE IF NOT EXISTS ${METADATA_TABLE} (\n namespace TEXT PRIMARY KEY,\n format_version INTEGER NOT NULL\n );\n CREATE TABLE IF NOT EXISTS ${RECORDS_TABLE} (\n namespace TEXT NOT NULL,\n table_name TEXT NOT NULL,\n key_tag TEXT NOT NULL,\n key_kind TEXT NOT NULL,\n key_number REAL,\n key_string TEXT,\n value_json TEXT NOT NULL,\n expires_at INTEGER,\n PRIMARY KEY (namespace, table_name, key_tag)\n );\n CREATE INDEX IF NOT EXISTS \"__vielzeug_vault_records_expiration\"\n ON ${RECORDS_TABLE} (namespace, table_name, expires_at);\n CREATE INDEX IF NOT EXISTS \"__vielzeug_vault_records_number_key\"\n ON ${RECORDS_TABLE} (namespace, table_name, key_kind, key_number);\n CREATE INDEX IF NOT EXISTS \"__vielzeug_vault_records_string_key\"\n ON ${RECORDS_TABLE} (namespace, table_name, key_kind, key_string);\n `,\n );\n}\n\nfunction initializeNamespace(database: SQLiteDatabase, name: string): void {\n const row = get(database, `SELECT format_version FROM ${METADATA_TABLE} WHERE namespace = ?`, [name]);\n\n if (row === undefined) {\n run(database, `INSERT INTO ${METADATA_TABLE} (namespace, format_version) VALUES (?, ?)`, [\n name,\n STORAGE_FORMAT_VERSION,\n ]);\n\n return;\n }\n\n if (row.format_version !== STORAGE_FORMAT_VERSION) {\n throw new VaultError(`SQLite storage format for \"${name}\" is not supported`);\n }\n}\n\nfunction assertName(name: string): void {\n if (name.length === 0) throw new VaultError('createSQLite: name must not be empty');\n}\n\nfunction assertJsonValue(value: unknown, seen: Set<object>, path: string): void {\n if (value === null || typeof value === 'boolean' || typeof value === 'string') return;\n\n if (typeof value === 'number') {\n if (Number.isFinite(value)) return;\n\n throw new VaultError(`SQLite serialization failed at ${path}: numbers must be finite`);\n }\n\n if (typeof value !== 'object') {\n throw new VaultError(`SQLite serialization failed at ${path}: expected a JSON-compatible value`);\n }\n\n if (seen.has(value as object)) {\n throw new VaultError(`SQLite serialization failed at ${path}: circular references are not supported`);\n }\n\n if (Array.isArray(value)) {\n seen.add(value);\n\n for (let index = 0; index < value.length; index += 1) {\n assertJsonValue(value[index], seen, `${path}[${String(index)}]`);\n }\n\n seen.delete(value);\n\n return;\n }\n\n const prototype = Object.getPrototypeOf(value);\n\n if (prototype !== null && prototype !== Object.prototype) {\n throw new VaultError(`SQLite serialization failed at ${path}: expected a plain object`);\n }\n\n seen.add(value as object);\n\n for (const [key, nested] of Object.entries(value)) {\n assertJsonValue(nested, seen, `${path}.${key}`);\n }\n\n seen.delete(value);\n}\n\nfunction encodeJson(value: unknown): string {\n assertJsonValue(value, new Set(), 'record');\n\n return JSON.stringify(value);\n}\n\nfunction decodeJson(json: string): unknown {\n try {\n return JSON.parse(json) as unknown;\n } catch (error) {\n if (error instanceof VaultError) throw error;\n\n throw new VaultError('stored record contains invalid JSON', { cause: error });\n }\n}\n\nfunction toKeyColumns(key: number | string): KeyColumns {\n const encoded = encodeVaultKey(key);\n\n return typeof key === 'number'\n ? { encoded, kind: 'number', number: key, string: null }\n : { encoded, kind: 'string', number: null, string: key };\n}\n\nfunction getStoredRow(row: SQLiteRow): StoredRow {\n const json = row.value_json;\n const rawExpiresAt = row.expires_at;\n const rowId = row.row_id;\n\n if (typeof json !== 'string' || typeof rowId !== 'number' || !Number.isInteger(rowId)) {\n throw new VaultError('SQLite storage contains a malformed record');\n }\n\n if (rawExpiresAt !== null && (typeof rawExpiresAt !== 'number' || !Number.isFinite(rawExpiresAt))) {\n throw new VaultError('SQLite storage contains a malformed expiration timestamp');\n }\n\n const expiresAt = typeof rawExpiresAt === 'number' ? rawExpiresAt : undefined;\n\n return { expiresAt, json, rowId };\n}\n\nfunction withStatement<T>(database: SQLiteDatabase, sql: string, work: (statement: SQLiteStatement) => T): T {\n const statement = database.prepare(sql);\n\n try {\n return work(statement);\n } finally {\n statement.finalize?.();\n }\n}\n\nfunction run(database: SQLiteDatabase, sql: string, parameters: SQLiteParameter[] = []): unknown {\n return withStatement(database, sql, (statement) => statement.run(...parameters));\n}\n\nfunction get(database: SQLiteDatabase, sql: string, parameters: SQLiteParameter[] = []): SQLiteRow | undefined {\n return withStatement(database, sql, (statement) => statement.get(...parameters) ?? undefined);\n}\n\nfunction all(database: SQLiteDatabase, sql: string, parameters: SQLiteParameter[] = []): readonly SQLiteRow[] {\n return withStatement(database, sql, (statement) => statement.all(...parameters));\n}\n\nfunction deleteExpired(database: SQLiteDatabase, name: string, table: string): void {\n run(\n database,\n `DELETE FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ? AND expires_at IS NOT NULL AND expires_at <= ?`,\n [name, table, Date.now()],\n );\n}\n\nfunction createDirectCore<S extends AnySchema, K extends keyof S & string>(\n database: SQLiteDatabase,\n name: string,\n schema: S,\n codecs: NonNullable<DurableStoreOptions<S>['codecs']>,\n inTransaction = false,\n): StorageBackend<S, K> {\n const getRecord = <T extends K>(table: T, key: KeyOf<S, T>): RecordOf<S, T> | undefined => {\n const columns = toKeyColumns(key);\n const row = get(\n database,\n `SELECT rowid AS row_id, expires_at, value_json\n FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ? AND key_tag = ?`,\n [name, table, columns.encoded],\n );\n\n if (row === undefined) return undefined;\n\n const stored = getStoredRow(row);\n\n if (isExpired(stored.expiresAt)) {\n run(database, `DELETE FROM ${RECORDS_TABLE} WHERE rowid = ?`, [stored.rowId]);\n\n return undefined;\n }\n\n try {\n const decoded = decodeJson(stored.json);\n\n return decodeRecord(codecs[table], decoded) as RecordOf<S, T>;\n } catch (err) {\n if (err instanceof VaultError) throw err;\n\n throw new VaultError(`validation failed for table \"${String(table)}\"`, { cause: err });\n }\n };\n\n const core: StorageBackend<S, K> = {\n async clear(table) {\n run(database, `DELETE FROM ${RECORDS_TABLE} WHERE namespace = ? AND table_name = ?`, [name, table]);\n },\n async delete(table, key) {\n const columns = toKeyColumns(key);\n const result = run(\n database,\n `DELETE FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ? AND key_tag = ?\n AND (expires_at IS NULL OR expires_at > ?)`,\n [name, table, columns.encoded, Date.now()],\n ) as { changes?: number } | undefined;\n\n return (result?.changes ?? 0) > 0;\n },\n async deleteMany(table, keys) {\n let deleted = 0;\n const maxKeysPerChunk = 996;\n const encodedKeys = keys.map((key) => toKeyColumns(key).encoded);\n\n for (let index = 0; index < encodedKeys.length; index += maxKeysPerChunk) {\n const chunk = encodedKeys.slice(index, index + maxKeysPerChunk);\n const placeholders = chunk.map(() => '?').join(', ');\n const result = run(\n database,\n `DELETE FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ? AND key_tag IN (${placeholders})\n AND (expires_at IS NULL OR expires_at > ?)`,\n [name, table, ...chunk, Date.now()],\n ) as { changes?: number } | undefined;\n deleted += result?.changes ?? 0;\n }\n\n return deleted;\n },\n async get(table, key) {\n return getRecord(table, key);\n },\n async getAll(table) {\n deleteExpired(database, name, table);\n\n const records = all(\n database,\n `SELECT rowid AS row_id, expires_at, value_json\n FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ?\n ORDER BY rowid`,\n [name, table],\n );\n\n return records.flatMap((row) => {\n const stored = getStoredRow(row);\n\n if (isExpired(stored.expiresAt)) {\n run(database, `DELETE FROM ${RECORDS_TABLE} WHERE rowid = ?`, [stored.rowId]);\n\n return [];\n }\n\n try {\n const decoded = decodeJson(stored.json);\n\n return [decodeRecord(codecs[table], decoded) as RecordOf<S, typeof table>];\n } catch (err) {\n if (err instanceof VaultError) throw err;\n\n throw new VaultError(`validation failed for table \"${String(table)}\"`, { cause: err });\n }\n });\n },\n async getMany(table, keys) {\n return keys.map((key) => getRecord(table, key));\n },\n async pruneAllExpired() {\n const results: Record<string, number> = {};\n\n for (const table of Object.keys(schema)) {\n results[table] = await core.pruneExpiredInTable(table as K);\n }\n\n return results;\n },\n async pruneExpiredInTable(table) {\n const beforeRow = get(\n database,\n `SELECT COUNT(*) AS count FROM ${RECORDS_TABLE} WHERE namespace = ? AND table_name = ?`,\n [name, table],\n );\n const before = beforeRow?.count;\n\n if (typeof before !== 'number') throw new VaultError('SQLite storage returned an invalid count');\n\n deleteExpired(database, name, table);\n\n const afterRow = get(\n database,\n `SELECT COUNT(*) AS count FROM ${RECORDS_TABLE} WHERE namespace = ? AND table_name = ?`,\n [name, table],\n );\n const after = afterRow?.count;\n\n if (typeof after !== 'number') throw new VaultError('SQLite storage returned an invalid count');\n\n return before - after;\n },\n async put(table, value, ttl) {\n const key = getRecordKey(schema, table, value);\n const columns = toKeyColumns(key);\n const expiresAt = ttl === undefined ? null : Date.now() + ttl;\n const encoded = encodeRecord(codecs[table], value as RecordOf<S, typeof table>);\n\n run(\n database,\n `INSERT INTO ${RECORDS_TABLE}\n (namespace, table_name, key_tag, key_kind, key_number, key_string, value_json, expires_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(namespace, table_name, key_tag) DO UPDATE SET\n key_kind = excluded.key_kind,\n key_number = excluded.key_number,\n key_string = excluded.key_string,\n value_json = excluded.value_json,\n expires_at = excluded.expires_at`,\n [name, table, columns.encoded, columns.kind, columns.number, columns.string, encodeJson(encoded), expiresAt],\n );\n },\n async putAll(table, values, ttl) {\n if (values.length === 0) return;\n\n const expiresAt = ttl === undefined ? null : Date.now() + ttl;\n const encodedJsonValues = values.map((v) =>\n encodeJson(encodeRecord(codecs[table], v as RecordOf<S, typeof table>)),\n );\n const columnsList = values.map((v) => toKeyColumns(getRecordKey(schema, table, v)));\n\n const writeAll = () => {\n for (let i = 0; i < values.length; i++) {\n const columns = columnsList[i];\n run(\n database,\n `INSERT INTO ${RECORDS_TABLE}\n (namespace, table_name, key_tag, key_kind, key_number, key_string, value_json, expires_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(namespace, table_name, key_tag) DO UPDATE SET\n key_kind = excluded.key_kind,\n key_number = excluded.key_number,\n key_string = excluded.key_string,\n value_json = excluded.value_json,\n expires_at = excluded.expires_at`,\n [\n name,\n table,\n columns.encoded,\n columns.kind,\n columns.number,\n columns.string,\n encodedJsonValues[i],\n expiresAt,\n ],\n );\n }\n };\n\n if (inTransaction) {\n writeAll();\n return;\n }\n\n database.exec('BEGIN');\n try {\n writeAll();\n database.exec('COMMIT');\n } catch (error) {\n try {\n database.exec('ROLLBACK');\n } catch (rollbackError) {\n throw new VaultError('SQLite putAll rollback failed', { cause: rollbackError });\n }\n throw error;\n }\n },\n };\n\n return core;\n}\n\n/**\n * Creates a SQLite-backed Vault store. The connection is caller-owned unless\n * `closeOnDispose` is explicitly enabled.\n */\nexport function createSQLite<S extends AnySchema>(options: SQLiteVaultOptions<S>): DocumentVaultStore<S> {\n const { closeOnDispose = false, database, name, schema, codecs } = options;\n\n assertName(name);\n\n if (!codecs) {\n throw new VaultError('createSQLite: codecs are required for durable persistence');\n }\n\n const state = getConnectionState(database);\n const namespaceReady = state.executor.run(async () => {\n await state.initialized;\n initializeNamespace(database, name);\n });\n let ownListener: ConnectionListener | undefined;\n\n const directCore = createDirectCore(database, name, schema, codecs);\n const withConnection = <T>(work: () => Promise<T>): Promise<T> =>\n state.executor.run(async () => {\n await state.initialized;\n await namespaceReady;\n\n return work();\n });\n const guardedCore = Object.fromEntries(\n Object.entries(directCore).map(([method, implementation]) => [\n method,\n (...arguments_: unknown[]) => {\n if (state.batchActive) {\n throw new VaultError(\n 'cannot call a SQLite store sharing this connection from batch(); use the transaction context instead',\n );\n }\n\n return withConnection(() => (implementation as (...args: unknown[]) => Promise<unknown>)(...arguments_));\n },\n ]),\n ) as unknown as StorageBackend<S>;\n\n let batch: BatchImpl<S> | undefined;\n const adapter = buildDocumentStore(schema, guardedCore, {\n codecs,\n onCrossTabMessage(notify) {\n const listener: ConnectionListener = (eventName, table) => {\n if (eventName === name && Object.hasOwn(schema, table)) notify(table as keyof S & string);\n };\n\n ownListener = listener;\n state.listeners.add(listener);\n\n return () => {\n state.listeners.delete(listener);\n\n if (ownListener === listener) ownListener = undefined;\n };\n },\n onMutation(table) {\n for (const listener of state.listeners) {\n if (listener !== ownListener) listener(name, table);\n }\n },\n onTransactions: (deps) => {\n batch = async (tables, fn) => {\n assertBatchTables(tables);\n\n if (state.batchActive) {\n throw new VaultError(\n 'cannot call a SQLite store sharing this connection from batch(); use the transaction context instead',\n );\n }\n\n return state.executor.run(async () => {\n await state.initialized;\n await namespaceReady;\n\n const dirtyTables = new Set<keyof S & string>();\n const txCore = createDirectCore<S, keyof S & string>(database, name, schema, codecs, true);\n let contextActive = true;\n const tx = buildTxContext(\n schema,\n txCore,\n (table) => dirtyTables.add(table),\n deps.validate,\n new Set<string>(tables),\n () => contextActive,\n );\n let transactionStarted = false;\n let committed = false;\n\n state.batchActive = true;\n\n try {\n database.exec('BEGIN IMMEDIATE');\n transactionStarted = true;\n\n const result = await fn(tx);\n\n database.exec('COMMIT');\n committed = true;\n\n for (const table of dirtyTables) {\n deps.notifyMutation(table);\n }\n\n return result;\n } catch (error) {\n if (transactionStarted && !committed) {\n try {\n database.exec('ROLLBACK');\n } catch (rollbackError) {\n throw new VaultError('SQLite batch rollback failed', { cause: rollbackError });\n }\n }\n\n throw error;\n } finally {\n contextActive = false;\n state.batchActive = false;\n }\n });\n };\n },\n schema,\n });\n\n if (!batch) throw new VaultError('SQLite transaction capability was not initialized');\n\n const batched = withBatch(adapter, batch, schema);\n const store = Object.assign(batched, {\n iterate<K extends keyof S & string>(table: K): AsyncIterable<RecordOf<S, K>> {\n if (adapter.disposed) throw new VaultDisposedError(`\"${name}\" is disposed`);\n\n return {\n [Symbol.asyncIterator](): AsyncIterator<RecordOf<S, K>> {\n let completed = false;\n let lastRowId = 0;\n let rows: RecordOf<S, K>[] = [];\n let index = 0;\n\n const loadNextPage = async (): Promise<boolean> => {\n const page = await state.executor.run(async () => {\n await state.initialized;\n await namespaceReady;\n const storedRows = all(\n database,\n `SELECT rowid AS row_id, expires_at, value_json\n FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ? AND rowid > ?\n ORDER BY rowid\n LIMIT ?`,\n [name, table, lastRowId, ITERATION_PAGE_SIZE],\n );\n const values: RecordOf<S, K>[] = [];\n\n for (const row of storedRows) {\n const stored = getStoredRow(row);\n lastRowId = stored.rowId;\n\n if (isExpired(stored.expiresAt)) {\n run(database, `DELETE FROM ${RECORDS_TABLE} WHERE rowid = ?`, [stored.rowId]);\n continue;\n }\n\n try {\n values.push(decodeRecord(codecs[table], decodeJson(stored.json)) as RecordOf<S, K>);\n } catch (err) {\n if (err instanceof VaultError) throw err;\n throw new VaultError(`validation failed for table \"${String(table)}\"`, { cause: err });\n }\n }\n\n return { done: storedRows.length === 0, values };\n });\n\n rows = page.values;\n index = 0;\n return page.done;\n };\n\n return {\n async next(): Promise<IteratorResult<RecordOf<S, K>>> {\n if (completed) return { done: true, value: undefined };\n if (adapter.disposed) throw new VaultDisposedError(`\"${name}\" is disposed`);\n\n if (state.batchActive) {\n throw new VaultError(\n 'cannot call a SQLite store sharing this connection from batch(); use the transaction context instead',\n );\n }\n\n try {\n while (index >= rows.length) {\n if (await loadNextPage()) {\n completed = true;\n return { done: true, value: undefined };\n }\n }\n\n return { done: false, value: rows[index++] };\n } catch (error) {\n completed = true;\n throw error;\n }\n },\n async return(value?: unknown): Promise<IteratorResult<RecordOf<S, K>>> {\n completed = true;\n return { done: true, value: value as RecordOf<S, K> };\n },\n async throw(error?: unknown): Promise<IteratorResult<RecordOf<S, K>>> {\n completed = true;\n throw error;\n },\n };\n },\n };\n },\n });\n\n if (closeOnDispose) {\n const dispose = store.dispose.bind(store);\n let closePromise: Promise<void> | undefined;\n\n store.dispose = async (): Promise<void> => {\n await dispose();\n closePromise ??= state.executor.run(() => database.close?.());\n await closePromise;\n };\n store[Symbol.asyncDispose] = async (): Promise<void> => {\n await store.dispose();\n };\n }\n\n return store;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sqlite.cjs","names":[],"sources":["../../src/adapters/sqlite.ts"],"sourcesContent":["import {\n assertBatchTables,\n batchScopeGuard,\n buildDocumentStore,\n buildOperations,\n type StorageBackend,\n} from '../adapter-core';\nimport { decodeRecord, encodeRecord } from '../codec';\nimport { VaultDisposedError, VaultError } from '../errors';\nimport { encodeVaultKey, getRecordKey } from '../internal';\nimport { isExpired } from '../ttl';\nimport type {\n AnySchema,\n CodecInput,\n DocumentVaultStore,\n DurableStoreOptions,\n KeyOf,\n RecordOf,\n TransactionContext,\n} from '../types';\n\nexport type { TransactionContext };\n\nexport type SQLiteParameter = null | number | string;\ntype SQLiteRow = Record<string, unknown>;\n\n/**\n * A synchronous SQLite statement with positional parameter binding.\n *\n * Adapters for drivers whose native statement API differs can implement this\n * structural protocol without adding a runtime dependency to Vault.\n */\nexport interface SQLiteStatement {\n all(...parameters: SQLiteParameter[]): readonly SQLiteRow[];\n finalize?(): void;\n get(...parameters: SQLiteParameter[]): SQLiteRow | null | undefined;\n run(...parameters: SQLiteParameter[]): unknown;\n}\n\n/**\n * A runtime-neutral synchronous SQLite connection.\n *\n * Node's `DatabaseSync`, Bun's `Database`, and Deno's `@db/sqlite` `Database`\n * satisfy this protocol directly.\n */\nexport interface SQLiteDatabase {\n close?(): void;\n exec(sql: string): void;\n prepare(sql: string): SQLiteStatement;\n}\n\nexport type SQLiteVaultOptions<S extends AnySchema> = DurableStoreOptions<S> & {\n /** Closes the caller-provided connection during store disposal when true. */\n closeOnDispose?: boolean;\n database: SQLiteDatabase;\n /** Namespace that isolates this store's records in the shared connection. */\n name: string;\n};\n\ntype ConnectionState = {\n batchActive: boolean;\n executor: ConnectionExecutor;\n initialized: Promise<void>;\n listeners: Set<ConnectionListener>;\n};\ntype ConnectionListener = (name: string, table: string) => void;\ntype StoredRow = { expiresAt: number | undefined; json: string; rowId: number };\n/** The direct core implements every backend operation except lazy iteration. */\ntype SqliteCore<S extends AnySchema, K extends keyof S & string> = StorageBackend<S, K> & {\n deleteMany<T extends K>(table: T, keys: readonly KeyOf<S, T>[]): Promise<number>;\n getMany<T extends K>(table: T, keys: readonly KeyOf<S, T>[]): Promise<Array<RecordOf<S, T> | undefined>>;\n pruneAllExpired(): Promise<Record<string, number>>;\n};\n\nconst connectionStates = new WeakMap<SQLiteDatabase, ConnectionState>();\nconst RECORDS_TABLE = '\"__vielzeug_vault_records\"';\nconst METADATA_TABLE = '\"__vielzeug_vault_metadata\"';\nconst STORAGE_FORMAT_VERSION = 2;\nconst ITERATION_PAGE_SIZE = 100;\nconst UPSERT_SQL = `INSERT INTO ${RECORDS_TABLE}\n (namespace, table_name, key_tag, value_json, expires_at)\n VALUES (?, ?, ?, ?, ?)\n ON CONFLICT(namespace, table_name, key_tag) DO UPDATE SET\n value_json = excluded.value_json,\n expires_at = excluded.expires_at`;\n\nclass ConnectionExecutor {\n private tail: Promise<void> = Promise.resolve();\n\n async acquire(): Promise<() => void> {\n let release: (() => void) | undefined;\n const previous = this.tail;\n\n this.tail = new Promise<void>((resolve) => {\n release = resolve;\n });\n await previous;\n\n return () => release?.();\n }\n\n async run<T>(work: () => T | Promise<T>): Promise<T> {\n const release = await this.acquire();\n\n try {\n return await work();\n } finally {\n release();\n }\n }\n}\n\nfunction getConnectionState(database: SQLiteDatabase): ConnectionState {\n const current = connectionStates.get(database);\n\n if (current) return current;\n\n const executor = new ConnectionExecutor();\n const state: ConnectionState = {\n batchActive: false,\n executor,\n initialized: executor.run(() => initializeDatabase(database)),\n listeners: new Set(),\n };\n\n connectionStates.set(database, state);\n\n return state;\n}\n\nfunction initializeDatabase(database: SQLiteDatabase): void {\n database.exec(\n `\n CREATE TABLE IF NOT EXISTS ${METADATA_TABLE} (\n namespace TEXT PRIMARY KEY,\n format_version INTEGER NOT NULL\n );\n CREATE TABLE IF NOT EXISTS ${RECORDS_TABLE} (\n namespace TEXT NOT NULL,\n table_name TEXT NOT NULL,\n key_tag TEXT NOT NULL,\n value_json TEXT NOT NULL,\n expires_at INTEGER,\n PRIMARY KEY (namespace, table_name, key_tag)\n );\n CREATE INDEX IF NOT EXISTS \"__vielzeug_vault_records_expiration\"\n ON ${RECORDS_TABLE} (namespace, table_name, expires_at);\n `,\n );\n}\n\nfunction initializeNamespace(database: SQLiteDatabase, name: string): void {\n const row = get(database, `SELECT format_version FROM ${METADATA_TABLE} WHERE namespace = ?`, [name]);\n\n if (row === undefined) {\n run(database, `INSERT INTO ${METADATA_TABLE} (namespace, format_version) VALUES (?, ?)`, [\n name,\n STORAGE_FORMAT_VERSION,\n ]);\n\n return;\n }\n\n if (row.format_version !== STORAGE_FORMAT_VERSION) {\n throw new VaultError(`SQLite storage format for \"${name}\" is not supported`);\n }\n}\n\nfunction assertName(name: string): void {\n if (name.length === 0) throw new VaultError('createSQLite: name must not be empty');\n}\n\nfunction assertJsonValue(value: unknown, seen: Set<object>, path: string): void {\n if (value === null || typeof value === 'boolean' || typeof value === 'string') return;\n\n if (typeof value === 'number') {\n if (Number.isFinite(value)) return;\n\n throw new VaultError(`SQLite serialization failed at ${path}: numbers must be finite`);\n }\n\n if (typeof value !== 'object') {\n throw new VaultError(`SQLite serialization failed at ${path}: expected a JSON-compatible value`);\n }\n\n if (seen.has(value as object)) {\n throw new VaultError(`SQLite serialization failed at ${path}: circular references are not supported`);\n }\n\n if (Array.isArray(value)) {\n seen.add(value);\n\n for (let index = 0; index < value.length; index += 1) {\n assertJsonValue(value[index], seen, `${path}[${String(index)}]`);\n }\n\n seen.delete(value);\n\n return;\n }\n\n const prototype = Object.getPrototypeOf(value);\n\n if (prototype !== null && prototype !== Object.prototype) {\n throw new VaultError(`SQLite serialization failed at ${path}: expected a plain object`);\n }\n\n seen.add(value as object);\n\n for (const [key, nested] of Object.entries(value)) {\n assertJsonValue(nested, seen, `${path}.${key}`);\n }\n\n seen.delete(value);\n}\n\nfunction encodeJson(value: unknown): string {\n assertJsonValue(value, new Set(), 'record');\n\n return JSON.stringify(value);\n}\n\n/** Returns `undefined` for unparseable JSON so callers can evict the corrupt row. */\nfunction decodeJson(json: string): unknown {\n try {\n return JSON.parse(json) as unknown;\n } catch {\n return undefined;\n }\n}\n\nfunction getStoredRow(row: SQLiteRow): StoredRow {\n const json = row.value_json;\n const rawExpiresAt = row.expires_at;\n const rowId = row.row_id;\n\n if (typeof json !== 'string' || typeof rowId !== 'number' || !Number.isInteger(rowId)) {\n throw new VaultError('SQLite storage contains a malformed record');\n }\n\n if (rawExpiresAt !== null && (typeof rawExpiresAt !== 'number' || !Number.isFinite(rawExpiresAt))) {\n throw new VaultError('SQLite storage contains a malformed expiration timestamp');\n }\n\n const expiresAt = typeof rawExpiresAt === 'number' ? rawExpiresAt : undefined;\n\n return { expiresAt, json, rowId };\n}\n\nfunction withStatement<T>(database: SQLiteDatabase, sql: string, work: (statement: SQLiteStatement) => T): T {\n const statement = database.prepare(sql);\n\n try {\n return work(statement);\n } finally {\n statement.finalize?.();\n }\n}\n\nfunction run(database: SQLiteDatabase, sql: string, parameters: SQLiteParameter[] = []): unknown {\n return withStatement(database, sql, (statement) => statement.run(...parameters));\n}\n\nfunction get(database: SQLiteDatabase, sql: string, parameters: SQLiteParameter[] = []): SQLiteRow | undefined {\n return withStatement(database, sql, (statement) => statement.get(...parameters) ?? undefined);\n}\n\nfunction all(database: SQLiteDatabase, sql: string, parameters: SQLiteParameter[] = []): readonly SQLiteRow[] {\n return withStatement(database, sql, (statement) => statement.all(...parameters));\n}\n\n/**\n * Decodes a stored row, self-healing: expired or unparseable rows are deleted\n * and reported as missing, matching the Web Storage adapter. Codec rejections\n * (schema drift on readable data) still throw so they stay visible.\n */\nfunction decodeRow<S extends AnySchema, K extends keyof S & string>(\n database: SQLiteDatabase,\n table: K,\n codec: CodecInput<RecordOf<S, K>>,\n stored: StoredRow,\n): RecordOf<S, K> | undefined {\n const decoded = isExpired(stored.expiresAt) ? undefined : decodeJson(stored.json);\n\n if (decoded === undefined) {\n run(database, `DELETE FROM ${RECORDS_TABLE} WHERE rowid = ?`, [stored.rowId]);\n\n return undefined;\n }\n\n try {\n return decodeRecord(codec, decoded) as RecordOf<S, K>;\n } catch (err) {\n if (err instanceof VaultError) throw err;\n\n throw new VaultError(`validation failed for table \"${String(table)}\"`, { cause: err });\n }\n}\n\nfunction deleteExpired(database: SQLiteDatabase, name: string, table: string): number {\n const result = run(\n database,\n `DELETE FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ? AND expires_at IS NOT NULL AND expires_at <= ?`,\n [name, table, Date.now()],\n ) as { changes?: number } | undefined;\n\n return result?.changes ?? 0;\n}\n\nfunction createDirectCore<S extends AnySchema, K extends keyof S & string>(\n database: SQLiteDatabase,\n name: string,\n schema: S,\n codecs: NonNullable<DurableStoreOptions<S>['codecs']>,\n inTransaction = false,\n): SqliteCore<S, K> {\n const getRecord = <T extends K>(table: T, key: KeyOf<S, T>): RecordOf<S, T> | undefined => {\n const row = get(\n database,\n `SELECT rowid AS row_id, expires_at, value_json\n FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ? AND key_tag = ?`,\n [name, table, encodeVaultKey(key)],\n );\n\n if (row === undefined) return undefined;\n\n return decodeRow(database, table, codecs[table], getStoredRow(row));\n };\n\n const core: SqliteCore<S, K> = {\n async clear(table) {\n run(database, `DELETE FROM ${RECORDS_TABLE} WHERE namespace = ? AND table_name = ?`, [name, table]);\n },\n async delete(table, key) {\n const result = run(\n database,\n `DELETE FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ? AND key_tag = ?\n AND (expires_at IS NULL OR expires_at > ?)`,\n [name, table, encodeVaultKey(key), Date.now()],\n ) as { changes?: number } | undefined;\n\n return (result?.changes ?? 0) > 0;\n },\n async deleteMany(table, keys) {\n let deleted = 0;\n const maxKeysPerChunk = 996;\n const encodedKeys = keys.map((key) => encodeVaultKey(key));\n\n for (let index = 0; index < encodedKeys.length; index += maxKeysPerChunk) {\n const chunk = encodedKeys.slice(index, index + maxKeysPerChunk);\n const placeholders = chunk.map(() => '?').join(', ');\n const result = run(\n database,\n `DELETE FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ? AND key_tag IN (${placeholders})\n AND (expires_at IS NULL OR expires_at > ?)`,\n [name, table, ...chunk, Date.now()],\n ) as { changes?: number } | undefined;\n deleted += result?.changes ?? 0;\n }\n\n return deleted;\n },\n async get(table, key) {\n return getRecord(table, key);\n },\n async getAll(table) {\n deleteExpired(database, name, table);\n\n const records = all(\n database,\n `SELECT rowid AS row_id, expires_at, value_json\n FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ?\n ORDER BY rowid`,\n [name, table],\n );\n\n return records.flatMap((row) => {\n const value = decodeRow(database, table, codecs[table], getStoredRow(row));\n\n return value === undefined ? [] : [value];\n });\n },\n async getMany(table, keys) {\n return keys.map((key) => getRecord(table, key));\n },\n async pruneAllExpired() {\n const results: Record<string, number> = {};\n\n for (const table of Object.keys(schema)) {\n results[table] = await core.pruneExpiredInTable(table as K);\n }\n\n return results;\n },\n async pruneExpiredInTable(table) {\n return deleteExpired(database, name, table);\n },\n async put(table, value, ttl) {\n const key = getRecordKey(schema, table, value);\n const expiresAt = ttl === undefined ? null : Date.now() + ttl;\n const encoded = encodeRecord(codecs[table], value as RecordOf<S, typeof table>);\n\n run(database, UPSERT_SQL, [name, table, encodeVaultKey(key), encodeJson(encoded), expiresAt]);\n },\n async putAll(table, values, ttl) {\n if (values.length === 0) return;\n\n const expiresAt = ttl === undefined ? null : Date.now() + ttl;\n const encodedJsonValues = values.map((v) =>\n encodeJson(encodeRecord(codecs[table], v as RecordOf<S, typeof table>)),\n );\n const encodedKeys = values.map((v) => encodeVaultKey(getRecordKey(schema, table, v)));\n\n const writeAll = () => {\n for (let i = 0; i < values.length; i++) {\n run(database, UPSERT_SQL, [name, table, encodedKeys[i], encodedJsonValues[i], expiresAt]);\n }\n };\n\n if (inTransaction) {\n writeAll();\n return;\n }\n\n database.exec('BEGIN');\n try {\n writeAll();\n database.exec('COMMIT');\n } catch (error) {\n try {\n database.exec('ROLLBACK');\n } catch (rollbackError) {\n throw new VaultError('SQLite putAll rollback failed', { cause: rollbackError });\n }\n throw error;\n }\n },\n };\n\n return core;\n}\n\n/**\n * Creates a SQLite-backed Vault store. The connection is caller-owned unless\n * `closeOnDispose` is explicitly enabled.\n */\nexport function createSQLite<S extends AnySchema>(options: SQLiteVaultOptions<S>): DocumentVaultStore<S> {\n const { closeOnDispose = false, database, name, schema, codecs } = options;\n\n assertName(name);\n\n if (!codecs) {\n throw new VaultError('createSQLite: codecs are required for durable persistence');\n }\n\n const state = getConnectionState(database);\n const namespaceReady = state.executor.run(async () => {\n await state.initialized;\n initializeNamespace(database, name);\n });\n let ownListener: ConnectionListener | undefined;\n\n const directCore = createDirectCore(database, name, schema, codecs);\n const withConnection = <T>(work: () => Promise<T>): Promise<T> =>\n state.executor.run(async () => {\n await state.initialized;\n await namespaceReady;\n\n return work();\n });\n\n // A synchronous SQLite connection cannot serve store calls while a batch\n // holds its transaction, so every guarded call checks the shared flag first.\n const guard = <A extends readonly unknown[], R>(work: (...args: A) => Promise<R>): ((...args: A) => Promise<R>) => {\n return (...args: A) => {\n if (state.batchActive) {\n throw new VaultError(\n 'cannot call a SQLite store sharing this connection from batch(); use the transaction context instead',\n );\n }\n\n return withConnection(() => work(...args));\n };\n };\n\n const guardedCore: StorageBackend<S> = {\n clear: guard((table) => directCore.clear(table)),\n delete: guard((table, key) => directCore.delete(table, key)),\n deleteMany: guard((table, keys) => directCore.deleteMany(table, keys)),\n get: guard((table, key) => directCore.get(table, key)),\n getAll: guard((table) => directCore.getAll(table)),\n getMany: guard((table, keys) => directCore.getMany(table, keys)),\n pruneAllExpired: guard(() => directCore.pruneAllExpired()),\n pruneExpiredInTable: guard((table) => directCore.pruneExpiredInTable(table)),\n put: guard((table, value, ttl) => directCore.put(table, value, ttl)),\n putAll: guard((table, values, ttl) => directCore.putAll(table, values, ttl)),\n };\n\n const adapter = buildDocumentStore(schema, guardedCore, {\n codecs,\n createBatch: (deps) => async (tables, fn) => {\n assertBatchTables(tables);\n\n if (state.batchActive) {\n throw new VaultError(\n 'cannot call a SQLite store sharing this connection from batch(); use the transaction context instead',\n );\n }\n\n return state.executor.run(async () => {\n await state.initialized;\n await namespaceReady;\n\n const dirtyTables = new Set<keyof S & string>();\n const txCore = createDirectCore<S, keyof S & string>(database, name, schema, codecs, true);\n let contextActive = true;\n const tx = buildOperations(\n schema,\n txCore,\n (table) => dirtyTables.add(table),\n deps.validate,\n batchScopeGuard(tables, () => contextActive),\n );\n let transactionStarted = false;\n\n state.batchActive = true;\n\n try {\n database.exec('BEGIN IMMEDIATE');\n transactionStarted = true;\n\n const result = await fn(tx);\n\n database.exec('COMMIT');\n\n for (const table of dirtyTables) {\n deps.notifyMutation(table);\n }\n\n return result;\n } catch (error) {\n if (transactionStarted) {\n try {\n database.exec('ROLLBACK');\n } catch (rollbackError) {\n throw new VaultError('SQLite batch rollback failed', { cause: rollbackError });\n }\n }\n\n throw error;\n } finally {\n contextActive = false;\n state.batchActive = false;\n }\n });\n },\n onCrossTabMessage(notify) {\n const listener: ConnectionListener = (eventName, table) => {\n if (eventName === name && Object.hasOwn(schema, table)) notify(table as keyof S & string);\n };\n\n ownListener = listener;\n state.listeners.add(listener);\n\n return () => {\n state.listeners.delete(listener);\n\n if (ownListener === listener) ownListener = undefined;\n };\n },\n onMutation(table) {\n for (const listener of state.listeners) {\n if (listener !== ownListener) listener(name, table);\n }\n },\n schema,\n });\n\n const store = Object.assign(adapter, {\n iterate<K extends keyof S & string>(table: K): AsyncIterable<RecordOf<S, K>> {\n if (adapter.disposed) throw new VaultDisposedError(`\"${name}\" is disposed`);\n\n return {\n [Symbol.asyncIterator](): AsyncIterator<RecordOf<S, K>> {\n let completed = false;\n let lastRowId = 0;\n let rows: RecordOf<S, K>[] = [];\n let index = 0;\n\n const loadNextPage = async (): Promise<boolean> => {\n const page = await state.executor.run(async () => {\n await state.initialized;\n await namespaceReady;\n const storedRows = all(\n database,\n `SELECT rowid AS row_id, expires_at, value_json\n FROM ${RECORDS_TABLE}\n WHERE namespace = ? AND table_name = ? AND rowid > ?\n ORDER BY rowid\n LIMIT ?`,\n [name, table, lastRowId, ITERATION_PAGE_SIZE],\n );\n const values: RecordOf<S, K>[] = [];\n\n for (const row of storedRows) {\n const stored = getStoredRow(row);\n lastRowId = stored.rowId;\n\n const value = decodeRow(database, table, codecs[table], stored);\n\n if (value !== undefined) values.push(value);\n }\n\n return { done: storedRows.length === 0, values };\n });\n\n rows = page.values;\n index = 0;\n return page.done;\n };\n\n return {\n async next(): Promise<IteratorResult<RecordOf<S, K>>> {\n if (completed) return { done: true, value: undefined };\n if (adapter.disposed) throw new VaultDisposedError(`\"${name}\" is disposed`);\n\n if (state.batchActive) {\n throw new VaultError(\n 'cannot call a SQLite store sharing this connection from batch(); use the transaction context instead',\n );\n }\n\n try {\n while (index >= rows.length) {\n if (await loadNextPage()) {\n completed = true;\n return { done: true, value: undefined };\n }\n }\n\n return { done: false, value: rows[index++] };\n } catch (error) {\n completed = true;\n throw error;\n }\n },\n async return(value?: unknown): Promise<IteratorResult<RecordOf<S, K>>> {\n completed = true;\n return { done: true, value: value as RecordOf<S, K> };\n },\n async throw(error?: unknown): Promise<IteratorResult<RecordOf<S, K>>> {\n completed = true;\n throw error;\n },\n };\n },\n };\n },\n });\n\n if (closeOnDispose) {\n const dispose = store.dispose.bind(store);\n let closePromise: Promise<void> | undefined;\n\n store.dispose = async (): Promise<void> => {\n await dispose();\n closePromise ??= state.executor.run(() => database.close?.());\n await closePromise;\n };\n store[Symbol.asyncDispose] = async (): Promise<void> => {\n await store.dispose();\n };\n }\n\n return store;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/adapters/sqlite.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/adapters/sqlite.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,SAAS,EAET,kBAAkB,EAClB,mBAAmB,EAGnB,kBAAkB,EACnB,MAAM,UAAU,CAAC;AAElB,YAAY,EAAE,kBAAkB,EAAE,CAAC;AAEnC,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;AACrD,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,GAAG,UAAU,EAAE,eAAe,EAAE,GAAG,SAAS,SAAS,EAAE,CAAC;IAC5D,QAAQ,CAAC,IAAI,IAAI,CAAC;IAClB,GAAG,CAAC,GAAG,UAAU,EAAE,eAAe,EAAE,GAAG,SAAS,GAAG,IAAI,GAAG,SAAS,CAAC;IACpE,GAAG,CAAC,GAAG,UAAU,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;CAChD;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,IAAI,IAAI,CAAC;IACf,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAAC;CACvC;AAED,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,SAAS,IAAI,mBAAmB,CAAC,CAAC,CAAC,GAAG;IAC7E,6EAA6E;IAC7E,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,EAAE,cAAc,CAAC;IACzB,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAsYF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,SAAS,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAqOvG"}
|