@delali/sirannon-db 0.3.4-next.62 → 0.3.4
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 +79 -56
- package/dist/backup/index.d.ts +44 -45
- package/dist/backup/index.mjs +7 -7
- package/dist/backup-scheduler/index.d.ts +42 -41
- package/dist/backup-scheduler/index.mjs +4 -4
- package/dist/baseline-Co3iIsN_.d.ts +19 -0
- package/dist/change-tracker-DqCdeEyx.d.ts +128 -0
- package/dist/{chunk-VOSJBZ6Q.mjs → chunk-2ES3DT4A.mjs} +71 -33
- package/dist/{chunk-6CMCO7S4.mjs → chunk-2O3PP4CF.mjs} +1 -1
- package/dist/{chunk-E7Q7HE46.mjs → chunk-3BZLZ47R.mjs} +26 -26
- package/dist/chunk-4KASJKKK.mjs +2501 -0
- package/dist/{chunk-MYNI2WFS.mjs → chunk-52XW3Z76.mjs} +40 -8
- package/dist/chunk-55YRLSM2.mjs +57 -0
- package/dist/{chunk-KDAHYFW7.mjs → chunk-6AOJCNRU.mjs} +5 -5
- package/dist/{chunk-KXTYR2OQ.mjs → chunk-A3PHCO6W.mjs} +39 -111
- package/dist/chunk-ADNWEHGZ.mjs +299 -0
- package/dist/{chunk-2QLXDHAP.mjs → chunk-BLMRNSUG.mjs} +11 -2
- package/dist/chunk-BVMZJOVM.mjs +5 -0
- package/dist/{chunk-IWGIYDMZ.mjs → chunk-BZWDPF4G.mjs} +1 -1
- package/dist/{chunk-YVF2ZJTE.mjs → chunk-CZL4D3BM.mjs} +1 -1
- package/dist/{chunk-7SC2TZAS.mjs → chunk-DX4WGJL7.mjs} +2 -2
- package/dist/{chunk-45MKELYA.mjs → chunk-ESTZZPT5.mjs} +132 -13
- package/dist/{chunk-QP5L5DFJ.mjs → chunk-FJPR2CJX.mjs} +3 -3
- package/dist/chunk-HR7K3GZW.mjs +36 -0
- package/dist/{chunk-LXCGPZPA.mjs → chunk-IEKIYO4V.mjs} +1 -1
- package/dist/{chunk-TUD5CJ76.mjs → chunk-KB4OLJAD.mjs} +26 -19
- package/dist/{chunk-PBRXXISQ.mjs → chunk-KINDFBQP.mjs} +3 -2
- package/dist/{chunk-E6IMX7RS.mjs → chunk-KJLNYOOL.mjs} +2 -2
- package/dist/{chunk-BTTFW4Z4.mjs → chunk-KU32OT4H.mjs} +2 -10
- package/dist/{chunk-JQWGHSEH.mjs → chunk-NVSQ2T5Q.mjs} +71 -70
- package/dist/{chunk-W4EUTJNT.mjs → chunk-NZGSDALX.mjs} +94 -96
- package/dist/{chunk-U445A3C4.mjs → chunk-QGVRRKB2.mjs} +1 -1
- package/dist/{chunk-GYCEJNU4.mjs → chunk-R7GBXNTO.mjs} +1 -1
- package/dist/{chunk-7C36BCSN.mjs → chunk-VDN6FHU4.mjs} +1 -1
- package/dist/{chunk-6IYS4WLH.mjs → chunk-VO3ZWA2G.mjs} +142 -115
- package/dist/chunk-WOMADPM4.mjs +12 -0
- package/dist/{chunk-OUSWVNWT.mjs → chunk-YCMB6GR4.mjs} +1 -1
- package/dist/{chunk-YNTDOFTN.mjs → chunk-YW7IKQ7T.mjs} +1 -1
- package/dist/{chunk-M2BEAH5I.mjs → chunk-ZN4HI5FK.mjs} +126 -72
- package/dist/{chunk-SBL6GN43.mjs → chunk-ZYWI45EN.mjs} +1 -1
- package/dist/client/index.d.ts +135 -137
- package/dist/client/index.mjs +177 -82
- package/dist/client/topology.d.ts +31 -31
- package/dist/client/topology.mjs +42 -23
- package/dist/client-base-BxTocU1x.d.ts +398 -0
- package/dist/client-streams-YKANXMWO.mjs +112 -0
- package/dist/codegen/cli.mjs +4 -4
- package/dist/codegen/index.d.ts +36 -29
- package/dist/codegen/index.mjs +4 -4
- package/dist/core/index.d.ts +130 -115
- package/dist/core/index.mjs +387 -297
- package/dist/core/writer-worker.mjs +3 -3
- package/dist/database-CGDsXW1K.d.ts +959 -0
- package/dist/database-backup-DcLhxoa1.d.ts +143 -0
- package/dist/driver/better-sqlite3.d.ts +11 -10
- package/dist/driver/better-sqlite3.mjs +11 -11
- package/dist/driver/bun.d.ts +9 -8
- package/dist/driver/expo.d.ts +6 -7
- package/dist/driver/node.d.ts +11 -10
- package/dist/driver/node.mjs +13 -11
- package/dist/driver/wa-sqlite.d.ts +6 -6
- package/dist/errors-CJUkQ-KL.d.ts +199 -0
- package/dist/file-migrations/index.d.ts +20 -18
- package/dist/file-migrations/index.mjs +3 -3
- package/dist/forward-rpc-VRWFZXHN.mjs +44 -0
- package/dist/operation-registry-CGhNT-Sn.d.ts +96 -0
- package/dist/primary-wins-CHNOYuN7.d.ts +81 -0
- package/dist/protocol-DFpNNsIT.d.ts +153 -0
- package/dist/query-types-5B02ixH0.d.ts +129 -0
- package/dist/react/index.d.ts +22 -22
- package/dist/replication/coordinator/etcd.d.ts +37 -31
- package/dist/replication/coordinator/etcd.mjs +296 -131
- package/dist/replication/index.d.ts +201 -161
- package/dist/replication/index.mjs +630 -529
- package/dist/restore-options-CH8mE-Tb.d.ts +84 -0
- package/dist/server/index.d.ts +201 -191
- package/dist/server/index.mjs +736 -619
- package/dist/server-options-aYtCkefX.d.ts +317 -0
- package/dist/server-streams-24XL4T43.mjs +254 -0
- package/dist/sirannon-J3EgPVD7.d.ts +179 -0
- package/dist/transport/grpc.d.ts +37 -24
- package/dist/transport/grpc.mjs +83 -3199
- package/dist/transport/memory.d.ts +25 -26
- package/dist/transport/memory.mjs +18 -9
- package/dist/types-BrAiDGOb.d.ts +505 -0
- package/dist/types-CEJG0eFS.d.ts +88 -0
- package/dist/types-Dc8oWlxj.d.ts +1580 -0
- package/dist/types-DqODKeOq.d.ts +123 -0
- package/dist/types-guEKSzMr.d.ts +367 -0
- package/package.json +7 -7
- package/dist/baseline-D93hcIEE.d.ts +0 -17
- package/dist/change-tracker-CjRFuZdB.d.ts +0 -144
- package/dist/client-base-Cmd9EVme.d.ts +0 -397
- package/dist/database-BLQvqjsw.d.ts +0 -917
- package/dist/database-backup-B7oszQ2n.d.ts +0 -141
- package/dist/errors-Dei4GdBb.d.ts +0 -196
- package/dist/operation-registry-oiPuSYI6.d.ts +0 -94
- package/dist/primary-wins-B0np8JS3.d.ts +0 -85
- package/dist/protocol-HI-nY8DD.d.ts +0 -152
- package/dist/query-types-p1liOP-b.d.ts +0 -127
- package/dist/restore-options-CksYsH1l.d.ts +0 -83
- package/dist/server-options-Bj5iJnjx.d.ts +0 -292
- package/dist/sirannon-BPxC5tC2.d.ts +0 -178
- package/dist/types-B0EhgDbr.d.ts +0 -340
- package/dist/types-CbjfRwrK.d.ts +0 -499
- package/dist/types-CjhxcjhA.d.ts +0 -123
- package/dist/types-DPSmjU54.d.ts +0 -1518
- package/dist/types-DTO4CYhW.d.ts +0 -88
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { I as SQLiteConnection } from './types-Dc8oWlxj.js';
|
|
2
|
+
import { C as ChangeEvent } from './query-types-5B02ixH0.js';
|
|
3
|
+
|
|
4
|
+
type PruneBoundarySource = 'device-sync' | 'replication' | 'device-cursors';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Configures a change tracker's retention period, change log table, and poll size.
|
|
8
|
+
*
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
interface ChangeTrackerOptions {
|
|
12
|
+
/**
|
|
13
|
+
* The age in milliseconds after which the tracker's cleanup can delete a change, which defaults to `3_600_000`, one hour.
|
|
14
|
+
*/
|
|
15
|
+
retention?: number;
|
|
16
|
+
/**
|
|
17
|
+
* The name of the change log table, which defaults to `_sirannon_changes`.
|
|
18
|
+
*/
|
|
19
|
+
changesTable?: string;
|
|
20
|
+
/**
|
|
21
|
+
* The number of changes that one poll requests, which defaults to 1000. A poll can return more, so that it ends on a transaction boundary.
|
|
22
|
+
*/
|
|
23
|
+
pollBatchSize?: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Records every insert, update, and delete on each table that you watch as a row in the change log, so that subscribers and replication can consume the changes in order.
|
|
28
|
+
*
|
|
29
|
+
* Once you watch each table that you want to capture, you can pass the tracker to a replication engine.
|
|
30
|
+
*
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
33
|
+
declare class ChangeTracker {
|
|
34
|
+
private readonly watched;
|
|
35
|
+
private lastSeq;
|
|
36
|
+
private readonly retentionMs;
|
|
37
|
+
private readonly changesTable;
|
|
38
|
+
private readonly pollBatchSize;
|
|
39
|
+
private changesTableReady;
|
|
40
|
+
private changesTableEnsured;
|
|
41
|
+
private watchedTablesCache;
|
|
42
|
+
private readonly stmtCache;
|
|
43
|
+
private readonly pruneBoundaries;
|
|
44
|
+
private lastPollAtTxBoundary;
|
|
45
|
+
constructor(options?: ChangeTrackerOptions);
|
|
46
|
+
/**
|
|
47
|
+
* Installs change-capture triggers on a table, so that every later write to it adds a row to the change log.
|
|
48
|
+
*
|
|
49
|
+
* @param conn - The writer connection on which the tracker creates the triggers.
|
|
50
|
+
* @param table - The name of the table to watch.
|
|
51
|
+
*/
|
|
52
|
+
watch(conn: SQLiteConnection, table: string): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Drops a table's change-capture triggers and removes the table from the watched set.
|
|
55
|
+
*
|
|
56
|
+
* @param conn - The writer connection on which the tracker drops the triggers.
|
|
57
|
+
* @param table - The name of the table to stop watching.
|
|
58
|
+
*/
|
|
59
|
+
unwatch(conn: SQLiteConnection, table: string): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Rebuilds the change-capture triggers on `conn` for every watched table
|
|
62
|
+
* whose column list has changed, without opening a nested transaction.
|
|
63
|
+
*
|
|
64
|
+
* Call it after a DDL statement inside an open transaction, so that the next
|
|
65
|
+
* write in that transaction records the new columns in `new_data`. You can
|
|
66
|
+
* also call it outside a transaction, in which case SQLite commits each
|
|
67
|
+
* `CREATE TRIGGER` and `DROP TRIGGER` statement on its own. The method skips
|
|
68
|
+
* a watched table that no longer exists, and it leaves that table's entry for
|
|
69
|
+
* `pruneDroppedTables` to remove after the commit. A
|
|
70
|
+
* driver error or an invalid column name propagates to the caller, so that
|
|
71
|
+
* the caller can roll back its transaction.
|
|
72
|
+
*
|
|
73
|
+
* @internal
|
|
74
|
+
*/
|
|
75
|
+
refreshAllTriggersUsingConnection(conn: SQLiteConnection): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Drops the change-capture triggers of each named table that the tracker
|
|
78
|
+
* watches, and removes that table from the watched set.
|
|
79
|
+
*
|
|
80
|
+
* Call it once a transaction that drops watched tables commits, and skip the
|
|
81
|
+
* call when that transaction rolls back. The method skips each table outside
|
|
82
|
+
* the watched set and issues `DROP TRIGGER IF EXISTS`, so a second call leaves
|
|
83
|
+
* the same state. When one transaction drops a table and creates another with
|
|
84
|
+
* the same name, `refreshAllTriggersUsingConnection` can
|
|
85
|
+
* install triggers on the new table. This method drops those triggers too, so
|
|
86
|
+
* you have to call `watch` again for the new table.
|
|
87
|
+
*
|
|
88
|
+
* @internal
|
|
89
|
+
*/
|
|
90
|
+
pruneDroppedTables(conn: SQLiteConnection, tables: readonly string[]): Promise<void>;
|
|
91
|
+
/** @internal */
|
|
92
|
+
poll(conn: SQLiteConnection): Promise<ChangeEvent[]>;
|
|
93
|
+
/** @internal */
|
|
94
|
+
get pollEndedAtTxBoundary(): boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Returns the sequence number of the last change that the tracker polled or skipped with `advanceToLatest`, so live subscribers receive only later changes.
|
|
97
|
+
*
|
|
98
|
+
* @internal
|
|
99
|
+
*/
|
|
100
|
+
get cursor(): bigint;
|
|
101
|
+
/** @internal */
|
|
102
|
+
readSinceTables(conn: SQLiteConnection, tables: readonly string[], afterSeq: bigint, upToSeq: bigint, limit: number): Promise<ChangeEvent[]>;
|
|
103
|
+
/**
|
|
104
|
+
* Returns the lowest sequence number in the change log, or `null` when the log is empty or missing.
|
|
105
|
+
*
|
|
106
|
+
* @internal
|
|
107
|
+
*/
|
|
108
|
+
getMinSeq(conn: SQLiteConnection): Promise<bigint | null>;
|
|
109
|
+
/** @internal */
|
|
110
|
+
advanceToLatest(conn: SQLiteConnection): Promise<void>;
|
|
111
|
+
/** @internal */
|
|
112
|
+
cleanup(conn: SQLiteConnection): Promise<number>;
|
|
113
|
+
/** @internal */
|
|
114
|
+
setPruneBoundary(source: PruneBoundarySource, seq: bigint): void;
|
|
115
|
+
/** @internal */
|
|
116
|
+
clearPruneBoundary(source: PruneBoundarySource): void;
|
|
117
|
+
/** @internal */
|
|
118
|
+
get changeLogTable(): string;
|
|
119
|
+
/** @internal */
|
|
120
|
+
get watchedTables(): ReadonlySet<string>;
|
|
121
|
+
private computeSeqBound;
|
|
122
|
+
private assertIdentifier;
|
|
123
|
+
private detectChangesTable;
|
|
124
|
+
private ensureChangesTable;
|
|
125
|
+
private installTriggers;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export { ChangeTracker as C, type ChangeTrackerOptions as a };
|
|
@@ -1,28 +1,35 @@
|
|
|
1
|
-
import { tokenizeSql, readSelectItems, findClauses } from './chunk-
|
|
2
|
-
import { operationRegistryDigest } from './chunk-
|
|
1
|
+
import { tokenizeSql, readSelectItems, findClauses } from './chunk-ZYWI45EN.mjs';
|
|
2
|
+
import { operationRegistryDigest } from './chunk-KB4OLJAD.mjs';
|
|
3
3
|
import { mkdirSync, writeFileSync } from 'fs';
|
|
4
4
|
import { resolve, dirname } from 'path';
|
|
5
5
|
import { pathToFileURL } from 'url';
|
|
6
6
|
|
|
7
7
|
// src/codegen/manifest.ts
|
|
8
8
|
var OPERATION_MANIFEST_VERSION = 1;
|
|
9
|
-
function buildOperationManifest(registry) {
|
|
9
|
+
function buildOperationManifest(registry, shared) {
|
|
10
10
|
const databases = {};
|
|
11
11
|
for (const databaseId of Object.keys(registry).sort()) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
12
|
+
databases[databaseId] = databaseManifest(registry[databaseId] ?? {});
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
version: OPERATION_MANIFEST_VERSION,
|
|
16
|
+
digest: operationRegistryDigest(registry, shared),
|
|
17
|
+
databases,
|
|
18
|
+
...shared === void 0 ? {} : { shared: databaseManifest(shared) }
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function databaseManifest(operations) {
|
|
22
|
+
const reads = {};
|
|
23
|
+
const writes = {};
|
|
24
|
+
for (const name of Object.keys(operations.reads ?? {}).sort()) {
|
|
25
|
+
const read = operations.reads?.[name];
|
|
26
|
+
if (read !== void 0) reads[name] = readShape(read);
|
|
27
|
+
}
|
|
28
|
+
for (const name of Object.keys(operations.writes ?? {}).sort()) {
|
|
29
|
+
const write2 = operations.writes?.[name];
|
|
30
|
+
if (write2 !== void 0) writes[name] = writeShape(write2);
|
|
24
31
|
}
|
|
25
|
-
return {
|
|
32
|
+
return { reads, writes };
|
|
26
33
|
}
|
|
27
34
|
function readShape(operation) {
|
|
28
35
|
const args = [...operation.args ?? []];
|
|
@@ -69,34 +76,48 @@ function renderOperationTypes(manifest, options) {
|
|
|
69
76
|
const declared = /* @__PURE__ */ new Map();
|
|
70
77
|
for (const databaseId of Object.keys(manifest.databases).sort()) {
|
|
71
78
|
const database = manifest.databases[databaseId];
|
|
72
|
-
|
|
79
|
+
const names = {
|
|
80
|
+
constant: identifier(databaseId),
|
|
81
|
+
rowPrefix: pascalCase(databaseId),
|
|
82
|
+
claimant: { owner: `database/${databaseId}`, label: databaseId }
|
|
83
|
+
};
|
|
84
|
+
lines.push("", ...renderOperations(names, database, declared));
|
|
85
|
+
}
|
|
86
|
+
if (manifest.shared !== void 0) {
|
|
87
|
+
const names = { constant: SHARED_CONSTANT, rowPrefix: SHARED_ROW_PREFIX, claimant: SHARED_CLAIMANT };
|
|
88
|
+
lines.push("", ...renderOperations(names, manifest.shared, declared));
|
|
73
89
|
}
|
|
74
90
|
return `${lines.join("\n")}
|
|
75
91
|
`;
|
|
76
92
|
}
|
|
77
|
-
|
|
93
|
+
var SHARED_CONSTANT = "sharedOperations";
|
|
94
|
+
var SHARED_ROW_PREFIX = "Shared";
|
|
95
|
+
var SHARED_CLAIMANT = { owner: "shared", label: SHARED_CONSTANT };
|
|
96
|
+
function claim(declared, generated, claimant) {
|
|
78
97
|
const taken = declared.get(generated);
|
|
79
|
-
if (taken !== void 0 && taken !==
|
|
98
|
+
if (taken !== void 0 && taken.owner !== claimant.owner) {
|
|
80
99
|
throw new Error(
|
|
81
|
-
`'${
|
|
100
|
+
`'${claimant.label}' and '${taken.label}' both generate the identifier '${generated}'. Rename one of them so the generated file declares each name once.`
|
|
82
101
|
);
|
|
83
102
|
}
|
|
84
|
-
declared.set(generated,
|
|
103
|
+
declared.set(generated, claimant);
|
|
85
104
|
return generated;
|
|
86
105
|
}
|
|
87
|
-
function
|
|
88
|
-
|
|
106
|
+
function readClaimant(claimant, name) {
|
|
107
|
+
return { owner: `${claimant.owner}/reads/${name}`, label: `${claimant.label}.reads.${name}` };
|
|
108
|
+
}
|
|
109
|
+
function renderOperations(names, database, declared) {
|
|
89
110
|
const rowTypes = /* @__PURE__ */ new Map();
|
|
90
111
|
const lines = [];
|
|
91
112
|
for (const [name, shape] of Object.entries(database.reads)) {
|
|
92
113
|
if (shape.columns === null) continue;
|
|
93
|
-
const rowType = claim(declared, `${
|
|
114
|
+
const rowType = claim(declared, `${names.rowPrefix}${pascalCase(name)}Row`, readClaimant(names.claimant, name));
|
|
94
115
|
rowTypes.set(name, rowType);
|
|
95
116
|
lines.push(`export interface ${rowType} {`);
|
|
96
117
|
for (const column of shape.columns) lines.push(` ${propertyKey(column)}: unknown`);
|
|
97
118
|
lines.push("}", "");
|
|
98
119
|
}
|
|
99
|
-
lines.push(`export const ${claim(declared,
|
|
120
|
+
lines.push(`export const ${claim(declared, names.constant, names.claimant)} = {`, " reads: {");
|
|
100
121
|
for (const [name, shape] of Object.entries(database.reads)) {
|
|
101
122
|
const row = rowTypes.get(name) ?? "Record<string, unknown>";
|
|
102
123
|
lines.push(
|
|
@@ -127,11 +148,15 @@ function identifier(value) {
|
|
|
127
148
|
function pascalCase(value) {
|
|
128
149
|
return value.split(/[^A-Za-z0-9]+/).filter((part) => part.length > 0).map((part) => part[0].toUpperCase() + part.slice(1)).join("");
|
|
129
150
|
}
|
|
130
|
-
var CODEGEN_USAGE = `sirannon-codegen --registry <module> --out <file> [--manifest <file>] [--export <name>] [--package <name>]
|
|
151
|
+
var CODEGEN_USAGE = `sirannon-codegen --registry <module> --out <file> [--manifest <file>] [--export <name>] [--shared-export <name>] [--package <name>]
|
|
131
152
|
|
|
132
|
-
Reads the
|
|
133
|
-
references a client calls
|
|
134
|
-
|
|
153
|
+
Reads the operations that you register with a server and writes the typed
|
|
154
|
+
references through which a client calls them. The generator takes the
|
|
155
|
+
per-database registry from the 'operations' export, or from the default
|
|
156
|
+
export, and the operations for every database from the 'sharedOperations'
|
|
157
|
+
export. The generator imports the registry module, so run it under a loader
|
|
158
|
+
that reads your source format when that format is not JavaScript.`;
|
|
159
|
+
var DEFAULT_SHARED_EXPORT = "sharedOperations";
|
|
135
160
|
function parseOptions(argv) {
|
|
136
161
|
const values = /* @__PURE__ */ new Map();
|
|
137
162
|
for (let i = 0; i < argv.length; i += 2) {
|
|
@@ -156,16 +181,28 @@ ${CODEGEN_USAGE}`);
|
|
|
156
181
|
out,
|
|
157
182
|
manifest: values.get("manifest"),
|
|
158
183
|
exportName: values.get("export"),
|
|
184
|
+
sharedExportName: values.get("shared-export"),
|
|
159
185
|
packageName: values.get("package")
|
|
160
186
|
};
|
|
161
187
|
}
|
|
162
|
-
function
|
|
188
|
+
function readShared(module, exportName, path) {
|
|
189
|
+
const candidate = module[exportName ?? DEFAULT_SHARED_EXPORT];
|
|
190
|
+
if (candidate === void 0 && exportName === void 0) return void 0;
|
|
191
|
+
if (candidate === void 0 || candidate === null || typeof candidate !== "object") {
|
|
192
|
+
throw new Error(`Module '${path}' exports no shared operations named '${exportName ?? DEFAULT_SHARED_EXPORT}'`);
|
|
193
|
+
}
|
|
194
|
+
return candidate;
|
|
195
|
+
}
|
|
196
|
+
function readRegistry(module, options, path) {
|
|
197
|
+
const shared = readShared(module, options.sharedExportName, path);
|
|
198
|
+
const { exportName } = options;
|
|
163
199
|
const candidate = exportName === void 0 ? module.operations ?? module.default : module[exportName];
|
|
164
|
-
if (candidate === void 0
|
|
200
|
+
if (candidate === void 0 && exportName === void 0 && shared !== void 0) return { registry: {}, shared };
|
|
201
|
+
if (candidate === void 0 || candidate === null || typeof candidate !== "object") {
|
|
165
202
|
const named = exportName === void 0 ? "'operations' or a default export" : `'${exportName}'`;
|
|
166
203
|
throw new Error(`Module '${path}' exports no operation registry named ${named}`);
|
|
167
204
|
}
|
|
168
|
-
return candidate;
|
|
205
|
+
return { registry: candidate, shared };
|
|
169
206
|
}
|
|
170
207
|
function write(path, contents) {
|
|
171
208
|
const target = resolve(path);
|
|
@@ -176,7 +213,8 @@ async function runCodegen(argv) {
|
|
|
176
213
|
const options = parseOptions(argv);
|
|
177
214
|
const modulePath = resolve(options.registry);
|
|
178
215
|
const imported = await import(pathToFileURL(modulePath).href);
|
|
179
|
-
const
|
|
216
|
+
const { registry, shared } = readRegistry(imported, options, modulePath);
|
|
217
|
+
const manifest = buildOperationManifest(registry, shared);
|
|
180
218
|
write(options.out, renderOperationTypes(manifest, { packageName: options.packageName }));
|
|
181
219
|
if (options.manifest !== void 0) {
|
|
182
220
|
write(options.manifest, `${JSON.stringify(manifest, null, 2)}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { planBackupRestore } from './chunk-
|
|
2
|
-
import { listStoredFilePieces, fetchStoredFile, checkpointLog } from './chunk-
|
|
3
|
-
import { destinationWithDeadline, DEFAULT_DESTINATION_TIMEOUT_MS, reportQuietly, LOG_HEADER_BYTES, LOG_FRAME_HEADER_BYTES, readLogHeader, foldLogChecksum, MAGIC_WITH_LITTLE_ENDIAN_CONTENT, LOG_FORMAT_VERSION } from './chunk-
|
|
4
|
-
import { readBackupChains, DEFAULT_CHAIN_NAME } from './chunk-
|
|
1
|
+
import { planBackupRestore } from './chunk-YW7IKQ7T.mjs';
|
|
2
|
+
import { listStoredFilePieces, fetchStoredFile, checkpointLog } from './chunk-QGVRRKB2.mjs';
|
|
3
|
+
import { destinationWithDeadline, DEFAULT_DESTINATION_TIMEOUT_MS, reportQuietly, LOG_HEADER_BYTES, LOG_FRAME_HEADER_BYTES, readLogHeader, foldLogChecksum, MAGIC_WITH_LITTLE_ENDIAN_CONTENT, LOG_FORMAT_VERSION } from './chunk-R7GBXNTO.mjs';
|
|
4
|
+
import { readBackupChains, DEFAULT_CHAIN_NAME } from './chunk-CZL4D3BM.mjs';
|
|
5
5
|
import { randomHex } from './chunk-QBBLSQHQ.mjs';
|
|
6
|
-
import { SirannonError } from './chunk-
|
|
6
|
+
import { SirannonError } from './chunk-KINDFBQP.mjs';
|
|
7
7
|
import { rename, open, rm, stat } from 'fs/promises';
|
|
8
8
|
|
|
9
9
|
// src/core/backup/write-fully.ts
|
|
@@ -134,11 +134,11 @@ var RestoreLogWriter = class _RestoreLogWriter {
|
|
|
134
134
|
expected;
|
|
135
135
|
closed = false;
|
|
136
136
|
/**
|
|
137
|
-
*
|
|
137
|
+
* Creates the log next to a restored database and writes its header.
|
|
138
138
|
*
|
|
139
|
-
* @param path -
|
|
140
|
-
* @param pageSize -
|
|
141
|
-
* @param logSequence -
|
|
139
|
+
* @param path - The path of the log file.
|
|
140
|
+
* @param pageSize - The page size of the database that Sirannon restores, in bytes.
|
|
141
|
+
* @param logSequence - The checkpoint sequence number to write into the header.
|
|
142
142
|
* @returns The writer, ready for the first piece.
|
|
143
143
|
*/
|
|
144
144
|
static async create(path, pageSize, logSequence) {
|
|
@@ -156,21 +156,20 @@ var RestoreLogWriter = class _RestoreLogWriter {
|
|
|
156
156
|
}
|
|
157
157
|
return new _RestoreLogWriter(handle, path, pageSize, salt1, salt2, checksum);
|
|
158
158
|
}
|
|
159
|
-
/**
|
|
159
|
+
/** The size of one frame in bytes, which is its header plus one page. */
|
|
160
160
|
get frameBytes() {
|
|
161
161
|
return LOG_FRAME_HEADER_BYTES + this.pageSize;
|
|
162
162
|
}
|
|
163
163
|
/**
|
|
164
|
-
* Starts a new change piece,
|
|
165
|
-
*
|
|
164
|
+
* Starts a new change piece, with the number of log header bytes before its
|
|
165
|
+
* first frame.
|
|
166
166
|
*
|
|
167
|
-
* Where the piece begins with a header,
|
|
168
|
-
* the record
|
|
169
|
-
*
|
|
170
|
-
* wrong length.
|
|
167
|
+
* Where the piece begins with a header, the writer checks that header against
|
|
168
|
+
* the chain record of the piece, since a record with the wrong page size would
|
|
169
|
+
* make SQLite read every frame at the wrong length.
|
|
171
170
|
*
|
|
172
|
-
* @param headerBytes -
|
|
173
|
-
* @param expected -
|
|
171
|
+
* @param headerBytes - The number of log header bytes before the frames.
|
|
172
|
+
* @param expected - The header values that the chain record of the piece states.
|
|
174
173
|
*/
|
|
175
174
|
beginPiece(headerBytes, expected) {
|
|
176
175
|
if (this.carry.byteLength > 0) {
|
|
@@ -183,11 +182,12 @@ var RestoreLogWriter = class _RestoreLogWriter {
|
|
|
183
182
|
this.expected = expected;
|
|
184
183
|
}
|
|
185
184
|
/**
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
* the
|
|
185
|
+
* Writes the salts and checksum of this log into every whole frame in the
|
|
186
|
+
* given bytes, and appends those frames to the log. Where a frame spans two
|
|
187
|
+
* stored pieces, the writer keeps the first part until the next call supplies
|
|
188
|
+
* the rest.
|
|
189
189
|
*
|
|
190
|
-
* @param bytes - The next
|
|
190
|
+
* @param bytes - The next bytes of the change piece.
|
|
191
191
|
*/
|
|
192
192
|
async add(bytes) {
|
|
193
193
|
let arriving = bytes;
|
|
@@ -251,10 +251,10 @@ var RestoreLogWriter = class _RestoreLogWriter {
|
|
|
251
251
|
}
|
|
252
252
|
}
|
|
253
253
|
/**
|
|
254
|
-
* Closes the log and
|
|
254
|
+
* Closes the log and returns its frame count and the resulting database size.
|
|
255
255
|
*
|
|
256
|
-
* @returns The frames the log
|
|
257
|
-
* @throws A `BACKUP_CHAIN_BROKEN` where the pieces
|
|
256
|
+
* @returns The number of frames in the log, and the number of pages in the database after SQLite applies them.
|
|
257
|
+
* @throws A `BACKUP_CHAIN_BROKEN` where the pieces end part-way through a frame, or where the last frame commits no transaction.
|
|
258
258
|
*/
|
|
259
259
|
async finish() {
|
|
260
260
|
await this.close();
|
|
@@ -270,7 +270,7 @@ var RestoreLogWriter = class _RestoreLogWriter {
|
|
|
270
270
|
}
|
|
271
271
|
return { frameCount: this.framesWritten, databasePages: this.lastDatabasePages };
|
|
272
272
|
}
|
|
273
|
-
/** Closes the log without checking it, which
|
|
273
|
+
/** Closes the log without checking it, which Sirannon does for a failed batch before it deletes the file. */
|
|
274
274
|
async abandon() {
|
|
275
275
|
await this.close().catch(() => {
|
|
276
276
|
});
|