@drej/sqlite 0.1.2
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/CHANGELOG.md +52 -0
- package/package.json +13 -0
- package/src/adapter.ts +97 -0
- package/src/index.ts +1 -0
- package/src/migrations.ts +16 -0
- package/tsconfig.json +13 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# @drej/sqlite
|
|
2
|
+
|
|
3
|
+
## 0.1.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [4c0ad93]
|
|
8
|
+
- Updated dependencies [b04f8eb]
|
|
9
|
+
- Updated dependencies [a971b7b]
|
|
10
|
+
- Updated dependencies [ce173be]
|
|
11
|
+
- Updated dependencies [86c2dde]
|
|
12
|
+
- Updated dependencies [82094ae]
|
|
13
|
+
- @drej/core@0.2.0
|
|
14
|
+
|
|
15
|
+
## 0.1.1
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- 0ea4c33: Rename npm scope from `@drej/*` to `@drej/*` and add TSDoc to all public API surfaces.
|
|
20
|
+
|
|
21
|
+
- All workspace packages now published under `@drej/*` (e.g. `@drej/sqlite`, `@drej/postgres`)
|
|
22
|
+
- `DrejClient`, `WorkflowBuilder`, `SandboxStepBuilder`, `IStorageAdapter`, `LedgerEvent`, `SandboxOpts` and all their members now have hover documentation visible in VS Code
|
|
23
|
+
|
|
24
|
+
- Updated dependencies [0ea4c33]
|
|
25
|
+
- @drej/core@0.1.1
|
|
26
|
+
|
|
27
|
+
## 0.1.0
|
|
28
|
+
|
|
29
|
+
### Minor Changes
|
|
30
|
+
|
|
31
|
+
- 5d77498: Introduce `@drej/sqlite` storage adapter.
|
|
32
|
+
|
|
33
|
+
`SQLiteAdapter` implements `IStorageAdapter` via Bun's built-in `bun:sqlite` — zero extra dependencies and no infrastructure required. Data persists across restarts, making it suitable for local development and single-process production workloads.
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { DrejClient } from "drej";
|
|
37
|
+
import { SQLiteAdapter } from "@drej/sqlite";
|
|
38
|
+
|
|
39
|
+
const client = new DrejClient({
|
|
40
|
+
baseUrl: "http://localhost:8080",
|
|
41
|
+
adapter: new SQLiteAdapter("./drej.db"),
|
|
42
|
+
});
|
|
43
|
+
await client.connect();
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
WAL mode is enabled on `connect()` for safe concurrent reads alongside ongoing writes.
|
|
47
|
+
|
|
48
|
+
### Patch Changes
|
|
49
|
+
|
|
50
|
+
- Updated dependencies [82e77fd]
|
|
51
|
+
- Updated dependencies [5d77498]
|
|
52
|
+
- @drej/core@0.1.0
|
package/package.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@drej/sqlite",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"publishConfig": { "access": "public" },
|
|
5
|
+
"main": "./src/index.ts",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"@drej/core": "workspace:*"
|
|
8
|
+
},
|
|
9
|
+
"devDependencies": {
|
|
10
|
+
"bun-types": "latest",
|
|
11
|
+
"typescript": "latest"
|
|
12
|
+
}
|
|
13
|
+
}
|
package/src/adapter.ts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Database } from "bun:sqlite";
|
|
2
|
+
import type { IStorageAdapter, LedgerEntry, LedgerEvent } from "@drej/core";
|
|
3
|
+
import { MIGRATION_SQL } from "./migrations";
|
|
4
|
+
|
|
5
|
+
type Row = {
|
|
6
|
+
run_id: string;
|
|
7
|
+
wf_name: string;
|
|
8
|
+
step_idx: number;
|
|
9
|
+
branch: number | null;
|
|
10
|
+
event: string;
|
|
11
|
+
payload: string | null;
|
|
12
|
+
error: string | null;
|
|
13
|
+
ts: number;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
function rowToEntry(row: Row): LedgerEntry {
|
|
17
|
+
return {
|
|
18
|
+
runId: row.run_id,
|
|
19
|
+
workflowName: row.wf_name,
|
|
20
|
+
stepIndex: row.step_idx,
|
|
21
|
+
branch: row.branch ?? undefined,
|
|
22
|
+
event: row.event as LedgerEvent,
|
|
23
|
+
payload: row.payload !== null ? (JSON.parse(row.payload) as unknown) : undefined,
|
|
24
|
+
error: row.error ?? undefined,
|
|
25
|
+
ts: row.ts,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export class SQLiteAdapter implements IStorageAdapter {
|
|
30
|
+
private readonly db: Database;
|
|
31
|
+
|
|
32
|
+
constructor(path: string) {
|
|
33
|
+
this.db = new Database(path, { create: true });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async connect(): Promise<void> {
|
|
37
|
+
this.db.exec(MIGRATION_SQL);
|
|
38
|
+
// WAL mode prevents writer from blocking readers on concurrent access
|
|
39
|
+
this.db.exec("PRAGMA journal_mode = WAL;");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async close(): Promise<void> {
|
|
43
|
+
this.db.close();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async append(entry: LedgerEntry): Promise<void> {
|
|
47
|
+
this.db
|
|
48
|
+
.prepare(
|
|
49
|
+
`INSERT INTO drej_events (run_id, wf_name, step_idx, branch, event, payload, error, ts)
|
|
50
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
51
|
+
)
|
|
52
|
+
.run(
|
|
53
|
+
entry.runId,
|
|
54
|
+
entry.workflowName,
|
|
55
|
+
entry.stepIndex,
|
|
56
|
+
entry.branch ?? null,
|
|
57
|
+
entry.event,
|
|
58
|
+
entry.payload !== undefined ? JSON.stringify(entry.payload) : null,
|
|
59
|
+
entry.error ?? null,
|
|
60
|
+
entry.ts,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async readAll(workflowName: string, runId: string): Promise<LedgerEntry[]> {
|
|
65
|
+
const rows = this.db
|
|
66
|
+
.prepare<Row, [string, string]>(
|
|
67
|
+
`SELECT run_id, wf_name, step_idx, branch, event, payload, error, ts
|
|
68
|
+
FROM drej_events
|
|
69
|
+
WHERE wf_name = ? AND run_id = ?
|
|
70
|
+
ORDER BY ts ASC`,
|
|
71
|
+
)
|
|
72
|
+
.all(workflowName, runId);
|
|
73
|
+
return rows.map(rowToEntry);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async lastCheckpoint(workflowName: string, runId: string): Promise<LedgerEntry | null> {
|
|
77
|
+
const row = this.db
|
|
78
|
+
.prepare<Row, [string, string]>(
|
|
79
|
+
`SELECT run_id, wf_name, step_idx, branch, event, payload, error, ts
|
|
80
|
+
FROM drej_events
|
|
81
|
+
WHERE wf_name = ? AND run_id = ? AND event = 'checkpoint'
|
|
82
|
+
ORDER BY ts DESC
|
|
83
|
+
LIMIT 1`,
|
|
84
|
+
)
|
|
85
|
+
.get(workflowName, runId);
|
|
86
|
+
return row ? rowToEntry(row) : null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async listRuns(workflowName: string): Promise<string[]> {
|
|
90
|
+
const rows = this.db
|
|
91
|
+
.prepare<{ run_id: string }, [string]>(
|
|
92
|
+
`SELECT DISTINCT run_id FROM drej_events WHERE wf_name = ?`,
|
|
93
|
+
)
|
|
94
|
+
.all(workflowName);
|
|
95
|
+
return rows.map((r) => r.run_id);
|
|
96
|
+
}
|
|
97
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SQLiteAdapter } from "./adapter";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const MIGRATION_SQL = `
|
|
2
|
+
CREATE TABLE IF NOT EXISTS drej_events (
|
|
3
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
4
|
+
run_id TEXT NOT NULL,
|
|
5
|
+
wf_name TEXT NOT NULL,
|
|
6
|
+
step_idx INTEGER NOT NULL,
|
|
7
|
+
branch INTEGER,
|
|
8
|
+
event TEXT NOT NULL,
|
|
9
|
+
payload TEXT,
|
|
10
|
+
error TEXT,
|
|
11
|
+
ts INTEGER NOT NULL
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
CREATE INDEX IF NOT EXISTS drej_events_run_id ON drej_events(run_id);
|
|
15
|
+
CREATE INDEX IF NOT EXISTS drej_events_wf_name ON drej_events(wf_name);
|
|
16
|
+
`;
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ESNext",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"strict": true,
|
|
7
|
+
"noEmit": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"allowImportingTsExtensions": true,
|
|
10
|
+
"types": ["bun-types"]
|
|
11
|
+
},
|
|
12
|
+
"include": ["src"]
|
|
13
|
+
}
|