@tessar/sqlite 0.0.0-stage → 0.1.0-alpha.0
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 +24 -2
- package/dist/backend.d.ts +4 -0
- package/dist/backend.js +99 -0
- package/dist/backend.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/ownership.d.ts +6 -0
- package/dist/ownership.js +35 -0
- package/dist/ownership.js.map +1 -0
- package/dist/schema.d.ts +3 -0
- package/dist/schema.js +34 -0
- package/dist/schema.js.map +1 -0
- package/package.json +31 -3
package/README.md
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @tessar/sqlite
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
SQLite persistence for Tessar's state and checkpoint contracts, using Node's
|
|
4
|
+
built-in SQLite API. Requires Node 24.14 or newer.
|
|
5
|
+
|
|
6
|
+
```sh
|
|
7
|
+
npm install @tessar/core@next @tessar/sqlite@next
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import { SqliteStoragePlugin } from "@tessar/sqlite";
|
|
12
|
+
|
|
13
|
+
const storage = new SqliteStoragePlugin({ filename: "./state.db" });
|
|
14
|
+
// Include storage in new Controller({ id, agent, plugins: [storage, ...] }).
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Core owns state/checkpoint behavior; this plugin supplies physical persistence.
|
|
18
|
+
Choose the backend before Controller initialization. Scope filters bind queries
|
|
19
|
+
to application-selected metadata; applications own authentication and authorization.
|
|
20
|
+
|
|
21
|
+
Node's SQLite API is experimental. This backend uses synchronous database
|
|
22
|
+
operations and is a reference implementation, not a server throughput claim.
|
|
23
|
+
|
|
24
|
+
This is an alpha release. See the
|
|
25
|
+
[repository](https://github.com/hphucdev-04/tessar) for usage and contracts.
|
package/dist/backend.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { DatabaseSync } from "node:sqlite";
|
|
2
|
+
import { canonicalJson, validateBatch, fail, immutable, matchesScope } from "@tessar/core";
|
|
3
|
+
import { initializeSchema, recordTables } from "./schema.js";
|
|
4
|
+
import { assertOwnership, createOwnership, transaction } from "./ownership.js";
|
|
5
|
+
export async function createSqliteBackend(options) {
|
|
6
|
+
const db = new DatabaseSync(options.filename);
|
|
7
|
+
try {
|
|
8
|
+
await initializeSchema(db);
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
db.close();
|
|
12
|
+
throw error;
|
|
13
|
+
}
|
|
14
|
+
let closed = false;
|
|
15
|
+
const getJson = (sql, ...values) => { const row = db.prepare(sql).get(...values); return row ? immutable(JSON.parse(row.body)) : null; };
|
|
16
|
+
const head = (id) => getJson("SELECT body FROM threads WHERE id=?", id);
|
|
17
|
+
const records = (kind, threadId, cp) => { const checkpointId = cp ?? head(threadId)?.currentCheckpointId; if (!checkpointId)
|
|
18
|
+
return []; return db.prepare("SELECT body FROM " + kind + " WHERE thread_id=? AND checkpoint_id=?").all(threadId, checkpointId).map(row => immutable(JSON.parse(row.body))); };
|
|
19
|
+
const ownerKey = (key) => canonicalJson([key.ownerType, key.ownerId, key.pluginId, key.namespace]);
|
|
20
|
+
return {
|
|
21
|
+
id: "sqlite", capabilities: { durable: true, atomicPublish: true, coordination: "multi-process" },
|
|
22
|
+
threads: {
|
|
23
|
+
get: async (id) => { const value = head(id); return value && !value.deleted ? value : null; },
|
|
24
|
+
list: async (query) => db.prepare("SELECT body FROM threads").all().map(r => immutable(JSON.parse(r.body))).filter(r => !r.deleted && matchesScope(r.scope, query?.scope))
|
|
25
|
+
},
|
|
26
|
+
checkpoints: {
|
|
27
|
+
get: async (id) => getJson("SELECT body FROM checkpoints WHERE id=?", id),
|
|
28
|
+
list: async (threadId) => db.prepare("SELECT body FROM checkpoints WHERE thread_id=? ORDER BY revision").all(threadId).map(r => immutable(JSON.parse(r.body)))
|
|
29
|
+
},
|
|
30
|
+
executions: {
|
|
31
|
+
get: async (kind, id, query) => {
|
|
32
|
+
if (!recordTables.includes(kind))
|
|
33
|
+
fail("InvalidConfiguration", "Unknown record kind");
|
|
34
|
+
if (query?.threadId)
|
|
35
|
+
return (records(kind, query.threadId, query.atCheckpointId).find((r) => r.id === id) ?? null);
|
|
36
|
+
if (query?.atCheckpointId)
|
|
37
|
+
return getJson("SELECT body FROM " + kind + " WHERE checkpoint_id=? AND id=?", query.atCheckpointId, id);
|
|
38
|
+
const rows = db.prepare("SELECT r.body FROM " + kind + " r JOIN threads t ON r.thread_id=t.id WHERE r.id=? AND r.checkpoint_id=json_extract(t.body,'$.currentCheckpointId')").get(id);
|
|
39
|
+
return rows ? immutable(JSON.parse(rows.body)) : null;
|
|
40
|
+
},
|
|
41
|
+
listRecords: async (kind, threadId, query) => records(kind, threadId, query?.atCheckpointId)
|
|
42
|
+
},
|
|
43
|
+
ownedState: {
|
|
44
|
+
get: async (key) => getJson("SELECT body FROM owned_states WHERE owner_key=?", ownerKey(key)),
|
|
45
|
+
compareAndSet: async (state, expected) => transaction(db, () => {
|
|
46
|
+
if (!["agent", "session"].includes(state.ownerType))
|
|
47
|
+
fail("InvalidConfiguration", "Execution state must use checkpoints");
|
|
48
|
+
const key = ownerKey(state), old = getJson("SELECT body FROM owned_states WHERE owner_key=?", key);
|
|
49
|
+
if ((old?.revision ?? 0) !== expected || state.revision !== expected + 1)
|
|
50
|
+
fail("CommitConflict", "Owned state revision changed");
|
|
51
|
+
db.prepare("INSERT INTO owned_states VALUES(?,?,?) ON CONFLICT(owner_key) DO UPDATE SET revision=excluded.revision,body=excluded.body").run(key, state.revision, canonicalJson(state));
|
|
52
|
+
})
|
|
53
|
+
},
|
|
54
|
+
ownership: createOwnership(db),
|
|
55
|
+
commits: {
|
|
56
|
+
stage: async (batch) => { validateBatch(batch); transaction(db, () => { const old = getJson("SELECT body FROM staging WHERE id=?", batch.commitId); if (old && canonicalJson(old) !== canonicalJson(batch))
|
|
57
|
+
fail("CommitConflict", "commitId payload mismatch"); if (!old)
|
|
58
|
+
db.prepare("INSERT INTO staging VALUES(?,?)").run(batch.commitId, canonicalJson(batch)); }); },
|
|
59
|
+
lookupCommit: async (id) => getJson("SELECT body FROM commits WHERE id=?", id),
|
|
60
|
+
publish: async (request) => transaction(db, () => {
|
|
61
|
+
const prior = getJson("SELECT body FROM commits WHERE id=?", request.commitId);
|
|
62
|
+
if (prior)
|
|
63
|
+
return prior;
|
|
64
|
+
assertOwnership(db, request.lease);
|
|
65
|
+
const batch = getJson("SELECT body FROM staging WHERE id=?", request.commitId);
|
|
66
|
+
if (!batch || batch.threadId !== request.threadId || batch.expectedRevision !== request.expectedRevision)
|
|
67
|
+
fail("CommitConflict", "Missing staged batch");
|
|
68
|
+
const old = head(batch.threadId), cp = batch.checkpoint;
|
|
69
|
+
if ((old?.revision ?? 0) !== batch.expectedRevision || old?.deleted || cp.parentCheckpointId !== (old?.currentCheckpointId ?? null))
|
|
70
|
+
fail("CommitConflict", "Head changed");
|
|
71
|
+
const merged = new Map();
|
|
72
|
+
for (const kind of recordTables)
|
|
73
|
+
for (const data of records(kind, batch.threadId))
|
|
74
|
+
merged.set(kind + ":" + data.id, { kind, id: data.id, threadId: batch.threadId, data });
|
|
75
|
+
for (const entry of batch.records)
|
|
76
|
+
merged.set(entry.kind + ":" + entry.id, entry);
|
|
77
|
+
if (cp.execution && !merged.has("streams:" + cp.execution.streamId))
|
|
78
|
+
fail("CommitConflict", "Missing stream reference");
|
|
79
|
+
if (cp.execution?.pendingInterruptId && !merged.has("interrupts:" + cp.execution.pendingInterruptId))
|
|
80
|
+
fail("CommitConflict", "Missing interrupt reference");
|
|
81
|
+
db.prepare("INSERT INTO checkpoints VALUES(?,?,?,?)").run(cp.id, cp.threadId, cp.revision, canonicalJson(cp));
|
|
82
|
+
for (const entry of merged.values())
|
|
83
|
+
db.prepare("INSERT INTO " + entry.kind + " VALUES(?,?,?,?)").run(batch.threadId, cp.id, entry.id, canonicalJson(entry.data));
|
|
84
|
+
cp.state.messages.forEach((message, position) => db.prepare("INSERT INTO messages VALUES(?,?,?,?,?)").run(cp.threadId, cp.id, message.id, position, canonicalJson(message)));
|
|
85
|
+
const stream = cp.execution ? merged.get("streams:" + cp.execution.streamId)?.data : null;
|
|
86
|
+
const info = { id: batch.threadId, scope: cp.state.scope, metadata: cp.state.metadata, revision: cp.revision, currentCheckpointId: cp.id, activeStreamId: stream && !["completed", "failed", "stopped", "cancelled"].includes(stream.status) ? stream.id : null, createdAt: old?.createdAt ?? cp.createdAt, updatedAt: cp.createdAt, parentThreadId: batch.lineage?.parentThreadId ?? old?.parentThreadId ?? null, sourceCheckpointId: batch.lineage?.sourceCheckpointId ?? old?.sourceCheckpointId ?? null, deleted: batch.deleteThread ?? false };
|
|
87
|
+
db.prepare("INSERT INTO threads VALUES(?,?) ON CONFLICT(id) DO UPDATE SET body=excluded.body").run(info.id, canonicalJson(info));
|
|
88
|
+
const receipt = { commitId: batch.commitId, threadId: batch.threadId, revision: cp.revision, checkpointId: cp.id };
|
|
89
|
+
db.prepare("INSERT INTO commits VALUES(?,?)").run(batch.commitId, canonicalJson(receipt));
|
|
90
|
+
return receipt;
|
|
91
|
+
})
|
|
92
|
+
},
|
|
93
|
+
close: async () => { if (!closed) {
|
|
94
|
+
closed = true;
|
|
95
|
+
db.close();
|
|
96
|
+
} }
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=backend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend.js","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./backend.js";
|
|
2
|
+
import type { Plugin, PluginContext } from "@tessar/core";
|
|
3
|
+
export declare class SqliteStoragePlugin implements Plugin {
|
|
4
|
+
private readonly options;
|
|
5
|
+
readonly id = "storage.sqlite";
|
|
6
|
+
constructor(options: {
|
|
7
|
+
filename: string;
|
|
8
|
+
});
|
|
9
|
+
setup(tessar: PluginContext): Promise<void>;
|
|
10
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from "./backend.js";
|
|
2
|
+
import { createSqliteBackend } from "./backend.js";
|
|
3
|
+
export class SqliteStoragePlugin {
|
|
4
|
+
options;
|
|
5
|
+
id = "storage.sqlite";
|
|
6
|
+
constructor(options) {
|
|
7
|
+
this.options = options;
|
|
8
|
+
}
|
|
9
|
+
async setup(tessar) { tessar.storage.registerBackend(await createSqliteBackend(this.options)); }
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAE7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,MAAM,OAAO,mBAAmB;IAEF,OAAO;IAD3B,EAAE,GAAC,gBAAgB,CAAC;IAC7B,YAA6B,OAAyB;uBAAzB,OAAO;IAAoB,CAAC;IACzD,KAAK,CAAC,KAAK,CAAC,MAAoB,IAAgB,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,MAAM,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA,CAAC;CACzH"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { DatabaseSync } from "node:sqlite";
|
|
2
|
+
import { type Lease, type OwnershipPort } from "@tessar/core";
|
|
3
|
+
export declare function databaseNow(db: DatabaseSync): number;
|
|
4
|
+
export declare function transaction<T>(db: DatabaseSync, action: () => T): T;
|
|
5
|
+
export declare function assertOwnership(db: DatabaseSync, lease: Lease): void;
|
|
6
|
+
export declare function createOwnership(db: DatabaseSync): OwnershipPort;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { fail } from "@tessar/core";
|
|
2
|
+
export function databaseNow(db) { return db.prepare("SELECT CAST((julianday('now') - 2440587.5)*86400000 AS INTEGER) AS now").get().now; }
|
|
3
|
+
export function transaction(db, action) { db.exec("BEGIN IMMEDIATE"); try {
|
|
4
|
+
const result = action();
|
|
5
|
+
db.exec("COMMIT");
|
|
6
|
+
return result;
|
|
7
|
+
}
|
|
8
|
+
catch (error) {
|
|
9
|
+
db.exec("ROLLBACK");
|
|
10
|
+
throw error;
|
|
11
|
+
} }
|
|
12
|
+
export function assertOwnership(db, lease) {
|
|
13
|
+
const row = db.prepare("SELECT * FROM leases WHERE thread_id=?").get(lease.threadId);
|
|
14
|
+
if (!row || row.owner_token !== lease.ownerToken || row.fencing_token !== lease.fencingToken || row.expires_at <= databaseNow(db))
|
|
15
|
+
fail("OwnershipLost", "Lease no longer owns thread");
|
|
16
|
+
}
|
|
17
|
+
const toLease = (row) => ({ threadId: row.thread_id, ownerToken: row.owner_token, fencingToken: row.fencing_token, expiresAt: new Date(row.expires_at).toISOString() });
|
|
18
|
+
export function createOwnership(db) {
|
|
19
|
+
return {
|
|
20
|
+
acquire: async (request) => transaction(db, () => {
|
|
21
|
+
if (!Number.isFinite(request.ttlMs) || request.ttlMs <= 0)
|
|
22
|
+
fail("InvalidConfiguration", "Invalid lease duration");
|
|
23
|
+
const previous = db.prepare("SELECT * FROM leases WHERE thread_id=?").get(request.threadId), now = databaseNow(db);
|
|
24
|
+
if (previous && previous.expires_at > now)
|
|
25
|
+
fail("OwnerActive", "Thread has active owner");
|
|
26
|
+
const row = { thread_id: request.threadId, owner_token: request.ownerToken, fencing_token: (previous?.fencing_token ?? 0) + 1, expires_at: now + request.ttlMs };
|
|
27
|
+
db.prepare("INSERT INTO leases VALUES(?,?,?,?) ON CONFLICT(thread_id) DO UPDATE SET owner_token=excluded.owner_token,fencing_token=excluded.fencing_token,expires_at=excluded.expires_at").run(row.thread_id, row.owner_token, row.fencing_token, row.expires_at);
|
|
28
|
+
return toLease(row);
|
|
29
|
+
}),
|
|
30
|
+
renew: async (lease, ttlMs) => transaction(db, () => { assertOwnership(db, lease); if (!Number.isFinite(ttlMs) || ttlMs <= 0)
|
|
31
|
+
fail("InvalidConfiguration", "Invalid lease duration"); const expires = databaseNow(db) + ttlMs; db.prepare("UPDATE leases SET expires_at=? WHERE thread_id=?").run(expires, lease.threadId); return { ...lease, expiresAt: new Date(expires).toISOString() }; }),
|
|
32
|
+
release: async (lease) => { db.prepare("UPDATE leases SET expires_at=0 WHERE thread_id=? AND owner_token=? AND fencing_token=?").run(lease.threadId, lease.ownerToken, lease.fencingToken); }
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=ownership.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ownership.js","sourceRoot":"","sources":["../src/ownership.ts"],"names":[],"mappings":"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"}
|
package/dist/schema.d.ts
ADDED
package/dist/schema.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { setTimeout } from "node:timers/promises";
|
|
2
|
+
export const recordTables = ["streams", "turns", "model_attempts", "tool_executions", "interrupts", "plugin_states"];
|
|
3
|
+
export async function initializeSchema(db) {
|
|
4
|
+
db.exec("PRAGMA busy_timeout=5000; PRAGMA foreign_keys=ON;");
|
|
5
|
+
const deadline = Date.now() + 5000;
|
|
6
|
+
for (;;) {
|
|
7
|
+
try {
|
|
8
|
+
db.exec("PRAGMA journal_mode=WAL;");
|
|
9
|
+
break;
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
// SQLite can return BUSY immediately while concurrent connections enable WAL.
|
|
13
|
+
if (![5, 6].includes(error.errcode ?? 0) || Date.now() >= deadline)
|
|
14
|
+
throw error;
|
|
15
|
+
await setTimeout(10);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
const version = db.prepare("PRAGMA user_version").get().user_version;
|
|
19
|
+
if (version !== 0 && version !== 1)
|
|
20
|
+
throw Error("Unsupported SQLite schema version");
|
|
21
|
+
db.exec(`
|
|
22
|
+
CREATE TABLE IF NOT EXISTS threads(id TEXT PRIMARY KEY,body TEXT NOT NULL);
|
|
23
|
+
CREATE TABLE IF NOT EXISTS checkpoints(id TEXT PRIMARY KEY,thread_id TEXT NOT NULL,revision INTEGER NOT NULL,body TEXT NOT NULL,UNIQUE(thread_id,revision));
|
|
24
|
+
CREATE TABLE IF NOT EXISTS staging(id TEXT PRIMARY KEY,body TEXT NOT NULL);
|
|
25
|
+
CREATE TABLE IF NOT EXISTS commits(id TEXT PRIMARY KEY,body TEXT NOT NULL);
|
|
26
|
+
CREATE TABLE IF NOT EXISTS leases(thread_id TEXT PRIMARY KEY,owner_token TEXT NOT NULL,fencing_token INTEGER NOT NULL,expires_at INTEGER NOT NULL);
|
|
27
|
+
CREATE TABLE IF NOT EXISTS owned_states(owner_key TEXT PRIMARY KEY,revision INTEGER NOT NULL,body TEXT NOT NULL);
|
|
28
|
+
CREATE TABLE IF NOT EXISTS messages(thread_id TEXT NOT NULL,checkpoint_id TEXT NOT NULL,id TEXT NOT NULL,position INTEGER NOT NULL,body TEXT NOT NULL,PRIMARY KEY(checkpoint_id,id));
|
|
29
|
+
`);
|
|
30
|
+
for (const table of recordTables)
|
|
31
|
+
db.exec("CREATE TABLE IF NOT EXISTS " + table + "(thread_id TEXT NOT NULL,checkpoint_id TEXT NOT NULL,id TEXT NOT NULL,body TEXT NOT NULL,PRIMARY KEY(checkpoint_id,id));CREATE INDEX IF NOT EXISTS " + table + "_thread ON " + table + "(thread_id);");
|
|
32
|
+
db.exec("PRAGMA user_version=1");
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,UAAU,EAAC,MAAM,sBAAsB,CAAC;AAChD,MAAM,CAAC,MAAM,YAAY,GAAC,CAAC,SAAS,EAAC,OAAO,EAAC,gBAAgB,EAAC,iBAAiB,EAAC,YAAY,EAAC,eAAe,CAAU,CAAC;AACvH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EAAe;IACpD,EAAE,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;IAC7D,MAAM,QAAQ,GAAC,IAAI,CAAC,GAAG,EAAE,GAAC,IAAI,CAAC;IAC/B,SAAO,CAAC;QACN,IAAG,CAAC;YAAA,EAAE,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;YAAA,MAAM;QAAA,CAAC;QAC/C,OAAM,KAAK,EAAC,CAAC;YACX,8EAA8E;YAC9E,IAAG,CAAC,CAAC,CAAC,EAAC,CAAC,CAAC,CAAC,QAAQ,CAAE,KAA2B,CAAC,OAAO,IAAE,CAAC,CAAC,IAAE,IAAI,CAAC,GAAG,EAAE,IAAE,QAAQ;gBAAC,MAAM,KAAK,CAAC;YAC9F,MAAM,UAAU,CAAC,EAAE,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,MAAM,OAAO,GAAE,EAAE,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,GAAG,EAA4B,CAAC,YAAY,CAAC;IAC9F,IAAG,OAAO,KAAG,CAAC,IAAE,OAAO,KAAG,CAAC;QAAC,MAAM,KAAK,CAAC,mCAAmC,CAAC,CAAC;IAC7E,EAAE,CAAC,IAAI,CAAC;;;;;;;;GAQP,CAAC,CAAC;IACH,KAAI,MAAM,KAAK,IAAI,YAAY;QAAC,EAAE,CAAC,IAAI,CAAC,6BAA6B,GAAC,KAAK,GAAC,qJAAqJ,GAAC,KAAK,GAAC,aAAa,GAAC,KAAK,GAAC,cAAc,CAAC,CAAC;IAC5Q,EAAE,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;AACnC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tessar/sqlite",
|
|
3
|
-
"version": "0.0.0
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0-alpha.0",
|
|
4
|
+
"description": "SQLite persistence for Tessar state and checkpoints using Node's built-in SQLite API.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=24.14.0"
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/hphucdev-04/tessar.git",
|
|
15
|
+
"directory": "packages/sqlite"
|
|
16
|
+
},
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public",
|
|
19
|
+
"registry": "https://registry.npmjs.org/"
|
|
20
|
+
},
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/index.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@tessar/core": "0.1.0-alpha.0"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsc -p tsconfig.json",
|
|
32
|
+
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
33
|
+
}
|
|
6
34
|
}
|