@delali/sirannon-db 0.1.6 → 0.1.8

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 (54) hide show
  1. package/README.md +154 -19
  2. package/dist/backup-scheduler/index.d.ts +18 -3
  3. package/dist/backup-scheduler/index.mjs +2 -2
  4. package/dist/{change-tracker-CFTQ9TSn.d.ts → change-tracker-CbmaMO-N.d.ts} +12 -2
  5. package/dist/chunk-4ISB7XMA.mjs +21 -0
  6. package/dist/chunk-BNUTBHHH.mjs +22 -0
  7. package/dist/chunk-CJLYFDP5.mjs +26 -0
  8. package/dist/chunk-CW6S3WL5.mjs +222 -0
  9. package/dist/chunk-DVWQD3GF.mjs +49 -0
  10. package/dist/chunk-GEZUUIKV.mjs +268 -0
  11. package/dist/{chunk-UVMVN3OT.mjs → chunk-H5AB6NIR.mjs} +1 -1
  12. package/dist/{chunk-UTO3ZAFS.mjs → chunk-HHRMRFFR.mjs} +148 -28
  13. package/dist/chunk-TKGHYWQ6.mjs +35 -0
  14. package/dist/chunk-UXLAO6ZH.mjs +352 -0
  15. package/dist/chunk-VLTICJOD.mjs +470 -0
  16. package/dist/{chunk-O7BHI3CF.mjs → chunk-YPYVQJ4C.mjs} +15 -1
  17. package/dist/client/index.d.ts +107 -15
  18. package/dist/client/index.mjs +348 -37
  19. package/dist/core/index.d.ts +70 -13
  20. package/dist/core/index.mjs +635 -192
  21. package/dist/core/writer-worker.d.ts +2 -0
  22. package/dist/core/writer-worker.mjs +129 -0
  23. package/dist/{database-BVY1GqE7.d.ts → database-DuGp0Rtr.d.ts} +51 -19
  24. package/dist/driver/better-sqlite3.d.ts +1 -1
  25. package/dist/driver/better-sqlite3.mjs +44 -6
  26. package/dist/driver/bun.mjs +35 -6
  27. package/dist/driver/expo.mjs +2 -2
  28. package/dist/driver/node.d.ts +1 -1
  29. package/dist/driver/node.mjs +48 -5
  30. package/dist/driver/wa-sqlite.d.ts +109 -0
  31. package/dist/driver/wa-sqlite.mjs +30 -2
  32. package/dist/{errors-C00ed08Q.d.ts → errors-5Nf5ZAEC.d.ts} +19 -1
  33. package/dist/file-migrations/index.d.ts +2 -3
  34. package/dist/file-migrations/index.mjs +1 -1
  35. package/dist/replication/coordinator/etcd.mjs +2 -2
  36. package/dist/replication/index.d.ts +7 -8
  37. package/dist/replication/index.mjs +79 -78
  38. package/dist/server/index.d.ts +111 -28
  39. package/dist/server/index.mjs +1016 -384
  40. package/dist/{sirannon-Cd-lK6T0.d.ts → sirannon-4SspRvP5.d.ts} +3 -3
  41. package/dist/transport/grpc.d.ts +3 -4
  42. package/dist/transport/grpc.mjs +2 -2
  43. package/dist/{types-Lc7ywFx7.d.ts → types-BsjobKbl.d.ts} +2 -2
  44. package/dist/{types-BeozgNPr.d.ts → types-D4p4UyDK.d.ts} +1 -1
  45. package/dist/types-D_hQW1hr.d.ts +494 -0
  46. package/package.json +3 -23
  47. package/dist/chunk-3MCMONVP.mjs +0 -115
  48. package/dist/chunk-74UN4DIE.mjs +0 -14
  49. package/dist/chunk-FB2U2Q3Y.mjs +0 -21
  50. package/dist/chunk-GS7T5YMI.mjs +0 -51
  51. package/dist/chunk-PXKAKK2V.mjs +0 -124
  52. package/dist/index-CLdNrcPz.d.ts +0 -16
  53. package/dist/types-BFSsG77t.d.ts +0 -29
  54. package/dist/types-D-74JiXb.d.ts +0 -265
@@ -1,115 +0,0 @@
1
- import { QueryError } from './chunk-O7BHI3CF.mjs';
2
-
3
- // src/core/query-executor.ts
4
- var STATEMENT_CACHE_CAPACITY = 128;
5
- var statementCaches = /* @__PURE__ */ new WeakMap();
6
- async function getStatement(conn, sql) {
7
- let cache = statementCaches.get(conn);
8
- if (!cache) {
9
- cache = /* @__PURE__ */ new Map();
10
- statementCaches.set(conn, cache);
11
- }
12
- const cached = cache.get(sql);
13
- if (cached) {
14
- cache.delete(sql);
15
- cache.set(sql, cached);
16
- return cached;
17
- }
18
- const pending = conn.prepare(sql);
19
- cache.set(sql, pending);
20
- if (cache.size > STATEMENT_CACHE_CAPACITY) {
21
- const oldest = cache.keys().next().value;
22
- if (oldest !== void 0) {
23
- cache.delete(oldest);
24
- }
25
- }
26
- try {
27
- return await pending;
28
- } catch (err) {
29
- cache.delete(sql);
30
- throw err;
31
- }
32
- }
33
- function bindParams(params) {
34
- if (params === void 0) return [];
35
- if (Array.isArray(params)) return params;
36
- return [params];
37
- }
38
- async function query(conn, sql, params) {
39
- try {
40
- const stmt = await getStatement(conn, sql);
41
- return await stmt.all(...bindParams(params));
42
- } catch (err) {
43
- throw new QueryError(err instanceof Error ? err.message : String(err), sql);
44
- }
45
- }
46
- async function queryOne(conn, sql, params) {
47
- try {
48
- const stmt = await getStatement(conn, sql);
49
- return await stmt.get(...bindParams(params));
50
- } catch (err) {
51
- throw new QueryError(err instanceof Error ? err.message : String(err), sql);
52
- }
53
- }
54
- async function execute(conn, sql, params) {
55
- try {
56
- const stmt = await getStatement(conn, sql);
57
- const result = await stmt.run(...bindParams(params));
58
- return {
59
- changes: result.changes,
60
- lastInsertRowId: result.lastInsertRowId
61
- };
62
- } catch (err) {
63
- throw new QueryError(err instanceof Error ? err.message : String(err), sql);
64
- }
65
- }
66
- async function executeBatch(conn, sql, paramsBatch) {
67
- try {
68
- const stmt = await getStatement(conn, sql);
69
- const results = [];
70
- for (const params of paramsBatch) {
71
- const result = await stmt.run(...bindParams(params));
72
- results.push({
73
- changes: result.changes,
74
- lastInsertRowId: result.lastInsertRowId
75
- });
76
- }
77
- return results;
78
- } catch (err) {
79
- throw new QueryError(err instanceof Error ? err.message : String(err), sql);
80
- }
81
- }
82
-
83
- // src/core/transaction.ts
84
- var Transaction = class _Transaction {
85
- constructor(conn) {
86
- this.conn = conn;
87
- }
88
- _lastInsertRowId = 0;
89
- async query(sql, params) {
90
- return query(this.conn, sql, params);
91
- }
92
- async execute(sql, params) {
93
- const result = await execute(this.conn, sql, params);
94
- this._lastInsertRowId = result.lastInsertRowId;
95
- return result;
96
- }
97
- async executeBatch(sql, paramsBatch) {
98
- const results = await executeBatch(this.conn, sql, paramsBatch);
99
- if (results.length > 0) {
100
- this._lastInsertRowId = results[results.length - 1].lastInsertRowId;
101
- }
102
- return results;
103
- }
104
- get lastInsertRowId() {
105
- return this._lastInsertRowId;
106
- }
107
- static async run(conn, fn) {
108
- return conn.transaction(async (txConn) => {
109
- const tx = new _Transaction(txConn);
110
- return fn(tx);
111
- });
112
- }
113
- };
114
-
115
- export { Transaction, execute, executeBatch, query, queryOne };
@@ -1,14 +0,0 @@
1
- import { SirannonError } from './chunk-O7BHI3CF.mjs';
2
-
3
- // src/core/driver/define.ts
4
- function defineDriver(config) {
5
- if (!config.capabilities || typeof config.open !== "function") {
6
- throw new SirannonError("Driver must define capabilities and open()", "INVALID_DRIVER");
7
- }
8
- return Object.freeze({
9
- capabilities: Object.freeze({ ...config.capabilities }),
10
- open: config.open
11
- });
12
- }
13
-
14
- export { defineDriver };
@@ -1,21 +0,0 @@
1
- // src/core/errors.ts
2
- var SirannonError = class extends Error {
3
- constructor(message, code) {
4
- super(message);
5
- this.code = code;
6
- this.name = "SirannonError";
7
- }
8
- };
9
-
10
- // src/core/driver/define.ts
11
- function defineDriver(config) {
12
- if (!config.capabilities || typeof config.open !== "function") {
13
- throw new SirannonError("Driver must define capabilities and open()", "INVALID_DRIVER");
14
- }
15
- return Object.freeze({
16
- capabilities: Object.freeze({ ...config.capabilities }),
17
- open: config.open
18
- });
19
- }
20
-
21
- export { defineDriver };
@@ -1,51 +0,0 @@
1
- // src/core/cdc/encoding.ts
2
- var BLOB_TAG = "__sirannon_blob";
3
- var INT_TAG = "__sirannon_int";
4
- var SAFE_INT_BOUND_TEXT = "9007199254740991";
5
- var HEX_BYTES_RE = /^[0-9a-fA-F]*$/;
6
- function decodeTaggedValues(value) {
7
- if (value === null || typeof value !== "object") return value;
8
- if (isBinaryValue(value)) return value;
9
- if (Array.isArray(value)) {
10
- return value.map(decodeTaggedValues);
11
- }
12
- const obj = value;
13
- const keys = Object.keys(obj);
14
- if (keys.length === 1) {
15
- const tag = keys[0];
16
- const tagValue = obj[tag];
17
- if (tag === BLOB_TAG && typeof tagValue === "string") {
18
- return decodeHexBytes(tagValue);
19
- }
20
- if (tag === INT_TAG && typeof tagValue === "string") {
21
- return BigInt(tagValue);
22
- }
23
- }
24
- const out = {};
25
- for (const k of keys) {
26
- out[k] = decodeTaggedValues(obj[k]);
27
- }
28
- return out;
29
- }
30
- function isBinaryValue(value) {
31
- return value instanceof Uint8Array || typeof Buffer !== "undefined" && Buffer.isBuffer(value);
32
- }
33
- function decodeHexBytes(hex) {
34
- if (hex.length % 2 !== 0 || !HEX_BYTES_RE.test(hex)) {
35
- throw new Error("Invalid CDC BLOB hex payload");
36
- }
37
- if (typeof Buffer !== "undefined") {
38
- return Buffer.from(hex, "hex");
39
- }
40
- const bytes = new Uint8Array(hex.length / 2);
41
- for (let i = 0; i < hex.length; i += 2) {
42
- const byte = Number.parseInt(hex.slice(i, i + 2), 16);
43
- if (Number.isNaN(byte)) {
44
- throw new Error("Invalid CDC BLOB hex payload");
45
- }
46
- bytes[i / 2] = byte;
47
- }
48
- return bytes;
49
- }
50
-
51
- export { SAFE_INT_BOUND_TEXT, decodeTaggedValues };
@@ -1,124 +0,0 @@
1
- import { BackupError } from './chunk-O7BHI3CF.mjs';
2
- import { existsSync, mkdirSync, rmSync, readdirSync, lstatSync } from 'fs';
3
- import { resolve, dirname, join } from 'path';
4
- import { Cron } from 'croner';
5
-
6
- var BACKUP_FILE_PREFIX = "backup";
7
- function hasControlCharacters(s) {
8
- for (let i = 0; i < s.length; i++) {
9
- const code = s.charCodeAt(i);
10
- if (code <= 31) return true;
11
- }
12
- return false;
13
- }
14
- var BackupManager = class {
15
- async backup(conn, destPath) {
16
- if (hasControlCharacters(destPath)) {
17
- throw new BackupError("Backup path contains invalid characters");
18
- }
19
- const segments = destPath.split(/[/\\]/);
20
- if (segments.includes("..")) {
21
- throw new BackupError("Backup path must not contain directory traversal segments");
22
- }
23
- const resolved = resolve(destPath);
24
- const dir = dirname(resolved);
25
- if (!existsSync(dir)) {
26
- try {
27
- mkdirSync(dir, { recursive: true });
28
- } catch (err) {
29
- throw new BackupError(
30
- `Failed to create backup directory '${dir}': ${err instanceof Error ? err.message : String(err)}`
31
- );
32
- }
33
- }
34
- if (existsSync(resolved)) {
35
- throw new BackupError(`Backup destination '${destPath}' already exists`);
36
- }
37
- const escaped = resolved.replace(/'/g, "''");
38
- try {
39
- await conn.exec(`VACUUM INTO '${escaped}'`);
40
- } catch (err) {
41
- try {
42
- rmSync(resolved, { force: true });
43
- } catch {
44
- }
45
- throw new BackupError(`Backup to '${destPath}' failed: ${err instanceof Error ? err.message : String(err)}`);
46
- }
47
- }
48
- generateFilename() {
49
- const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
50
- return `${BACKUP_FILE_PREFIX}-${ts}.db`;
51
- }
52
- rotate(dir, maxFiles) {
53
- if (maxFiles <= 0) return;
54
- const resolved = resolve(dir);
55
- if (!existsSync(resolved)) return;
56
- let entries;
57
- try {
58
- entries = readdirSync(resolved).filter((f) => f.startsWith(`${BACKUP_FILE_PREFIX}-`) && f.endsWith(".db")).map((f) => {
59
- const filePath = join(resolved, f);
60
- return { path: filePath, mtimeMs: lstatSync(filePath).mtimeMs };
61
- }).sort((a, b) => b.mtimeMs - a.mtimeMs);
62
- } catch (err) {
63
- throw new BackupError(
64
- `Failed to list backup files in '${dir}': ${err instanceof Error ? err.message : String(err)}`
65
- );
66
- }
67
- for (const entry of entries.slice(maxFiles)) {
68
- try {
69
- rmSync(entry.path, { force: true });
70
- } catch {
71
- }
72
- }
73
- }
74
- };
75
- var DEFAULT_MAX_FILES = 5;
76
- var BackupScheduler = class {
77
- manager;
78
- constructor(manager) {
79
- this.manager = manager ?? new BackupManager();
80
- }
81
- schedule(conn, options) {
82
- const { cron: cronExpr, destDir, maxFiles = DEFAULT_MAX_FILES, onError } = options;
83
- const resolvedDir = resolve(destDir);
84
- if (!existsSync(resolvedDir)) {
85
- try {
86
- mkdirSync(resolvedDir, { recursive: true });
87
- } catch (err) {
88
- throw new BackupError(
89
- `Failed to create backup directory '${destDir}': ${err instanceof Error ? err.message : String(err)}`
90
- );
91
- }
92
- }
93
- let job;
94
- try {
95
- job = new Cron(
96
- cronExpr,
97
- {
98
- unref: true,
99
- catch: (err) => {
100
- if (onError) {
101
- const error = err instanceof Error ? err : new BackupError(typeof err === "string" ? err : "Scheduled backup failed");
102
- onError(error);
103
- }
104
- }
105
- },
106
- async () => {
107
- const filename = this.manager.generateFilename();
108
- const destPath = join(resolvedDir, filename);
109
- await this.manager.backup(conn, destPath);
110
- this.manager.rotate(resolvedDir, maxFiles);
111
- }
112
- );
113
- } catch (err) {
114
- throw new BackupError(
115
- `Invalid cron expression '${cronExpr}': ${err instanceof Error ? err.message : String(err)}`
116
- );
117
- }
118
- return () => {
119
- job.stop();
120
- };
121
- }
122
- };
123
-
124
- export { BackupManager, BackupScheduler };
@@ -1,16 +0,0 @@
1
- import { a as SQLiteConnection } from './types-BFSsG77t.js';
2
- import { m as BackupScheduleOptions } from './types-D-74JiXb.js';
3
-
4
- declare class BackupManager {
5
- backup(conn: SQLiteConnection, destPath: string): Promise<void>;
6
- generateFilename(): string;
7
- rotate(dir: string, maxFiles: number): void;
8
- }
9
-
10
- declare class BackupScheduler {
11
- private readonly manager;
12
- constructor(manager?: BackupManager);
13
- schedule(conn: SQLiteConnection, options: BackupScheduleOptions): () => void;
14
- }
15
-
16
- export { BackupManager as B, BackupScheduler as a };
@@ -1,29 +0,0 @@
1
- interface RunResult {
2
- changes: number;
3
- lastInsertRowId: number | bigint;
4
- }
5
- interface SQLiteStatement {
6
- all<T = unknown>(...params: unknown[]): Promise<T[]>;
7
- get<T = unknown>(...params: unknown[]): Promise<T | undefined>;
8
- run(...params: unknown[]): Promise<RunResult>;
9
- }
10
- interface SQLiteConnection {
11
- exec(sql: string): Promise<void>;
12
- prepare(sql: string): Promise<SQLiteStatement>;
13
- transaction<T>(fn: (conn: SQLiteConnection) => Promise<T>): Promise<T>;
14
- close(): Promise<void>;
15
- }
16
- interface OpenOptions {
17
- readonly?: boolean;
18
- walMode?: boolean;
19
- }
20
- interface DriverCapabilities {
21
- multipleConnections: boolean;
22
- extensions: boolean;
23
- }
24
- interface SQLiteDriver {
25
- readonly capabilities: DriverCapabilities;
26
- open(path: string, options?: OpenOptions): Promise<SQLiteConnection>;
27
- }
28
-
29
- export type { DriverCapabilities as D, OpenOptions as O, RunResult as R, SQLiteDriver as S, SQLiteConnection as a, SQLiteStatement as b };
@@ -1,265 +0,0 @@
1
- import { a as SQLiteConnection, S as SQLiteDriver } from './types-BFSsG77t.js';
2
-
3
- declare class Transaction {
4
- private readonly conn;
5
- private _lastInsertRowId;
6
- constructor(conn: SQLiteConnection);
7
- query<T = Record<string, unknown>>(sql: string, params?: Params): Promise<T[]>;
8
- execute(sql: string, params?: Params): Promise<ExecuteResult>;
9
- executeBatch(sql: string, paramsBatch: Params[]): Promise<ExecuteResult[]>;
10
- get lastInsertRowId(): number | bigint;
11
- static run<T>(conn: SQLiteConnection, fn: (tx: Transaction) => Promise<T>): Promise<T>;
12
- }
13
-
14
- /** Query parameter types: named (object) or positional (array). */
15
- type Params = Record<string, unknown> | unknown[];
16
- type WriteConcernLevel = 'local' | 'majority' | 'all';
17
- interface WriteConcern {
18
- level: WriteConcernLevel;
19
- timeoutMs?: number;
20
- }
21
- type ReadConcernLevel = 'local' | 'majority' | 'linearizable';
22
- interface ReadConcern {
23
- level: ReadConcernLevel;
24
- }
25
- interface QueryOptions {
26
- writeConcern?: WriteConcern;
27
- readConcern?: ReadConcern;
28
- }
29
- interface ClusterReadEndpointInfo {
30
- nodeId: string;
31
- endpoint: string;
32
- readConcerns: ReadConcernLevel[];
33
- }
34
- interface ClusterStatusInfo {
35
- databaseId: string;
36
- replicationGroupId?: string;
37
- role?: 'primary' | 'replica';
38
- currentPrimary?: {
39
- nodeId: string;
40
- endpoint?: string;
41
- } | null;
42
- primaryTerm?: bigint;
43
- readEndpoints?: ClusterReadEndpointInfo[];
44
- health: 'healthy' | 'degraded' | 'failing_over' | 'unavailable' | 'repairing' | 'syncing';
45
- }
46
- /** Result returned by mutation statements (INSERT, UPDATE, DELETE). */
47
- interface ExecuteResult {
48
- changes: number;
49
- lastInsertRowId: number | bigint;
50
- }
51
- /** CDC operation type. */
52
- type ChangeOperation = 'insert' | 'update' | 'delete';
53
- /** Event emitted when a watched table row changes. */
54
- interface ChangeEvent<T = Record<string, unknown>> {
55
- type: ChangeOperation;
56
- table: string;
57
- row: T;
58
- oldRow?: T;
59
- seq: bigint;
60
- timestamp: number;
61
- }
62
- /** Context passed to query hooks. */
63
- interface QueryHookContext {
64
- databaseId: string;
65
- sql: string;
66
- params?: Params;
67
- metadata?: Record<string, unknown>;
68
- writeConcern?: WriteConcern;
69
- readConcern?: ReadConcern;
70
- }
71
- /** Hook invoked before a query is executed. Throw to deny. */
72
- type BeforeQueryHook = (ctx: QueryHookContext) => void | Promise<void>;
73
- /** Hook invoked after a query is executed. */
74
- type AfterQueryHook = (ctx: QueryHookContext & {
75
- durationMs: number;
76
- }) => void | Promise<void>;
77
- /** Context passed to connection hooks. */
78
- interface ConnectionHookContext {
79
- databaseId: string;
80
- path: string;
81
- }
82
- /** Hook invoked before a database connection is established. */
83
- type BeforeConnectHook = (ctx: ConnectionHookContext) => void | Promise<void>;
84
- /** Hook invoked when a database is opened. */
85
- type DatabaseOpenHook = (ctx: ConnectionHookContext) => void | Promise<void>;
86
- /** Hook invoked when a database is closed. */
87
- type DatabaseCloseHook = (ctx: ConnectionHookContext) => void | Promise<void>;
88
- /** Hook invoked before a subscription is created. Throw to deny. */
89
- type BeforeSubscribeHook = (ctx: {
90
- databaseId: string;
91
- table: string;
92
- filter?: Record<string, unknown>;
93
- }) => void | Promise<void>;
94
- /** Aggregated hook configuration. */
95
- interface HookConfig {
96
- onBeforeQuery?: BeforeQueryHook | BeforeQueryHook[];
97
- onAfterQuery?: AfterQueryHook | AfterQueryHook[];
98
- onBeforeConnect?: BeforeConnectHook | BeforeConnectHook[];
99
- onDatabaseOpen?: DatabaseOpenHook | DatabaseOpenHook[];
100
- onDatabaseClose?: DatabaseCloseHook | DatabaseCloseHook[];
101
- onBeforeSubscribe?: BeforeSubscribeHook | BeforeSubscribeHook[];
102
- }
103
- /** Metrics emitted after a query completes. */
104
- interface QueryMetrics {
105
- databaseId: string;
106
- sql: string;
107
- durationMs: number;
108
- rowsReturned?: number;
109
- changes?: number;
110
- error?: boolean;
111
- }
112
- /** Metrics emitted when a connection opens or closes. */
113
- interface ConnectionMetrics {
114
- databaseId: string;
115
- path: string;
116
- readerCount: number;
117
- event: 'open' | 'close';
118
- }
119
- /** Metrics emitted when a CDC event is dispatched. */
120
- interface CDCMetrics {
121
- databaseId: string;
122
- table: string;
123
- operation: ChangeOperation;
124
- subscriberCount: number;
125
- }
126
- /** Callbacks for metrics collection. */
127
- interface MetricsConfig {
128
- onQueryComplete?: (metrics: QueryMetrics) => void;
129
- onConnectionOpen?: (metrics: ConnectionMetrics) => void;
130
- onConnectionClose?: (metrics: ConnectionMetrics) => void;
131
- onCDCEvent?: (metrics: CDCMetrics) => void;
132
- }
133
- /** Configuration for automatic database lifecycle management. */
134
- interface LifecycleConfig {
135
- autoOpen?: {
136
- resolver: (id: string) => {
137
- path: string;
138
- options?: DatabaseOptions;
139
- } | undefined;
140
- };
141
- /** Milliseconds before an idle database is closed. 0 = disabled. */
142
- idleTimeout?: number;
143
- /** Maximum number of concurrently open databases. 0 = unlimited. */
144
- maxOpen?: number;
145
- }
146
- /** Options for opening a single database. */
147
- interface DatabaseOptions {
148
- /** Open the database in read-only mode. */
149
- readOnly?: boolean;
150
- /** Number of read connections in the pool. Default: 4. */
151
- readPoolSize?: number;
152
- /** Enable WAL mode. Default: true. */
153
- walMode?: boolean;
154
- /** CDC polling interval in milliseconds. Default: 50. */
155
- cdcPollInterval?: number;
156
- /** CDC retention period in milliseconds. Default: 3_600_000 (1 hour). */
157
- cdcRetention?: number;
158
- }
159
- /** Top-level options for the Sirannon database registry. */
160
- interface SirannonOptions {
161
- driver: SQLiteDriver;
162
- hooks?: HookConfig;
163
- metrics?: MetricsConfig;
164
- lifecycle?: LifecycleConfig;
165
- }
166
- /** Options for scheduled backups. */
167
- interface BackupScheduleOptions {
168
- /** Cron expression (e.g., '0 * * * *' for hourly). */
169
- cron: string;
170
- /** Directory to store backup files. */
171
- destDir: string;
172
- /** Maximum number of backup files to keep. Default: 5. */
173
- maxFiles?: number;
174
- /** Called when a scheduled backup fails. Without this, errors are silently discarded. */
175
- onError?: (error: Error) => void;
176
- }
177
- /** Builder for creating CDC subscriptions with optional filters. */
178
- interface SubscriptionBuilder {
179
- filter(conditions: Record<string, unknown>): SubscriptionBuilder;
180
- subscribe(callback: (event: ChangeEvent) => void): Subscription;
181
- }
182
- /** Handle for an active subscription. */
183
- interface Subscription {
184
- unsubscribe(): void;
185
- }
186
- /** Context passed to the onRequest middleware hook. */
187
- interface RequestContext {
188
- headers: Record<string, string>;
189
- method: string;
190
- path: string;
191
- databaseId?: string;
192
- remoteAddress: string;
193
- }
194
- /** Return this from an onRequest hook to deny the request with a custom response. */
195
- interface RequestDenial {
196
- status: number;
197
- code: string;
198
- message: string;
199
- }
200
- /** Middleware hook for auth, rate limiting, and request validation. */
201
- type OnRequestHook = (ctx: RequestContext) => undefined | RequestDenial | Promise<undefined | RequestDenial>;
202
- interface ServerExecutionTarget {
203
- query<T = Record<string, unknown>>(sql: string, params?: Params, options?: QueryOptions): Promise<T[]>;
204
- execute(sql: string, params?: Params, options?: QueryOptions): Promise<ExecuteResult>;
205
- transaction<T>(fn: (tx: Transaction) => Promise<T>, options?: QueryOptions): Promise<T>;
206
- }
207
- type ServerExecutionTargetResolver = (databaseId: string) => ServerExecutionTarget | null | undefined | Promise<ServerExecutionTarget | null | undefined>;
208
- /** Options for the standalone HTTP + WS server. */
209
- interface ServerOptions {
210
- host?: string;
211
- port?: number;
212
- cors?: boolean | CorsOptions;
213
- onRequest?: OnRequestHook;
214
- resolveExecutionTarget?: ServerExecutionTargetResolver;
215
- getReplicationStatus?: () => ReplicationStatusInfo | null;
216
- getClusterStatus?: (databaseId: string) => ClusterStatusInfo | null;
217
- }
218
- interface ReplicationStatusInfo {
219
- role: string;
220
- writeForwarding: boolean;
221
- peers: number;
222
- localSeq: bigint;
223
- replicationGroupId?: string;
224
- primaryTerm?: bigint;
225
- currentPrimary?: string;
226
- coordinator?: {
227
- connected: boolean;
228
- authority: boolean;
229
- };
230
- controller?: {
231
- state: 'disabled' | 'standby' | 'active' | 'lost';
232
- };
233
- inSyncReplicas?: string[];
234
- laggingReplicas?: string[];
235
- syncState?: string;
236
- readAvailability?: 'available' | 'unavailable';
237
- writeAvailability?: 'available' | 'unavailable';
238
- }
239
- /** CORS configuration. */
240
- interface CorsOptions {
241
- origin?: string | string[];
242
- methods?: string[];
243
- headers?: string[];
244
- }
245
- /** Options for the mountable WebSocket handler. */
246
- interface WSHandlerOptions {
247
- /** Maximum message size in bytes. Default: 1_048_576 (1 MB). */
248
- maxPayloadLength?: number;
249
- resolveExecutionTarget?: ServerExecutionTargetResolver;
250
- }
251
- /** Options for the client SDK. */
252
- interface ClientOptions {
253
- /** Transport to use. Default: 'websocket'. */
254
- transport?: 'websocket' | 'http';
255
- /** Custom headers for HTTP requests. */
256
- headers?: Record<string, string>;
257
- /** WebSocket subprotocols sent during the browser-compatible handshake. */
258
- webSocketProtocols?: string | string[];
259
- /** Reconnect on WebSocket disconnect. Default: true. */
260
- autoReconnect?: boolean;
261
- /** Reconnect interval in ms. Default: 1000. */
262
- reconnectInterval?: number;
263
- }
264
-
265
- export { type AfterQueryHook as A, type BeforeQueryHook as B, type ChangeEvent as C, type DatabaseOptions as D, type ExecuteResult as E, type HookConfig as H, type LifecycleConfig as L, type MetricsConfig as M, type OnRequestHook as O, type Params as P, type QueryHookContext as Q, type ReadConcern as R, type SirannonOptions as S, Transaction as T, type WriteConcern as W, type BeforeConnectHook as a, type DatabaseOpenHook as b, type DatabaseCloseHook as c, type ServerOptions as d, type WSHandlerOptions as e, type ConnectionHookContext as f, type BeforeSubscribeHook as g, type QueryMetrics as h, type ConnectionMetrics as i, type CDCMetrics as j, type QueryOptions as k, type SubscriptionBuilder as l, type BackupScheduleOptions as m, type ChangeOperation as n, type ClientOptions as o, type ClusterReadEndpointInfo as p, type ClusterStatusInfo as q, type CorsOptions as r, type ReadConcernLevel as s, type ReplicationStatusInfo as t, type RequestContext as u, type RequestDenial as v, type ServerExecutionTarget as w, type ServerExecutionTargetResolver as x, type Subscription as y, type WriteConcernLevel as z };