@hatk/hatk 0.0.1-alpha.11 → 0.0.1-alpha.111
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.d.ts +19 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +113 -0
- package/dist/backfill.d.ts +36 -2
- package/dist/backfill.d.ts.map +1 -1
- package/dist/backfill.js +153 -37
- package/dist/car.js +1 -1
- package/dist/classifiers.d.ts +228 -0
- package/dist/classifiers.d.ts.map +1 -0
- package/dist/classifiers.js +688 -0
- package/dist/cli.js +248 -1043
- package/dist/config.d.ts +179 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +78 -8
- package/dist/database/adapter-factory.d.ts +6 -0
- package/dist/database/adapter-factory.d.ts.map +1 -0
- package/dist/database/adapter-factory.js +20 -0
- package/dist/database/adapters/duckdb-search.d.ts +12 -0
- package/dist/database/adapters/duckdb-search.d.ts.map +1 -0
- package/dist/database/adapters/duckdb-search.js +27 -0
- package/dist/database/adapters/duckdb.d.ts +25 -0
- package/dist/database/adapters/duckdb.d.ts.map +1 -0
- package/dist/database/adapters/duckdb.js +161 -0
- package/dist/database/adapters/sqlite-search.d.ts +16 -0
- package/dist/database/adapters/sqlite-search.d.ts.map +1 -0
- package/dist/database/adapters/sqlite-search.js +76 -0
- package/dist/database/adapters/sqlite.d.ts +18 -0
- package/dist/database/adapters/sqlite.d.ts.map +1 -0
- package/dist/database/adapters/sqlite.js +88 -0
- package/dist/database/db.d.ts +290 -0
- package/dist/database/db.d.ts.map +1 -0
- package/dist/database/db.js +2073 -0
- package/dist/database/dialect.d.ts +45 -0
- package/dist/database/dialect.d.ts.map +1 -0
- package/dist/database/dialect.js +72 -0
- package/dist/{fts.d.ts → database/fts.d.ts} +7 -0
- package/dist/database/fts.d.ts.map +1 -0
- package/dist/{fts.js → database/fts.js} +122 -34
- package/dist/database/index.d.ts +7 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +6 -0
- package/dist/database/ports.d.ts +50 -0
- package/dist/database/ports.d.ts.map +1 -0
- package/dist/database/ports.js +1 -0
- package/dist/database/schema.d.ts +91 -0
- package/dist/database/schema.d.ts.map +1 -0
- package/dist/{schema.js → database/schema.js} +153 -54
- package/dist/dev-entry.d.ts +8 -0
- package/dist/dev-entry.d.ts.map +1 -0
- package/dist/dev-entry.js +131 -0
- package/dist/feeds.d.ts +26 -8
- package/dist/feeds.d.ts.map +1 -1
- package/dist/feeds.js +72 -16
- package/dist/hooks.d.ts +102 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +186 -0
- package/dist/hydrate.d.ts +55 -6
- package/dist/hydrate.d.ts.map +1 -1
- package/dist/hydrate.js +21 -20
- package/dist/indexer.d.ts +194 -3
- package/dist/indexer.d.ts.map +1 -1
- package/dist/indexer.js +627 -92
- package/dist/jetstream.d.ts +118 -0
- package/dist/jetstream.d.ts.map +1 -0
- package/dist/jetstream.js +238 -0
- package/dist/labels.d.ts +36 -0
- package/dist/labels.d.ts.map +1 -1
- package/dist/labels.js +71 -6
- package/dist/lex-types.d.ts +2 -0
- package/dist/lex-types.d.ts.map +1 -1
- package/dist/lexicon-resolve.d.ts.map +1 -1
- package/dist/lexicon-resolve.js +27 -112
- package/dist/lexicons/com/atproto/label/defs.json +75 -0
- package/dist/lexicons/com/atproto/moderation/defs.json +30 -0
- package/dist/lexicons/com/atproto/repo/strongRef.json +21 -0
- package/dist/lexicons/dev/hatk/applyWrites.json +87 -0
- package/dist/lexicons/dev/hatk/createRecord.json +40 -0
- package/dist/lexicons/dev/hatk/createReport.json +48 -0
- package/dist/lexicons/dev/hatk/deleteRecord.json +25 -0
- package/dist/lexicons/dev/hatk/describeCollections.json +41 -0
- package/dist/lexicons/dev/hatk/describeFeeds.json +29 -0
- package/dist/lexicons/dev/hatk/describeLabels.json +45 -0
- package/dist/lexicons/dev/hatk/getFeed.json +30 -0
- package/dist/lexicons/dev/hatk/getPreferences.json +19 -0
- package/dist/lexicons/dev/hatk/getRecord.json +26 -0
- package/dist/lexicons/dev/hatk/getRecords.json +32 -0
- package/dist/lexicons/dev/hatk/putPreference.json +28 -0
- package/dist/lexicons/dev/hatk/putRecord.json +41 -0
- package/dist/lexicons/dev/hatk/searchRecords.json +32 -0
- package/dist/lexicons/dev/hatk/uploadBlob.json +23 -0
- package/dist/logger.d.ts +29 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +29 -0
- package/dist/main.js +212 -75
- package/dist/mst.d.ts +15 -0
- package/dist/mst.d.ts.map +1 -1
- package/dist/mst.js +13 -0
- package/dist/oauth/db.d.ts +27 -1
- package/dist/oauth/db.d.ts.map +1 -1
- package/dist/oauth/db.js +80 -19
- package/dist/oauth/discovery.d.ts +10 -0
- package/dist/oauth/discovery.d.ts.map +1 -1
- package/dist/oauth/discovery.js +54 -2
- package/dist/oauth/server.d.ts +131 -1
- package/dist/oauth/server.d.ts.map +1 -1
- package/dist/oauth/server.js +504 -39
- package/dist/oauth/service-describe.d.ts +42 -0
- package/dist/oauth/service-describe.d.ts.map +1 -0
- package/dist/oauth/service-describe.js +108 -0
- package/dist/oauth/session.d.ts +32 -0
- package/dist/oauth/session.d.ts.map +1 -0
- package/dist/oauth/session.js +131 -0
- package/dist/opengraph.d.ts +10 -0
- package/dist/opengraph.d.ts.map +1 -1
- package/dist/opengraph.js +94 -42
- package/dist/pds-proxy.d.ts +92 -0
- package/dist/pds-proxy.d.ts.map +1 -0
- package/dist/pds-proxy.js +396 -0
- package/dist/private-collections.d.ts +13 -0
- package/dist/private-collections.d.ts.map +1 -0
- package/dist/private-collections.js +27 -0
- package/dist/push.d.ts +54 -0
- package/dist/push.d.ts.map +1 -0
- package/dist/push.js +367 -0
- package/dist/renderer.d.ts +27 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/renderer.js +46 -0
- package/dist/resolve-hatk.d.ts +6 -0
- package/dist/resolve-hatk.d.ts.map +1 -0
- package/dist/resolve-hatk.js +20 -0
- package/dist/response.d.ts +16 -0
- package/dist/response.d.ts.map +1 -0
- package/dist/response.js +69 -0
- package/dist/scanner.d.ts +22 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +92 -0
- package/dist/seed.d.ts +19 -0
- package/dist/seed.d.ts.map +1 -1
- package/dist/seed.js +43 -4
- package/dist/server-init.d.ts +8 -0
- package/dist/server-init.d.ts.map +1 -0
- package/dist/server-init.js +75 -0
- package/dist/server.d.ts +46 -3
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1137 -649
- package/dist/setup.d.ts +28 -1
- package/dist/setup.d.ts.map +1 -1
- package/dist/setup.js +50 -3
- package/dist/spaces/blob.d.ts +112 -0
- package/dist/spaces/blob.d.ts.map +1 -0
- package/dist/spaces/blob.js +460 -0
- package/dist/spaces/credential.d.ts +82 -0
- package/dist/spaces/credential.d.ts.map +1 -0
- package/dist/spaces/credential.js +220 -0
- package/dist/spaces/engine.d.ts +97 -0
- package/dist/spaces/engine.d.ts.map +1 -0
- package/dist/spaces/engine.js +563 -0
- package/dist/spaces/guard.d.ts +41 -0
- package/dist/spaces/guard.d.ts.map +1 -0
- package/dist/spaces/guard.js +79 -0
- package/dist/spaces/identity.d.ts +37 -0
- package/dist/spaces/identity.d.ts.map +1 -0
- package/dist/spaces/identity.js +93 -0
- package/dist/spaces/index.d.ts +56 -0
- package/dist/spaces/index.d.ts.map +1 -0
- package/dist/spaces/index.js +134 -0
- package/dist/spaces/notify.d.ts +60 -0
- package/dist/spaces/notify.d.ts.map +1 -0
- package/dist/spaces/notify.js +128 -0
- package/dist/spaces/records.d.ts +37 -0
- package/dist/spaces/records.d.ts.map +1 -0
- package/dist/spaces/records.js +63 -0
- package/dist/spaces/signature.d.ts +36 -0
- package/dist/spaces/signature.d.ts.map +1 -0
- package/dist/spaces/signature.js +83 -0
- package/dist/spaces/store.d.ts +51 -0
- package/dist/spaces/store.d.ts.map +1 -0
- package/dist/spaces/store.js +99 -0
- package/dist/spaces/uri.d.ts +60 -0
- package/dist/spaces/uri.d.ts.map +1 -0
- package/dist/spaces/uri.js +97 -0
- package/dist/spaces/verify.d.ts +46 -0
- package/dist/spaces/verify.d.ts.map +1 -0
- package/dist/spaces/verify.js +94 -0
- package/dist/spaces/viewer.d.ts +51 -0
- package/dist/spaces/viewer.d.ts.map +1 -0
- package/dist/spaces/viewer.js +167 -0
- package/dist/spaces/visibility.d.ts +57 -0
- package/dist/spaces/visibility.d.ts.map +1 -0
- package/dist/spaces/visibility.js +81 -0
- package/dist/templates/feed.tpl +18 -0
- package/dist/templates/hook.tpl +5 -0
- package/dist/templates/label.tpl +15 -0
- package/dist/templates/og.tpl +17 -0
- package/dist/templates/seed.tpl +11 -0
- package/dist/templates/setup.tpl +5 -0
- package/dist/templates/test-feed.tpl +19 -0
- package/dist/templates/test-xrpc.tpl +19 -0
- package/dist/templates/xrpc.tpl +53 -0
- package/dist/test.d.ts +3 -1
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +60 -36
- package/dist/views.js +1 -1
- package/dist/vite-plugin.d.ts +1 -1
- package/dist/vite-plugin.d.ts.map +1 -1
- package/dist/vite-plugin.js +254 -66
- package/dist/xrpc.d.ts +143 -12
- package/dist/xrpc.d.ts.map +1 -1
- package/dist/xrpc.js +282 -55
- package/package.json +29 -9
- package/public/admin-auth.js +271 -306
- package/public/admin.html +652 -61
- package/dist/db.d.ts +0 -135
- package/dist/db.d.ts.map +0 -1
- package/dist/db.js +0 -1365
- package/dist/fts.d.ts.map +0 -1
- package/dist/oauth/hooks.d.ts +0 -10
- package/dist/oauth/hooks.d.ts.map +0 -1
- package/dist/oauth/hooks.js +0 -40
- package/dist/schema.d.ts +0 -51
- package/dist/schema.d.ts.map +0 -1
- package/dist/test-browser.d.ts +0 -14
- package/dist/test-browser.d.ts.map +0 -1
- package/dist/test-browser.js +0 -26
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite FTS5-based search port with incremental updates.
|
|
3
|
+
*
|
|
4
|
+
* Uses external content FTS5 tables (content=shadowTable) so the FTS index
|
|
5
|
+
* references the shadow data table. Updates happen incrementally per-record
|
|
6
|
+
* instead of dropping and rebuilding the entire index.
|
|
7
|
+
*/
|
|
8
|
+
/** Quote an identifier. Lexicon property names are SQL-agnostic (`group`, `order`, `from` are all legal), so every column is quoted. */
|
|
9
|
+
const q = (name) => `"${name.replace(/"/g, '""')}"`;
|
|
10
|
+
export class SQLiteSearchPort {
|
|
11
|
+
port;
|
|
12
|
+
constructor(port) {
|
|
13
|
+
this.port = port;
|
|
14
|
+
}
|
|
15
|
+
async indexExists(shadowTable) {
|
|
16
|
+
const rows = await this.port.query(`SELECT 1 FROM sqlite_master WHERE type='table' AND name IN ($1, $2)`, [
|
|
17
|
+
shadowTable,
|
|
18
|
+
`${shadowTable}_fts`,
|
|
19
|
+
]);
|
|
20
|
+
return rows.length >= 2;
|
|
21
|
+
}
|
|
22
|
+
async buildIndex(shadowTable, sourceQuery, searchColumns) {
|
|
23
|
+
await this.port.execute(`DROP TABLE IF EXISTS ${shadowTable}_fts`, []);
|
|
24
|
+
await this.port.execute(`DROP TABLE IF EXISTS ${shadowTable}`, []);
|
|
25
|
+
// Create shadow data table from source query
|
|
26
|
+
await this.port.execute(`CREATE TABLE ${shadowTable} AS ${sourceQuery}`, []);
|
|
27
|
+
await this.port.execute(`CREATE UNIQUE INDEX IF NOT EXISTS ${shadowTable}_uri ON ${shadowTable}(uri)`, []);
|
|
28
|
+
// Create FTS5 virtual table with external content pointing to shadow table
|
|
29
|
+
const colList = searchColumns.map(q).join(', ');
|
|
30
|
+
await this.port.execute(`CREATE VIRTUAL TABLE ${shadowTable}_fts USING fts5(uri UNINDEXED, ${colList}, content=${shadowTable}, content_rowid=rowid, tokenize='porter unicode61 remove_diacritics 2')`, []);
|
|
31
|
+
// Populate FTS from shadow table
|
|
32
|
+
const selectCols = ['uri', ...searchColumns].map((c) => `COALESCE(CAST(${q(c)} AS TEXT), '')`);
|
|
33
|
+
await this.port.execute(`INSERT INTO ${shadowTable}_fts (uri, ${colList}) SELECT ${selectCols.join(', ')} FROM ${shadowTable}`, []);
|
|
34
|
+
}
|
|
35
|
+
async updateIndex(shadowTable, uri, row, searchColumns) {
|
|
36
|
+
const colList = searchColumns.map(q).join(', ');
|
|
37
|
+
// Remove old FTS entry if record already indexed
|
|
38
|
+
await this._deleteFromFts(shadowTable, uri, searchColumns);
|
|
39
|
+
// Upsert shadow table
|
|
40
|
+
const placeholders = searchColumns.map((_, i) => `$${i + 2}`);
|
|
41
|
+
const setClauses = searchColumns.map((c, i) => `${q(c)} = $${i + 2}`);
|
|
42
|
+
const values = [uri, ...searchColumns.map((c) => row[c] ?? null)];
|
|
43
|
+
await this.port.execute(`INSERT INTO ${shadowTable} (uri, ${colList}) VALUES ($1, ${placeholders.join(', ')}) ON CONFLICT(uri) DO UPDATE SET ${setClauses.join(', ')}`, values);
|
|
44
|
+
// Read back rowid and insert new FTS entry
|
|
45
|
+
const rows = await this.port.query(`SELECT rowid FROM ${shadowTable} WHERE uri = $1`, [uri]);
|
|
46
|
+
if (rows.length > 0) {
|
|
47
|
+
const rowid = rows[0].rowid;
|
|
48
|
+
const ftsPlaceholders = searchColumns.map((_, i) => `$${i + 3}`);
|
|
49
|
+
await this.port.execute(`INSERT INTO ${shadowTable}_fts(rowid, uri, ${colList}) VALUES($1, $2, ${ftsPlaceholders.join(', ')})`, [rowid, uri, ...searchColumns.map((c) => row[c] ?? '')]);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async deleteFromIndex(shadowTable, uri, searchColumns) {
|
|
53
|
+
await this._deleteFromFts(shadowTable, uri, searchColumns);
|
|
54
|
+
await this.port.execute(`DELETE FROM ${shadowTable} WHERE uri = $1`, [uri]);
|
|
55
|
+
}
|
|
56
|
+
async _deleteFromFts(shadowTable, uri, searchColumns) {
|
|
57
|
+
const colList = searchColumns.map(q).join(', ');
|
|
58
|
+
const rows = await this.port.query(`SELECT rowid, uri, ${colList} FROM ${shadowTable} WHERE uri = $1`, [uri]);
|
|
59
|
+
if (rows.length === 0)
|
|
60
|
+
return;
|
|
61
|
+
const old = rows[0];
|
|
62
|
+
const placeholders = searchColumns.map((_, i) => `$${i + 3}`);
|
|
63
|
+
await this.port.execute(`INSERT INTO ${shadowTable}_fts(${shadowTable}_fts, rowid, uri, ${colList}) VALUES('delete', $1, $2, ${placeholders.join(', ')})`, [old.rowid, uri, ...searchColumns.map((c) => old[c] ?? '')]);
|
|
64
|
+
}
|
|
65
|
+
async search(shadowTable, query, _searchColumns, limit, offset) {
|
|
66
|
+
const escaped = query.replace(/['"*(){}[\]^~\\:.]/g, ' ').trim();
|
|
67
|
+
if (!escaped)
|
|
68
|
+
return [];
|
|
69
|
+
const sql = `SELECT uri, -bm25(${shadowTable}_fts) AS score
|
|
70
|
+
FROM ${shadowTable}_fts
|
|
71
|
+
WHERE ${shadowTable}_fts MATCH $1
|
|
72
|
+
ORDER BY score DESC
|
|
73
|
+
LIMIT $2 OFFSET $3`;
|
|
74
|
+
return this.port.query(sql, [escaped, limit, offset]);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { DatabasePort, BulkInserter, Dialect } from '../ports.ts';
|
|
2
|
+
export declare class SQLiteAdapter implements DatabasePort {
|
|
3
|
+
dialect: Dialect;
|
|
4
|
+
private db;
|
|
5
|
+
open(path: string): Promise<void>;
|
|
6
|
+
close(): void;
|
|
7
|
+
query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T[]>;
|
|
8
|
+
execute(sql: string, params?: unknown[]): Promise<void>;
|
|
9
|
+
executeMultiple(sql: string): Promise<void>;
|
|
10
|
+
beginTransaction(): Promise<void>;
|
|
11
|
+
commit(): Promise<void>;
|
|
12
|
+
rollback(): Promise<void>;
|
|
13
|
+
createBulkInserter(table: string, columns: string[], options?: {
|
|
14
|
+
onConflict?: 'ignore' | 'replace';
|
|
15
|
+
batchSize?: number;
|
|
16
|
+
}): Promise<BulkInserter>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../../src/database/adapters/sqlite.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAqBtE,qBAAa,aAAc,YAAW,YAAY;IAChD,OAAO,EAAE,OAAO,CAAW;IAE3B,OAAO,CAAC,EAAE,CAAoB;IAExB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvC,KAAK,IAAI,IAAI;IAMP,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAMrF,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3D,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIjC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAIvB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzB,kBAAkB,CACtB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAClE,OAAO,CAAC,YAAY,CAAC;CAmCzB"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
/**
|
|
3
|
+
* Translate DuckDB-style `$1, $2` placeholders to SQLite `?` placeholders.
|
|
4
|
+
* Handles repeated references to the same `$N` by duplicating the param value.
|
|
5
|
+
* Returns the translated SQL and expanded params array.
|
|
6
|
+
*/
|
|
7
|
+
function translateParams(sql, params) {
|
|
8
|
+
if (params.length === 0)
|
|
9
|
+
return { sql, params };
|
|
10
|
+
const expandedParams = [];
|
|
11
|
+
const translated = sql.replace(/\$(\d+)/g, (_match, numStr) => {
|
|
12
|
+
const idx = parseInt(numStr) - 1; // $1 → index 0
|
|
13
|
+
const val = params[idx];
|
|
14
|
+
expandedParams.push(typeof val === 'boolean' ? (val ? 1 : 0) : val);
|
|
15
|
+
return '?';
|
|
16
|
+
});
|
|
17
|
+
return { sql: translated, params: expandedParams };
|
|
18
|
+
}
|
|
19
|
+
export class SQLiteAdapter {
|
|
20
|
+
dialect = 'sqlite';
|
|
21
|
+
db;
|
|
22
|
+
async open(path) {
|
|
23
|
+
this.db = new Database(path === ':memory:' ? ':memory:' : path);
|
|
24
|
+
this.db.pragma('journal_mode = WAL');
|
|
25
|
+
this.db.pragma('synchronous = NORMAL');
|
|
26
|
+
this.db.pragma('foreign_keys = ON');
|
|
27
|
+
}
|
|
28
|
+
close() {
|
|
29
|
+
try {
|
|
30
|
+
this.db?.close();
|
|
31
|
+
}
|
|
32
|
+
catch { }
|
|
33
|
+
}
|
|
34
|
+
async query(sql, params = []) {
|
|
35
|
+
const t = translateParams(sql, params);
|
|
36
|
+
const stmt = this.db.prepare(t.sql);
|
|
37
|
+
return stmt.all(...t.params);
|
|
38
|
+
}
|
|
39
|
+
async execute(sql, params = []) {
|
|
40
|
+
const t = translateParams(sql, params);
|
|
41
|
+
const stmt = this.db.prepare(t.sql);
|
|
42
|
+
stmt.run(...t.params);
|
|
43
|
+
}
|
|
44
|
+
async executeMultiple(sql) {
|
|
45
|
+
this.db.exec(sql);
|
|
46
|
+
}
|
|
47
|
+
async beginTransaction() {
|
|
48
|
+
this.db.exec('BEGIN');
|
|
49
|
+
}
|
|
50
|
+
async commit() {
|
|
51
|
+
this.db.exec('COMMIT');
|
|
52
|
+
}
|
|
53
|
+
async rollback() {
|
|
54
|
+
this.db.exec('ROLLBACK');
|
|
55
|
+
}
|
|
56
|
+
async createBulkInserter(table, columns, options) {
|
|
57
|
+
const placeholders = columns.map(() => '?').join(', ');
|
|
58
|
+
const conflict = options?.onConflict === 'ignore' ? ' OR IGNORE' : options?.onConflict === 'replace' ? ' OR REPLACE' : '';
|
|
59
|
+
const sql = `INSERT${conflict} INTO ${table} (${columns.join(', ')}) VALUES (${placeholders})`;
|
|
60
|
+
const stmt = this.db.prepare(sql);
|
|
61
|
+
const buffer = [];
|
|
62
|
+
const batchSize = options?.batchSize ?? 5000;
|
|
63
|
+
const flushBuffer = this.db.transaction(() => {
|
|
64
|
+
for (const row of buffer) {
|
|
65
|
+
stmt.run(...row);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
const flush = () => {
|
|
69
|
+
if (buffer.length > 0) {
|
|
70
|
+
flushBuffer();
|
|
71
|
+
buffer.length = 0;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
return {
|
|
75
|
+
append(values) {
|
|
76
|
+
buffer.push(values);
|
|
77
|
+
if (buffer.length >= batchSize)
|
|
78
|
+
flush();
|
|
79
|
+
},
|
|
80
|
+
async flush() {
|
|
81
|
+
flush();
|
|
82
|
+
},
|
|
83
|
+
async close() {
|
|
84
|
+
flush();
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import { type TableSchema } from './schema.ts';
|
|
2
|
+
import type { Row } from '../lex-types.ts';
|
|
3
|
+
import type { DatabasePort } from './ports.ts';
|
|
4
|
+
import { type SqlDialect } from './dialect.ts';
|
|
5
|
+
export declare function getDatabasePort(): DatabasePort;
|
|
6
|
+
export declare function getSqlDialect(): SqlDialect;
|
|
7
|
+
export declare function closeDatabase(): void;
|
|
8
|
+
export declare function runBatch(operations: Array<{
|
|
9
|
+
sql: string;
|
|
10
|
+
params: unknown[];
|
|
11
|
+
}>): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Open the database and leave its schema correct, whether it is new or not.
|
|
14
|
+
*
|
|
15
|
+
* The order is the point. An index names a column, so it cannot be built until
|
|
16
|
+
* the column is there, and on an existing database the column only arrives when
|
|
17
|
+
* `migrateSchema` runs — `CREATE TABLE IF NOT EXISTS` sees a table already and
|
|
18
|
+
* adds nothing. So: create the tables, reconcile the columns against the
|
|
19
|
+
* lexicons, then build the indexes.
|
|
20
|
+
*
|
|
21
|
+
* `indexStatements` may be left out, and callers that build from nothing do:
|
|
22
|
+
* a combined script passed as `ddlStatements` is valid on an empty database,
|
|
23
|
+
* because there every column is created with its table.
|
|
24
|
+
*/
|
|
25
|
+
export declare function initDatabase(adapter: DatabasePort, dbPath: string, tableSchemas: TableSchema[], ddlStatements: string[], indexStatements?: string[]): Promise<MigrationChange[]>;
|
|
26
|
+
interface MigrationChange {
|
|
27
|
+
table: string;
|
|
28
|
+
action: 'add' | 'drop' | 'retype';
|
|
29
|
+
column: string;
|
|
30
|
+
type?: string;
|
|
31
|
+
}
|
|
32
|
+
export declare function migrateSchema(tableSchemas: TableSchema[]): Promise<MigrationChange[]>;
|
|
33
|
+
export declare function getCursor(key: string): Promise<string | null>;
|
|
34
|
+
export declare function setCursor(key: string, value: string): Promise<void>;
|
|
35
|
+
export declare function getRepoStatus(did: string): Promise<string | null>;
|
|
36
|
+
export declare function setRepoStatus(did: string, status: string, rev?: string, opts?: {
|
|
37
|
+
retryCount?: number;
|
|
38
|
+
retryAfter?: number;
|
|
39
|
+
handle?: string | null;
|
|
40
|
+
}): Promise<void>;
|
|
41
|
+
/** Update the handle for a DID if it exists in _repos. */
|
|
42
|
+
export declare function updateRepoHandle(did: string, handle: string): Promise<void>;
|
|
43
|
+
export declare function getRepoRev(did: string): Promise<string | null>;
|
|
44
|
+
export declare function getRepoRetryInfo(did: string): Promise<{
|
|
45
|
+
retryCount: number;
|
|
46
|
+
retryAfter: number;
|
|
47
|
+
} | null>;
|
|
48
|
+
export declare function listRetryEligibleRepos(maxRetries: number): Promise<string[]>;
|
|
49
|
+
export declare function listPendingRepos(): Promise<string[]>;
|
|
50
|
+
export declare function listActiveRepoDids(): Promise<string[]>;
|
|
51
|
+
/**
|
|
52
|
+
* Repo statuses whose records no read serves: taken down by an admin here, or
|
|
53
|
+
* gone quiet on the network — deactivated (or suspended, or taken down by its
|
|
54
|
+
* host) and deleted. A SQL list, for `status NOT IN ...`.
|
|
55
|
+
*/
|
|
56
|
+
export declare const HIDDEN_REPO_STATUSES = "('takendown', 'deactivated', 'deleted')";
|
|
57
|
+
/**
|
|
58
|
+
* Remove every record an account holds in the index, public and in spaces:
|
|
59
|
+
* what an account deleted on the network leaves behind. Each goes the way
|
|
60
|
+
* {@link deleteRecord} takes one — out of the search index, its child and
|
|
61
|
+
* union rows, then the row itself.
|
|
62
|
+
*/
|
|
63
|
+
export declare function purgeRepoRecords(did: string): Promise<number>;
|
|
64
|
+
export declare function removeRepo(did: string): Promise<void>;
|
|
65
|
+
export declare function getRepoHandle(did: string): Promise<string | null>;
|
|
66
|
+
export declare function listAllRepoStatuses(): Promise<Array<{
|
|
67
|
+
did: string;
|
|
68
|
+
status: string;
|
|
69
|
+
}>>;
|
|
70
|
+
export declare function listReposPaginated(opts?: {
|
|
71
|
+
limit?: number;
|
|
72
|
+
offset?: number;
|
|
73
|
+
status?: string;
|
|
74
|
+
q?: string;
|
|
75
|
+
}): Promise<{
|
|
76
|
+
repos: any[];
|
|
77
|
+
total: number;
|
|
78
|
+
}>;
|
|
79
|
+
export declare function getCollectionCounts(): Promise<Record<string, number>>;
|
|
80
|
+
export declare function getRepoStatusCounts(): Promise<Record<string, number>>;
|
|
81
|
+
export declare function getDatabaseSize(): Promise<Record<string, string>>;
|
|
82
|
+
export declare function getLabelCount(val: string): Promise<number>;
|
|
83
|
+
export declare function deleteLabels(val: string): Promise<number>;
|
|
84
|
+
export declare function getRecentRecords(collection: string, limit: number): Promise<any[]>;
|
|
85
|
+
export declare function getSchemaDump(): Promise<string>;
|
|
86
|
+
export declare function buildInsertOp(collection: string, uri: string, cid: string, authorDid: string, record: Record<string, any>): {
|
|
87
|
+
sql: string;
|
|
88
|
+
params: any[];
|
|
89
|
+
};
|
|
90
|
+
export declare function insertRecord(collection: string, uri: string, cid: string, authorDid: string, record: Record<string, any>): Promise<void>;
|
|
91
|
+
export declare function deleteRecord(collection: string, uri: string): Promise<void>;
|
|
92
|
+
/**
|
|
93
|
+
* Remove every row a writer holds in one space.
|
|
94
|
+
*
|
|
95
|
+
* Scoped by `(space, did)` rather than by DID alone: the same account can hold
|
|
96
|
+
* public repo records in the same collections, and a full re-read of one space
|
|
97
|
+
* must not take those with it. Child and union rows are cleared by parent URI
|
|
98
|
+
* for the same reason — `parent_did` does not say which space a row came from.
|
|
99
|
+
*/
|
|
100
|
+
export declare function purgeSpaceRecords(space: string, did: string, collections: Iterable<string>): Promise<void>;
|
|
101
|
+
/** Every writer holding rows for a space, as the index currently has it. */
|
|
102
|
+
export declare function listSpaceRecordDids(space: string, collections: Iterable<string>): Promise<string[]>;
|
|
103
|
+
export declare function insertLabels(labels: Array<{
|
|
104
|
+
src: string;
|
|
105
|
+
uri: string;
|
|
106
|
+
val: string;
|
|
107
|
+
neg?: boolean;
|
|
108
|
+
cts?: string;
|
|
109
|
+
exp?: string;
|
|
110
|
+
}>): Promise<void>;
|
|
111
|
+
export declare function queryLabelsForUris(uris: string[]): Promise<Map<string, Array<{
|
|
112
|
+
src: string;
|
|
113
|
+
uri: string;
|
|
114
|
+
val: string;
|
|
115
|
+
neg: boolean;
|
|
116
|
+
cts: string;
|
|
117
|
+
exp: string | null;
|
|
118
|
+
}>>>;
|
|
119
|
+
export interface BulkRecord {
|
|
120
|
+
collection: string;
|
|
121
|
+
uri: string;
|
|
122
|
+
cid: string;
|
|
123
|
+
did: string;
|
|
124
|
+
record: Record<string, any>;
|
|
125
|
+
}
|
|
126
|
+
export declare function bulkInsertRecords(records: BulkRecord[]): Promise<number>;
|
|
127
|
+
interface QueryOpts {
|
|
128
|
+
limit?: number;
|
|
129
|
+
cursor?: string;
|
|
130
|
+
filters?: Record<string, string>;
|
|
131
|
+
sort?: string;
|
|
132
|
+
order?: 'asc' | 'desc';
|
|
133
|
+
}
|
|
134
|
+
export declare function queryRecords(collection: string, opts?: QueryOpts): Promise<{
|
|
135
|
+
records: any[];
|
|
136
|
+
cursor?: string;
|
|
137
|
+
}>;
|
|
138
|
+
export declare function getRecordByUri(uri: string): Promise<any | null>;
|
|
139
|
+
export declare function getRecordsByUris(collection: string, uris: string[]): Promise<any[]>;
|
|
140
|
+
/** Fetch records by URIs and return as a shaped Map keyed by URI. */
|
|
141
|
+
export declare function getRecordsMap<R = unknown>(collection: string, uris: string[]): Promise<Map<string, Row<R>>>;
|
|
142
|
+
/**
|
|
143
|
+
* Multi-phase search across any collection's records.
|
|
144
|
+
*
|
|
145
|
+
* 1. **BM25** — Full-text search via DuckDB FTS. Multi-word queries use conjunctive
|
|
146
|
+
* mode (ALL terms required) to avoid spurious single-token matches.
|
|
147
|
+
* 2. **Exact substring** — ILIKE scan on all TEXT/JSON columns catches phrase matches
|
|
148
|
+
* that BM25 missed or ranked low (e.g. "bad bunny"). Results are prepended to BM25.
|
|
149
|
+
* 3. **Recent rows** — ILIKE scan of rows ingested since the last FTS rebuild, so newly
|
|
150
|
+
* written records are immediately searchable before the index catches up.
|
|
151
|
+
* 4. **Fuzzy** — Jaro-Winkler similarity fallback for typo tolerance when earlier phases
|
|
152
|
+
* return fewer than `limit` results.
|
|
153
|
+
*
|
|
154
|
+
* All phases derive searchable columns generically from the collection schema — no
|
|
155
|
+
* column names are hardcoded.
|
|
156
|
+
*/
|
|
157
|
+
export declare function searchRecords(collection: string, query: string, opts?: {
|
|
158
|
+
limit?: number;
|
|
159
|
+
cursor?: string;
|
|
160
|
+
fuzzy?: boolean;
|
|
161
|
+
}): Promise<{
|
|
162
|
+
records: any[];
|
|
163
|
+
cursor?: string;
|
|
164
|
+
}>;
|
|
165
|
+
export declare function querySQL(sql: string, params?: unknown[]): Promise<unknown[]>;
|
|
166
|
+
export declare function runSQL(sql: string, params?: unknown[]): Promise<void>;
|
|
167
|
+
export declare function createBulkInserterSQL(table: string, columns: string[], options?: {
|
|
168
|
+
onConflict?: 'ignore' | 'replace';
|
|
169
|
+
batchSize?: number;
|
|
170
|
+
}): Promise<import('./ports.ts').BulkInserter>;
|
|
171
|
+
export declare function getSchema(collection: string): TableSchema | undefined;
|
|
172
|
+
/** Every registered collection's table schema. */
|
|
173
|
+
export declare function listSchemas(): TableSchema[];
|
|
174
|
+
export declare function countByField(collection: string, field: string, value: string): Promise<number>;
|
|
175
|
+
export declare function countByFieldBatch(collection: string, field: string, values: string[]): Promise<Map<string, number>>;
|
|
176
|
+
export declare function findByField(collection: string, field: string, value: string): Promise<any | null>;
|
|
177
|
+
export declare function findByFieldBatch(collection: string, field: string, values: string[]): Promise<Map<string, any[]>>;
|
|
178
|
+
export declare function lookupByFieldBatch(collection: string, field: string, values: string[]): Promise<Map<string, Row<unknown>>>;
|
|
179
|
+
export declare function findUriByFields(collection: string, conditions: {
|
|
180
|
+
field: string;
|
|
181
|
+
value: string;
|
|
182
|
+
}[]): Promise<string | null>;
|
|
183
|
+
export declare function normalizeValue(v: any): any;
|
|
184
|
+
export declare function getChildRows(childTableName: string, parentUris: string[]): Promise<Map<string, any[]>>;
|
|
185
|
+
export declare function reshapeRow(row: any, childData?: Map<string, Map<string, any[]>>, unionData?: Map<string, Map<string, Map<string, any[]>>>): Row<unknown> | null;
|
|
186
|
+
export declare function packCursor(sortVal: unknown, cid: string): string;
|
|
187
|
+
export declare function unpackCursor(cursor: string): {
|
|
188
|
+
primary: string;
|
|
189
|
+
cid: string;
|
|
190
|
+
} | null;
|
|
191
|
+
export declare function queryLabelsByDid(did: string): Promise<any[]>;
|
|
192
|
+
export declare function searchAccounts(query: string, limit?: number): Promise<any[]>;
|
|
193
|
+
export declare function getAccountRecordCount(did: string): Promise<number>;
|
|
194
|
+
export declare function getAllRecordUrisForDid(did: string): Promise<string[]>;
|
|
195
|
+
export declare function isTakendownDid(did: string): Promise<boolean>;
|
|
196
|
+
export declare function getPreferences(did: string): Promise<Record<string, any>>;
|
|
197
|
+
export declare function putPreference(did: string, key: string, value: any): Promise<void>;
|
|
198
|
+
export declare function resolveHandleToDid(handle: string): Promise<string | null>;
|
|
199
|
+
export declare function filterTakendownDids(dids: string[]): Promise<Set<string>>;
|
|
200
|
+
export declare function insertReport(report: {
|
|
201
|
+
subjectUri: string;
|
|
202
|
+
subjectDid: string;
|
|
203
|
+
label: string;
|
|
204
|
+
reason?: string;
|
|
205
|
+
reportedBy: string;
|
|
206
|
+
}): Promise<{
|
|
207
|
+
id: number;
|
|
208
|
+
}>;
|
|
209
|
+
export declare function queryReports(opts: {
|
|
210
|
+
status?: string;
|
|
211
|
+
label?: string;
|
|
212
|
+
limit?: number;
|
|
213
|
+
offset?: number;
|
|
214
|
+
}): Promise<{
|
|
215
|
+
reports: any[];
|
|
216
|
+
total: number;
|
|
217
|
+
}>;
|
|
218
|
+
export declare function resolveReport(id: number, action: 'resolved' | 'dismissed', resolvedBy: string): Promise<{
|
|
219
|
+
subjectUri: string;
|
|
220
|
+
label: string;
|
|
221
|
+
} | null>;
|
|
222
|
+
export declare function getOpenReportCount(): Promise<number>;
|
|
223
|
+
export interface ClassificationRow {
|
|
224
|
+
subjectUri: string;
|
|
225
|
+
subjectDid: string;
|
|
226
|
+
classifier: string;
|
|
227
|
+
signals: Record<string, {
|
|
228
|
+
score: number;
|
|
229
|
+
type: string;
|
|
230
|
+
choice?: string;
|
|
231
|
+
confidence?: number;
|
|
232
|
+
}>;
|
|
233
|
+
/** The state the model was shown, kept so a reviewer sees what it judged. */
|
|
234
|
+
state: Record<string, unknown>;
|
|
235
|
+
topSignal: string | null;
|
|
236
|
+
topScore: number;
|
|
237
|
+
fingerprint: string;
|
|
238
|
+
model: string | null;
|
|
239
|
+
}
|
|
240
|
+
/** Replace this subject's score for this classifier. */
|
|
241
|
+
export declare function upsertClassification(row: ClassificationRow): Promise<void>;
|
|
242
|
+
/**
|
|
243
|
+
* Fingerprints of everything already scored by this classifier, so a rescan can
|
|
244
|
+
* skip subjects whose state has not changed since.
|
|
245
|
+
*/
|
|
246
|
+
export declare function getClassificationFingerprints(classifier: string): Promise<Map<string, string>>;
|
|
247
|
+
/** The stored fingerprint for one subject under one classifier, if it was scored. */
|
|
248
|
+
export declare function getClassificationFingerprint(classifier: string, subjectUri: string): Promise<string | undefined>;
|
|
249
|
+
/** An open report already filed against this subject with this label, if any. */
|
|
250
|
+
export declare function findOpenReport(subjectUri: string, label: string): Promise<number | null>;
|
|
251
|
+
/**
|
|
252
|
+
* The review queue: one entry per subject, not per classifier.
|
|
253
|
+
*
|
|
254
|
+
* A subject scored by three classifiers has three rows in `_classifications`,
|
|
255
|
+
* and returning them separately puts the same account in the queue three times.
|
|
256
|
+
* The signals are merged instead, each tagged with the classifier it came from,
|
|
257
|
+
* so one card carries everything known about the account.
|
|
258
|
+
*/
|
|
259
|
+
export declare function queryClassifications(opts: {
|
|
260
|
+
classifier?: string;
|
|
261
|
+
signal?: string;
|
|
262
|
+
minScore?: number;
|
|
263
|
+
/** `pending` is what still needs a decision; see the state filter below. */
|
|
264
|
+
state?: 'all' | 'pending' | 'actioned';
|
|
265
|
+
limit?: number;
|
|
266
|
+
offset?: number;
|
|
267
|
+
}): Promise<{
|
|
268
|
+
rows: any[];
|
|
269
|
+
total: number;
|
|
270
|
+
}>;
|
|
271
|
+
/** Rollups for the review tab header. */
|
|
272
|
+
export declare function getClassificationStats(): Promise<{
|
|
273
|
+
total: number;
|
|
274
|
+
pending: number;
|
|
275
|
+
byClassifier: Record<string, number>;
|
|
276
|
+
lastScan: string | null;
|
|
277
|
+
}>;
|
|
278
|
+
/**
|
|
279
|
+
* A sample of one repo's records across the given collections, newest first.
|
|
280
|
+
*
|
|
281
|
+
* Feeds the review queue's inline context: judging an account means seeing what
|
|
282
|
+
* it actually posted, not just its DID.
|
|
283
|
+
*/
|
|
284
|
+
export declare function getRecordsByDid(did: string, collections: string[], perCollection?: number): Promise<Record<string, any[]>>;
|
|
285
|
+
/** Row counts per collection for one repo. */
|
|
286
|
+
export declare function getRecordCountsByDid(did: string, collections: string[]): Promise<Record<string, number>>;
|
|
287
|
+
/** Open report ids filed against a subject, whatever the label. */
|
|
288
|
+
export declare function findOpenReportsForSubject(subjectUri: string): Promise<number[]>;
|
|
289
|
+
export {};
|
|
290
|
+
//# sourceMappingURL=db.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/database/db.ts"],"names":[],"mappings":"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"}
|