@breeztech/breez-sdk-spark 0.11.0-dev2 → 0.11.0-dev4
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/breez-sdk-spark.tgz +0 -0
- package/bundler/breez_sdk_spark_wasm.d.ts +760 -592
- package/bundler/breez_sdk_spark_wasm_bg.js +342 -42
- package/bundler/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/bundler/breez_sdk_spark_wasm_bg.wasm.d.ts +10 -3
- package/deno/breez_sdk_spark_wasm.d.ts +760 -592
- package/deno/breez_sdk_spark_wasm.js +310 -42
- package/deno/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/deno/breez_sdk_spark_wasm_bg.wasm.d.ts +10 -3
- package/nodejs/breez_sdk_spark_wasm.d.ts +760 -592
- package/nodejs/breez_sdk_spark_wasm.js +343 -42
- package/nodejs/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/nodejs/breez_sdk_spark_wasm_bg.wasm.d.ts +10 -3
- package/nodejs/index.js +10 -0
- package/nodejs/package.json +1 -0
- package/nodejs/postgres-tree-store/errors.cjs +13 -0
- package/nodejs/postgres-tree-store/index.cjs +798 -0
- package/nodejs/postgres-tree-store/migrations.cjs +150 -0
- package/nodejs/postgres-tree-store/package.json +9 -0
- package/package.json +1 -1
- package/web/breez_sdk_spark_wasm.d.ts +770 -595
- package/web/breez_sdk_spark_wasm.js +310 -42
- package/web/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/web/breez_sdk_spark_wasm_bg.wasm.d.ts +10 -3
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database Migration Manager for Breez SDK PostgreSQL Tree Store
|
|
3
|
+
*
|
|
4
|
+
* Uses a tree_schema_migrations table + pg_advisory_xact_lock to safely run
|
|
5
|
+
* migrations from concurrent processes.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { TreeStoreError } = require("./errors.cjs");
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Advisory lock ID for tree store migrations.
|
|
12
|
+
* Uses a different lock ID from the storage migrations to avoid contention.
|
|
13
|
+
* Derived from ASCII bytes of "TREE" (0x54524545).
|
|
14
|
+
*/
|
|
15
|
+
const MIGRATION_LOCK_ID = "1414743365"; // 0x54524545 as decimal string
|
|
16
|
+
|
|
17
|
+
class TreeStoreMigrationManager {
|
|
18
|
+
constructor(logger = null) {
|
|
19
|
+
this.logger = logger;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Run all pending migrations inside a single transaction with an advisory lock.
|
|
24
|
+
* @param {import('pg').Pool} pool
|
|
25
|
+
*/
|
|
26
|
+
async migrate(pool) {
|
|
27
|
+
const client = await pool.connect();
|
|
28
|
+
try {
|
|
29
|
+
await client.query("BEGIN");
|
|
30
|
+
|
|
31
|
+
// Transaction-level advisory lock — automatically released on COMMIT/ROLLBACK
|
|
32
|
+
await client.query(`SELECT pg_advisory_xact_lock(${MIGRATION_LOCK_ID})`);
|
|
33
|
+
|
|
34
|
+
// Create the migrations tracking table if needed
|
|
35
|
+
await client.query(`
|
|
36
|
+
CREATE TABLE IF NOT EXISTS tree_schema_migrations (
|
|
37
|
+
version INTEGER PRIMARY KEY,
|
|
38
|
+
applied_at TIMESTAMPTZ DEFAULT NOW()
|
|
39
|
+
)
|
|
40
|
+
`);
|
|
41
|
+
|
|
42
|
+
// Get current version
|
|
43
|
+
const versionResult = await client.query(
|
|
44
|
+
"SELECT COALESCE(MAX(version), 0) AS version FROM tree_schema_migrations"
|
|
45
|
+
);
|
|
46
|
+
const currentVersion = versionResult.rows[0].version;
|
|
47
|
+
|
|
48
|
+
const migrations = this._getMigrations();
|
|
49
|
+
|
|
50
|
+
if (currentVersion >= migrations.length) {
|
|
51
|
+
this._log("info", `Tree store database is up to date (version ${currentVersion})`);
|
|
52
|
+
await client.query("COMMIT");
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
this._log(
|
|
57
|
+
"info",
|
|
58
|
+
`Migrating tree store database from version ${currentVersion} to ${migrations.length}`
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
for (let i = currentVersion; i < migrations.length; i++) {
|
|
62
|
+
const migration = migrations[i];
|
|
63
|
+
const version = i + 1;
|
|
64
|
+
this._log("debug", `Running tree store migration ${version}: ${migration.name}`);
|
|
65
|
+
|
|
66
|
+
for (const sql of migration.sql) {
|
|
67
|
+
await client.query(sql);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
await client.query(
|
|
71
|
+
"INSERT INTO tree_schema_migrations (version) VALUES ($1)",
|
|
72
|
+
[version]
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
await client.query("COMMIT");
|
|
77
|
+
this._log("info", "Tree store database migration completed successfully");
|
|
78
|
+
} catch (error) {
|
|
79
|
+
await client.query("ROLLBACK").catch(() => {});
|
|
80
|
+
throw new TreeStoreError(
|
|
81
|
+
`Tree store migration failed: ${error.message}`,
|
|
82
|
+
error
|
|
83
|
+
);
|
|
84
|
+
} finally {
|
|
85
|
+
client.release();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
_log(level, message) {
|
|
90
|
+
if (this.logger && typeof this.logger.log === "function") {
|
|
91
|
+
this.logger.log({ line: message, level });
|
|
92
|
+
} else if (level === "error") {
|
|
93
|
+
console.error(`[TreeStoreMigrationManager] ${message}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Migrations matching the Rust PostgresTreeStore schema exactly.
|
|
99
|
+
*/
|
|
100
|
+
_getMigrations() {
|
|
101
|
+
return [
|
|
102
|
+
{
|
|
103
|
+
name: "Create tree store tables",
|
|
104
|
+
sql: [
|
|
105
|
+
`CREATE TABLE IF NOT EXISTS tree_reservations (
|
|
106
|
+
id TEXT PRIMARY KEY,
|
|
107
|
+
purpose TEXT NOT NULL,
|
|
108
|
+
pending_change_amount BIGINT NOT NULL DEFAULT 0,
|
|
109
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
110
|
+
)`,
|
|
111
|
+
|
|
112
|
+
`CREATE TABLE IF NOT EXISTS tree_leaves (
|
|
113
|
+
id TEXT PRIMARY KEY,
|
|
114
|
+
status TEXT NOT NULL,
|
|
115
|
+
is_missing_from_operators BOOLEAN NOT NULL DEFAULT FALSE,
|
|
116
|
+
reservation_id TEXT REFERENCES tree_reservations(id) ON DELETE SET NULL,
|
|
117
|
+
data JSONB NOT NULL,
|
|
118
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
119
|
+
added_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
120
|
+
)`,
|
|
121
|
+
|
|
122
|
+
`CREATE TABLE IF NOT EXISTS tree_spent_leaves (
|
|
123
|
+
leaf_id TEXT PRIMARY KEY,
|
|
124
|
+
spent_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
125
|
+
)`,
|
|
126
|
+
|
|
127
|
+
`CREATE INDEX IF NOT EXISTS idx_tree_leaves_available ON tree_leaves(status, is_missing_from_operators)
|
|
128
|
+
WHERE status = 'Available' AND is_missing_from_operators = FALSE`,
|
|
129
|
+
|
|
130
|
+
`CREATE INDEX IF NOT EXISTS idx_tree_leaves_reservation ON tree_leaves(reservation_id)
|
|
131
|
+
WHERE reservation_id IS NOT NULL`,
|
|
132
|
+
|
|
133
|
+
`CREATE INDEX IF NOT EXISTS idx_tree_leaves_added_at ON tree_leaves(added_at)`,
|
|
134
|
+
],
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: "Add swap status tracking",
|
|
138
|
+
sql: [
|
|
139
|
+
`CREATE TABLE IF NOT EXISTS tree_swap_status (
|
|
140
|
+
id INTEGER PRIMARY KEY DEFAULT 1 CHECK (id = 1),
|
|
141
|
+
last_completed_at TIMESTAMPTZ
|
|
142
|
+
)`,
|
|
143
|
+
`INSERT INTO tree_swap_status (id) VALUES (1) ON CONFLICT DO NOTHING`,
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
module.exports = { TreeStoreMigrationManager };
|
package/package.json
CHANGED