@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.
- package/README.md +154 -19
- package/dist/backup-scheduler/index.d.ts +18 -3
- package/dist/backup-scheduler/index.mjs +2 -2
- package/dist/{change-tracker-CFTQ9TSn.d.ts → change-tracker-CbmaMO-N.d.ts} +12 -2
- package/dist/chunk-4ISB7XMA.mjs +21 -0
- package/dist/chunk-BNUTBHHH.mjs +22 -0
- package/dist/chunk-CJLYFDP5.mjs +26 -0
- package/dist/chunk-CW6S3WL5.mjs +222 -0
- package/dist/chunk-DVWQD3GF.mjs +49 -0
- package/dist/chunk-GEZUUIKV.mjs +268 -0
- package/dist/{chunk-UVMVN3OT.mjs → chunk-H5AB6NIR.mjs} +1 -1
- package/dist/{chunk-UTO3ZAFS.mjs → chunk-HHRMRFFR.mjs} +148 -28
- package/dist/chunk-TKGHYWQ6.mjs +35 -0
- package/dist/chunk-UXLAO6ZH.mjs +352 -0
- package/dist/chunk-VLTICJOD.mjs +470 -0
- package/dist/{chunk-O7BHI3CF.mjs → chunk-YPYVQJ4C.mjs} +15 -1
- package/dist/client/index.d.ts +107 -15
- package/dist/client/index.mjs +348 -37
- package/dist/core/index.d.ts +70 -13
- package/dist/core/index.mjs +635 -192
- package/dist/core/writer-worker.d.ts +2 -0
- package/dist/core/writer-worker.mjs +129 -0
- package/dist/{database-BVY1GqE7.d.ts → database-DuGp0Rtr.d.ts} +51 -19
- package/dist/driver/better-sqlite3.d.ts +1 -1
- package/dist/driver/better-sqlite3.mjs +44 -6
- package/dist/driver/bun.mjs +35 -6
- package/dist/driver/expo.mjs +2 -2
- package/dist/driver/node.d.ts +1 -1
- package/dist/driver/node.mjs +48 -5
- package/dist/driver/wa-sqlite.d.ts +109 -0
- package/dist/driver/wa-sqlite.mjs +30 -2
- package/dist/{errors-C00ed08Q.d.ts → errors-5Nf5ZAEC.d.ts} +19 -1
- package/dist/file-migrations/index.d.ts +2 -3
- package/dist/file-migrations/index.mjs +1 -1
- package/dist/replication/coordinator/etcd.mjs +2 -2
- package/dist/replication/index.d.ts +7 -8
- package/dist/replication/index.mjs +79 -78
- package/dist/server/index.d.ts +111 -28
- package/dist/server/index.mjs +1016 -384
- package/dist/{sirannon-Cd-lK6T0.d.ts → sirannon-4SspRvP5.d.ts} +3 -3
- package/dist/transport/grpc.d.ts +3 -4
- package/dist/transport/grpc.mjs +2 -2
- package/dist/{types-Lc7ywFx7.d.ts → types-BsjobKbl.d.ts} +2 -2
- package/dist/{types-BeozgNPr.d.ts → types-D4p4UyDK.d.ts} +1 -1
- package/dist/types-D_hQW1hr.d.ts +494 -0
- package/package.json +3 -23
- package/dist/chunk-3MCMONVP.mjs +0 -115
- package/dist/chunk-74UN4DIE.mjs +0 -14
- package/dist/chunk-FB2U2Q3Y.mjs +0 -21
- package/dist/chunk-GS7T5YMI.mjs +0 -51
- package/dist/chunk-PXKAKK2V.mjs +0 -124
- package/dist/index-CLdNrcPz.d.ts +0 -16
- package/dist/types-BFSsG77t.d.ts +0 -29
- package/dist/types-D-74JiXb.d.ts +0 -265
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { D as Database } from './database-
|
|
2
|
-
import { S as SQLiteDriver } from './types-
|
|
3
|
-
import { S as SirannonOptions, D as DatabaseOptions, B as BeforeQueryHook, A as AfterQueryHook, a as BeforeConnectHook, b as DatabaseOpenHook, c as DatabaseCloseHook } from './types-D-74JiXb.js';
|
|
1
|
+
import { D as Database } from './database-DuGp0Rtr.js';
|
|
2
|
+
import { S as SirannonOptions, a as SQLiteDriver, D as DatabaseOptions, B as BeforeQueryHook, A as AfterQueryHook, b as BeforeConnectHook, c as DatabaseOpenHook, d as DatabaseCloseHook } from './types-D_hQW1hr.js';
|
|
4
3
|
|
|
5
4
|
declare class Sirannon {
|
|
6
5
|
readonly options: SirannonOptions;
|
|
@@ -14,6 +13,7 @@ declare class Sirannon {
|
|
|
14
13
|
constructor(options: SirannonOptions);
|
|
15
14
|
get driver(): SQLiteDriver;
|
|
16
15
|
open(id: string, path: string, options?: DatabaseOptions): Promise<Database>;
|
|
16
|
+
private withRegistryDefaults;
|
|
17
17
|
close(id: string): Promise<void>;
|
|
18
18
|
get(id: string): Database | undefined;
|
|
19
19
|
resolve(id: string): Promise<Database | undefined>;
|
package/dist/transport/grpc.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { BinaryWriter, BinaryReader } from '@bufbuild/protobuf/wire';
|
|
2
2
|
import { Client, ClientDuplexStream, CallOptions, Metadata, ServiceError, ClientUnaryCall, ChannelCredentials, ClientOptions, ServerDuplexStream, Server } from '@grpc/grpc-js';
|
|
3
3
|
import { HealthImplementation } from 'grpc-health-check';
|
|
4
|
-
import { R as ReplicationBatch, a as ReplicationAck, F as ForwardedTransaction, b as ForwardedTransactionResult, N as NodeInfo, S as SyncRequest, c as SyncBatch, d as SyncComplete, e as SyncAck, f as ReplicationTransport, T as TopologyRole, g as TransportConfig } from '../types-
|
|
5
|
-
import '../change-tracker-
|
|
6
|
-
import '../types-
|
|
7
|
-
import '../types-D-74JiXb.js';
|
|
4
|
+
import { R as ReplicationBatch, a as ReplicationAck, F as ForwardedTransaction, b as ForwardedTransactionResult, N as NodeInfo, S as SyncRequest, c as SyncBatch, d as SyncComplete, e as SyncAck, f as ReplicationTransport, T as TopologyRole, g as TransportConfig } from '../types-BsjobKbl.js';
|
|
5
|
+
import '../change-tracker-CbmaMO-N.js';
|
|
6
|
+
import '../types-D_hQW1hr.js';
|
|
8
7
|
import '../types-BEu1I_9_.js';
|
|
9
8
|
|
|
10
9
|
interface ColumnValue {
|
package/dist/transport/grpc.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { TransportError } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
import { TransportError } from '../chunk-H5AB6NIR.mjs';
|
|
2
|
+
import '../chunk-YPYVQJ4C.mjs';
|
|
3
3
|
import { makeGenericClientConstructor, Metadata, Server, status, ServerCredentials, credentials } from '@grpc/grpc-js';
|
|
4
4
|
import { BinaryWriter, BinaryReader } from '@bufbuild/protobuf/wire';
|
|
5
5
|
import { readFileSync } from 'fs';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as ChangeTracker } from './change-tracker-
|
|
2
|
-
import {
|
|
1
|
+
import { C as ChangeTracker } from './change-tracker-CbmaMO-N.js';
|
|
2
|
+
import { e as SQLiteConnection } from './types-D_hQW1hr.js';
|
|
3
3
|
import { C as ClusterCoordinator, j as CoordinatorCompatibilityMetadata, c as ReplicationGroupState } from './types-BEu1I_9_.js';
|
|
4
4
|
|
|
5
5
|
interface NodeInfo {
|
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
declare class Transaction {
|
|
2
|
+
private readonly conn;
|
|
3
|
+
private _lastInsertRowId;
|
|
4
|
+
constructor(conn: SQLiteConnection);
|
|
5
|
+
query<T = Record<string, unknown>>(sql: string, params?: Params): Promise<T[]>;
|
|
6
|
+
execute(sql: string, params?: Params): Promise<ExecuteResult>;
|
|
7
|
+
executeBatch(sql: string, paramsBatch: Params[]): Promise<ExecuteResult[]>;
|
|
8
|
+
get lastInsertRowId(): number | bigint;
|
|
9
|
+
static run<T>(conn: SQLiteConnection, fn: (tx: Transaction) => Promise<T>): Promise<T>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** Query parameter types: named (object) or positional (array). */
|
|
13
|
+
type Params = Record<string, unknown> | unknown[];
|
|
14
|
+
type WriteConcernLevel = 'local' | 'majority' | 'all';
|
|
15
|
+
interface WriteConcern {
|
|
16
|
+
level: WriteConcernLevel;
|
|
17
|
+
timeoutMs?: number;
|
|
18
|
+
}
|
|
19
|
+
type ReadConcernLevel = 'local' | 'majority' | 'linearizable';
|
|
20
|
+
interface ReadConcern {
|
|
21
|
+
level: ReadConcernLevel;
|
|
22
|
+
}
|
|
23
|
+
interface QueryOptions {
|
|
24
|
+
writeConcern?: WriteConcern;
|
|
25
|
+
readConcern?: ReadConcern;
|
|
26
|
+
}
|
|
27
|
+
interface ClusterReadEndpointInfo {
|
|
28
|
+
nodeId: string;
|
|
29
|
+
endpoint: string;
|
|
30
|
+
readConcerns: ReadConcernLevel[];
|
|
31
|
+
}
|
|
32
|
+
interface ClusterStatusInfo {
|
|
33
|
+
databaseId: string;
|
|
34
|
+
replicationGroupId?: string;
|
|
35
|
+
role?: 'primary' | 'replica';
|
|
36
|
+
currentPrimary?: {
|
|
37
|
+
nodeId: string;
|
|
38
|
+
endpoint?: string;
|
|
39
|
+
} | null;
|
|
40
|
+
primaryTerm?: bigint;
|
|
41
|
+
readEndpoints?: ClusterReadEndpointInfo[];
|
|
42
|
+
health: 'healthy' | 'degraded' | 'failing_over' | 'unavailable' | 'repairing' | 'syncing';
|
|
43
|
+
}
|
|
44
|
+
/** Result returned by mutation statements (INSERT, UPDATE, DELETE). */
|
|
45
|
+
interface ExecuteResult {
|
|
46
|
+
changes: number;
|
|
47
|
+
lastInsertRowId: number | bigint;
|
|
48
|
+
}
|
|
49
|
+
/** CDC operation type. */
|
|
50
|
+
type ChangeOperation = 'insert' | 'update' | 'delete';
|
|
51
|
+
/** Event emitted when a watched table row changes. */
|
|
52
|
+
interface ChangeEvent<T = Record<string, unknown>> {
|
|
53
|
+
type: ChangeOperation;
|
|
54
|
+
table: string;
|
|
55
|
+
row: T;
|
|
56
|
+
oldRow?: T;
|
|
57
|
+
seq: bigint;
|
|
58
|
+
timestamp: number;
|
|
59
|
+
}
|
|
60
|
+
/** Context passed to query hooks. */
|
|
61
|
+
interface QueryHookContext {
|
|
62
|
+
databaseId: string;
|
|
63
|
+
sql: string;
|
|
64
|
+
params?: Params;
|
|
65
|
+
metadata?: Record<string, unknown>;
|
|
66
|
+
writeConcern?: WriteConcern;
|
|
67
|
+
readConcern?: ReadConcern;
|
|
68
|
+
}
|
|
69
|
+
/** Hook invoked before a query is executed. Throw to deny. */
|
|
70
|
+
type BeforeQueryHook = (ctx: QueryHookContext) => void | Promise<void>;
|
|
71
|
+
/** Hook invoked after a query is executed. */
|
|
72
|
+
type AfterQueryHook = (ctx: QueryHookContext & {
|
|
73
|
+
durationMs: number;
|
|
74
|
+
}) => void | Promise<void>;
|
|
75
|
+
/** Context passed to connection hooks. */
|
|
76
|
+
interface ConnectionHookContext {
|
|
77
|
+
databaseId: string;
|
|
78
|
+
path: string;
|
|
79
|
+
}
|
|
80
|
+
/** Hook invoked before a database connection is established. */
|
|
81
|
+
type BeforeConnectHook = (ctx: ConnectionHookContext) => void | Promise<void>;
|
|
82
|
+
/** Hook invoked when a database is opened. */
|
|
83
|
+
type DatabaseOpenHook = (ctx: ConnectionHookContext) => void | Promise<void>;
|
|
84
|
+
/** Hook invoked when a database is closed. */
|
|
85
|
+
type DatabaseCloseHook = (ctx: ConnectionHookContext) => void | Promise<void>;
|
|
86
|
+
/** Hook invoked before a subscription is created. Throw to deny. */
|
|
87
|
+
type BeforeSubscribeHook = (ctx: {
|
|
88
|
+
databaseId: string;
|
|
89
|
+
table: string;
|
|
90
|
+
filter?: Record<string, unknown>;
|
|
91
|
+
}) => void | Promise<void>;
|
|
92
|
+
/** Aggregated hook configuration. */
|
|
93
|
+
interface HookConfig {
|
|
94
|
+
onBeforeQuery?: BeforeQueryHook | BeforeQueryHook[];
|
|
95
|
+
onAfterQuery?: AfterQueryHook | AfterQueryHook[];
|
|
96
|
+
onBeforeConnect?: BeforeConnectHook | BeforeConnectHook[];
|
|
97
|
+
onDatabaseOpen?: DatabaseOpenHook | DatabaseOpenHook[];
|
|
98
|
+
onDatabaseClose?: DatabaseCloseHook | DatabaseCloseHook[];
|
|
99
|
+
onBeforeSubscribe?: BeforeSubscribeHook | BeforeSubscribeHook[];
|
|
100
|
+
}
|
|
101
|
+
/** Metrics emitted after a query completes. */
|
|
102
|
+
interface QueryMetrics {
|
|
103
|
+
databaseId: string;
|
|
104
|
+
sql: string;
|
|
105
|
+
durationMs: number;
|
|
106
|
+
rowsReturned?: number;
|
|
107
|
+
changes?: number;
|
|
108
|
+
error?: boolean;
|
|
109
|
+
}
|
|
110
|
+
/** Metrics emitted when a connection opens or closes. */
|
|
111
|
+
interface ConnectionMetrics {
|
|
112
|
+
databaseId: string;
|
|
113
|
+
path: string;
|
|
114
|
+
readerCount: number;
|
|
115
|
+
event: 'open' | 'close';
|
|
116
|
+
}
|
|
117
|
+
/** Metrics emitted when a CDC event is dispatched. */
|
|
118
|
+
interface CDCMetrics {
|
|
119
|
+
databaseId: string;
|
|
120
|
+
table: string;
|
|
121
|
+
operation: ChangeOperation;
|
|
122
|
+
subscriberCount: number;
|
|
123
|
+
}
|
|
124
|
+
/** Callbacks for metrics collection. */
|
|
125
|
+
interface MetricsConfig {
|
|
126
|
+
onQueryComplete?: (metrics: QueryMetrics) => void;
|
|
127
|
+
onConnectionOpen?: (metrics: ConnectionMetrics) => void;
|
|
128
|
+
onConnectionClose?: (metrics: ConnectionMetrics) => void;
|
|
129
|
+
onCDCEvent?: (metrics: CDCMetrics) => void;
|
|
130
|
+
}
|
|
131
|
+
/** Configuration for automatic database lifecycle management. */
|
|
132
|
+
interface LifecycleConfig {
|
|
133
|
+
autoOpen?: {
|
|
134
|
+
resolver: (id: string) => {
|
|
135
|
+
path: string;
|
|
136
|
+
options?: DatabaseOptions;
|
|
137
|
+
} | undefined;
|
|
138
|
+
};
|
|
139
|
+
/** Milliseconds before an idle database is closed. 0 = disabled. */
|
|
140
|
+
idleTimeout?: number;
|
|
141
|
+
/** Maximum number of concurrently open databases. 0 = unlimited. */
|
|
142
|
+
maxOpen?: number;
|
|
143
|
+
}
|
|
144
|
+
/** Options for opening a single database. */
|
|
145
|
+
interface DatabaseOptions {
|
|
146
|
+
/** Open the database in read-only mode. */
|
|
147
|
+
readOnly?: boolean;
|
|
148
|
+
/** Number of read connections in the pool. Default: 4. */
|
|
149
|
+
readPoolSize?: number;
|
|
150
|
+
/** Enable WAL mode. Default: true. */
|
|
151
|
+
walMode?: boolean;
|
|
152
|
+
/**
|
|
153
|
+
* Writer durability (`PRAGMA synchronous`). Default: 'normal'. This is the
|
|
154
|
+
* level restored after every bulk load, whatever the load relaxed it to.
|
|
155
|
+
*/
|
|
156
|
+
synchronous?: SynchronousLevel;
|
|
157
|
+
/** CDC polling interval in milliseconds. Default: 50. */
|
|
158
|
+
cdcPollInterval?: number;
|
|
159
|
+
/** CDC retention period in milliseconds. Default: 3_600_000 (1 hour). */
|
|
160
|
+
cdcRetention?: number;
|
|
161
|
+
/**
|
|
162
|
+
* Run writes on a dedicated worker thread so disk flushes never block the
|
|
163
|
+
* thread serving connections; reads stay on the calling thread. Requires a
|
|
164
|
+
* driver with a worker entry (the `better-sqlite3` and `node` drivers have
|
|
165
|
+
* one), otherwise opening throws. Default: off.
|
|
166
|
+
*/
|
|
167
|
+
writerWorker?: boolean | WriterWorkerOptions;
|
|
168
|
+
}
|
|
169
|
+
interface WriterWorkerOptions {
|
|
170
|
+
/** Writes allowed in flight before new writes are rejected with a busy signal. Default: 1024. */
|
|
171
|
+
maxPendingWrites?: number;
|
|
172
|
+
/** Per-operation deadline in ms; when an operation stalls past it, its caller is rejected loudly while the worker keeps running, so a stalled write's outcome is indeterminate. 0 disables it. Default: 30000. */
|
|
173
|
+
writeTimeoutMs?: number;
|
|
174
|
+
/** Restarts the worker this many times after it crashes on its own before writes fail permanently. Default: 5. */
|
|
175
|
+
maxRestarts?: number;
|
|
176
|
+
}
|
|
177
|
+
/** Top-level options for the Sirannon database registry. */
|
|
178
|
+
interface SirannonOptions {
|
|
179
|
+
driver: SQLiteDriver;
|
|
180
|
+
hooks?: HookConfig;
|
|
181
|
+
metrics?: MetricsConfig;
|
|
182
|
+
lifecycle?: LifecycleConfig;
|
|
183
|
+
writerWorker?: boolean | WriterWorkerOptions;
|
|
184
|
+
}
|
|
185
|
+
/** Options for scheduled backups. */
|
|
186
|
+
interface BackupScheduleOptions {
|
|
187
|
+
/** Cron expression (e.g., '0 * * * *' for hourly). */
|
|
188
|
+
cron: string;
|
|
189
|
+
/** Directory to store backup files. */
|
|
190
|
+
destDir: string;
|
|
191
|
+
/** Maximum number of backup files to keep. Default: 5. */
|
|
192
|
+
maxFiles?: number;
|
|
193
|
+
/**
|
|
194
|
+
* Sirannon evaluates the cron expression in this IANA time zone (e.g. 'America/New_York').
|
|
195
|
+
* When omitted, it uses the host's local time zone, which also sets the daylight saving rules that apply.
|
|
196
|
+
*/
|
|
197
|
+
timezone?: string;
|
|
198
|
+
/** Called when a scheduled backup fails. Without this, errors are silently discarded. */
|
|
199
|
+
onError?: (error: Error) => void;
|
|
200
|
+
}
|
|
201
|
+
/** Builder for creating CDC subscriptions with optional filters. */
|
|
202
|
+
interface SubscriptionBuilder {
|
|
203
|
+
filter(conditions: Record<string, unknown>): SubscriptionBuilder;
|
|
204
|
+
subscribe(callback: (event: ChangeEvent) => void): Subscription;
|
|
205
|
+
}
|
|
206
|
+
/** Handle for an active subscription. */
|
|
207
|
+
interface Subscription {
|
|
208
|
+
unsubscribe(): void;
|
|
209
|
+
}
|
|
210
|
+
/** Context passed to the onRequest middleware hook. */
|
|
211
|
+
interface RequestContext {
|
|
212
|
+
headers: Record<string, string>;
|
|
213
|
+
method: string;
|
|
214
|
+
path: string;
|
|
215
|
+
databaseId?: string;
|
|
216
|
+
remoteAddress: string;
|
|
217
|
+
}
|
|
218
|
+
/** Return this from an onRequest hook to deny the request with a custom response. */
|
|
219
|
+
interface RequestDenial {
|
|
220
|
+
status: number;
|
|
221
|
+
code: string;
|
|
222
|
+
message: string;
|
|
223
|
+
}
|
|
224
|
+
/** Middleware hook for auth, rate limiting, and request validation. */
|
|
225
|
+
type OnRequestHook = (ctx: RequestContext) => undefined | RequestDenial | Promise<undefined | RequestDenial>;
|
|
226
|
+
/**
|
|
227
|
+
* Durability level in force while a bulk load runs. SQLite sanctions 'off' for
|
|
228
|
+
* a from-scratch load that the operator can re-run after a power loss; 'off'
|
|
229
|
+
* gives up corruption safety, so it fits only a load that starts from nothing.
|
|
230
|
+
* 'normal' keeps WAL-mode corruption safety and suits loads into a database
|
|
231
|
+
* that already holds data the operator cannot afford to lose.
|
|
232
|
+
*/
|
|
233
|
+
type BulkLoadDurability = 'off' | 'normal';
|
|
234
|
+
interface BulkLoadOptions {
|
|
235
|
+
/** Durability during the load. Default: 'off'. */
|
|
236
|
+
durability?: BulkLoadDurability;
|
|
237
|
+
/**
|
|
238
|
+
* Whether this load ends with a WAL checkpoint. Default: true. Set it false
|
|
239
|
+
* on every load but the last of a multi-batch import so the one fsyncing
|
|
240
|
+
* checkpoint is paid once at the end instead of once per batch; the
|
|
241
|
+
* configured durability is still restored after each batch regardless, so an
|
|
242
|
+
* abandoned import never leaves the writer at the relaxed level.
|
|
243
|
+
*/
|
|
244
|
+
checkpoint?: boolean;
|
|
245
|
+
}
|
|
246
|
+
/** Aggregate outcome of a bulk load. Summed rather than per-row so a
|
|
247
|
+
* million-row load never holds a million result objects in memory. */
|
|
248
|
+
interface BulkLoadResult {
|
|
249
|
+
rowsLoaded: number;
|
|
250
|
+
changes: number;
|
|
251
|
+
}
|
|
252
|
+
interface ServerExecutionTarget {
|
|
253
|
+
query<T = Record<string, unknown>>(sql: string, params?: Params, options?: QueryOptions): Promise<T[]>;
|
|
254
|
+
/**
|
|
255
|
+
* Optional single-pass read that returns rows already encoded for the wire
|
|
256
|
+
* (safe-range integers as plain numbers, larger integers and BLOBs as tagged
|
|
257
|
+
* envelopes). When present the server uses it instead of {@link query}
|
|
258
|
+
* followed by a separate tag-encoding walk. A target that omits it stays
|
|
259
|
+
* correct: the server falls back to encoding {@link query} rows itself.
|
|
260
|
+
*/
|
|
261
|
+
queryForWire?(sql: string, params?: Params, options?: QueryOptions): Promise<unknown[]>;
|
|
262
|
+
execute(sql: string, params?: Params, options?: QueryOptions): Promise<ExecuteResult>;
|
|
263
|
+
transaction<T>(fn: (tx: Transaction) => Promise<T>, options?: QueryOptions): Promise<T>;
|
|
264
|
+
/**
|
|
265
|
+
* Optional entry point for a transaction whose statements are all known
|
|
266
|
+
* before it starts, which lets concurrent transactions share one commit. A
|
|
267
|
+
* target that omits it stays correct: the server falls back to
|
|
268
|
+
* {@link transaction} and runs the statements one at a time.
|
|
269
|
+
*/
|
|
270
|
+
executeTransaction?(statements: readonly {
|
|
271
|
+
sql: string;
|
|
272
|
+
params?: Params;
|
|
273
|
+
}[], options?: QueryOptions): Promise<ExecuteResult[]>;
|
|
274
|
+
/**
|
|
275
|
+
* Optional bulk-load entry point. Targets that proxy to a remote primary
|
|
276
|
+
* may omit it; the server rejects load requests for such targets instead
|
|
277
|
+
* of silently degrading to per-statement writes.
|
|
278
|
+
*/
|
|
279
|
+
bulkLoad?(sql: string, paramsBatch: Params[], options?: BulkLoadOptions): Promise<BulkLoadResult>;
|
|
280
|
+
}
|
|
281
|
+
type ServerExecutionTargetResolver = (databaseId: string) => ServerExecutionTarget | null | undefined | Promise<ServerExecutionTarget | null | undefined>;
|
|
282
|
+
/** Options for the standalone HTTP + WS server. */
|
|
283
|
+
interface ServerOptions {
|
|
284
|
+
host?: string;
|
|
285
|
+
port?: number;
|
|
286
|
+
cors?: boolean | CorsOptions;
|
|
287
|
+
/**
|
|
288
|
+
* Maximum HTTP request body and WebSocket message size in bytes. Applied
|
|
289
|
+
* identically to both transports. Must be a positive, finite integer no
|
|
290
|
+
* larger than 4_294_967_295 (the unsigned 32-bit ceiling uWebSockets.js can
|
|
291
|
+
* store; larger values would silently wrap modulo 2^32).
|
|
292
|
+
* Default: 1_048_576 (1 MB), matching the general web default and acting as
|
|
293
|
+
* a denial-of-service guard on a memory-limited server.
|
|
294
|
+
*/
|
|
295
|
+
maxBodyBytes?: number;
|
|
296
|
+
/**
|
|
297
|
+
* Maximum bytes buffered per WebSocket connection before the server stops
|
|
298
|
+
* absorbing backpressure. A single frame can be as large as `maxBodyBytes`,
|
|
299
|
+
* so this must hold several of them; the resolved value is raised to at
|
|
300
|
+
* least `maxBodyBytes` and, like `maxBodyBytes`, must not exceed
|
|
301
|
+
* 4_294_967_295. When the buffer is exceeded the server closes the
|
|
302
|
+
* connection so the client reconnects rather than losing a frame silently.
|
|
303
|
+
* Default: the larger of 16 MB and `maxBodyBytes`.
|
|
304
|
+
*/
|
|
305
|
+
maxWebSocketBackpressureBytes?: number;
|
|
306
|
+
/**
|
|
307
|
+
* How long, in milliseconds, change events are retained for WebSocket CDC
|
|
308
|
+
* subscriptions. Retention bounds both on-disk growth of the change log and
|
|
309
|
+
* how far back a reconnecting subscriber can resume. Default: 3_600_000
|
|
310
|
+
* (one hour).
|
|
311
|
+
*/
|
|
312
|
+
cdcRetentionMs?: number;
|
|
313
|
+
onRequest?: OnRequestHook;
|
|
314
|
+
resolveExecutionTarget?: ServerExecutionTargetResolver;
|
|
315
|
+
getReplicationStatus?: () => ReplicationStatusInfo | null;
|
|
316
|
+
getClusterStatus?: (databaseId: string) => ClusterStatusInfo | null;
|
|
317
|
+
}
|
|
318
|
+
interface ReplicationStatusInfo {
|
|
319
|
+
role: string;
|
|
320
|
+
writeForwarding: boolean;
|
|
321
|
+
peers: number;
|
|
322
|
+
localSeq: bigint;
|
|
323
|
+
replicationGroupId?: string;
|
|
324
|
+
primaryTerm?: bigint;
|
|
325
|
+
currentPrimary?: string;
|
|
326
|
+
coordinator?: {
|
|
327
|
+
connected: boolean;
|
|
328
|
+
authority: boolean;
|
|
329
|
+
};
|
|
330
|
+
controller?: {
|
|
331
|
+
state: 'disabled' | 'standby' | 'active' | 'lost';
|
|
332
|
+
};
|
|
333
|
+
inSyncReplicas?: string[];
|
|
334
|
+
laggingReplicas?: string[];
|
|
335
|
+
syncState?: string;
|
|
336
|
+
readAvailability?: 'available' | 'unavailable';
|
|
337
|
+
writeAvailability?: 'available' | 'unavailable';
|
|
338
|
+
}
|
|
339
|
+
/** CORS configuration. */
|
|
340
|
+
interface CorsOptions {
|
|
341
|
+
origin?: string | string[];
|
|
342
|
+
methods?: string[];
|
|
343
|
+
headers?: string[];
|
|
344
|
+
}
|
|
345
|
+
/** Options for the mountable WebSocket handler. */
|
|
346
|
+
interface WSHandlerOptions {
|
|
347
|
+
/** Maximum message size in bytes. Default: 1_048_576 (1 MB). */
|
|
348
|
+
maxPayloadLength?: number;
|
|
349
|
+
/** Change-log retention for CDC subscriptions in milliseconds. Default: 3_600_000. */
|
|
350
|
+
cdcRetentionMs?: number;
|
|
351
|
+
resolveExecutionTarget?: ServerExecutionTargetResolver;
|
|
352
|
+
}
|
|
353
|
+
/** Options for the client SDK. */
|
|
354
|
+
interface ClientOptions {
|
|
355
|
+
/** Transport to use. Default: 'websocket'. */
|
|
356
|
+
transport?: 'websocket' | 'http';
|
|
357
|
+
/** Custom headers for HTTP requests. */
|
|
358
|
+
headers?: Record<string, string>;
|
|
359
|
+
/** WebSocket subprotocols sent during the browser-compatible handshake. */
|
|
360
|
+
webSocketProtocols?: string | string[];
|
|
361
|
+
/** Reconnect on WebSocket disconnect. Default: true. */
|
|
362
|
+
autoReconnect?: boolean;
|
|
363
|
+
/** Reconnect interval in ms. Default: 1000. */
|
|
364
|
+
reconnectInterval?: number;
|
|
365
|
+
/**
|
|
366
|
+
* Per-request timeout in milliseconds for the WebSocket transport. A bulk
|
|
367
|
+
* load or batch of tens of millions of rows can legitimately run longer than
|
|
368
|
+
* the default, so raise this for large writes. Set to 0 to wait indefinitely.
|
|
369
|
+
* Default: 30000.
|
|
370
|
+
*/
|
|
371
|
+
requestTimeout?: number;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
interface WorkerHostOptions {
|
|
375
|
+
writeTimeoutMs?: number;
|
|
376
|
+
maxRestarts?: number;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
interface RunResult {
|
|
380
|
+
changes: number;
|
|
381
|
+
lastInsertRowId: number | bigint;
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Tells a caller running inside the operation that holds the writer from one
|
|
385
|
+
* merely waiting on it. A runtime without async context tracking cannot answer
|
|
386
|
+
* this, and answering it wrongly runs one caller's writes inside another
|
|
387
|
+
* caller's transaction.
|
|
388
|
+
*/
|
|
389
|
+
interface WriterContext {
|
|
390
|
+
run<T>(operation: () => T): T;
|
|
391
|
+
isActive(): boolean;
|
|
392
|
+
exit<T>(operation: () => T): T;
|
|
393
|
+
}
|
|
394
|
+
interface BackupEngine {
|
|
395
|
+
backup(conn: SQLiteConnection, destPath: string): Promise<void>;
|
|
396
|
+
schedule(conn: SQLiteConnection, options: BackupScheduleOptions, runExclusive: (op: () => Promise<void>) => Promise<void>): () => void;
|
|
397
|
+
}
|
|
398
|
+
interface BatchSummary {
|
|
399
|
+
rowsLoaded: number;
|
|
400
|
+
changes: number;
|
|
401
|
+
}
|
|
402
|
+
interface SQLiteStatement {
|
|
403
|
+
all<T = unknown>(...params: unknown[]): Promise<T[]>;
|
|
404
|
+
get<T = unknown>(...params: unknown[]): Promise<T | undefined>;
|
|
405
|
+
run(...params: unknown[]): Promise<RunResult>;
|
|
406
|
+
/**
|
|
407
|
+
* Like {@link all} but skips the safe-range BigInt narrowing, leaving every
|
|
408
|
+
* integer as a BigInt. The server wire path narrows and tags in one pass, so
|
|
409
|
+
* feeding it raw rows avoids a second walk. Optional: a driver that omits it
|
|
410
|
+
* falls back to {@link all}, still correct but with the extra narrowing walk.
|
|
411
|
+
*/
|
|
412
|
+
allRaw?<T = unknown>(...params: unknown[]): Promise<T[]>;
|
|
413
|
+
}
|
|
414
|
+
interface GroupRunError {
|
|
415
|
+
message: string;
|
|
416
|
+
name?: string;
|
|
417
|
+
code?: string;
|
|
418
|
+
}
|
|
419
|
+
type GroupRunOutcome = {
|
|
420
|
+
ok: true;
|
|
421
|
+
results: RunResult[];
|
|
422
|
+
} | {
|
|
423
|
+
ok: false;
|
|
424
|
+
error: GroupRunError;
|
|
425
|
+
};
|
|
426
|
+
interface SQLiteConnection {
|
|
427
|
+
exec(sql: string): Promise<void>;
|
|
428
|
+
prepare(sql: string): Promise<SQLiteStatement>;
|
|
429
|
+
transaction<T>(fn: (conn: SQLiteConnection) => Promise<T>): Promise<T>;
|
|
430
|
+
close(): Promise<void>;
|
|
431
|
+
runBatch?(sql: string, paramsBatch: readonly unknown[][]): Promise<RunResult[]>;
|
|
432
|
+
runBatchSummary?(sql: string, paramsBatch: readonly unknown[][]): Promise<BatchSummary>;
|
|
433
|
+
/**
|
|
434
|
+
* Runs several independent units in one transaction, one outcome per unit in
|
|
435
|
+
* order. A unit is one write or one whole transaction, and a unit that fails
|
|
436
|
+
* must not disturb the others.
|
|
437
|
+
*/
|
|
438
|
+
runGroup?(units: readonly {
|
|
439
|
+
statements: readonly {
|
|
440
|
+
sql: string;
|
|
441
|
+
params?: readonly unknown[];
|
|
442
|
+
}[];
|
|
443
|
+
}[]): Promise<GroupRunOutcome[]>;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* SQLite `PRAGMA synchronous` level applied to a connection. `normal` is safe
|
|
447
|
+
* from corruption in WAL mode but can lose the most recent commits on power
|
|
448
|
+
* loss; `full` fsyncs every commit; `extra` adds a directory sync after the
|
|
449
|
+
* rollback journal is unlinked in DELETE journal mode and equals `full` in
|
|
450
|
+
* WAL mode; `off` hands writes to the OS without syncing and is sanctioned
|
|
451
|
+
* only for re-runnable bulk loads.
|
|
452
|
+
*/
|
|
453
|
+
type SynchronousLevel = 'off' | 'normal' | 'full' | 'extra';
|
|
454
|
+
interface OpenOptions {
|
|
455
|
+
readonly?: boolean;
|
|
456
|
+
walMode?: boolean;
|
|
457
|
+
synchronous?: SynchronousLevel;
|
|
458
|
+
}
|
|
459
|
+
interface DriverCapabilities {
|
|
460
|
+
multipleConnections: boolean;
|
|
461
|
+
extensions: boolean;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Lets a worker thread rebuild the driver, since the driver's `open` function
|
|
465
|
+
* cannot cross the thread boundary. `specifier` must be importable from the
|
|
466
|
+
* worker and `config` must survive a structured clone; the worker imports the
|
|
467
|
+
* module and calls its `exportName` factory (default export otherwise) with it.
|
|
468
|
+
*/
|
|
469
|
+
interface DriverWorkerEntry {
|
|
470
|
+
specifier: string;
|
|
471
|
+
exportName?: string;
|
|
472
|
+
config?: unknown;
|
|
473
|
+
}
|
|
474
|
+
interface SQLiteDriver {
|
|
475
|
+
readonly capabilities: DriverCapabilities;
|
|
476
|
+
open(path: string, options?: OpenOptions): Promise<SQLiteConnection>;
|
|
477
|
+
readonly worker?: DriverWorkerEntry;
|
|
478
|
+
/**
|
|
479
|
+
* Offloads writes to a worker thread. Only a driver whose runtime has
|
|
480
|
+
* threads implements this, which is what keeps the thread machinery out of
|
|
481
|
+
* bundles built for runtimes that do not.
|
|
482
|
+
*/
|
|
483
|
+
startWriterHost?(path: string, options: OpenOptions, hostOptions?: WorkerHostOptions): Promise<SQLiteConnection>;
|
|
484
|
+
createWriterContext?(): WriterContext;
|
|
485
|
+
createBackupEngine?(): BackupEngine;
|
|
486
|
+
/**
|
|
487
|
+
* Makes an extension path absolute. Passing a bare name to `load_extension`
|
|
488
|
+
* would let the dynamic linker search its own paths and open a different
|
|
489
|
+
* library than the operator named.
|
|
490
|
+
*/
|
|
491
|
+
resolveExtensionPath?(extensionPath: string): string;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
export { type WriteConcernLevel as $, type AfterQueryHook as A, type BeforeQueryHook as B, type ChangeEvent as C, type DatabaseOptions as D, type ExecuteResult as E, type DriverCapabilities as F, type DriverWorkerEntry as G, type HookConfig as H, type OpenOptions as I, type ReadConcernLevel as J, type ReplicationStatusInfo as K, type LifecycleConfig as L, type MetricsConfig as M, type RequestContext as N, type OnRequestHook as O, type Params as P, type QueryHookContext as Q, type ReadConcern as R, type SirannonOptions as S, Transaction as T, type RequestDenial as U, type RunResult as V, type WriteConcern as W, type SQLiteStatement as X, type ServerExecutionTarget as Y, type ServerExecutionTargetResolver as Z, type Subscription as _, type SQLiteDriver as a, type WriterWorkerOptions as a0, type BeforeConnectHook as b, type DatabaseOpenHook as c, type DatabaseCloseHook as d, type SQLiteConnection as e, type BackupScheduleOptions as f, type BulkLoadDurability as g, type BulkLoadResult as h, type ServerOptions as i, type WSHandlerOptions as j, type ConnectionHookContext as k, type BeforeSubscribeHook as l, type QueryMetrics as m, type ConnectionMetrics as n, type CDCMetrics as o, type QueryOptions as p, type BulkLoadOptions as q, type SubscriptionBuilder as r, type SynchronousLevel as s, type WorkerHostOptions as t, type BatchSummary as u, type ChangeOperation as v, type ClientOptions as w, type ClusterReadEndpointInfo as x, type ClusterStatusInfo as y, type CorsOptions as z };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@delali/sirannon-db",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.8",
|
|
5
5
|
"description": "A production-grade library that turns SQLite databases into a networked data layer with real-time subscriptions.",
|
|
6
6
|
"author": "Delali (https://sondelali.com)",
|
|
7
7
|
"license": "Apache-2.0",
|
|
@@ -95,7 +95,6 @@
|
|
|
95
95
|
"@bufbuild/protobuf": ">=2.0.0",
|
|
96
96
|
"@grpc/grpc-js": ">=1.10.0",
|
|
97
97
|
"better-sqlite3": ">=12.0.0",
|
|
98
|
-
"croner": ">=10.0.0",
|
|
99
98
|
"expo-sqlite": ">=14.0.0",
|
|
100
99
|
"etcd3": ">=1.1.2",
|
|
101
100
|
"grpc-health-check": ">=2.0.0",
|
|
@@ -112,9 +111,6 @@
|
|
|
112
111
|
"better-sqlite3": {
|
|
113
112
|
"optional": true
|
|
114
113
|
},
|
|
115
|
-
"croner": {
|
|
116
|
-
"optional": true
|
|
117
|
-
},
|
|
118
114
|
"expo-sqlite": {
|
|
119
115
|
"optional": true
|
|
120
116
|
},
|
|
@@ -136,17 +132,12 @@
|
|
|
136
132
|
"@grpc/grpc-js": "1.14.3",
|
|
137
133
|
"@types/better-sqlite3": "7.6.13",
|
|
138
134
|
"@types/node": "25.3.3",
|
|
139
|
-
"@types/pg": "8.20.0",
|
|
140
135
|
"@vitest/coverage-v8": "4.0.18",
|
|
141
136
|
"better-sqlite3": "12.6.2",
|
|
142
|
-
"croner": "10.0.1",
|
|
143
137
|
"etcd3": "1.1.2",
|
|
144
138
|
"grpc-health-check": "2.1.0",
|
|
145
139
|
"grpc-tools": "1.13.1",
|
|
146
|
-
"pg": "8.20.0",
|
|
147
140
|
"selfsigned": "5.5.0",
|
|
148
|
-
"simple-statistics": "7.8.7",
|
|
149
|
-
"tinybench": "6.0.0",
|
|
150
141
|
"ts-proto": "2.11.6",
|
|
151
142
|
"tsup": "8.5.1",
|
|
152
143
|
"tsx": "4.21.0",
|
|
@@ -156,27 +147,16 @@
|
|
|
156
147
|
},
|
|
157
148
|
"scripts": {
|
|
158
149
|
"build": "rm -rf dist && tsup",
|
|
150
|
+
"check:bundle": "node scripts/assert-browser-bundle.mjs",
|
|
159
151
|
"test": "vitest run",
|
|
160
152
|
"test:coverage": "vitest run --coverage",
|
|
161
153
|
"test:e2e": "vitest run --config vitest.e2e.config.ts",
|
|
162
154
|
"test:failover": "vitest run --config vitest.failover.config.ts",
|
|
163
155
|
"test:soak": "vitest run --config vitest.soak.config.ts",
|
|
164
156
|
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
|
|
165
|
-
"lint": "biome check .",
|
|
157
|
+
"lint": "biome check --error-on-warnings .",
|
|
166
158
|
"lint:fix": "biome check --write .",
|
|
167
159
|
"format": "biome format --write .",
|
|
168
|
-
"bench": "node --expose-gc --import tsx benchmarks/run-all.ts",
|
|
169
|
-
"bench:micro": "node --expose-gc --import tsx benchmarks/micro/point-select.ts",
|
|
170
|
-
"bench:ycsb": "node --expose-gc --import tsx benchmarks/ycsb/workload-a.ts",
|
|
171
|
-
"bench:oltp": "node --expose-gc --import tsx benchmarks/oltp/tpc-c-lite.ts",
|
|
172
|
-
"bench:scaling": "node --expose-gc --import tsx benchmarks/scaling/concurrency.ts",
|
|
173
|
-
"bench:pool": "node --expose-gc --import tsx benchmarks/scaling/pool-sweep.ts",
|
|
174
|
-
"bench:cdc": "node --expose-gc --import tsx benchmarks/sirannon/cdc-latency.ts",
|
|
175
|
-
"bench:docker": "node --import tsx benchmarks/run-docker.ts",
|
|
176
|
-
"bench:docker:e2e": "node --import tsx benchmarks/run-e2e.ts",
|
|
177
|
-
"bench:docker:engine": "node --expose-gc --import tsx benchmarks/run-engine.ts",
|
|
178
|
-
"bench:statistical": "node --expose-gc --import tsx benchmarks/run-statistical.ts",
|
|
179
|
-
"bench:charts": "python3 benchmarks/scripts/generate-charts.py benchmarks/results/",
|
|
180
160
|
"proto:gen": "grpc_tools_node_protoc --plugin=protoc-gen-ts_proto=./node_modules/.bin/protoc-gen-ts_proto --ts_proto_out=src/transport/grpc/generated --ts_proto_opt=forceLong=bigint --ts_proto_opt=esModuleInterop=true --ts_proto_opt=outputServices=grpc-js --ts_proto_opt=env=node -I src/transport/grpc/proto src/transport/grpc/proto/replication.proto"
|
|
181
161
|
}
|
|
182
162
|
}
|