@breeztech/breez-sdk-spark 0.13.9-debug → 0.13.11-dev1
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 +1113 -1050
- package/bundler/breez_sdk_spark_wasm.js +5 -1
- package/bundler/breez_sdk_spark_wasm_bg.js +1493 -1628
- package/bundler/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/bundler/breez_sdk_spark_wasm_bg.wasm.d.ts +14 -6
- package/deno/breez_sdk_spark_wasm.d.ts +1113 -1050
- package/deno/breez_sdk_spark_wasm.js +1394 -1284
- package/deno/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/deno/breez_sdk_spark_wasm_bg.wasm.d.ts +14 -6
- package/nodejs/breez_sdk_spark_wasm.d.ts +1113 -1050
- package/nodejs/breez_sdk_spark_wasm.js +2527 -2654
- package/nodejs/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/nodejs/breez_sdk_spark_wasm_bg.wasm.d.ts +14 -6
- package/nodejs/index.js +34 -0
- package/nodejs/index.mjs +5 -4
- package/nodejs/mysql-storage/errors.cjs +19 -0
- package/nodejs/mysql-storage/index.cjs +1366 -0
- package/nodejs/mysql-storage/migrations.cjs +387 -0
- package/nodejs/mysql-storage/package.json +9 -0
- package/nodejs/mysql-token-store/errors.cjs +9 -0
- package/nodejs/mysql-token-store/index.cjs +988 -0
- package/nodejs/mysql-token-store/migrations.cjs +255 -0
- package/nodejs/mysql-token-store/package.json +9 -0
- package/nodejs/mysql-tree-store/errors.cjs +9 -0
- package/nodejs/mysql-tree-store/index.cjs +939 -0
- package/nodejs/mysql-tree-store/migrations.cjs +221 -0
- package/nodejs/mysql-tree-store/package.json +9 -0
- package/nodejs/package.json +3 -0
- package/nodejs/postgres-storage/index.cjs +147 -92
- package/nodejs/postgres-storage/migrations.cjs +85 -4
- package/nodejs/postgres-token-store/index.cjs +186 -101
- package/nodejs/postgres-token-store/migrations.cjs +92 -3
- package/nodejs/postgres-tree-store/index.cjs +177 -93
- package/nodejs/postgres-tree-store/migrations.cjs +80 -3
- package/package.json +1 -1
- package/ssr/index.js +19 -14
- package/web/breez_sdk_spark_wasm.d.ts +1267 -1195
- package/web/breez_sdk_spark_wasm.js +2295 -2169
- package/web/breez_sdk_spark_wasm_bg.wasm +0 -0
- package/web/breez_sdk_spark_wasm_bg.wasm.d.ts +14 -6
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tree store migrations for MySQL 8.0+. Mirrors `postgres-tree-store/migrations.cjs`.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { TreeStoreError } = require("./errors.cjs");
|
|
6
|
+
|
|
7
|
+
const TREE_MIGRATIONS_TABLE = "tree_schema_migrations";
|
|
8
|
+
const MIGRATION_LOCK_NAME = "breez_mysql_tree_store_migration_lock";
|
|
9
|
+
const MIGRATION_LOCK_TIMEOUT = 60;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Runs a single migration step. Plain strings are run as-is; tagged objects
|
|
13
|
+
* (`{ op: 'dropPrimaryKey', table }`) are guarded against partial-apply replay
|
|
14
|
+
* by checking `information_schema` first. MySQL DDL implicitly commits, so
|
|
15
|
+
* if the migration crashes between two DDL statements the version row never
|
|
16
|
+
* gets recorded — and on retry, an unguarded DROP PRIMARY KEY would fail
|
|
17
|
+
* (`ER_CANT_DROP_FIELD_OR_KEY`) because the PK is already gone.
|
|
18
|
+
*/
|
|
19
|
+
async function runMigrationStep(conn, step) {
|
|
20
|
+
if (typeof step === "string") {
|
|
21
|
+
await conn.query(step);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (step.op === "dropPrimaryKey") {
|
|
25
|
+
const [rows] = await conn.query(
|
|
26
|
+
`SELECT COUNT(*) AS c FROM information_schema.table_constraints
|
|
27
|
+
WHERE table_schema = DATABASE()
|
|
28
|
+
AND table_name = ?
|
|
29
|
+
AND constraint_type = 'PRIMARY KEY'`,
|
|
30
|
+
[step.table]
|
|
31
|
+
);
|
|
32
|
+
if (rows[0].c > 0) {
|
|
33
|
+
await conn.query(`ALTER TABLE \`${step.table}\` DROP PRIMARY KEY`);
|
|
34
|
+
}
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
throw new Error(`Unknown migration step op: ${JSON.stringify(step)}`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
class MysqlTreeStoreMigrationManager {
|
|
41
|
+
constructor(logger = null) {
|
|
42
|
+
this.logger = logger;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async migrate(pool, identity) {
|
|
46
|
+
const conn = await pool.getConnection();
|
|
47
|
+
try {
|
|
48
|
+
const [lockRows] = await conn.query(
|
|
49
|
+
"SELECT GET_LOCK(?, ?) AS acquired",
|
|
50
|
+
[MIGRATION_LOCK_NAME, MIGRATION_LOCK_TIMEOUT]
|
|
51
|
+
);
|
|
52
|
+
if (!lockRows || lockRows[0].acquired !== 1) {
|
|
53
|
+
throw new TreeStoreError(
|
|
54
|
+
`Failed to acquire tree store migration lock within ${MIGRATION_LOCK_TIMEOUT}s`
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
await conn.query("START TRANSACTION");
|
|
60
|
+
|
|
61
|
+
await conn.query(`
|
|
62
|
+
CREATE TABLE IF NOT EXISTS \`${TREE_MIGRATIONS_TABLE}\` (
|
|
63
|
+
version INT PRIMARY KEY,
|
|
64
|
+
applied_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)
|
|
65
|
+
)
|
|
66
|
+
`);
|
|
67
|
+
|
|
68
|
+
const [versionRows] = await conn.query(
|
|
69
|
+
`SELECT COALESCE(MAX(version), 0) AS version FROM \`${TREE_MIGRATIONS_TABLE}\``
|
|
70
|
+
);
|
|
71
|
+
const currentVersion = versionRows[0].version;
|
|
72
|
+
|
|
73
|
+
const migrations = this._getMigrations(identity);
|
|
74
|
+
|
|
75
|
+
if (currentVersion >= migrations.length) {
|
|
76
|
+
await conn.query("COMMIT");
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
for (let i = currentVersion; i < migrations.length; i++) {
|
|
81
|
+
const migration = migrations[i];
|
|
82
|
+
const version = i + 1;
|
|
83
|
+
for (const step of migration.sql) {
|
|
84
|
+
await runMigrationStep(conn, step);
|
|
85
|
+
}
|
|
86
|
+
await conn.query(
|
|
87
|
+
`INSERT INTO \`${TREE_MIGRATIONS_TABLE}\` (version) VALUES (?)`,
|
|
88
|
+
[version]
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
await conn.query("COMMIT");
|
|
93
|
+
} catch (error) {
|
|
94
|
+
await conn.query("ROLLBACK").catch(() => {});
|
|
95
|
+
throw new TreeStoreError(
|
|
96
|
+
`Tree store migration failed: ${error.message}`,
|
|
97
|
+
error
|
|
98
|
+
);
|
|
99
|
+
} finally {
|
|
100
|
+
await conn
|
|
101
|
+
.query("SELECT RELEASE_LOCK(?)", [MIGRATION_LOCK_NAME])
|
|
102
|
+
.catch(() => {});
|
|
103
|
+
}
|
|
104
|
+
} finally {
|
|
105
|
+
conn.release();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
_getMigrations(identity) {
|
|
110
|
+
const idHex = Buffer.from(identity).toString("hex");
|
|
111
|
+
const idLit = `UNHEX('${idHex}')`;
|
|
112
|
+
|
|
113
|
+
return [
|
|
114
|
+
{
|
|
115
|
+
name: "Create tree store tables",
|
|
116
|
+
sql: [
|
|
117
|
+
`CREATE TABLE IF NOT EXISTS tree_reservations (
|
|
118
|
+
id VARCHAR(255) NOT NULL PRIMARY KEY,
|
|
119
|
+
purpose VARCHAR(64) NOT NULL,
|
|
120
|
+
pending_change_amount BIGINT NOT NULL DEFAULT 0,
|
|
121
|
+
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)
|
|
122
|
+
)`,
|
|
123
|
+
`CREATE TABLE IF NOT EXISTS tree_leaves (
|
|
124
|
+
id VARCHAR(255) NOT NULL PRIMARY KEY,
|
|
125
|
+
status VARCHAR(64) NOT NULL,
|
|
126
|
+
is_missing_from_operators TINYINT(1) NOT NULL DEFAULT 0,
|
|
127
|
+
reservation_id VARCHAR(255) NULL,
|
|
128
|
+
data JSON NOT NULL,
|
|
129
|
+
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
130
|
+
added_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
|
131
|
+
CONSTRAINT fk_tree_leaves_reservation FOREIGN KEY (reservation_id)
|
|
132
|
+
REFERENCES tree_reservations(id) ON DELETE SET NULL
|
|
133
|
+
)`,
|
|
134
|
+
`CREATE TABLE IF NOT EXISTS tree_spent_leaves (
|
|
135
|
+
leaf_id VARCHAR(255) NOT NULL PRIMARY KEY,
|
|
136
|
+
spent_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)
|
|
137
|
+
)`,
|
|
138
|
+
`CREATE INDEX idx_tree_leaves_available
|
|
139
|
+
ON tree_leaves(status, is_missing_from_operators)`,
|
|
140
|
+
`CREATE INDEX idx_tree_leaves_reservation ON tree_leaves(reservation_id)`,
|
|
141
|
+
`CREATE INDEX idx_tree_leaves_added_at ON tree_leaves(added_at)`,
|
|
142
|
+
],
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
name: "Add swap status tracking",
|
|
146
|
+
sql: [
|
|
147
|
+
`CREATE TABLE IF NOT EXISTS tree_swap_status (
|
|
148
|
+
id INT NOT NULL PRIMARY KEY DEFAULT 1,
|
|
149
|
+
last_completed_at DATETIME(6) NULL,
|
|
150
|
+
CHECK (id = 1)
|
|
151
|
+
)`,
|
|
152
|
+
`INSERT INTO tree_swap_status (id) VALUES (1)
|
|
153
|
+
ON DUPLICATE KEY UPDATE id = id`,
|
|
154
|
+
],
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
name: "Promote leaf value to BIGINT column with covering index",
|
|
158
|
+
sql: [
|
|
159
|
+
`ALTER TABLE tree_leaves
|
|
160
|
+
ADD COLUMN value BIGINT NOT NULL DEFAULT 0`,
|
|
161
|
+
`UPDATE tree_leaves
|
|
162
|
+
SET value = CAST(JSON_UNQUOTE(JSON_EXTRACT(data, '$.value')) AS UNSIGNED)
|
|
163
|
+
WHERE value = 0`,
|
|
164
|
+
`CREATE INDEX idx_tree_leaves_slim
|
|
165
|
+
ON tree_leaves(status, is_missing_from_operators, reservation_id, value)`,
|
|
166
|
+
],
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
name: "Multi-tenant scoping: add user_id and rewrite primary keys / FKs",
|
|
170
|
+
sql: [
|
|
171
|
+
// Drop the existing FK so we can rewrite the parent PK.
|
|
172
|
+
`ALTER TABLE tree_leaves DROP FOREIGN KEY fk_tree_leaves_reservation`,
|
|
173
|
+
|
|
174
|
+
// tree_reservations: scope by user_id.
|
|
175
|
+
`ALTER TABLE tree_reservations ADD COLUMN user_id VARBINARY(33) NULL`,
|
|
176
|
+
`UPDATE tree_reservations SET user_id = ${idLit} WHERE user_id IS NULL`,
|
|
177
|
+
`ALTER TABLE tree_reservations MODIFY COLUMN user_id VARBINARY(33) NOT NULL`,
|
|
178
|
+
`ALTER TABLE tree_reservations DROP PRIMARY KEY, ADD PRIMARY KEY (user_id, id)`,
|
|
179
|
+
|
|
180
|
+
// tree_leaves: scope by user_id, rekey, re-add composite FK.
|
|
181
|
+
`ALTER TABLE tree_leaves ADD COLUMN user_id VARBINARY(33) NULL`,
|
|
182
|
+
`UPDATE tree_leaves SET user_id = ${idLit} WHERE user_id IS NULL`,
|
|
183
|
+
`ALTER TABLE tree_leaves MODIFY COLUMN user_id VARBINARY(33) NOT NULL`,
|
|
184
|
+
`ALTER TABLE tree_leaves DROP PRIMARY KEY, ADD PRIMARY KEY (user_id, id)`,
|
|
185
|
+
`ALTER TABLE tree_leaves
|
|
186
|
+
ADD CONSTRAINT fk_tree_leaves_reservation_user
|
|
187
|
+
FOREIGN KEY (user_id, reservation_id)
|
|
188
|
+
REFERENCES tree_reservations(user_id, id)`,
|
|
189
|
+
`DROP INDEX idx_tree_leaves_available ON tree_leaves`,
|
|
190
|
+
`DROP INDEX idx_tree_leaves_reservation ON tree_leaves`,
|
|
191
|
+
`DROP INDEX idx_tree_leaves_added_at ON tree_leaves`,
|
|
192
|
+
`DROP INDEX idx_tree_leaves_slim ON tree_leaves`,
|
|
193
|
+
`CREATE INDEX idx_tree_leaves_user_available
|
|
194
|
+
ON tree_leaves(user_id, status, is_missing_from_operators)`,
|
|
195
|
+
`CREATE INDEX idx_tree_leaves_user_reservation
|
|
196
|
+
ON tree_leaves(user_id, reservation_id)`,
|
|
197
|
+
`CREATE INDEX idx_tree_leaves_user_added_at ON tree_leaves(user_id, added_at)`,
|
|
198
|
+
`CREATE INDEX idx_tree_leaves_user_slim
|
|
199
|
+
ON tree_leaves(user_id, status, is_missing_from_operators, reservation_id, value)`,
|
|
200
|
+
|
|
201
|
+
// tree_spent_leaves: scope by user_id.
|
|
202
|
+
`ALTER TABLE tree_spent_leaves ADD COLUMN user_id VARBINARY(33) NULL`,
|
|
203
|
+
`UPDATE tree_spent_leaves SET user_id = ${idLit} WHERE user_id IS NULL`,
|
|
204
|
+
`ALTER TABLE tree_spent_leaves MODIFY COLUMN user_id VARBINARY(33) NOT NULL`,
|
|
205
|
+
`ALTER TABLE tree_spent_leaves DROP PRIMARY KEY, ADD PRIMARY KEY (user_id, leaf_id)`,
|
|
206
|
+
|
|
207
|
+
// tree_swap_status was a singleton (PK id=1, CHECK id=1). Drop the PK
|
|
208
|
+
// and the id column, then re-key by user_id.
|
|
209
|
+
{ op: "dropPrimaryKey", table: "tree_swap_status" },
|
|
210
|
+
`ALTER TABLE tree_swap_status DROP COLUMN id`,
|
|
211
|
+
`ALTER TABLE tree_swap_status ADD COLUMN user_id VARBINARY(33) NULL`,
|
|
212
|
+
`UPDATE tree_swap_status SET user_id = ${idLit} WHERE user_id IS NULL`,
|
|
213
|
+
`ALTER TABLE tree_swap_status MODIFY COLUMN user_id VARBINARY(33) NOT NULL`,
|
|
214
|
+
`ALTER TABLE tree_swap_status ADD PRIMARY KEY (user_id)`,
|
|
215
|
+
],
|
|
216
|
+
},
|
|
217
|
+
];
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
module.exports = { MysqlTreeStoreMigrationManager };
|