bunqueue-dashboard 0.0.35 → 0.0.36

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.
Files changed (173) hide show
  1. package/README.md +18 -11
  2. package/agent/backup/processExecutor.ts +90 -0
  3. package/agent/backup/resultValidation.ts +85 -0
  4. package/agent/backup/routes.ts +160 -0
  5. package/agent/backup/runner.ts +91 -0
  6. package/agent/backup/standaloneWorker.ts +23 -0
  7. package/agent/backup/workerExecutor.ts +40 -0
  8. package/agent/backup/workerFactory.ts +21 -0
  9. package/agent/backup/workerProtocol.ts +10 -0
  10. package/agent/db/core.ts +141 -0
  11. package/agent/db/csvExport.ts +172 -0
  12. package/agent/db/exportTimeout.ts +190 -0
  13. package/agent/db/query.ts +82 -0
  14. package/agent/db/queryTimeout.ts +76 -0
  15. package/agent/db/schema.ts +79 -0
  16. package/agent/db/tables.ts +157 -0
  17. package/agent/db/types.ts +118 -0
  18. package/agent/db/workerFactory.ts +25 -0
  19. package/agent/db.ts +43 -1099
  20. package/agent/errorMessage.ts +9 -0
  21. package/agent/flow/routes.ts +250 -0
  22. package/agent/flow/service.ts +266 -0
  23. package/agent/flow/types.ts +34 -0
  24. package/agent/flow/validation.ts +230 -0
  25. package/agent/index.ts +5 -17
  26. package/agent/logger.ts +121 -17
  27. package/agent/managedTarget.ts +43 -0
  28. package/agent/manager/config.ts +84 -0
  29. package/agent/manager/logs.ts +83 -0
  30. package/agent/manager/process.ts +233 -0
  31. package/agent/manager/storage.ts +28 -0
  32. package/agent/manager/types.ts +38 -0
  33. package/agent/manager.ts +10 -490
  34. package/agent/queue/routes.ts +128 -0
  35. package/agent/queue/runtime.ts +119 -0
  36. package/agent/queue/types.ts +34 -0
  37. package/agent/queue/validation.ts +100 -0
  38. package/agent/server/controlRoutes.ts +153 -0
  39. package/agent/server/databaseRoutes.ts +165 -0
  40. package/agent/server/errors.ts +48 -0
  41. package/agent/server/handler.ts +146 -0
  42. package/agent/server/jsonBody.ts +109 -0
  43. package/agent/server/lifecycle.ts +72 -0
  44. package/agent/server/managedRuntime.ts +41 -0
  45. package/agent/server/policy.ts +60 -0
  46. package/agent/server/router.ts +150 -0
  47. package/agent/server/types.ts +39 -0
  48. package/agent/server/workflowReadRoutes.ts +80 -0
  49. package/agent/server.ts +16 -441
  50. package/agent/shutdown.ts +156 -0
  51. package/agent/workflow/codec.ts +78 -0
  52. package/agent/workflow/detail.ts +63 -0
  53. package/agent/workflow/list.ts +87 -0
  54. package/agent/workflow/runtime.ts +274 -0
  55. package/agent/workflow/runtimeConfig.ts +103 -0
  56. package/agent/workflow/runtimeRoutes.ts +162 -0
  57. package/agent/workflow/sqlite.ts +52 -0
  58. package/agent/workflow/stats.ts +79 -0
  59. package/agent/workflow/types.ts +81 -0
  60. package/agent/workflow/validation.ts +114 -0
  61. package/agent/workflows.ts +14 -489
  62. package/dist/.vite/manifest.json +595 -234
  63. package/dist/assets/AddJob-UUa2fSXE.js +3 -0
  64. package/dist/assets/Alerts-7oGYfQMb.js +1 -0
  65. package/dist/assets/{AreaChart-REK4ZsTC.js → AreaChart-w0ruozXH.js} +1 -1
  66. package/dist/assets/Benchmark-C2NFp_kj.js +1 -0
  67. package/dist/assets/BulkAddJobs-CL4yBae-.js +5 -0
  68. package/dist/assets/Button-BPqpRZJD.js +1 -0
  69. package/dist/assets/Card-C7NMhqUt.js +1 -0
  70. package/dist/assets/{CopilotPanel-COLw-atS.js → CopilotPanel-BQ2Cgo9p.js} +3 -3
  71. package/dist/assets/Cron-DfWBhoBf.js +1 -0
  72. package/dist/assets/CronManager-DAK7RSOX.js +1 -0
  73. package/dist/assets/Database-DqL7giEj.js +3 -0
  74. package/dist/assets/Diagnostics-D98YwN-6.js +1 -0
  75. package/dist/assets/Dlq-BHmA5PTI.js +1 -0
  76. package/dist/assets/DlqControl-DihxvP-i.js +1 -0
  77. package/dist/assets/DlqPro-ncgnDtpE.js +1 -0
  78. package/dist/assets/Flows-B5N5Cil0.js +2 -0
  79. package/dist/assets/JobInspector-B40nFiGh.js +2 -0
  80. package/dist/assets/Jobs-Bla3IEef.js +1 -0
  81. package/dist/assets/JobsPro-CnczVx7x.js +1 -0
  82. package/dist/assets/Logs-T91Q3cH0.js +1 -0
  83. package/dist/assets/LogsPro-CMn6-Wwv.js +1 -0
  84. package/dist/assets/{McpServer-CbaU52l2.js → McpServer-BQBabwW-.js} +2 -2
  85. package/dist/assets/Metrics-DxT_RI2B.js +1 -0
  86. package/dist/assets/MetricsPro-Cjen-nAP.js +1 -0
  87. package/dist/assets/Overview-XN2ej8ph.js +1 -0
  88. package/dist/assets/PageHeader-BXlZSBcc.js +1 -0
  89. package/dist/assets/Pagination-Q-vf4hsX.js +1 -0
  90. package/dist/assets/QueueActions-C-Aferd6.js +1 -0
  91. package/dist/assets/QueueControl-B8Q9NX6t.js +1 -0
  92. package/dist/assets/QueueDetail-BMhG0jUB.js +1 -0
  93. package/dist/assets/QueueDetailPro-BKTTyLR4.js +1 -0
  94. package/dist/assets/Queues-COqPMoY9.js +1 -0
  95. package/dist/assets/QueuesOverview-pWdrPy8Z.js +1 -0
  96. package/dist/assets/S3Backup-BmsZ8xtq.js +1 -0
  97. package/dist/assets/S3BackupPro-AtlsPUJL.js +3 -0
  98. package/dist/assets/ServerControl-D3XwHr72.js +3 -0
  99. package/dist/assets/Settings-BofKZoHn.js +1 -0
  100. package/dist/assets/StatusBadge-B0I7hNBX.js +1 -0
  101. package/dist/assets/Usage-DAR9E22v.js +1 -0
  102. package/dist/assets/UsagePro-Bc30N2Lo.js +1 -0
  103. package/dist/assets/Webhooks-Bg2k1PU4.js +1 -0
  104. package/dist/assets/Workers-BqUZMJVQ.js +1 -0
  105. package/dist/assets/WorkersPro-C9aSadUh.js +1 -0
  106. package/dist/assets/Workflows-BEFMfHmo.js +1 -0
  107. package/dist/assets/api-CQ5Z7xR7.js +1 -0
  108. package/dist/assets/bq-BeBxa743.js +1 -0
  109. package/dist/assets/cn-zFEt5SO8.js +1 -0
  110. package/dist/assets/connectionStore-DbBYqHEY.js +1 -0
  111. package/dist/assets/controlConnectionEpoch-CFSO6237.js +1 -0
  112. package/dist/assets/feedback-BnGE2oW2.js +1 -0
  113. package/dist/assets/{form-DsUq0w8s.js → form-tC20r4Ma.js} +1 -1
  114. package/dist/assets/format-Cg7VCIZW.js +1 -0
  115. package/dist/assets/icons-CIvFfU2b.js +1 -0
  116. package/dist/assets/index-Cui9IwWy.js +8 -0
  117. package/dist/assets/index-DOze4TKg.css +1 -0
  118. package/dist/assets/install-Cd9Is10G.js +3 -0
  119. package/dist/assets/{react-vendor-Bjui4wS4.js → react-vendor-CyjgmGTq.js} +3 -3
  120. package/dist/assets/responses-kPO4rSu5.js +1 -0
  121. package/dist/assets/toastStore-CS_9Xndn.js +1 -0
  122. package/dist/assets/usePolledData-DzlUpBOO.js +1 -0
  123. package/dist/assets/{useServerActionGuard-CItj3hvh.js → useServerActionGuard-BlH-Kso1.js} +1 -1
  124. package/dist/assets/useThroughputSeries-C2pa1Wd_.js +1 -0
  125. package/dist/index.html +16 -5
  126. package/package.json +12 -3
  127. package/scripts/embedded.gen.ts +152 -126
  128. package/scripts/serve.ts +96 -484
  129. package/scripts/serveHandler.ts +217 -0
  130. package/scripts/servePolicy.ts +133 -0
  131. package/dist/assets/AddJob-CG28MSxU.js +0 -3
  132. package/dist/assets/Alerts-D9JojJrj.js +0 -1
  133. package/dist/assets/Benchmark-BVjUH9dG.js +0 -1
  134. package/dist/assets/BulkAddJobs-BHzUCMj_.js +0 -5
  135. package/dist/assets/Cron-DoEHDHwy.js +0 -1
  136. package/dist/assets/CronManager-vulcesqJ.js +0 -1
  137. package/dist/assets/Database-DlB_t04Z.js +0 -3
  138. package/dist/assets/Diagnostics-DddCUgeR.js +0 -1
  139. package/dist/assets/Dlq-DMKrsSMP.js +0 -1
  140. package/dist/assets/DlqControl-9m0Re_TH.js +0 -1
  141. package/dist/assets/DlqPro-Dmw-0wta.js +0 -1
  142. package/dist/assets/Flows-C3-9nXW4.js +0 -1
  143. package/dist/assets/JobInspector-DwIfABmI.js +0 -2
  144. package/dist/assets/Jobs-j8tTS3NC.js +0 -1
  145. package/dist/assets/JobsPro-CS__CJJl.js +0 -1
  146. package/dist/assets/Logs-BB-VDPA1.js +0 -1
  147. package/dist/assets/LogsPro-RNtSQZRT.js +0 -1
  148. package/dist/assets/Metrics-ivcddPwT.js +0 -1
  149. package/dist/assets/MetricsPro-xjZno4vg.js +0 -1
  150. package/dist/assets/Overview-D84aD2ph.js +0 -1
  151. package/dist/assets/Pagination-Bfi4vkpp.js +0 -1
  152. package/dist/assets/QueueActions-DTbD6uek.js +0 -1
  153. package/dist/assets/QueueControl-B5xK_SQ-.js +0 -1
  154. package/dist/assets/QueueDetail-BH59kwm9.js +0 -1
  155. package/dist/assets/QueueDetailPro-DoN25ndy.js +0 -1
  156. package/dist/assets/Queues-CKMJqFHX.js +0 -1
  157. package/dist/assets/QueuesOverview-BX1lzojl.js +0 -1
  158. package/dist/assets/S3Backup-Bz3GfoZ9.js +0 -1
  159. package/dist/assets/S3BackupPro-BC_6-uX-.js +0 -2
  160. package/dist/assets/ServerControl-CSSrN8G5.js +0 -3
  161. package/dist/assets/Settings-DkqmZUIS.js +0 -1
  162. package/dist/assets/Usage-Ba20p0xd.js +0 -1
  163. package/dist/assets/UsagePro-C2pQwjN9.js +0 -1
  164. package/dist/assets/Webhooks-CVuuvb0L.js +0 -1
  165. package/dist/assets/Workers-C1wPU6CS.js +0 -1
  166. package/dist/assets/WorkersPro-B0vEkC0T.js +0 -1
  167. package/dist/assets/Workflows-C8Qmkflf.js +0 -1
  168. package/dist/assets/cn-CMFYpumL.js +0 -1
  169. package/dist/assets/connectionStore-Cd9-3Fw0.js +0 -1
  170. package/dist/assets/index-BCNzbhhD.css +0 -1
  171. package/dist/assets/index-CAtsVmyh.js +0 -8
  172. package/dist/assets/install-D0eRLf9F.js +0 -3
  173. package/dist/assets/useThroughputSeries-DjxGN8ob.js +0 -1
@@ -0,0 +1,79 @@
1
+ import { ident, knownTable, openDb } from './core';
2
+ import type { DbInfo, DbTableSchema } from './types';
3
+
4
+ /** Column definitions, indexes and original DDL for one table. */
5
+ export function dbSchema(path: string, table: string): DbTableSchema {
6
+ const db = openDb(path);
7
+ try {
8
+ const name = knownTable(db, table);
9
+ const columns = (
10
+ db.query(`PRAGMA table_info(${ident(name)})`).all() as {
11
+ name: string;
12
+ type: string;
13
+ notnull: number;
14
+ dflt_value: string | null;
15
+ pk: number;
16
+ }[]
17
+ ).map((column) => ({
18
+ name: column.name,
19
+ type: column.type || 'ANY',
20
+ notNull: column.notnull === 1,
21
+ defaultValue: column.dflt_value,
22
+ primaryKey: column.pk > 0,
23
+ }));
24
+ const indexes = (
25
+ db.query(`PRAGMA index_list(${ident(name)})`).all() as { name: string; unique: number }[]
26
+ ).map((index) => ({
27
+ name: index.name,
28
+ unique: index.unique === 1,
29
+ columns: (
30
+ db.query(`PRAGMA index_info(${ident(index.name)})`).all() as { name: string }[]
31
+ ).map((column) => column.name),
32
+ }));
33
+ const master = db
34
+ .query("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = ?")
35
+ .get(name) as { sql: string | null } | null;
36
+ const { c: rowCount } = db.query(`SELECT COUNT(*) AS c FROM ${ident(name)}`).get() as {
37
+ c: number;
38
+ };
39
+ return { table: name, columns, indexes, sql: master?.sql ?? null, rowCount };
40
+ } finally {
41
+ db.close();
42
+ }
43
+ }
44
+
45
+ /** Store-level metadata: engine version, pragmas, object counts, on-disk size. */
46
+ export function dbInfo(path: string): DbInfo {
47
+ const db = openDb(path);
48
+ try {
49
+ const one = (sql: string) => (db.query(sql).values()[0] as unknown[])[0];
50
+ const count = (type: string) =>
51
+ (
52
+ db
53
+ .query(
54
+ "SELECT COUNT(*) AS c FROM sqlite_master WHERE type = ? AND name NOT LIKE 'sqlite_%'"
55
+ )
56
+ .get(type) as { c: number }
57
+ ).c;
58
+ const size = (file: string) => {
59
+ try {
60
+ return Bun.file(file).size || 0;
61
+ } catch {
62
+ return 0;
63
+ }
64
+ };
65
+ return {
66
+ sqliteVersion: String(one('SELECT sqlite_version()')),
67
+ pageSize: Number(one('PRAGMA page_size')),
68
+ pageCount: Number(one('PRAGMA page_count')),
69
+ journalMode: String(one('PRAGMA journal_mode')),
70
+ freelistPages: Number(one('PRAGMA freelist_count')),
71
+ tables: count('table'),
72
+ indexes: count('index'),
73
+ fileSize: size(path),
74
+ walSize: size(`${path}-wal`),
75
+ };
76
+ } finally {
77
+ db.close();
78
+ }
79
+ }
@@ -0,0 +1,157 @@
1
+ import {
2
+ bigintCell,
3
+ boundRowid,
4
+ buildFilter,
5
+ ident,
6
+ isTruncated,
7
+ knownTable,
8
+ openDb,
9
+ safeIntegers,
10
+ sanitize,
11
+ } from './core';
12
+ import {
13
+ MAX_FULL_CELL,
14
+ MAX_ROWS,
15
+ type DbFilter,
16
+ type DbRowId,
17
+ type DbRowsOptions,
18
+ type DbRowsPage,
19
+ type DbTableInfo,
20
+ } from './types';
21
+
22
+ /** All user tables with row + column counts. */
23
+ export function dbTables(path: string): DbTableInfo[] {
24
+ const db = openDb(path);
25
+ try {
26
+ const tables = db
27
+ .query(
28
+ "SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' ORDER BY name"
29
+ )
30
+ .all() as { name: string }[];
31
+ return tables.map(({ name }) => {
32
+ const { c } = db.query(`SELECT COUNT(*) AS c FROM ${ident(name)}`).get() as { c: number };
33
+ const columns = db.query(`PRAGMA table_info(${ident(name)})`).all();
34
+ return { name, rows: c, columns: columns.length };
35
+ });
36
+ } finally {
37
+ db.close();
38
+ }
39
+ }
40
+
41
+ /** One page of a table's rows from a single SQLite snapshot. */
42
+ export function dbRows(
43
+ path: string,
44
+ table: string,
45
+ limit: number,
46
+ offset: number,
47
+ orderBy?: string,
48
+ dir: 'asc' | 'desc' = 'asc',
49
+ filter?: DbFilter,
50
+ options: Readonly<DbRowsOptions> = {}
51
+ ): DbRowsPage {
52
+ const boundedLimit = Math.max(1, Math.min(MAX_ROWS, Math.floor(limit) || 50));
53
+ const boundedOffset = Number.isFinite(offset)
54
+ ? Math.max(0, Math.min(Number.MAX_SAFE_INTEGER, Math.floor(offset) || 0))
55
+ : 0;
56
+ const db = openDb(path);
57
+ try {
58
+ const snapshot = db.transaction((): DbRowsPage => {
59
+ const name = knownTable(db, table);
60
+ const columns = (
61
+ db.query(`PRAGMA table_info(${ident(name)})`).all() as { name: string }[]
62
+ ).map((column) => column.name);
63
+
64
+ let order = '';
65
+ let sortColumn: string | null = null;
66
+ if (orderBy) {
67
+ sortColumn = columns.find((column) => column === orderBy) ?? null;
68
+ if (!sortColumn) throw new Error(`No such column: ${orderBy}`);
69
+ order = ` ORDER BY ${ident(sortColumn)} ${dir === 'desc' ? 'DESC' : 'ASC'}`;
70
+ }
71
+ const { clause, params, applied } = buildFilter(columns, filter);
72
+ const { c: total } = db
73
+ .query(`SELECT COUNT(*) AS c FROM ${ident(name)}${clause}`)
74
+ .get(...(params as [])) as { c: number };
75
+ options.afterCount?.();
76
+
77
+ let rowids: (DbRowId | null)[] = [];
78
+ let rawRows: unknown[][];
79
+ try {
80
+ const statement = db.query(
81
+ `SELECT rowid AS __rid, * FROM ${ident(name)}${clause}${order} LIMIT ? OFFSET ?`
82
+ );
83
+ safeIntegers(statement);
84
+ const rows = statement.values(...(params as []), boundedLimit, boundedOffset) as unknown[][];
85
+ rowids = rows.map((row) =>
86
+ typeof row[0] === 'bigint'
87
+ ? bigintCell(row[0])
88
+ : typeof row[0] === 'number' && Number.isSafeInteger(row[0])
89
+ ? row[0]
90
+ : null
91
+ );
92
+ rawRows = rows.map((row) => row.slice(1));
93
+ } catch {
94
+ const statement = db.query(
95
+ `SELECT * FROM ${ident(name)}${clause}${order} LIMIT ? OFFSET ?`
96
+ );
97
+ safeIntegers(statement);
98
+ rawRows = statement.values(
99
+ ...(params as []),
100
+ boundedLimit,
101
+ boundedOffset
102
+ ) as unknown[][];
103
+ rowids = rawRows.map(() => null);
104
+ }
105
+
106
+ return {
107
+ table: name,
108
+ columns,
109
+ rows: sanitize(rawRows),
110
+ rowids,
111
+ truncatedCells: rawRows.map((row) => row.map(isTruncated)),
112
+ total,
113
+ limit: boundedLimit,
114
+ offset: boundedOffset,
115
+ orderBy: sortColumn,
116
+ dir: dir === 'desc' ? 'desc' : 'asc',
117
+ filter: applied,
118
+ };
119
+ });
120
+ return snapshot.deferred();
121
+ } finally {
122
+ db.close();
123
+ }
124
+ }
125
+
126
+ /** Full, untruncated value of a single cell, keyed by rowid. */
127
+ export function dbCell(
128
+ path: string,
129
+ table: string,
130
+ rowid: DbRowId,
131
+ column: string
132
+ ): { value: unknown } {
133
+ const db = openDb(path);
134
+ try {
135
+ const name = knownTable(db, table);
136
+ const columns = (
137
+ db.query(`PRAGMA table_info(${ident(name)})`).all() as { name: string }[]
138
+ ).map((entry) => entry.name);
139
+ const resolvedColumn = columns.find((entry) => entry === column);
140
+ if (!resolvedColumn) throw new Error(`No such column: ${column}`);
141
+ const statement = db.query(
142
+ `SELECT ${ident(resolvedColumn)} AS v FROM ${ident(name)} WHERE rowid = ?`
143
+ );
144
+ safeIntegers(statement);
145
+ const row = statement.get(boundRowid(rowid)) as { v: unknown } | null;
146
+ if (!row) throw new Error('Row not found');
147
+ let value = row.v;
148
+ if (value instanceof Uint8Array) value = `<blob ${value.byteLength} B — binary, not shown>`;
149
+ else if (typeof value === 'bigint') value = bigintCell(value);
150
+ else if (typeof value === 'string' && value.length > MAX_FULL_CELL) {
151
+ value = `${value.slice(0, MAX_FULL_CELL)}…`;
152
+ }
153
+ return { value };
154
+ } finally {
155
+ db.close();
156
+ }
157
+ }
@@ -0,0 +1,118 @@
1
+ /** Hard cap on rows returned by any endpoint. */
2
+ export const MAX_ROWS = 500;
3
+ /** Cell strings longer than this are truncated server-side. */
4
+ export const MAX_CELL = 2000;
5
+ /** Full single-cell fetch hard cap. */
6
+ export const MAX_FULL_CELL = 1_000_000;
7
+ export const DB_EXPORT_MAX_ROWS = 200_000;
8
+ export const DB_EXPORT_MAX_BYTES = 16 * 1024 * 1024;
9
+ export const DB_EXPORT_MAX_COLUMNS = 256;
10
+ export const DB_EXPORT_MAX_IDENTIFIER_CHARS = 1024;
11
+ export const DB_EXPORT_MAX_FILTER_CHARS = 4096;
12
+ export const DB_EXPORT_TIMEOUT_MS = 15_000;
13
+ export const QUERY_TIMEOUT_MS = 5000;
14
+ export const MAX_CONCURRENT_QUERIES = 2;
15
+ export const MAX_CONCURRENT_EXPORTS = 1;
16
+
17
+ /** Thrown when the database file does not exist yet (maps to HTTP 404). */
18
+ export class MissingDbError extends Error {
19
+ readonly missing = true;
20
+ }
21
+
22
+ /** Maps a saturated export worker pool to HTTP 429. */
23
+ export class DbExportBusyError extends Error {}
24
+
25
+ /** Maps export worker startup/crash/timeout failures to HTTP 503. */
26
+ export class DbExportUnavailableError extends Error {}
27
+
28
+ export interface DbTableInfo {
29
+ name: string;
30
+ rows: number;
31
+ columns: number;
32
+ }
33
+
34
+ export interface DbFilter {
35
+ column: string;
36
+ op: 'contains' | 'eq' | 'ne';
37
+ value: string;
38
+ }
39
+
40
+ export interface DbRowsPage {
41
+ table: string;
42
+ columns: string[];
43
+ rows: unknown[][];
44
+ rowids: (DbRowId | null)[];
45
+ truncatedCells: boolean[][];
46
+ total: number;
47
+ limit: number;
48
+ offset: number;
49
+ orderBy: string | null;
50
+ dir: 'asc' | 'desc';
51
+ filter: DbFilter | null;
52
+ }
53
+
54
+ export type DbExportCap = 'rows' | 'bytes' | null;
55
+
56
+ export interface DbCsvExport {
57
+ table: string;
58
+ content: Uint8Array<ArrayBuffer>;
59
+ rowCount: number;
60
+ bytes: number;
61
+ cap: DbExportCap;
62
+ }
63
+
64
+ /** Tests may lower a cap, but callers can never raise the production ceiling. */
65
+ export interface DbExportLimits {
66
+ maxRows?: number;
67
+ maxBytes?: number;
68
+ onSnapshot?: () => void;
69
+ }
70
+
71
+ export interface DbRowsOptions {
72
+ afterCount?: () => void;
73
+ }
74
+
75
+ /** JSON/query-string-safe SQLite rowid. */
76
+ export type DbRowId = number | string;
77
+
78
+ export interface DbColumnInfo {
79
+ name: string;
80
+ type: string;
81
+ notNull: boolean;
82
+ defaultValue: string | null;
83
+ primaryKey: boolean;
84
+ }
85
+
86
+ export interface DbIndexInfo {
87
+ name: string;
88
+ unique: boolean;
89
+ columns: string[];
90
+ }
91
+
92
+ export interface DbTableSchema {
93
+ table: string;
94
+ columns: DbColumnInfo[];
95
+ indexes: DbIndexInfo[];
96
+ sql: string | null;
97
+ rowCount: number;
98
+ }
99
+
100
+ export interface DbInfo {
101
+ sqliteVersion: string;
102
+ pageSize: number;
103
+ pageCount: number;
104
+ journalMode: string;
105
+ freelistPages: number;
106
+ tables: number;
107
+ indexes: number;
108
+ fileSize: number;
109
+ walSize: number;
110
+ }
111
+
112
+ export interface DbQueryResult {
113
+ columns: string[];
114
+ rows: unknown[][];
115
+ rowCount: number;
116
+ truncated: boolean;
117
+ ms: number;
118
+ }
@@ -0,0 +1,25 @@
1
+ let workerUrl = new URL('../dbQueryWorker.ts', import.meta.url).href;
2
+
3
+ const spawnWorker = (): Worker => new Worker(workerUrl, { type: 'module' });
4
+ let queryFactory: () => Worker = spawnWorker;
5
+ let exportFactory: () => Worker = spawnWorker;
6
+
7
+ export function createQueryWorker(): Worker {
8
+ return queryFactory();
9
+ }
10
+
11
+ export function createExportWorker(): Worker {
12
+ return exportFactory();
13
+ }
14
+
15
+ export function setQueryWorkerUrl(url: string): void {
16
+ workerUrl = url;
17
+ }
18
+
19
+ export function setQueryWorkerFactory(factory: (() => Worker) | null): void {
20
+ queryFactory = factory ?? spawnWorker;
21
+ }
22
+
23
+ export function setExportWorkerFactory(factory: (() => Worker) | null): void {
24
+ exportFactory = factory ?? spawnWorker;
25
+ }