@haverstack/adapter-sqlite 0.1.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/LICENSE +7 -0
- package/README.md +77 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +601 -0
- package/dist/index.js.map +1 -0
- package/package.json +46 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
|
|
2
|
+
|
|
3
|
+
To the extent possible under law, the Haverstack contributors have waived all
|
|
4
|
+
copyright and related or neighboring rights to Haverstack. This work is
|
|
5
|
+
published from the United States.
|
|
6
|
+
|
|
7
|
+
https://creativecommons.org/publicdomain/zero/1.0/
|
package/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# @haverstack/adapter-sqlite
|
|
2
|
+
|
|
3
|
+
SQLite storage adapter for [Haverstack](https://www.npmjs.com/package/@haverstack/core).
|
|
4
|
+
|
|
5
|
+
Implements the `StackAdapter` interface using [sql.js](https://github.com/sql-js/sql.js). Runs in Node.js without native compilation. The database is held in memory and flushed to disk after every write.
|
|
6
|
+
|
|
7
|
+
> **Status:** Early development. APIs are unstable.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install @haverstack/adapter-sqlite @haverstack/core
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { Stack } from '@haverstack/core';
|
|
19
|
+
import { SQLiteAdapter } from '@haverstack/adapter-sqlite';
|
|
20
|
+
|
|
21
|
+
// First run — create a new database
|
|
22
|
+
const adapter = await SQLiteAdapter.initialize({
|
|
23
|
+
path: './my-stack.db',
|
|
24
|
+
entityId: 'my-entity-id',
|
|
25
|
+
timezone: 'America/New_York',
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Subsequent runs — open the existing database
|
|
29
|
+
// const adapter = await SQLiteAdapter.open({ path: './my-stack.db' });
|
|
30
|
+
|
|
31
|
+
const stack = await Stack.create(adapter);
|
|
32
|
+
|
|
33
|
+
// ... use the stack (see @haverstack/core for the full API)
|
|
34
|
+
|
|
35
|
+
await stack.flush();
|
|
36
|
+
await stack.close();
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## API
|
|
40
|
+
|
|
41
|
+
### `SQLiteAdapter.initialize(opts)`
|
|
42
|
+
|
|
43
|
+
Creates a new database at `opts.path`. Throws if the file already exists.
|
|
44
|
+
|
|
45
|
+
| Option | Type | Description |
|
|
46
|
+
| ---------- | -------- | -------------------------------------- |
|
|
47
|
+
| `path` | `string` | Absolute path to the `.db` file |
|
|
48
|
+
| `entityId` | `string` | Entity ID of the stack owner |
|
|
49
|
+
| `timezone` | `string` | IANA timezone string (e.g. `America/New_York`) |
|
|
50
|
+
|
|
51
|
+
### `SQLiteAdapter.open(opts)`
|
|
52
|
+
|
|
53
|
+
Opens an existing database at `opts.path`. Throws if the file does not exist.
|
|
54
|
+
|
|
55
|
+
| Option | Type | Description |
|
|
56
|
+
| ------ | -------- | --------------------------------------- |
|
|
57
|
+
| `path` | `string` | Absolute path to an existing `.db` file |
|
|
58
|
+
|
|
59
|
+
## Storage layout
|
|
60
|
+
|
|
61
|
+
Given a database at `./my-stack.db`, attachments are stored in `./attachments/`.
|
|
62
|
+
|
|
63
|
+
## Capabilities
|
|
64
|
+
|
|
65
|
+
| Feature | Supported |
|
|
66
|
+
| ------------------ | --------- |
|
|
67
|
+
| Full-text search | Yes (FTS4) |
|
|
68
|
+
| Content field query | Yes |
|
|
69
|
+
| Sortable fields | `createdAt`, `updatedAt`, `version` |
|
|
70
|
+
|
|
71
|
+
## License
|
|
72
|
+
|
|
73
|
+
[CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/) — public domain.
|
|
74
|
+
|
|
75
|
+
## Monorepo
|
|
76
|
+
|
|
77
|
+
Part of [haverstack/core](https://github.com/haverstack/core).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stack — SQLite Adapter
|
|
3
|
+
* -------------------------------------------------------
|
|
4
|
+
* Implements StackAdapter using sql.js (SQLite compiled to
|
|
5
|
+
* WebAssembly). Runs in Node, browsers, and other runtimes
|
|
6
|
+
* without native compilation.
|
|
7
|
+
*
|
|
8
|
+
* The database is held in memory and flushed to disk on every
|
|
9
|
+
* write. Attachments are stored as files in an `attachments/`
|
|
10
|
+
* subdirectory next to the database file.
|
|
11
|
+
*
|
|
12
|
+
* Stack config (timezone, entity_id, etc.) is stored in a
|
|
13
|
+
* `stack_config` key/value table.
|
|
14
|
+
*/
|
|
15
|
+
import type { StackAdapter, StackRecord, StackType, TypeId, RecordVersion, StackQuery, QueryResult, Association, AdapterCapabilities } from '@haverstack/core';
|
|
16
|
+
export type SQLiteInitializeOptions = {
|
|
17
|
+
/** Absolute path to the .db file. Must not already exist. */
|
|
18
|
+
path: string;
|
|
19
|
+
/** IANA timezone string e.g. "America/New_York". */
|
|
20
|
+
timezone: string;
|
|
21
|
+
/** Entity ID of the stack owner. */
|
|
22
|
+
entityId: string;
|
|
23
|
+
};
|
|
24
|
+
export type SQLiteOpenOptions = {
|
|
25
|
+
/** Absolute path to an existing .db file. */
|
|
26
|
+
path: string;
|
|
27
|
+
};
|
|
28
|
+
export declare class SQLiteAdapter implements StackAdapter {
|
|
29
|
+
private readonly SQL;
|
|
30
|
+
private readonly path;
|
|
31
|
+
readonly capabilities: AdapterCapabilities;
|
|
32
|
+
private db;
|
|
33
|
+
private readonly attachmentsDir;
|
|
34
|
+
private constructor();
|
|
35
|
+
/**
|
|
36
|
+
* Initialize a new stack database. Fails if the file already exists —
|
|
37
|
+
* use open() for existing databases.
|
|
38
|
+
*/
|
|
39
|
+
static initialize(opts: SQLiteInitializeOptions): Promise<SQLiteAdapter>;
|
|
40
|
+
/**
|
|
41
|
+
* Open an existing stack database. Fails if the file does not exist —
|
|
42
|
+
* use initialize() for new databases.
|
|
43
|
+
*/
|
|
44
|
+
static open(opts: SQLiteOpenOptions): Promise<SQLiteAdapter>;
|
|
45
|
+
getConfig(key: string): Promise<string | null>;
|
|
46
|
+
setConfig(key: string, value: string): Promise<void>;
|
|
47
|
+
/** Flush the in-memory database to disk. Called after every write. */
|
|
48
|
+
private persist;
|
|
49
|
+
createRecord(record: StackRecord): Promise<StackRecord>;
|
|
50
|
+
getRecord(id: string): Promise<StackRecord | null>;
|
|
51
|
+
updateRecord(id: string, changes: Partial<StackRecord>): Promise<StackRecord>;
|
|
52
|
+
deleteRecord(id: string, opts?: {
|
|
53
|
+
hard?: boolean;
|
|
54
|
+
}): Promise<void>;
|
|
55
|
+
queryRecords(query: StackQuery): Promise<QueryResult>;
|
|
56
|
+
getVersions(id: string): Promise<RecordVersion[]>;
|
|
57
|
+
getVersion(id: string, version: number): Promise<RecordVersion | null>;
|
|
58
|
+
saveVersion(id: string, version: RecordVersion): Promise<void>;
|
|
59
|
+
saveType(type: StackType): Promise<void>;
|
|
60
|
+
getType(id: TypeId): Promise<StackType | null>;
|
|
61
|
+
listTypes(): Promise<StackType[]>;
|
|
62
|
+
putAttachment(data: Uint8Array, mimeType: string): Promise<string>;
|
|
63
|
+
getAttachment(fileId: string): Promise<Uint8Array>;
|
|
64
|
+
deleteAttachment(fileId: string): Promise<void>;
|
|
65
|
+
associate(recordId: string, association: Association): Promise<void>;
|
|
66
|
+
dissociate(recordId: string, association: Association): Promise<void>;
|
|
67
|
+
private insertAssociations;
|
|
68
|
+
private getAssociationsForRecord;
|
|
69
|
+
private updateFts;
|
|
70
|
+
private execQuery;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,601 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stack — SQLite Adapter
|
|
3
|
+
* -------------------------------------------------------
|
|
4
|
+
* Implements StackAdapter using sql.js (SQLite compiled to
|
|
5
|
+
* WebAssembly). Runs in Node, browsers, and other runtimes
|
|
6
|
+
* without native compilation.
|
|
7
|
+
*
|
|
8
|
+
* The database is held in memory and flushed to disk on every
|
|
9
|
+
* write. Attachments are stored as files in an `attachments/`
|
|
10
|
+
* subdirectory next to the database file.
|
|
11
|
+
*
|
|
12
|
+
* Stack config (timezone, entity_id, etc.) is stored in a
|
|
13
|
+
* `stack_config` key/value table.
|
|
14
|
+
*/
|
|
15
|
+
import initSqlJs from 'sql.js';
|
|
16
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
|
|
17
|
+
import { readFile, writeFile } from 'fs/promises';
|
|
18
|
+
import { join, dirname } from 'path';
|
|
19
|
+
import { generateId } from '@haverstack/core';
|
|
20
|
+
// -------------------------------------------------------
|
|
21
|
+
// SQL — schema
|
|
22
|
+
// -------------------------------------------------------
|
|
23
|
+
const SCHEMA_SQL = `
|
|
24
|
+
CREATE TABLE IF NOT EXISTS stack_config (
|
|
25
|
+
key TEXT PRIMARY KEY,
|
|
26
|
+
value TEXT NOT NULL
|
|
27
|
+
) STRICT;
|
|
28
|
+
|
|
29
|
+
CREATE TABLE IF NOT EXISTS records (
|
|
30
|
+
id TEXT PRIMARY KEY,
|
|
31
|
+
type_id TEXT NOT NULL,
|
|
32
|
+
created_at INTEGER NOT NULL,
|
|
33
|
+
updated_at INTEGER NOT NULL,
|
|
34
|
+
content TEXT NOT NULL CHECK (json_valid(content)),
|
|
35
|
+
version INTEGER NOT NULL DEFAULT 1,
|
|
36
|
+
parent_id TEXT,
|
|
37
|
+
entity_id TEXT,
|
|
38
|
+
app_id TEXT,
|
|
39
|
+
deleted_at INTEGER,
|
|
40
|
+
permissions TEXT CHECK (permissions IS NULL OR json_valid(permissions))
|
|
41
|
+
) STRICT;
|
|
42
|
+
|
|
43
|
+
CREATE TABLE IF NOT EXISTS associations (
|
|
44
|
+
record_id TEXT NOT NULL REFERENCES records(id),
|
|
45
|
+
kind TEXT NOT NULL CHECK (kind IN ('tag', 'attachment', 'relationship')),
|
|
46
|
+
label TEXT NOT NULL,
|
|
47
|
+
file_id TEXT NOT NULL DEFAULT '',
|
|
48
|
+
mime_type TEXT,
|
|
49
|
+
related_id TEXT NOT NULL DEFAULT '',
|
|
50
|
+
PRIMARY KEY (record_id, kind, label, file_id, related_id)
|
|
51
|
+
) STRICT;
|
|
52
|
+
|
|
53
|
+
CREATE TABLE IF NOT EXISTS versions (
|
|
54
|
+
record_id TEXT NOT NULL REFERENCES records(id),
|
|
55
|
+
version INTEGER NOT NULL,
|
|
56
|
+
content TEXT NOT NULL CHECK (json_valid(content)),
|
|
57
|
+
updated_at INTEGER NOT NULL,
|
|
58
|
+
entity_id TEXT,
|
|
59
|
+
PRIMARY KEY (record_id, version)
|
|
60
|
+
) STRICT;
|
|
61
|
+
|
|
62
|
+
CREATE TABLE IF NOT EXISTS types (
|
|
63
|
+
id TEXT PRIMARY KEY,
|
|
64
|
+
base_id TEXT NOT NULL,
|
|
65
|
+
version INTEGER NOT NULL,
|
|
66
|
+
name TEXT NOT NULL,
|
|
67
|
+
schema TEXT NOT NULL CHECK (json_valid(schema)),
|
|
68
|
+
schema_hash TEXT NOT NULL,
|
|
69
|
+
migrates_from TEXT,
|
|
70
|
+
created_at INTEGER NOT NULL
|
|
71
|
+
) STRICT;
|
|
72
|
+
|
|
73
|
+
CREATE TABLE IF NOT EXISTS attachments (
|
|
74
|
+
file_id TEXT PRIMARY KEY,
|
|
75
|
+
mime_type TEXT NOT NULL,
|
|
76
|
+
created_at INTEGER NOT NULL,
|
|
77
|
+
path TEXT NOT NULL
|
|
78
|
+
) STRICT;
|
|
79
|
+
|
|
80
|
+
-- Indexes
|
|
81
|
+
CREATE INDEX IF NOT EXISTS idx_records_type_id ON records(type_id);
|
|
82
|
+
CREATE INDEX IF NOT EXISTS idx_records_parent_id ON records(parent_id);
|
|
83
|
+
CREATE INDEX IF NOT EXISTS idx_records_entity_id ON records(entity_id);
|
|
84
|
+
CREATE INDEX IF NOT EXISTS idx_records_app_id ON records(app_id);
|
|
85
|
+
CREATE INDEX IF NOT EXISTS idx_records_deleted_at ON records(deleted_at);
|
|
86
|
+
CREATE INDEX IF NOT EXISTS idx_records_created_at ON records(created_at);
|
|
87
|
+
CREATE INDEX IF NOT EXISTS idx_records_updated_at ON records(updated_at);
|
|
88
|
+
CREATE INDEX IF NOT EXISTS idx_assoc_record_id ON associations(record_id);
|
|
89
|
+
CREATE INDEX IF NOT EXISTS idx_assoc_kind_label ON associations(kind, label);
|
|
90
|
+
CREATE INDEX IF NOT EXISTS idx_types_base_id ON types(base_id);
|
|
91
|
+
|
|
92
|
+
-- Full-text search (FTS4 — compatible with sql.js)
|
|
93
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS records_fts USING fts4(
|
|
94
|
+
content,
|
|
95
|
+
content='records'
|
|
96
|
+
);
|
|
97
|
+
`;
|
|
98
|
+
// -------------------------------------------------------
|
|
99
|
+
// Row <-> domain object mapping
|
|
100
|
+
// -------------------------------------------------------
|
|
101
|
+
const toMs = (d) => d.getTime();
|
|
102
|
+
const fromMs = (ms) => new Date(ms);
|
|
103
|
+
const rowToRecord = (row, associations) => {
|
|
104
|
+
const record = {
|
|
105
|
+
id: row.id,
|
|
106
|
+
typeId: row.type_id,
|
|
107
|
+
createdAt: fromMs(row.created_at),
|
|
108
|
+
updatedAt: fromMs(row.updated_at),
|
|
109
|
+
content: JSON.parse(row.content),
|
|
110
|
+
version: row.version,
|
|
111
|
+
};
|
|
112
|
+
if (row.parent_id)
|
|
113
|
+
record.parentId = row.parent_id;
|
|
114
|
+
if (row.entity_id)
|
|
115
|
+
record.entityId = row.entity_id;
|
|
116
|
+
if (row.app_id)
|
|
117
|
+
record.appId = row.app_id;
|
|
118
|
+
if (row.deleted_at)
|
|
119
|
+
record.deletedAt = fromMs(row.deleted_at);
|
|
120
|
+
if (row.permissions)
|
|
121
|
+
record.permissions = JSON.parse(row.permissions);
|
|
122
|
+
if (associations.length)
|
|
123
|
+
record.associations = associations;
|
|
124
|
+
return record;
|
|
125
|
+
};
|
|
126
|
+
const rowToAssociation = (row) => {
|
|
127
|
+
if (row.kind === 'tag') {
|
|
128
|
+
return { kind: 'tag', label: row.label };
|
|
129
|
+
}
|
|
130
|
+
if (row.kind === 'attachment') {
|
|
131
|
+
return {
|
|
132
|
+
kind: 'attachment',
|
|
133
|
+
label: row.label,
|
|
134
|
+
fileId: row.file_id,
|
|
135
|
+
mimeType: row.mime_type,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
// relationship
|
|
139
|
+
return {
|
|
140
|
+
kind: 'relationship',
|
|
141
|
+
label: row.label,
|
|
142
|
+
recordId: row.related_id,
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
const rowToType = (row) => {
|
|
146
|
+
const t = {
|
|
147
|
+
id: row.id,
|
|
148
|
+
baseId: row.base_id,
|
|
149
|
+
version: row.version,
|
|
150
|
+
name: row.name,
|
|
151
|
+
schema: JSON.parse(row.schema),
|
|
152
|
+
schemaHash: row.schema_hash,
|
|
153
|
+
createdAt: fromMs(row.created_at),
|
|
154
|
+
};
|
|
155
|
+
if (row.migrates_from)
|
|
156
|
+
t.migratesFrom = row.migrates_from;
|
|
157
|
+
return t;
|
|
158
|
+
};
|
|
159
|
+
const rowToVersion = (row) => {
|
|
160
|
+
const v = {
|
|
161
|
+
version: row.version,
|
|
162
|
+
content: JSON.parse(row.content),
|
|
163
|
+
updatedAt: fromMs(row.updated_at),
|
|
164
|
+
};
|
|
165
|
+
if (row.entity_id)
|
|
166
|
+
v.entityId = row.entity_id;
|
|
167
|
+
return v;
|
|
168
|
+
};
|
|
169
|
+
// -------------------------------------------------------
|
|
170
|
+
// Query building
|
|
171
|
+
// -------------------------------------------------------
|
|
172
|
+
const buildWhereClause = (query) => {
|
|
173
|
+
const conditions = [];
|
|
174
|
+
const params = [];
|
|
175
|
+
const f = query.filter ?? {};
|
|
176
|
+
if (!f.includeDeleted) {
|
|
177
|
+
conditions.push('r.deleted_at IS NULL');
|
|
178
|
+
}
|
|
179
|
+
if (f.typeId !== undefined) {
|
|
180
|
+
const ids = Array.isArray(f.typeId) ? f.typeId : [f.typeId];
|
|
181
|
+
conditions.push(`r.type_id IN (${ids.map(() => '?').join(',')})`);
|
|
182
|
+
params.push(...ids);
|
|
183
|
+
}
|
|
184
|
+
if (f.parentId !== undefined) {
|
|
185
|
+
if (f.parentId === null) {
|
|
186
|
+
conditions.push('r.parent_id IS NULL');
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
conditions.push('r.parent_id = ?');
|
|
190
|
+
params.push(f.parentId);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (f.appId !== undefined) {
|
|
194
|
+
const ids = Array.isArray(f.appId) ? f.appId : [f.appId];
|
|
195
|
+
conditions.push(`r.app_id IN (${ids.map(() => '?').join(',')})`);
|
|
196
|
+
params.push(...ids);
|
|
197
|
+
}
|
|
198
|
+
if (f.entityId !== undefined) {
|
|
199
|
+
const ids = Array.isArray(f.entityId) ? f.entityId : [f.entityId];
|
|
200
|
+
conditions.push(`r.entity_id IN (${ids.map(() => '?').join(',')})`);
|
|
201
|
+
params.push(...ids);
|
|
202
|
+
}
|
|
203
|
+
if (f.createdAt?.after) {
|
|
204
|
+
conditions.push('r.created_at > ?');
|
|
205
|
+
params.push(toMs(f.createdAt.after));
|
|
206
|
+
}
|
|
207
|
+
if (f.createdAt?.before) {
|
|
208
|
+
conditions.push('r.created_at < ?');
|
|
209
|
+
params.push(toMs(f.createdAt.before));
|
|
210
|
+
}
|
|
211
|
+
if (f.updatedAt?.after) {
|
|
212
|
+
conditions.push('r.updated_at > ?');
|
|
213
|
+
params.push(toMs(f.updatedAt.after));
|
|
214
|
+
}
|
|
215
|
+
if (f.updatedAt?.before) {
|
|
216
|
+
conditions.push('r.updated_at < ?');
|
|
217
|
+
params.push(toMs(f.updatedAt.before));
|
|
218
|
+
}
|
|
219
|
+
// Tag filter — record must have ALL specified tags
|
|
220
|
+
if (f.tags?.length) {
|
|
221
|
+
for (const tag of f.tags) {
|
|
222
|
+
conditions.push(`EXISTS (SELECT 1 FROM associations a WHERE a.record_id = r.id AND a.kind = 'tag' AND a.label = ?)`);
|
|
223
|
+
params.push(tag);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
// Attachment label filter
|
|
227
|
+
if (f.hasAttachment) {
|
|
228
|
+
conditions.push(`EXISTS (SELECT 1 FROM associations a WHERE a.record_id = r.id AND a.kind = 'attachment' AND a.label = ?)`);
|
|
229
|
+
params.push(f.hasAttachment);
|
|
230
|
+
}
|
|
231
|
+
// Relationship filter
|
|
232
|
+
if (f.relatedTo) {
|
|
233
|
+
conditions.push(`EXISTS (SELECT 1 FROM associations a WHERE a.record_id = r.id AND a.kind = 'relationship' AND a.related_id = ?` +
|
|
234
|
+
(f.relatedTo.label ? ` AND a.label = ?` : '') +
|
|
235
|
+
`)`);
|
|
236
|
+
params.push(f.relatedTo.recordId);
|
|
237
|
+
if (f.relatedTo.label)
|
|
238
|
+
params.push(f.relatedTo.label);
|
|
239
|
+
}
|
|
240
|
+
// Content field filters (top-level scalar exact match)
|
|
241
|
+
if (f.content) {
|
|
242
|
+
for (const [key, value] of Object.entries(f.content)) {
|
|
243
|
+
conditions.push(`json_extract(r.content, ?) = ?`);
|
|
244
|
+
params.push(`$.${key}`, value);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
// Full-text search
|
|
248
|
+
if (f.search) {
|
|
249
|
+
conditions.push(`r.rowid IN (SELECT rowid FROM records_fts WHERE records_fts MATCH ?)`);
|
|
250
|
+
params.push(f.search);
|
|
251
|
+
}
|
|
252
|
+
// Cursor (created_at + id for stable pagination)
|
|
253
|
+
if (query.cursor) {
|
|
254
|
+
const [cursorTs, cursorId] = Buffer.from(query.cursor, 'base64').toString().split('|');
|
|
255
|
+
const sortDir = query.sort?.direction ?? 'desc';
|
|
256
|
+
const op = sortDir === 'asc' ? '>' : '<';
|
|
257
|
+
conditions.push(`(r.created_at ${op} ? OR (r.created_at = ? AND r.id ${op} ?))`);
|
|
258
|
+
params.push(Number(cursorTs), Number(cursorTs), cursorId);
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
sql: conditions.length ? `WHERE ${conditions.join(' AND ')}` : '',
|
|
262
|
+
params,
|
|
263
|
+
};
|
|
264
|
+
};
|
|
265
|
+
const buildOrderClause = (query) => {
|
|
266
|
+
const field = query.sort?.field ?? 'created_at';
|
|
267
|
+
const dir = (query.sort?.direction ?? 'desc').toUpperCase();
|
|
268
|
+
const col = field === 'createdAt' ? 'created_at' : field === 'updatedAt' ? 'updated_at' : field;
|
|
269
|
+
return `ORDER BY r.${col} ${dir}, r.id ${dir}`;
|
|
270
|
+
};
|
|
271
|
+
const makeCursor = (record) => Buffer.from(`${toMs(record.createdAt)}|${record.id}`).toString('base64');
|
|
272
|
+
// -------------------------------------------------------
|
|
273
|
+
// SQLite adapter
|
|
274
|
+
// -------------------------------------------------------
|
|
275
|
+
export class SQLiteAdapter {
|
|
276
|
+
SQL;
|
|
277
|
+
path;
|
|
278
|
+
capabilities = {
|
|
279
|
+
fullTextSearch: true,
|
|
280
|
+
contentFieldQuery: true,
|
|
281
|
+
sortableFields: ['createdAt', 'updatedAt', 'version'],
|
|
282
|
+
};
|
|
283
|
+
db;
|
|
284
|
+
attachmentsDir;
|
|
285
|
+
constructor(SQL, path) {
|
|
286
|
+
this.SQL = SQL;
|
|
287
|
+
this.path = path;
|
|
288
|
+
this.attachmentsDir = join(dirname(path), 'attachments');
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Initialize a new stack database. Fails if the file already exists —
|
|
292
|
+
* use open() for existing databases.
|
|
293
|
+
*/
|
|
294
|
+
static async initialize(opts) {
|
|
295
|
+
if (existsSync(opts.path)) {
|
|
296
|
+
throw new Error(`Cannot initialize: database already exists at "${opts.path}". ` +
|
|
297
|
+
`Use SQLiteAdapter.open() instead.`);
|
|
298
|
+
}
|
|
299
|
+
const SQL = await initSqlJs();
|
|
300
|
+
const adapter = new SQLiteAdapter(SQL, opts.path);
|
|
301
|
+
adapter.db = new SQL.Database();
|
|
302
|
+
adapter.db.run(SCHEMA_SQL);
|
|
303
|
+
mkdirSync(adapter.attachmentsDir, { recursive: true });
|
|
304
|
+
adapter.db.run(`INSERT INTO stack_config (key, value) VALUES
|
|
305
|
+
('entity_id', ?), ('timezone', ?), ('version', '1')`, [opts.entityId, opts.timezone]);
|
|
306
|
+
adapter.persist();
|
|
307
|
+
return adapter;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Open an existing stack database. Fails if the file does not exist —
|
|
311
|
+
* use initialize() for new databases.
|
|
312
|
+
*/
|
|
313
|
+
static async open(opts) {
|
|
314
|
+
if (!existsSync(opts.path)) {
|
|
315
|
+
throw new Error(`Cannot open: no database found at "${opts.path}". ` +
|
|
316
|
+
`Use SQLiteAdapter.initialize() to create one.`);
|
|
317
|
+
}
|
|
318
|
+
const SQL = await initSqlJs();
|
|
319
|
+
const adapter = new SQLiteAdapter(SQL, opts.path);
|
|
320
|
+
const fileBuffer = readFileSync(opts.path);
|
|
321
|
+
adapter.db = new SQL.Database(fileBuffer);
|
|
322
|
+
adapter.db.run(SCHEMA_SQL); // safe — all statements use CREATE IF NOT EXISTS
|
|
323
|
+
mkdirSync(adapter.attachmentsDir, { recursive: true });
|
|
324
|
+
return adapter;
|
|
325
|
+
}
|
|
326
|
+
// -------------------------------------------------------
|
|
327
|
+
// Config
|
|
328
|
+
// -------------------------------------------------------
|
|
329
|
+
async getConfig(key) {
|
|
330
|
+
const stmt = this.db.prepare('SELECT value FROM stack_config WHERE key = ?');
|
|
331
|
+
stmt.bind([key]);
|
|
332
|
+
if (stmt.step()) {
|
|
333
|
+
const row = stmt.getAsObject();
|
|
334
|
+
stmt.free();
|
|
335
|
+
return row.value;
|
|
336
|
+
}
|
|
337
|
+
stmt.free();
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
async setConfig(key, value) {
|
|
341
|
+
this.db.run('INSERT OR REPLACE INTO stack_config (key, value) VALUES (?, ?)', [key, value]);
|
|
342
|
+
this.persist();
|
|
343
|
+
}
|
|
344
|
+
// -------------------------------------------------------
|
|
345
|
+
// Persistence
|
|
346
|
+
// -------------------------------------------------------
|
|
347
|
+
/** Flush the in-memory database to disk. Called after every write. */
|
|
348
|
+
persist() {
|
|
349
|
+
const data = this.db.export();
|
|
350
|
+
writeFileSync(this.path, Buffer.from(data));
|
|
351
|
+
}
|
|
352
|
+
// -------------------------------------------------------
|
|
353
|
+
// Records
|
|
354
|
+
// -------------------------------------------------------
|
|
355
|
+
async createRecord(record) {
|
|
356
|
+
this.db.run(`INSERT INTO records
|
|
357
|
+
(id, type_id, created_at, updated_at, content, version,
|
|
358
|
+
parent_id, entity_id, app_id, deleted_at, permissions)
|
|
359
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
360
|
+
record.id,
|
|
361
|
+
record.typeId,
|
|
362
|
+
toMs(record.createdAt),
|
|
363
|
+
toMs(record.updatedAt),
|
|
364
|
+
JSON.stringify(record.content),
|
|
365
|
+
record.version,
|
|
366
|
+
record.parentId ?? null,
|
|
367
|
+
record.entityId ?? null,
|
|
368
|
+
record.appId ?? null,
|
|
369
|
+
record.deletedAt ? toMs(record.deletedAt) : null,
|
|
370
|
+
record.permissions ? JSON.stringify(record.permissions) : null,
|
|
371
|
+
]);
|
|
372
|
+
if (record.associations?.length) {
|
|
373
|
+
this.insertAssociations(record.id, record.associations);
|
|
374
|
+
}
|
|
375
|
+
this.updateFts(record.id, JSON.stringify(record.content));
|
|
376
|
+
this.persist();
|
|
377
|
+
return record;
|
|
378
|
+
}
|
|
379
|
+
async getRecord(id) {
|
|
380
|
+
const stmt = this.db.prepare('SELECT * FROM records r WHERE r.id = ?');
|
|
381
|
+
stmt.bind([id]);
|
|
382
|
+
if (!stmt.step()) {
|
|
383
|
+
stmt.free();
|
|
384
|
+
return null;
|
|
385
|
+
}
|
|
386
|
+
const row = stmt.getAsObject();
|
|
387
|
+
stmt.free();
|
|
388
|
+
const associations = this.getAssociationsForRecord(id);
|
|
389
|
+
return rowToRecord(row, associations);
|
|
390
|
+
}
|
|
391
|
+
async updateRecord(id, changes) {
|
|
392
|
+
const setClauses = [];
|
|
393
|
+
const params = [];
|
|
394
|
+
if (changes.content !== undefined) {
|
|
395
|
+
setClauses.push('content = ?');
|
|
396
|
+
params.push(JSON.stringify(changes.content));
|
|
397
|
+
}
|
|
398
|
+
if (changes.typeId !== undefined) {
|
|
399
|
+
setClauses.push('type_id = ?');
|
|
400
|
+
params.push(changes.typeId);
|
|
401
|
+
}
|
|
402
|
+
if (changes.updatedAt !== undefined) {
|
|
403
|
+
setClauses.push('updated_at = ?');
|
|
404
|
+
params.push(toMs(changes.updatedAt));
|
|
405
|
+
}
|
|
406
|
+
if (changes.version !== undefined) {
|
|
407
|
+
setClauses.push('version = ?');
|
|
408
|
+
params.push(changes.version);
|
|
409
|
+
}
|
|
410
|
+
if (changes.deletedAt !== undefined) {
|
|
411
|
+
setClauses.push('deleted_at = ?');
|
|
412
|
+
params.push(toMs(changes.deletedAt));
|
|
413
|
+
}
|
|
414
|
+
if (changes.permissions !== undefined) {
|
|
415
|
+
setClauses.push('permissions = ?');
|
|
416
|
+
params.push(changes.permissions.length ? JSON.stringify(changes.permissions) : null);
|
|
417
|
+
}
|
|
418
|
+
if (setClauses.length) {
|
|
419
|
+
params.push(id);
|
|
420
|
+
this.db.run(`UPDATE records SET ${setClauses.join(', ')} WHERE id = ?`, params);
|
|
421
|
+
}
|
|
422
|
+
// Replace associations if provided
|
|
423
|
+
if (changes.associations !== undefined) {
|
|
424
|
+
this.db.run('DELETE FROM associations WHERE record_id = ?', [id]);
|
|
425
|
+
if (changes.associations.length) {
|
|
426
|
+
this.insertAssociations(id, changes.associations);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
if (changes.content !== undefined) {
|
|
430
|
+
this.updateFts(id, JSON.stringify(changes.content));
|
|
431
|
+
}
|
|
432
|
+
this.persist();
|
|
433
|
+
const updated = await this.getRecord(id);
|
|
434
|
+
if (!updated)
|
|
435
|
+
throw new Error(`Record not found after update: "${id}"`);
|
|
436
|
+
return updated;
|
|
437
|
+
}
|
|
438
|
+
async deleteRecord(id, opts = {}) {
|
|
439
|
+
if (opts.hard) {
|
|
440
|
+
this.db.run('DELETE FROM associations WHERE record_id = ?', [id]);
|
|
441
|
+
this.db.run('DELETE FROM versions WHERE record_id = ?', [id]);
|
|
442
|
+
this.db.run(`DELETE FROM records_fts WHERE docid = (SELECT rowid FROM records WHERE id = ?)`, [id]);
|
|
443
|
+
this.db.run('DELETE FROM records WHERE id = ?', [id]);
|
|
444
|
+
}
|
|
445
|
+
else {
|
|
446
|
+
this.db.run('UPDATE records SET deleted_at = ? WHERE id = ?', [toMs(new Date()), id]);
|
|
447
|
+
}
|
|
448
|
+
this.persist();
|
|
449
|
+
}
|
|
450
|
+
async queryRecords(query) {
|
|
451
|
+
const { sql: where, params } = buildWhereClause(query);
|
|
452
|
+
const order = buildOrderClause(query);
|
|
453
|
+
const limit = query.limit ?? 50;
|
|
454
|
+
// Fetch one extra to determine if there's a next page
|
|
455
|
+
const rows = this.execQuery(`SELECT r.* FROM records r ${where} ${order} LIMIT ?`, [...params, limit + 1]);
|
|
456
|
+
const hasMore = rows.length > limit;
|
|
457
|
+
const page = hasMore ? rows.slice(0, limit) : rows;
|
|
458
|
+
const records = page.map((row) => {
|
|
459
|
+
const associations = this.getAssociationsForRecord(row.id);
|
|
460
|
+
return rowToRecord(row, associations);
|
|
461
|
+
});
|
|
462
|
+
// Total count (without pagination)
|
|
463
|
+
const countRows = this.execQuery(`SELECT COUNT(*) as total FROM records r ${where}`, params);
|
|
464
|
+
const total = countRows[0]?.total ?? 0;
|
|
465
|
+
const lastRecord = records[records.length - 1];
|
|
466
|
+
const cursor = hasMore && lastRecord ? makeCursor(lastRecord) : null;
|
|
467
|
+
return { records, cursor, total };
|
|
468
|
+
}
|
|
469
|
+
// -------------------------------------------------------
|
|
470
|
+
// Versions
|
|
471
|
+
// -------------------------------------------------------
|
|
472
|
+
async getVersions(id) {
|
|
473
|
+
const rows = this.execQuery('SELECT * FROM versions WHERE record_id = ? ORDER BY version DESC', [id]);
|
|
474
|
+
return rows.map(rowToVersion);
|
|
475
|
+
}
|
|
476
|
+
async getVersion(id, version) {
|
|
477
|
+
const rows = this.execQuery('SELECT * FROM versions WHERE record_id = ? AND version = ?', [id, version]);
|
|
478
|
+
return rows.length ? rowToVersion(rows[0]) : null;
|
|
479
|
+
}
|
|
480
|
+
async saveVersion(id, version) {
|
|
481
|
+
this.db.run(`INSERT OR IGNORE INTO versions (record_id, version, content, updated_at, entity_id)
|
|
482
|
+
VALUES (?, ?, ?, ?, ?)`, [
|
|
483
|
+
id,
|
|
484
|
+
version.version,
|
|
485
|
+
JSON.stringify(version.content),
|
|
486
|
+
toMs(version.updatedAt),
|
|
487
|
+
version.entityId ?? null,
|
|
488
|
+
]);
|
|
489
|
+
this.persist();
|
|
490
|
+
}
|
|
491
|
+
// -------------------------------------------------------
|
|
492
|
+
// Types
|
|
493
|
+
// -------------------------------------------------------
|
|
494
|
+
async saveType(type) {
|
|
495
|
+
this.db.run(`INSERT OR REPLACE INTO types
|
|
496
|
+
(id, base_id, version, name, schema, schema_hash, migrates_from, created_at)
|
|
497
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [
|
|
498
|
+
type.id,
|
|
499
|
+
type.baseId,
|
|
500
|
+
type.version,
|
|
501
|
+
type.name,
|
|
502
|
+
JSON.stringify(type.schema),
|
|
503
|
+
type.schemaHash,
|
|
504
|
+
type.migratesFrom ?? null,
|
|
505
|
+
toMs(type.createdAt),
|
|
506
|
+
]);
|
|
507
|
+
this.persist();
|
|
508
|
+
}
|
|
509
|
+
async getType(id) {
|
|
510
|
+
const rows = this.execQuery('SELECT * FROM types WHERE id = ?', [id]);
|
|
511
|
+
return rows.length ? rowToType(rows[0]) : null;
|
|
512
|
+
}
|
|
513
|
+
async listTypes() {
|
|
514
|
+
const rows = this.execQuery('SELECT * FROM types ORDER BY base_id, version');
|
|
515
|
+
return rows.map(rowToType);
|
|
516
|
+
}
|
|
517
|
+
// -------------------------------------------------------
|
|
518
|
+
// Attachments
|
|
519
|
+
// -------------------------------------------------------
|
|
520
|
+
async putAttachment(data, mimeType) {
|
|
521
|
+
const fileId = generateId();
|
|
522
|
+
const ext = mimeType.split('/')[1] ?? 'bin';
|
|
523
|
+
const filename = `${fileId}.${ext}`;
|
|
524
|
+
const filePath = join(this.attachmentsDir, filename);
|
|
525
|
+
await writeFile(filePath, data);
|
|
526
|
+
this.db.run('INSERT INTO attachments (file_id, mime_type, created_at, path) VALUES (?, ?, ?, ?)', [fileId, mimeType, toMs(new Date()), filename]);
|
|
527
|
+
this.persist();
|
|
528
|
+
return fileId;
|
|
529
|
+
}
|
|
530
|
+
async getAttachment(fileId) {
|
|
531
|
+
const rows = this.execQuery('SELECT path FROM attachments WHERE file_id = ?', [fileId]);
|
|
532
|
+
if (!rows.length) {
|
|
533
|
+
throw new Error(`Attachment not found: "${fileId}"`);
|
|
534
|
+
}
|
|
535
|
+
const filePath = join(this.attachmentsDir, rows[0].path);
|
|
536
|
+
return readFile(filePath);
|
|
537
|
+
}
|
|
538
|
+
async deleteAttachment(fileId) {
|
|
539
|
+
this.db.run('DELETE FROM attachments WHERE file_id = ?', [fileId]);
|
|
540
|
+
this.persist();
|
|
541
|
+
}
|
|
542
|
+
// -------------------------------------------------------
|
|
543
|
+
// Private helpers
|
|
544
|
+
// -------------------------------------------------------
|
|
545
|
+
async associate(recordId, association) {
|
|
546
|
+
this.insertAssociations(recordId, [association]);
|
|
547
|
+
this.persist();
|
|
548
|
+
}
|
|
549
|
+
async dissociate(recordId, association) {
|
|
550
|
+
this.db.run(`DELETE FROM associations
|
|
551
|
+
WHERE record_id = ?
|
|
552
|
+
AND kind = ?
|
|
553
|
+
AND label = ?
|
|
554
|
+
AND file_id = ?
|
|
555
|
+
AND related_id = ?`, [
|
|
556
|
+
recordId,
|
|
557
|
+
association.kind,
|
|
558
|
+
association.label,
|
|
559
|
+
association.kind === 'attachment' ? association.fileId : '',
|
|
560
|
+
association.kind === 'relationship' ? association.recordId : '',
|
|
561
|
+
]);
|
|
562
|
+
this.persist();
|
|
563
|
+
}
|
|
564
|
+
insertAssociations(recordId, associations) {
|
|
565
|
+
for (const assoc of associations) {
|
|
566
|
+
this.db.run(`INSERT OR IGNORE INTO associations
|
|
567
|
+
(record_id, kind, label, file_id, mime_type, related_id)
|
|
568
|
+
VALUES (?, ?, ?, ?, ?, ?)`, [
|
|
569
|
+
recordId,
|
|
570
|
+
assoc.kind,
|
|
571
|
+
assoc.label,
|
|
572
|
+
assoc.kind === 'attachment' ? assoc.fileId : '',
|
|
573
|
+
assoc.kind === 'attachment' ? assoc.mimeType : null,
|
|
574
|
+
assoc.kind === 'relationship' ? assoc.recordId : '',
|
|
575
|
+
]);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
getAssociationsForRecord(recordId) {
|
|
579
|
+
const rows = this.execQuery('SELECT * FROM associations WHERE record_id = ?', [recordId]);
|
|
580
|
+
return rows.map(rowToAssociation);
|
|
581
|
+
}
|
|
582
|
+
updateFts(recordId, content) {
|
|
583
|
+
// FTS4 content table — delete old entry then insert new one
|
|
584
|
+
this.db.run(`DELETE FROM records_fts WHERE docid = (SELECT rowid FROM records WHERE id = ?)`, [
|
|
585
|
+
recordId,
|
|
586
|
+
]);
|
|
587
|
+
this.db.run(`INSERT INTO records_fts(docid, content)
|
|
588
|
+
SELECT rowid, ? FROM records WHERE id = ?`, [content, recordId]);
|
|
589
|
+
}
|
|
590
|
+
execQuery(sql, params = []) {
|
|
591
|
+
const stmt = this.db.prepare(sql);
|
|
592
|
+
stmt.bind(params);
|
|
593
|
+
const results = [];
|
|
594
|
+
while (stmt.step()) {
|
|
595
|
+
results.push(stmt.getAsObject());
|
|
596
|
+
}
|
|
597
|
+
stmt.free();
|
|
598
|
+
return results;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@haverstack/adapter-sqlite",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "SQLite storage adapter for Haverstack",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"import": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"main": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/haverstack/core",
|
|
20
|
+
"directory": "packages/adapter-sqlite"
|
|
21
|
+
},
|
|
22
|
+
"license": "CC0-1.0",
|
|
23
|
+
"keywords": [
|
|
24
|
+
"haverstack",
|
|
25
|
+
"sqlite",
|
|
26
|
+
"adapter",
|
|
27
|
+
"personal data",
|
|
28
|
+
"storage"
|
|
29
|
+
],
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"sql.js": "^1.14.0",
|
|
32
|
+
"@haverstack/core": "0.1.0"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^22.0.0",
|
|
36
|
+
"@types/sql.js": "^1.4.9",
|
|
37
|
+
"typescript": "^5.5.0",
|
|
38
|
+
"vitest": "^2.0.0"
|
|
39
|
+
},
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "tsc -p tsconfig.build.json",
|
|
42
|
+
"test": "vitest run",
|
|
43
|
+
"typecheck": "tsc --noEmit",
|
|
44
|
+
"lint": "eslint src tests"
|
|
45
|
+
}
|
|
46
|
+
}
|