@hatk/hatk 0.0.1-alpha.95 → 0.0.1-alpha.97

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.
@@ -9,7 +9,20 @@ export declare function runBatch(operations: Array<{
9
9
  sql: string;
10
10
  params: unknown[];
11
11
  }>): Promise<void>;
12
- export declare function initDatabase(adapter: DatabasePort, dbPath: string, tableSchemas: TableSchema[], ddlStatements: string[]): 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[]>;
13
26
  interface MigrationChange {
14
27
  table: string;
15
28
  action: 'add' | 'drop' | 'retype';
@@ -192,5 +205,69 @@ export declare function resolveReport(id: number, action: 'resolved' | 'dismisse
192
205
  label: string;
193
206
  } | null>;
194
207
  export declare function getOpenReportCount(): Promise<number>;
208
+ export interface ClassificationRow {
209
+ subjectUri: string;
210
+ subjectDid: string;
211
+ classifier: string;
212
+ signals: Record<string, {
213
+ score: number;
214
+ type: string;
215
+ choice?: string;
216
+ confidence?: number;
217
+ }>;
218
+ /** The state the model was shown, kept so a reviewer sees what it judged. */
219
+ state: Record<string, unknown>;
220
+ topSignal: string | null;
221
+ topScore: number;
222
+ fingerprint: string;
223
+ model: string | null;
224
+ }
225
+ /** Replace this subject's score for this classifier. */
226
+ export declare function upsertClassification(row: ClassificationRow): Promise<void>;
227
+ /**
228
+ * Fingerprints of everything already scored by this classifier, so a rescan can
229
+ * skip subjects whose state has not changed since.
230
+ */
231
+ export declare function getClassificationFingerprints(classifier: string): Promise<Map<string, string>>;
232
+ /** An open report already filed against this subject with this label, if any. */
233
+ export declare function findOpenReport(subjectUri: string, label: string): Promise<number | null>;
234
+ /**
235
+ * The review queue: one entry per subject, not per classifier.
236
+ *
237
+ * A subject scored by three classifiers has three rows in `_classifications`,
238
+ * and returning them separately puts the same account in the queue three times.
239
+ * The signals are merged instead, each tagged with the classifier it came from,
240
+ * so one card carries everything known about the account.
241
+ */
242
+ export declare function queryClassifications(opts: {
243
+ classifier?: string;
244
+ signal?: string;
245
+ minScore?: number;
246
+ /** `pending` is what still needs a decision; see the state filter below. */
247
+ state?: 'all' | 'pending' | 'actioned';
248
+ limit?: number;
249
+ offset?: number;
250
+ }): Promise<{
251
+ rows: any[];
252
+ total: number;
253
+ }>;
254
+ /** Rollups for the review tab header. */
255
+ export declare function getClassificationStats(): Promise<{
256
+ total: number;
257
+ pending: number;
258
+ byClassifier: Record<string, number>;
259
+ lastScan: string | null;
260
+ }>;
261
+ /**
262
+ * A sample of one repo's records across the given collections, newest first.
263
+ *
264
+ * Feeds the review queue's inline context: judging an account means seeing what
265
+ * it actually posted, not just its DID.
266
+ */
267
+ export declare function getRecordsByDid(did: string, collections: string[], perCollection?: number): Promise<Record<string, any[]>>;
268
+ /** Row counts per collection for one repo. */
269
+ export declare function getRecordCountsByDid(did: string, collections: string[]): Promise<Record<string, number>>;
270
+ /** Open report ids filed against a subject, whatever the label. */
271
+ export declare function findOpenReportsForSubject(subjectUri: string): Promise<number[]>;
195
272
  export {};
196
273
  //# sourceMappingURL=db.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/database/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAkB,MAAM,aAAa,CAAA;AAC9D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAA;AAI1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC9C,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,cAAc,CAAA;AAQ1D,wBAAgB,eAAe,IAAI,YAAY,CAE9C;AACD,wBAAgB,aAAa,IAAI,UAAU,CAE1C;AAED,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAMD,wBAAsB,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAcnG;AAMD,wBAAsB,YAAY,CAChC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,WAAW,EAAE,EAC3B,aAAa,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,IAAI,CAAC,CA8Kf;AAED,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAA;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAoED,wBAAsB,aAAa,CAAC,YAAY,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CA8F3F;AAuDD,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGnE;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzE;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGvE;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,GAAG,CAAC,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC1E,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED,0DAA0D;AAC1D,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjF;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGpE;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAO9G;AAED,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAOlF;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAG1D;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAG5D;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3D;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGvE;AAED,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAE3F;AAED,wBAAsB,kBAAkB,CACtC,IAAI,GAAE;IACJ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,CAAC,CAAC,EAAE,MAAM,CAAA;CACN,GACL,OAAO,CAAC;IAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CA8B1C;AAED,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAmB3E;AAED,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAO3E;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAcvE;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKhE;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI/D;AAED,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CASxF;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAiCrD;AAED,wBAAgB,aAAa,CAC3B,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC1B;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,GAAG,EAAE,CAAA;CAAE,CAkChC;AAED,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC1B,OAAO,CAAC,IAAI,CAAC,CAqGf;AAWD,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBjF;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BhH;AAED,4EAA4E;AAC5E,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CASzG;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAClG,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CACR,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAAC,CAC7G,CAqBA;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAC5B;AASD,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAwO9E;AAuCD,UAAU,SAAS;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;CACvB;AAED,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE,SAAc,GACnB,OAAO,CAAC;IAAE,OAAO,EAAE,GAAG,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAoG9C;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAiCrE;AAED,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAsCzF;AAED,qEAAqE;AACrE,wBAAsB,aAAa,CAAC,CAAC,GAAG,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CASjH;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAC9D,OAAO,CAAC;IAAE,OAAO,EAAE,GAAG,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAmI9C;AAGD,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAEtF;AAED,wBAAsB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/E;AAED,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAClE,OAAO,CAAC,OAAO,YAAY,EAAE,YAAY,CAAC,CAE5C;AAED,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAErE;AAED,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CASpG;AAED,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAe9B;AAED,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CASvG;AAED,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CA8B7B;AAED,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CASpC;AAED,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,GAC7C,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWxB;AAKD,wBAAgB,cAAc,CAAC,CAAC,EAAE,GAAG,GAAG,GAAG,CAI1C;AAED,wBAAsB,YAAY,CAAC,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAc5G;AAiBD,wBAAgB,UAAU,CACxB,GAAG,EAAE,GAAG,EACR,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAC3C,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,GACvD,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,CAyHrB;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAGhE;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CASpF;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAIlE;AAED,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAKtF;AAED,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOxE;AAED,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAO3E;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGlE;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAW9E;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAOvF;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAI/E;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAQ9E;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE;IACzC,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;CACnB,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAO1B;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,GAAG,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CA8B7C;AAED,wBAAsB,aAAa,CACjC,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,UAAU,GAAG,WAAW,EAChC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAevD;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAK1D"}
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/database/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAkB,MAAM,aAAa,CAAA;AAC9D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAA;AAI1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC9C,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,cAAc,CAAA;AAQ1D,wBAAgB,eAAe,IAAI,YAAY,CAE9C;AACD,wBAAgB,aAAa,IAAI,UAAU,CAE1C;AAED,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAMD,wBAAsB,QAAQ,CAAC,UAAU,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAcnG;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,WAAW,EAAE,EAC3B,aAAa,EAAE,MAAM,EAAE,EACvB,eAAe,GAAE,MAAM,EAAO,GAC7B,OAAO,CAAC,eAAe,EAAE,CAAC,CAgO5B;AAED,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAA;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAoED,wBAAsB,aAAa,CAAC,YAAY,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CA8F3F;AAuDD,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGnE;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEzE;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGvE;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,GAAG,CAAC,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC1E,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED,0DAA0D;AAC1D,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjF;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGpE;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAO9G;AAED,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAOlF;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAG1D;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAG5D;AAED,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3D;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAGvE;AAED,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAE3F;AAED,wBAAsB,kBAAkB,CACtC,IAAI,GAAE;IACJ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,CAAC,CAAC,EAAE,MAAM,CAAA;CACN,GACL,OAAO,CAAC;IAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CA8B1C;AAED,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAmB3E;AAED,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAO3E;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAcvE;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKhE;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI/D;AAED,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CASxF;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAiCrD;AAED,wBAAgB,aAAa,CAC3B,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC1B;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,GAAG,EAAE,CAAA;CAAE,CAkChC;AAED,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC1B,OAAO,CAAC,IAAI,CAAC,CAqGf;AAWD,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBjF;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BhH;AAED,4EAA4E;AAC5E,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CASzG;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAClG,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CACR,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAAC,CAC7G,CAqBA;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAC5B;AASD,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAwO9E;AAuCD,UAAU,SAAS;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;CACvB;AAED,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,IAAI,GAAE,SAAc,GACnB,OAAO,CAAC;IAAE,OAAO,EAAE,GAAG,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAoG9C;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAiCrE;AAED,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAsCzF;AAED,qEAAqE;AACrE,wBAAsB,aAAa,CAAC,CAAC,GAAG,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CASjH;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,GAC9D,OAAO,CAAC;IAAE,OAAO,EAAE,GAAG,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAmI9C;AAGD,wBAAsB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAEtF;AAED,wBAAsB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/E;AAED,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAClE,OAAO,CAAC,OAAO,YAAY,EAAE,YAAY,CAAC,CAE5C;AAED,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAErE;AAED,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CASpG;AAED,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAe9B;AAED,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CASvG;AAED,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CA8B7B;AAED,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CASpC;AAED,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,GAC7C,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWxB;AAKD,wBAAgB,cAAc,CAAC,CAAC,EAAE,GAAG,GAAG,GAAG,CAI1C;AAED,wBAAsB,YAAY,CAAC,cAAc,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAc5G;AAiBD,wBAAgB,UAAU,CACxB,GAAG,EAAE,GAAG,EACR,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAC3C,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,GACvD,GAAG,CAAC,OAAO,CAAC,GAAG,IAAI,CAyHrB;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAGhE;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CASpF;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAIlE;AAED,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAKtF;AAED,wBAAsB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOxE;AAED,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAO3E;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGlE;AAED,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAW9E;AAED,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAOvF;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAI/E;AAED,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAQ9E;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE;IACzC,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;CACnB,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAO1B;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACvC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,GAAG,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CA8B7C;AAED,wBAAsB,aAAa,CACjC,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,UAAU,GAAG,WAAW,EAChC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAevD;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAK1D;AAID,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC9F,6EAA6E;IAC7E,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED,wDAAwD;AACxD,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBhF;AAED;;;GAGG;AACH,wBAAsB,6BAA6B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAMpG;AAED,iFAAiF;AACjF,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAM9F;AAED;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,UAAU,CAAA;IACtC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAsG1C;AAED,yCAAyC;AACzC,wBAAsB,sBAAsB,IAAI,OAAO,CAAC;IACtD,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACpC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB,CAAC,CA2BD;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EAAE,EACrB,aAAa,SAAI,GAChB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAYhC;AAED,8CAA8C;AAC9C,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAa9G;AAED,mEAAmE;AACnE,wBAAsB,yBAAyB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAKrF"}
@@ -40,7 +40,20 @@ export async function runBatch(operations) {
40
40
  async function all(sql, params = []) {
41
41
  return port.query(sql, params);
42
42
  }
43
- export async function initDatabase(adapter, dbPath, tableSchemas, ddlStatements) {
43
+ /**
44
+ * Open the database and leave its schema correct, whether it is new or not.
45
+ *
46
+ * The order is the point. An index names a column, so it cannot be built until
47
+ * the column is there, and on an existing database the column only arrives when
48
+ * `migrateSchema` runs — `CREATE TABLE IF NOT EXISTS` sees a table already and
49
+ * adds nothing. So: create the tables, reconcile the columns against the
50
+ * lexicons, then build the indexes.
51
+ *
52
+ * `indexStatements` may be left out, and callers that build from nothing do:
53
+ * a combined script passed as `ddlStatements` is valid on an empty database,
54
+ * because there every column is created with its table.
55
+ */
56
+ export async function initDatabase(adapter, dbPath, tableSchemas, ddlStatements, indexStatements = []) {
44
57
  port = adapter;
45
58
  dialect = getDialect(adapter.dialect);
46
59
  await port.open(dbPath);
@@ -175,6 +188,43 @@ export async function initDatabase(adapter, dbPath, tableSchemas, ddlStatements)
175
188
  }
176
189
  await run(`CREATE INDEX IF NOT EXISTS idx_reports_status ON _reports(status)`);
177
190
  await run(`CREATE INDEX IF NOT EXISTS idx_reports_subject_uri ON _reports(subject_uri)`);
191
+ // Classifier scores. One row per (subject, classifier); a rescan replaces it.
192
+ // `fingerprint` hashes the state that was scored, so an unchanged subject is
193
+ // skipped on the next scan instead of being paid for again.
194
+ if (dialect.supportsSequences) {
195
+ await run(`CREATE SEQUENCE IF NOT EXISTS _classifications_seq START 1`);
196
+ await run(`CREATE TABLE IF NOT EXISTS _classifications (
197
+ id INTEGER PRIMARY KEY DEFAULT nextval('_classifications_seq'),
198
+ subject_uri TEXT NOT NULL,
199
+ subject_did TEXT NOT NULL,
200
+ classifier TEXT NOT NULL,
201
+ signals ${dialect.jsonType} NOT NULL,
202
+ state ${dialect.jsonType},
203
+ top_signal TEXT,
204
+ top_score DOUBLE NOT NULL DEFAULT 0,
205
+ fingerprint TEXT NOT NULL,
206
+ model TEXT,
207
+ scanned_at ${dialect.timestampType} NOT NULL
208
+ )`);
209
+ }
210
+ else {
211
+ await run(`CREATE TABLE IF NOT EXISTS _classifications (
212
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
213
+ subject_uri TEXT NOT NULL,
214
+ subject_did TEXT NOT NULL,
215
+ classifier TEXT NOT NULL,
216
+ signals TEXT NOT NULL,
217
+ state TEXT,
218
+ top_signal TEXT,
219
+ top_score REAL NOT NULL DEFAULT 0,
220
+ fingerprint TEXT NOT NULL,
221
+ model TEXT,
222
+ scanned_at TEXT NOT NULL
223
+ )`);
224
+ }
225
+ await run(`CREATE UNIQUE INDEX IF NOT EXISTS idx_classifications_subject ON _classifications(subject_uri, classifier)`);
226
+ await run(`CREATE INDEX IF NOT EXISTS idx_classifications_score ON _classifications(top_score)`);
227
+ await run(`CREATE INDEX IF NOT EXISTS idx_classifications_did ON _classifications(subject_did)`);
178
228
  // Push notification tokens
179
229
  await run(`CREATE TABLE IF NOT EXISTS _push_tokens (
180
230
  did TEXT NOT NULL,
@@ -205,6 +255,14 @@ export async function initDatabase(adapter, dbPath, tableSchemas, ddlStatements)
205
255
  await run(`ALTER TABLE _oauth_requests ADD COLUMN pds_token_endpoint TEXT`);
206
256
  }
207
257
  catch { }
258
+ // Now the columns the indexes below name are all present, on a database of
259
+ // any age. A new collection's table was created above and needs nothing; an
260
+ // existing one gets whatever the lexicons have gained since it was written.
261
+ const changes = await migrateSchema(tableSchemas);
262
+ for (const ddl of indexStatements) {
263
+ await port.executeMultiple(ddl);
264
+ }
265
+ return changes;
208
266
  }
209
267
  /** Normalize SQL type names to handle dialect differences (e.g. VARCHAR → TEXT) */
210
268
  function normalizeType(type) {
@@ -1773,3 +1831,197 @@ export async function getOpenReportCount() {
1773
1831
  const rows = await all(`SELECT ${dialect.countAsInteger} as count FROM _reports WHERE status = 'open'`);
1774
1832
  return Number(rows[0]?.count || 0);
1775
1833
  }
1834
+ /** Replace this subject's score for this classifier. */
1835
+ export async function upsertClassification(row) {
1836
+ await run(`DELETE FROM _classifications WHERE subject_uri = $1 AND classifier = $2`, [
1837
+ row.subjectUri,
1838
+ row.classifier,
1839
+ ]);
1840
+ await run(`INSERT INTO _classifications
1841
+ (subject_uri, subject_did, classifier, signals, state, top_signal, top_score, fingerprint, model, scanned_at)
1842
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)`, [
1843
+ row.subjectUri,
1844
+ row.subjectDid,
1845
+ row.classifier,
1846
+ JSON.stringify(row.signals),
1847
+ JSON.stringify(row.state),
1848
+ row.topSignal,
1849
+ row.topScore,
1850
+ row.fingerprint,
1851
+ row.model,
1852
+ new Date().toISOString(),
1853
+ ]);
1854
+ }
1855
+ /**
1856
+ * Fingerprints of everything already scored by this classifier, so a rescan can
1857
+ * skip subjects whose state has not changed since.
1858
+ */
1859
+ export async function getClassificationFingerprints(classifier) {
1860
+ const rows = await all(`SELECT subject_uri, fingerprint FROM _classifications WHERE classifier = $1`, [classifier]);
1861
+ return new Map(rows.map((r) => [r.subject_uri, r.fingerprint]));
1862
+ }
1863
+ /** An open report already filed against this subject with this label, if any. */
1864
+ export async function findOpenReport(subjectUri, label) {
1865
+ const rows = await all(`SELECT id FROM _reports WHERE subject_uri = $1 AND label = $2 AND status = 'open' LIMIT 1`, [subjectUri, label]);
1866
+ return rows.length ? rows[0].id : null;
1867
+ }
1868
+ /**
1869
+ * The review queue: one entry per subject, not per classifier.
1870
+ *
1871
+ * A subject scored by three classifiers has three rows in `_classifications`,
1872
+ * and returning them separately puts the same account in the queue three times.
1873
+ * The signals are merged instead, each tagged with the classifier it came from,
1874
+ * so one card carries everything known about the account.
1875
+ */
1876
+ export async function queryClassifications(opts) {
1877
+ const conditions = [];
1878
+ const params = [];
1879
+ let idx = 1;
1880
+ if (opts.classifier) {
1881
+ conditions.push(`c.classifier = $${idx++}`);
1882
+ params.push(opts.classifier);
1883
+ }
1884
+ if (opts.signal) {
1885
+ conditions.push(`c.top_signal = $${idx++}`);
1886
+ params.push(opts.signal);
1887
+ }
1888
+ if (opts.minScore != null) {
1889
+ conditions.push(`c.top_score >= $${idx++}`);
1890
+ params.push(opts.minScore);
1891
+ }
1892
+ // Pending means a report is open against the subject: something crossed a
1893
+ // threshold and nobody has decided it. A high score on a question carrying no
1894
+ // threshold is context rather than queue — browsable under `all`.
1895
+ if (opts.state === 'pending') {
1896
+ conditions.push(`(rp.status IS NULL OR rp.status = 'active')`);
1897
+ conditions.push(`EXISTS (SELECT 1 FROM _reports x WHERE x.subject_uri = c.subject_uri AND x.status = 'open')`);
1898
+ }
1899
+ else if (opts.state === 'actioned') {
1900
+ conditions.push(`(rp.status = 'takendown'
1901
+ OR (EXISTS (SELECT 1 FROM _reports x WHERE x.subject_uri = c.subject_uri AND x.status <> 'open')
1902
+ AND NOT EXISTS (SELECT 1 FROM _reports x WHERE x.subject_uri = c.subject_uri AND x.status = 'open')))`);
1903
+ }
1904
+ const where = conditions.length ? `WHERE ${conditions.join(' AND ')}` : '';
1905
+ const from = `FROM _classifications c LEFT JOIN _repos rp ON c.subject_did = rp.did`;
1906
+ const limit = opts.limit ?? 50;
1907
+ const offset = opts.offset ?? 0;
1908
+ const countRows = await all(`SELECT ${dialect.countAsInteger} as count FROM (SELECT c.subject_uri ${from} ${where} GROUP BY c.subject_uri) g`, params);
1909
+ const page = await all(`SELECT c.subject_uri, c.subject_did, MAX(c.top_score) AS score
1910
+ ${from} ${where}
1911
+ GROUP BY c.subject_uri, c.subject_did
1912
+ ORDER BY score DESC LIMIT $${idx++} OFFSET $${idx++}`, [...params, limit, offset]);
1913
+ if (!page.length)
1914
+ return { rows: [], total: Number(countRows[0]?.count || 0) };
1915
+ const uris = page.map((p) => p.subject_uri);
1916
+ const placeholders = uris.map((_, i) => `$${i + 1}`).join(',');
1917
+ const detail = await all(`SELECT c.*, rp.handle, rp.status AS repo_status,
1918
+ (SELECT x.id FROM _reports x WHERE x.subject_uri = c.subject_uri AND x.status = 'open' LIMIT 1) AS report_id,
1919
+ (SELECT x.status FROM _reports x WHERE x.subject_uri = c.subject_uri ORDER BY x.created_at DESC LIMIT 1) AS report_status
1920
+ FROM _classifications c LEFT JOIN _repos rp ON c.subject_did = rp.did
1921
+ WHERE c.subject_uri IN (${placeholders})`, uris);
1922
+ const byUri = new Map();
1923
+ for (const row of detail) {
1924
+ for (const col of ['signals', 'state']) {
1925
+ if (typeof row[col] === 'string') {
1926
+ try {
1927
+ row[col] = JSON.parse(row[col]);
1928
+ }
1929
+ catch { }
1930
+ }
1931
+ }
1932
+ let entry = byUri.get(row.subject_uri);
1933
+ if (!entry) {
1934
+ entry = {
1935
+ subject_uri: row.subject_uri,
1936
+ subject_did: row.subject_did,
1937
+ handle: row.handle,
1938
+ repo_status: row.repo_status,
1939
+ report_id: row.report_id,
1940
+ report_status: row.report_status,
1941
+ classifiers: [],
1942
+ signals: {},
1943
+ state: {},
1944
+ top_signal: null,
1945
+ top_score: 0,
1946
+ scanned_at: row.scanned_at,
1947
+ };
1948
+ byUri.set(row.subject_uri, entry);
1949
+ }
1950
+ entry.classifiers.push(row.classifier);
1951
+ // Every classifier builds its own view of the subject; show the richest.
1952
+ if (Object.keys(row.state || {}).length > Object.keys(entry.state).length)
1953
+ entry.state = row.state;
1954
+ for (const [name, sig] of Object.entries(row.signals || {})) {
1955
+ entry.signals[name] = { ...sig, classifier: row.classifier };
1956
+ if (sig.score > entry.top_score) {
1957
+ entry.top_score = sig.score;
1958
+ entry.top_signal = name;
1959
+ }
1960
+ }
1961
+ }
1962
+ const rows = page.map((p) => byUri.get(p.subject_uri)).filter(Boolean);
1963
+ return { rows, total: Number(countRows[0]?.count || 0) };
1964
+ }
1965
+ /** Rollups for the review tab header. */
1966
+ export async function getClassificationStats() {
1967
+ const [totalRows, pendingRows, byRows, lastRows] = await Promise.all([
1968
+ all(`SELECT ${dialect.countAsInteger} as count FROM (SELECT subject_uri FROM _classifications GROUP BY subject_uri) g`),
1969
+ // Distinct subjects, not rows: the queue shows one card per account, so a
1970
+ // row count would overstate it by the number of classifiers.
1971
+ all(`SELECT ${dialect.countAsInteger} as count FROM (
1972
+ SELECT c.subject_uri FROM _classifications c
1973
+ WHERE EXISTS (SELECT 1 FROM _reports x WHERE x.subject_uri = c.subject_uri AND x.status = 'open')
1974
+ GROUP BY c.subject_uri
1975
+ ) g`),
1976
+ all(`SELECT classifier, ${dialect.countAsInteger} as count FROM _classifications GROUP BY classifier`),
1977
+ all(`SELECT scanned_at FROM _classifications ORDER BY scanned_at DESC LIMIT 1`),
1978
+ ]);
1979
+ const byClassifier = {};
1980
+ for (const r of byRows)
1981
+ byClassifier[r.classifier] = Number(r.count);
1982
+ return {
1983
+ total: Number(totalRows[0]?.count || 0),
1984
+ pending: Number(pendingRows[0]?.count || 0),
1985
+ byClassifier,
1986
+ lastScan: lastRows[0]?.scanned_at ?? null,
1987
+ };
1988
+ }
1989
+ /**
1990
+ * A sample of one repo's records across the given collections, newest first.
1991
+ *
1992
+ * Feeds the review queue's inline context: judging an account means seeing what
1993
+ * it actually posted, not just its DID.
1994
+ */
1995
+ export async function getRecordsByDid(did, collections, perCollection = 6) {
1996
+ const out = {};
1997
+ for (const collection of collections) {
1998
+ const schema = schemas.get(collection);
1999
+ if (!schema)
2000
+ continue;
2001
+ const rows = await all(`SELECT * FROM ${schema.tableName} WHERE did = $1 ORDER BY indexed_at DESC LIMIT $2`, [did, perCollection]);
2002
+ if (rows.length)
2003
+ out[collection] = rows.map((r) => reshapeRow(r)).filter(Boolean);
2004
+ }
2005
+ return out;
2006
+ }
2007
+ /** Row counts per collection for one repo. */
2008
+ export async function getRecordCountsByDid(did, collections) {
2009
+ const out = {};
2010
+ for (const collection of collections) {
2011
+ const schema = schemas.get(collection);
2012
+ if (!schema)
2013
+ continue;
2014
+ const rows = await all(`SELECT ${dialect.countAsInteger} as count FROM ${schema.tableName} WHERE did = $1`, [did]);
2015
+ const n = Number(rows[0]?.count || 0);
2016
+ if (n)
2017
+ out[collection] = n;
2018
+ }
2019
+ return out;
2020
+ }
2021
+ /** Open report ids filed against a subject, whatever the label. */
2022
+ export async function findOpenReportsForSubject(subjectUri) {
2023
+ const rows = await all(`SELECT id FROM _reports WHERE subject_uri = $1 AND status = 'open'`, [
2024
+ subjectUri,
2025
+ ]);
2026
+ return rows.map((r) => r.id);
2027
+ }
@@ -3,5 +3,5 @@ export type { SqlDialect } from './dialect.ts';
3
3
  export { getDialect, DUCKDB_DIALECT, SQLITE_DIALECT } from './dialect.ts';
4
4
  export { createAdapter } from './adapter-factory.ts';
5
5
  export { initDatabase, closeDatabase, querySQL, runSQL, insertRecord, deleteRecord, queryRecords, searchRecords, getRecordByUri, getCursor, setCursor, bulkInsertRecords, packCursor, unpackCursor, } from './db.ts';
6
- export { type TableSchema, type ColumnDef, type ChildTableSchema, loadLexicons, discoverCollections, buildSchemas, generateTableSchema, generateCreateTableSQL, toSnakeCase, getLexicon, getLexiconArray, getAllLexicons, storeLexicons, columnName, } from './schema.ts';
6
+ export { type TableSchema, type ColumnDef, type ChildTableSchema, loadLexicons, discoverCollections, buildSchemas, generateTableSchema, generateCreateTableSQL, generateSchemaDDL, type SchemaDDL, toSnakeCase, getLexicon, getLexiconArray, getAllLexicons, storeLexicons, columnName, } from './schema.ts';
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/database/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACjF,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAGpD,OAAO,EACL,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,cAAc,EACd,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,YAAY,GACb,MAAM,SAAS,CAAA;AAGhB,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,mBAAmB,EACnB,sBAAsB,EACtB,WAAW,EACX,UAAU,EACV,eAAe,EACf,cAAc,EACd,aAAa,EACb,UAAU,GACX,MAAM,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/database/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACjF,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAGpD,OAAO,EACL,YAAY,EACZ,aAAa,EACb,QAAQ,EACR,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,cAAc,EACd,SAAS,EACT,SAAS,EACT,iBAAiB,EACjB,UAAU,EACV,YAAY,GACb,MAAM,SAAS,CAAA;AAGhB,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,KAAK,SAAS,EACd,WAAW,EACX,UAAU,EACV,eAAe,EACf,cAAc,EACd,aAAa,EACb,UAAU,GACX,MAAM,aAAa,CAAA"}
@@ -3,4 +3,4 @@ export { createAdapter } from "./adapter-factory.js";
3
3
  // Re-export commonly used functions from db.ts
4
4
  export { initDatabase, closeDatabase, querySQL, runSQL, insertRecord, deleteRecord, queryRecords, searchRecords, getRecordByUri, getCursor, setCursor, bulkInsertRecords, packCursor, unpackCursor, } from "./db.js";
5
5
  // Re-export schema utilities
6
- export { loadLexicons, discoverCollections, buildSchemas, generateTableSchema, generateCreateTableSQL, toSnakeCase, getLexicon, getLexiconArray, getAllLexicons, storeLexicons, columnName, } from "./schema.js";
6
+ export { loadLexicons, discoverCollections, buildSchemas, generateTableSchema, generateCreateTableSQL, generateSchemaDDL, toSnakeCase, getLexicon, getLexiconArray, getAllLexicons, storeLexicons, columnName, } from "./schema.js";
@@ -52,6 +52,32 @@ export declare function getAllLexicons(): Array<{
52
52
  /** Get all stored lexicons as a flat array (for @bigmoves/lexicon validators) */
53
53
  export declare function getLexiconArray(): any[];
54
54
  export declare function generateTableSchema(nsid: string, lexicon: any, lexicons?: Map<string, any>, dialect?: SqlDialect): TableSchema;
55
+ /**
56
+ * The DDL for a schema, with the tables kept apart from their indexes.
57
+ *
58
+ * They have to be separable because they cannot always run together. An index
59
+ * names a column, and on a database that predates that column the index is the
60
+ * statement that fails — `CREATE TABLE IF NOT EXISTS` has already decided the
61
+ * table is fine as it stands, and the column only arrives when `migrateSchema`
62
+ * runs. So a boot against an existing database creates the tables, reconciles
63
+ * the columns, and only then builds the indexes.
64
+ */
65
+ export interface SchemaDDL {
66
+ /** `CREATE TABLE` for the collection and its child and union-branch tables. */
67
+ tables: string[];
68
+ /** `CREATE INDEX` for all of them, safe to run only once the columns exist. */
69
+ indexes: string[];
70
+ }
71
+ /** The DDL for a schema, split into the two passes {@link SchemaDDL} describes. */
72
+ export declare function generateSchemaDDL(schema: TableSchema, dialect?: SqlDialect): SchemaDDL;
73
+ /**
74
+ * Both passes as one script, in an order that is valid on a fresh database.
75
+ *
76
+ * What every caller that builds a database from nothing wants — a test, a
77
+ * fixture, the `hatk schema` dump. A boot that may meet an existing database
78
+ * wants {@link generateSchemaDDL} instead, so the migration can run between
79
+ * the two passes.
80
+ */
55
81
  export declare function generateCreateTableSQL(schema: TableSchema, dialect?: SqlDialect): string;
56
82
  /**
57
83
  * Build table schemas and DDL from lexicons and collections.
@@ -60,5 +86,6 @@ export declare function generateCreateTableSQL(schema: TableSchema, dialect?: Sq
60
86
  export declare function buildSchemas(lexicons: Map<string, any>, collections: string[], dialect?: SqlDialect): {
61
87
  schemas: TableSchema[];
62
88
  ddlStatements: string[];
89
+ indexStatements: string[];
63
90
  };
64
91
  //# sourceMappingURL=schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/database/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/database/schema.ts"],"names":[],"mappings":"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"}
@@ -337,8 +337,8 @@ export function generateTableSchema(nsid, lexicon, lexicons, dialect = DUCKDB_DI
337
337
  unions,
338
338
  };
339
339
  }
340
- // Generate CREATE TABLE SQL from a TableSchema
341
- export function generateCreateTableSQL(schema, dialect = DUCKDB_DIALECT) {
340
+ /** The DDL for a schema, split into the two passes {@link SchemaDDL} describes. */
341
+ export function generateSchemaDDL(schema, dialect = DUCKDB_DIALECT) {
342
342
  // `space` is the permissioned space a row came from, and NULL for everything
343
343
  // off the firehose. It is the only per-row visibility marker in the schema:
344
344
  // a space record is readable by whoever the space's authority admits, so no
@@ -368,22 +368,24 @@ export function generateCreateTableSQL(schema, dialect = DUCKDB_DIALECT) {
368
368
  for (const refCol of schema.refColumns) {
369
369
  indexes.push(`CREATE INDEX IF NOT EXISTS idx_${prefix}_${refCol} ON ${schema.tableName}(${q(refCol)});`);
370
370
  }
371
- // Child table DDL
372
- const childDDL = [];
371
+ // Child and union-branch tables, kept apart from their indexes for the same
372
+ // reason the top-level ones are.
373
+ const childTables = [];
374
+ const childIndexes = [];
373
375
  for (const child of schema.children) {
374
376
  const childLines = [' parent_uri TEXT NOT NULL', ' parent_did TEXT NOT NULL'];
375
377
  for (const col of child.columns) {
376
378
  const nullable = col.notNull ? ' NOT NULL' : '';
377
379
  childLines.push(` ${q(col.name)} ${col.sqlType}${nullable}`);
378
380
  }
379
- childDDL.push(`CREATE TABLE IF NOT EXISTS ${child.tableName} (\n${childLines.join(',\n')}\n);`);
381
+ childTables.push(`CREATE TABLE IF NOT EXISTS ${child.tableName} (\n${childLines.join(',\n')}\n);`);
380
382
  const childPrefix = `${prefix}__${toSnakeCase(child.fieldName)}`;
381
- childDDL.push(`CREATE INDEX IF NOT EXISTS idx_${childPrefix}_parent ON ${child.tableName}(parent_uri);`);
382
- childDDL.push(`CREATE INDEX IF NOT EXISTS idx_${childPrefix}_did ON ${child.tableName}(parent_did);`);
383
+ childIndexes.push(`CREATE INDEX IF NOT EXISTS idx_${childPrefix}_parent ON ${child.tableName}(parent_uri);`);
384
+ childIndexes.push(`CREATE INDEX IF NOT EXISTS idx_${childPrefix}_did ON ${child.tableName}(parent_did);`);
383
385
  for (const col of child.columns) {
384
386
  if (col.isJson || col.sqlType === 'BLOB')
385
387
  continue;
386
- childDDL.push(`CREATE INDEX IF NOT EXISTS idx_${childPrefix}_${col.name} ON ${child.tableName}(${q(col.name)});`);
388
+ childIndexes.push(`CREATE INDEX IF NOT EXISTS idx_${childPrefix}_${col.name} ON ${child.tableName}(${q(col.name)});`);
387
389
  }
388
390
  }
389
391
  // Union branch table DDL
@@ -394,18 +396,30 @@ export function generateCreateTableSQL(schema, dialect = DUCKDB_DIALECT) {
394
396
  const nullable = col.notNull ? ' NOT NULL' : '';
395
397
  branchLines.push(` ${q(col.name)} ${col.sqlType}${nullable}`);
396
398
  }
397
- childDDL.push(`CREATE TABLE IF NOT EXISTS ${branch.tableName} (\n${branchLines.join(',\n')}\n);`);
399
+ childTables.push(`CREATE TABLE IF NOT EXISTS ${branch.tableName} (\n${branchLines.join(',\n')}\n);`);
398
400
  const branchPrefix = branch.tableName.replace(/"/g, '').replace(/\./g, '_');
399
- childDDL.push(`CREATE INDEX IF NOT EXISTS idx_${branchPrefix}_parent ON ${branch.tableName}(parent_uri);`);
400
- childDDL.push(`CREATE INDEX IF NOT EXISTS idx_${branchPrefix}_did ON ${branch.tableName}(parent_did);`);
401
+ childIndexes.push(`CREATE INDEX IF NOT EXISTS idx_${branchPrefix}_parent ON ${branch.tableName}(parent_uri);`);
402
+ childIndexes.push(`CREATE INDEX IF NOT EXISTS idx_${branchPrefix}_did ON ${branch.tableName}(parent_did);`);
401
403
  for (const col of branch.columns) {
402
404
  if (col.isJson || col.sqlType === 'BLOB')
403
405
  continue;
404
- childDDL.push(`CREATE INDEX IF NOT EXISTS idx_${branchPrefix}_${col.name} ON ${branch.tableName}(${q(col.name)});`);
406
+ childIndexes.push(`CREATE INDEX IF NOT EXISTS idx_${branchPrefix}_${col.name} ON ${branch.tableName}(${q(col.name)});`);
405
407
  }
406
408
  }
407
409
  }
408
- return [createTable, ...indexes, ...childDDL].join('\n');
410
+ return { tables: [createTable, ...childTables], indexes: [...indexes, ...childIndexes] };
411
+ }
412
+ /**
413
+ * Both passes as one script, in an order that is valid on a fresh database.
414
+ *
415
+ * What every caller that builds a database from nothing wants — a test, a
416
+ * fixture, the `hatk schema` dump. A boot that may meet an existing database
417
+ * wants {@link generateSchemaDDL} instead, so the migration can run between
418
+ * the two passes.
419
+ */
420
+ export function generateCreateTableSQL(schema, dialect = DUCKDB_DIALECT) {
421
+ const { tables, indexes } = generateSchemaDDL(schema, dialect);
422
+ return [...tables, ...indexes].join('\n');
409
423
  }
410
424
  /**
411
425
  * Build table schemas and DDL from lexicons and collections.
@@ -414,27 +428,30 @@ export function generateCreateTableSQL(schema, dialect = DUCKDB_DIALECT) {
414
428
  export function buildSchemas(lexicons, collections, dialect = DUCKDB_DIALECT) {
415
429
  const schemas = [];
416
430
  const ddlStatements = [];
431
+ const indexStatements = [];
417
432
  for (const nsid of collections) {
418
433
  const lexicon = lexicons.get(nsid);
419
434
  if (!lexicon) {
420
- const genericDDL = `CREATE TABLE IF NOT EXISTS "${nsid}" (
435
+ const prefix = nsid.replace(/\./g, '_');
436
+ ddlStatements.push(`CREATE TABLE IF NOT EXISTS "${nsid}" (
421
437
  uri TEXT PRIMARY KEY,
422
438
  cid TEXT,
423
439
  did TEXT NOT NULL,
424
440
  space TEXT,
425
441
  indexed_at ${dialect.timestampType} NOT NULL,
426
442
  data ${dialect.jsonType}
427
- );
428
- CREATE INDEX IF NOT EXISTS idx_${nsid.replace(/\./g, '_')}_indexed ON "${nsid}"(indexed_at DESC);
429
- CREATE INDEX IF NOT EXISTS idx_${nsid.replace(/\./g, '_')}_author ON "${nsid}"(did);
430
- CREATE INDEX IF NOT EXISTS idx_${nsid.replace(/\./g, '_')}_space ON "${nsid}"(space);`;
443
+ );`);
444
+ indexStatements.push(`CREATE INDEX IF NOT EXISTS idx_${prefix}_indexed ON "${nsid}"(indexed_at DESC);
445
+ CREATE INDEX IF NOT EXISTS idx_${prefix}_author ON "${nsid}"(did);
446
+ CREATE INDEX IF NOT EXISTS idx_${prefix}_space ON "${nsid}"(space);`);
431
447
  schemas.push({ collection: nsid, tableName: `"${nsid}"`, columns: [], refColumns: [], children: [], unions: [] });
432
- ddlStatements.push(genericDDL);
433
448
  continue;
434
449
  }
435
450
  const schema = generateTableSchema(nsid, lexicon, lexicons, dialect);
436
451
  schemas.push(schema);
437
- ddlStatements.push(generateCreateTableSQL(schema, dialect));
452
+ const { tables, indexes } = generateSchemaDDL(schema, dialect);
453
+ ddlStatements.push(tables.join('\n'));
454
+ indexStatements.push(indexes.join('\n'));
438
455
  }
439
- return { schemas, ddlStatements };
456
+ return { schemas, ddlStatements, indexStatements };
440
457
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dev-entry.d.ts","sourceRoot":"","sources":["../src/dev-entry.ts"],"names":[],"mappings":"AAiIA,eAAO,MAAM,OAAO,yCAKlB,CAAA;AAEF,yEAAyE;AACzE,wBAAsB,YAAY,kBAEjC;AAED,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA"}
1
+ {"version":3,"file":"dev-entry.d.ts","sourceRoot":"","sources":["../src/dev-entry.ts"],"names":[],"mappings":"AAgIA,eAAO,MAAM,OAAO,yCAKlB,CAAA;AAEF,yEAAyE;AACzE,wBAAsB,YAAY,kBAEjC;AAED,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA"}
package/dist/dev-entry.js CHANGED
@@ -5,7 +5,7 @@
5
5
  import { loadConfig } from "./config.js";
6
6
  import { validatableLexicons, loadLexicons, storeLexicons, discoverCollections, buildSchemas, } from "./database/schema.js";
7
7
  import { discoverViews } from "./views.js";
8
- import { initDatabase, migrateSchema, getSchemaDump } from "./database/db.js";
8
+ import { initDatabase, getSchemaDump } from "./database/db.js";
9
9
  import { createAdapter } from "./database/adapter-factory.js";
10
10
  import { getDialect } from "./database/dialect.js";
11
11
  import { setSearchPort } from "./database/fts.js";
@@ -44,14 +44,13 @@ storeLexicons(lexicons);
44
44
  const collections = config.collections.length > 0 ? config.collections : discoverCollections(lexicons);
45
45
  discoverViews();
46
46
  const engineDialect = getDialect(config.databaseEngine);
47
- const { schemas, ddlStatements } = buildSchemas(lexicons, collections, engineDialect);
47
+ const { schemas, ddlStatements, indexStatements } = buildSchemas(lexicons, collections, engineDialect);
48
48
  if (config.database !== ':memory:') {
49
49
  mkdirSync(dirname(config.database), { recursive: true });
50
50
  }
51
51
  const { adapter, searchPort } = await createAdapter(config.databaseEngine);
52
52
  setSearchPort(searchPort);
53
- await initDatabase(adapter, config.database, schemas, ddlStatements);
54
- await migrateSchema(schemas);
53
+ await initDatabase(adapter, config.database, schemas, ddlStatements, indexStatements);
55
54
  // Write db/schema.sql
56
55
  try {
57
56
  const { mkdirSync, writeFileSync } = await import('node:fs');