@rei-standard/amsg-server 2.6.0-next.34 → 2.6.0-next.35
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/dist/adapters/d1.d.ts +28 -4
- package/dist/adapters/interface.d.ts +1 -0
- package/dist/adapters/schema.sqlite.d.ts +13 -1
- package/dist/{chunk-BACG4KJQ.mjs → chunk-INQD6LRY.mjs} +216 -47
- package/dist/{chunk-5GRXWKQR.cjs → chunk-UG5ZNM5J.cjs} +234 -65
- package/dist/cloudflare.cjs +2 -2
- package/dist/cloudflare.mjs +1 -1
- package/dist/index.cjs +25 -25
- package/dist/index.mjs +1 -1
- package/dist/lib/schema-version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -5070,6 +5070,66 @@ var CLOUD_DATA_TABLES_SQL = [
|
|
|
5070
5070
|
lease_allowed INTEGER CONSTRAINT cloud_lease_guard CHECK (lease_allowed = 1)
|
|
5071
5071
|
)`
|
|
5072
5072
|
];
|
|
5073
|
+
var CLOUD_DATA_WORK_TABLES_SQL = [
|
|
5074
|
+
`CREATE TABLE IF NOT EXISTS cloud_data_work (
|
|
5075
|
+
user_id TEXT NOT NULL, kind TEXT NOT NULL, id TEXT NOT NULL,
|
|
5076
|
+
next_run_at INTEGER, expires_at INTEGER,
|
|
5077
|
+
PRIMARY KEY (user_id, kind, id)
|
|
5078
|
+
)`,
|
|
5079
|
+
`CREATE TABLE IF NOT EXISTS cloud_data_maintenance (
|
|
5080
|
+
name TEXT PRIMARY KEY, cursor INTEGER NOT NULL, upper_bound INTEGER NOT NULL,
|
|
5081
|
+
completed INTEGER NOT NULL DEFAULT 0
|
|
5082
|
+
)`
|
|
5083
|
+
];
|
|
5084
|
+
CLOUD_DATA_TABLES_SQL.push(...CLOUD_DATA_WORK_TABLES_SQL);
|
|
5085
|
+
var CLOUD_DATA_WORK_INDEXES = [
|
|
5086
|
+
{
|
|
5087
|
+
name: "idx_cloud_work_due",
|
|
5088
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_cloud_work_due
|
|
5089
|
+
ON cloud_data_work (kind, next_run_at) WHERE next_run_at IS NOT NULL`,
|
|
5090
|
+
description: "Only due cleanup operations",
|
|
5091
|
+
critical: true
|
|
5092
|
+
},
|
|
5093
|
+
{
|
|
5094
|
+
name: "idx_cloud_work_expiry",
|
|
5095
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_cloud_work_expiry
|
|
5096
|
+
ON cloud_data_work (expires_at) WHERE expires_at IS NOT NULL`,
|
|
5097
|
+
description: "Only expired management records",
|
|
5098
|
+
critical: true
|
|
5099
|
+
}
|
|
5100
|
+
];
|
|
5101
|
+
SQLITE_ALL_INDEXES.push(...CLOUD_DATA_WORK_INDEXES);
|
|
5102
|
+
var chunkPrefixSql = "char(31)||'amsg-chunks'||char(31)";
|
|
5103
|
+
var logicalNamespaceSql = `CASE WHEN substr(OLD.namespace,1,13)=${chunkPrefixSql}
|
|
5104
|
+
THEN substr(OLD.namespace,14) ELSE OLD.namespace END`;
|
|
5105
|
+
var logicalKeySql = `CASE WHEN substr(OLD.namespace,1,13)=${chunkPrefixSql} AND instr(OLD.key,char(31))>0
|
|
5106
|
+
THEN substr(OLD.key,1,instr(OLD.key,char(31))-1) ELSE OLD.key END`;
|
|
5107
|
+
var CLOUD_DATA_DELETE_TRIGGERS = [
|
|
5108
|
+
...[
|
|
5109
|
+
["scheduled_messages", "task", "uuid"],
|
|
5110
|
+
["llm_credentials", "credential", "cred_id"],
|
|
5111
|
+
["message_outbox", "outbox", "message_id"],
|
|
5112
|
+
["push_subscriptions", "subscription", "user_id"]
|
|
5113
|
+
].map(([table, type, column]) => ({
|
|
5114
|
+
name: `trg_cloud_metadata_${type}_delete`,
|
|
5115
|
+
sql: `CREATE TRIGGER IF NOT EXISTS trg_cloud_metadata_${type}_delete AFTER DELETE ON ${table}
|
|
5116
|
+
BEGIN DELETE FROM cloud_resource_metadata WHERE user_id=OLD.user_id
|
|
5117
|
+
AND resource_key=json_array('${type}'${column ? ",OLD." + column : ""}); END`
|
|
5118
|
+
})),
|
|
5119
|
+
{ name: "trg_cloud_metadata_state_delete", sql: `CREATE TRIGGER IF NOT EXISTS trg_cloud_metadata_state_delete
|
|
5120
|
+
AFTER DELETE ON client_state BEGIN
|
|
5121
|
+
DELETE FROM cloud_resource_metadata WHERE user_id=OLD.user_id
|
|
5122
|
+
AND resource_key=json_array('state',${logicalNamespaceSql},${logicalKeySql})
|
|
5123
|
+
AND NOT EXISTS (SELECT 1 FROM client_state r WHERE r.user_id=OLD.user_id
|
|
5124
|
+
AND r.namespace=(${logicalNamespaceSql}) AND r.key=(${logicalKeySql}))
|
|
5125
|
+
AND NOT EXISTS (SELECT 1 FROM client_state r WHERE r.user_id=OLD.user_id
|
|
5126
|
+
AND r.namespace=${chunkPrefixSql}||(${logicalNamespaceSql})
|
|
5127
|
+
AND r.key >= (${logicalKeySql})||char(31) AND r.key < (${logicalKeySql})||char(32)); END` },
|
|
5128
|
+
{ name: "trg_cloud_work_delete", sql: `CREATE TRIGGER IF NOT EXISTS trg_cloud_work_delete
|
|
5129
|
+
AFTER DELETE ON cloud_data_records BEGIN
|
|
5130
|
+
DELETE FROM cloud_data_work WHERE user_id=OLD.user_id AND kind=OLD.kind AND id=OLD.id;
|
|
5131
|
+
DELETE FROM cloud_data_record_chunks WHERE user_id=OLD.user_id AND kind=OLD.kind AND id=OLD.id; END` }
|
|
5132
|
+
];
|
|
5073
5133
|
function parseTableName(sql) {
|
|
5074
5134
|
const match = /CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?([A-Za-z_][A-Za-z0-9_]*)/i.exec(sql);
|
|
5075
5135
|
return match ? match[1] : "";
|
|
@@ -5105,7 +5165,8 @@ var SQLITE_REQUIRED_SCHEMA = Object.freeze({
|
|
|
5105
5165
|
describeTable(MESSAGE_OUTBOX_TABLE_SQL),
|
|
5106
5166
|
...CLOUD_DATA_TABLES_SQL.map(describeTable)
|
|
5107
5167
|
])),
|
|
5108
|
-
indexes: Object.freeze(SQLITE_ALL_INDEXES.filter((index) => index.critical).map((index) => index.name))
|
|
5168
|
+
indexes: Object.freeze(SQLITE_ALL_INDEXES.filter((index) => index.critical).map((index) => index.name)),
|
|
5169
|
+
triggers: Object.freeze(CLOUD_DATA_DELETE_TRIGGERS.map((trigger) => trigger.name))
|
|
5109
5170
|
});
|
|
5110
5171
|
|
|
5111
5172
|
// src/server/adapters/d1.js
|
|
@@ -5304,7 +5365,7 @@ var D1Adapter = class {
|
|
|
5304
5365
|
}
|
|
5305
5366
|
return { id: row.id, userId: row.user_id, kind: row.kind, data, updatedAt: row.updated_at };
|
|
5306
5367
|
}
|
|
5307
|
-
async putCloudDataRecord(userId, kind, id, data, { idempotencyKey = null, createOnly = false, leaseToken } = {}) {
|
|
5368
|
+
async putCloudDataRecord(userId, kind, id, data, { idempotencyKey = null, createOnly = false, leaseToken, work } = {}) {
|
|
5308
5369
|
const slices = [];
|
|
5309
5370
|
if (data.length > 200 * 1024) for (let offset = 0; offset < data.length; offset += 200 * 1024) slices.push(data.slice(offset, offset + 200 * 1024));
|
|
5310
5371
|
const rootValue = slices.length ? "amsg-record" + slices.length : data;
|
|
@@ -5331,6 +5392,12 @@ var D1Adapter = class {
|
|
|
5331
5392
|
SELECT ?,?,?,?,?,? WHERE ${rootGate}`
|
|
5332
5393
|
).bind(userId, kind, id, index, slices[index], writeToken, userId, kind, id, writeToken));
|
|
5333
5394
|
}
|
|
5395
|
+
const schedule = _nullishCoalesce(work, () => ( (["inventory", "plan"].includes(kind) ? { nextRunAt: null, expiresAt: now + 36e5 } : null)));
|
|
5396
|
+
if (schedule) statements.push(this._db.prepare(
|
|
5397
|
+
`INSERT INTO cloud_data_work (user_id,kind,id,next_run_at,expires_at)
|
|
5398
|
+
SELECT ?,?,?,?,? WHERE ${rootGate}
|
|
5399
|
+
ON CONFLICT (user_id,kind,id) DO UPDATE SET next_run_at=excluded.next_run_at,expires_at=excluded.expires_at`
|
|
5400
|
+
).bind(userId, kind, id, _nullishCoalesce(schedule.nextRunAt, () => ( null)), _nullishCoalesce(schedule.expiresAt, () => ( null)), userId, kind, id, writeToken));
|
|
5334
5401
|
if (!this.cloudDataManagement) throw new Error("Cloud management requires transactional batches");
|
|
5335
5402
|
const results = await this._db.batch(statements);
|
|
5336
5403
|
if (leaseToken !== void 0 && !results[0].meta.changes) throw Object.assign(new Error("Cloud operation processing lease was lost"), { code: "CLOUD_LEASE_LOST" });
|
|
@@ -5408,23 +5475,85 @@ var D1Adapter = class {
|
|
|
5408
5475
|
]);
|
|
5409
5476
|
return results[1].meta.changes || 0;
|
|
5410
5477
|
}
|
|
5411
|
-
|
|
5412
|
-
|
|
5478
|
+
async listDueCloudDataOperations(now = Date.now(), limit = 25) {
|
|
5479
|
+
const result = await this._db.prepare(`SELECT r.* FROM cloud_data_work w JOIN cloud_data_records r
|
|
5480
|
+
ON r.user_id=w.user_id AND r.kind=w.kind AND r.id=w.id
|
|
5481
|
+
WHERE w.kind='operation' AND w.next_run_at IS NOT NULL AND w.next_run_at<=?
|
|
5482
|
+
AND (r.lease_until IS NULL OR r.lease_until<=?)
|
|
5483
|
+
ORDER BY w.next_run_at LIMIT ?`).bind(now, now, limit).all();
|
|
5484
|
+
return Promise.all((result.results || []).map((row) => this._cloudRecordForList(row)));
|
|
5485
|
+
}
|
|
5486
|
+
async cleanupExpiredCloudDataRecords(now = Date.now(), limit = 100) {
|
|
5487
|
+
const result = await this._db.prepare(`DELETE FROM cloud_data_records WHERE rowid IN (
|
|
5488
|
+
SELECT r.rowid FROM cloud_data_work w JOIN cloud_data_records r
|
|
5489
|
+
ON r.user_id=w.user_id AND r.kind=w.kind AND r.id=w.id
|
|
5490
|
+
WHERE w.expires_at IS NOT NULL AND w.expires_at<=?
|
|
5491
|
+
AND (r.lease_until IS NULL OR r.lease_until<=?) ORDER BY w.expires_at LIMIT ?
|
|
5492
|
+
)`).bind(now, now, limit).run();
|
|
5493
|
+
return result.meta.changes || 0;
|
|
5494
|
+
}
|
|
5495
|
+
async getCloudMaintenanceBatch(name, table, limit = 100) {
|
|
5496
|
+
if (!["cloud_resource_metadata", "cloud_data_records"].includes(table)) throw new Error("Invalid maintenance source");
|
|
5497
|
+
let marker = await this._db.prepare("SELECT * FROM cloud_data_maintenance WHERE name=?").bind(name).first();
|
|
5498
|
+
if (!marker) {
|
|
5499
|
+
await this._db.prepare(`INSERT INTO cloud_data_maintenance (name,cursor,upper_bound,completed)
|
|
5500
|
+
SELECT ?,0,COALESCE(MAX(rowid),0),0 FROM ${table} WHERE 1 ON CONFLICT (name) DO NOTHING`).bind(name).run();
|
|
5501
|
+
marker = await this._db.prepare("SELECT * FROM cloud_data_maintenance WHERE name=?").bind(name).first();
|
|
5502
|
+
}
|
|
5503
|
+
if (marker.completed) return { rows: [], completed: true };
|
|
5504
|
+
const result = await this._db.prepare(`SELECT rowid AS maintenance_rowid,* FROM ${table}
|
|
5505
|
+
WHERE rowid>? AND rowid<=? ORDER BY rowid LIMIT ?`).bind(marker.cursor, marker.upper_bound, limit).all();
|
|
5506
|
+
return { rows: result.results || [], upperBound: marker.upper_bound, cursor: marker.cursor, completed: false };
|
|
5507
|
+
}
|
|
5508
|
+
async finishCloudMaintenanceBatch(name, cursor, completed) {
|
|
5509
|
+
await this._db.prepare(`UPDATE cloud_data_maintenance SET cursor=MAX(cursor,?),completed=MAX(completed,?) WHERE name=?`).bind(cursor, completed ? 1 : 0, name).run();
|
|
5510
|
+
}
|
|
5511
|
+
async indexCloudDataRecordWork(userId, kind, id, work, expectedWriteToken = null) {
|
|
5512
|
+
await this._db.prepare(`INSERT INTO cloud_data_work (user_id,kind,id,next_run_at,expires_at)
|
|
5513
|
+
SELECT user_id,kind,id,?,? FROM cloud_data_records WHERE user_id=? AND kind=? AND id=? AND write_token IS ?
|
|
5514
|
+
ON CONFLICT (user_id,kind,id) DO NOTHING`).bind(_nullishCoalesce(work.nextRunAt, () => ( null)), _nullishCoalesce(work.expiresAt, () => ( null)), userId, kind, id, expectedWriteToken).run();
|
|
5515
|
+
}
|
|
5516
|
+
async readCloudMaintenanceRecord(row) {
|
|
5517
|
+
return this._cloudRecordForList(row);
|
|
5518
|
+
}
|
|
5519
|
+
async repairCloudResourceMetadata(limit = 100) {
|
|
5520
|
+
const name = "metadata-sidecars-v1";
|
|
5521
|
+
const batch = await this.getCloudMaintenanceBatch(name, "cloud_resource_metadata", limit);
|
|
5522
|
+
if (batch.completed) return;
|
|
5523
|
+
const cursor = _nullishCoalesce(_optionalChain([batch, 'access', _45 => _45.rows, 'access', _46 => _46.at, 'call', _47 => _47(-1), 'optionalAccess', _48 => _48.maintenance_rowid]), () => ( batch.upperBound));
|
|
5524
|
+
if (batch.rows.length) await this.cleanupCloudResourceMetadata(null, { after: batch.cursor, through: cursor });
|
|
5525
|
+
await this.finishCloudMaintenanceBatch(name, cursor, batch.rows.length < limit || cursor >= batch.upperBound);
|
|
5526
|
+
}
|
|
5527
|
+
/** One explicit repair, or a bounded upgrade batch; never called as a recurring sweep. */
|
|
5528
|
+
async cleanupCloudResourceMetadata(userId = null, range = null) {
|
|
5413
5529
|
const targets = {
|
|
5414
|
-
task: `SELECT 1 FROM scheduled_messages r WHERE r.user_id=m.user_id AND r.uuid=json_extract(m.resource_key,'$[1]')
|
|
5415
|
-
state:
|
|
5416
|
-
|
|
5417
|
-
|
|
5530
|
+
task: [`SELECT 1 FROM scheduled_messages r WHERE r.user_id=m.user_id AND r.uuid=json_extract(m.resource_key,'$[1]')`],
|
|
5531
|
+
state: [
|
|
5532
|
+
`SELECT 1 FROM client_state r WHERE r.user_id=m.user_id
|
|
5533
|
+
AND r.namespace=json_extract(m.resource_key,'$[1]') AND r.key=json_extract(m.resource_key,'$[2]')`,
|
|
5534
|
+
`SELECT 1 FROM client_state r WHERE r.user_id=m.user_id
|
|
5535
|
+
AND r.namespace=char(31)||'amsg-chunks'||char(31)||json_extract(m.resource_key,'$[1]')
|
|
5418
5536
|
AND r.key >= json_extract(m.resource_key,'$[2]')||char(31)
|
|
5419
|
-
AND r.key < json_extract(m.resource_key,'$[2]')||char(32)
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
|
|
5537
|
+
AND r.key < json_extract(m.resource_key,'$[2]')||char(32)`
|
|
5538
|
+
],
|
|
5539
|
+
credential: [`SELECT 1 FROM llm_credentials r WHERE r.user_id=m.user_id AND r.cred_id=json_extract(m.resource_key,'$[1]')`],
|
|
5540
|
+
outbox: [`SELECT 1 FROM message_outbox r WHERE r.user_id=m.user_id AND r.message_id=json_extract(m.resource_key,'$[1]')`],
|
|
5541
|
+
subscription: [`SELECT 1 FROM push_subscriptions r WHERE r.user_id=m.user_id`]
|
|
5423
5542
|
};
|
|
5424
|
-
const statements = Object.entries(targets).map(([type, exists]) =>
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5543
|
+
const statements = Object.entries(targets).map(([type, exists]) => {
|
|
5544
|
+
const conditions = ["json_valid(resource_key)", "json_extract(resource_key,'$[0]')=?"];
|
|
5545
|
+
const args = [type];
|
|
5546
|
+
if (userId !== null) {
|
|
5547
|
+
conditions.unshift("user_id=?");
|
|
5548
|
+
args.unshift(userId);
|
|
5549
|
+
}
|
|
5550
|
+
if (range) {
|
|
5551
|
+
conditions.unshift("m.rowid>? AND m.rowid<=?");
|
|
5552
|
+
args.unshift(range.after, range.through);
|
|
5553
|
+
}
|
|
5554
|
+
return this._db.prepare(`DELETE FROM cloud_resource_metadata AS m WHERE ${conditions.join(" AND ")}
|
|
5555
|
+
AND ${exists.map((sql) => `NOT EXISTS (${sql})`).join(" AND ")}`).bind(...args);
|
|
5556
|
+
});
|
|
5428
5557
|
const results = await this._cloudBatch(statements, userId);
|
|
5429
5558
|
return results.reduce((sum, result) => sum + (result.meta.changes || 0), 0);
|
|
5430
5559
|
}
|
|
@@ -5465,7 +5594,7 @@ var D1Adapter = class {
|
|
|
5465
5594
|
if (!guard) return true;
|
|
5466
5595
|
const condition = this._cloudGuardPredicate(userId, guard);
|
|
5467
5596
|
const row = await this._db.prepare(`SELECT ${condition.sql} AS valid`).bind(...condition.args).first();
|
|
5468
|
-
return !!_optionalChain([row, 'optionalAccess',
|
|
5597
|
+
return !!_optionalChain([row, 'optionalAccess', _49 => _49.valid]);
|
|
5469
5598
|
}
|
|
5470
5599
|
/** Delete only the exact physical snapshot; no untrusted SQL identifiers. */
|
|
5471
5600
|
async deleteCloudResourceRows(userId, locators, { operationId, leaseToken } = {}) {
|
|
@@ -5564,6 +5693,7 @@ var D1Adapter = class {
|
|
|
5564
5693
|
indexResults.push({ name: index.name, status: "failed", description: index.description, critical: !!index.critical, error: error.message });
|
|
5565
5694
|
}
|
|
5566
5695
|
}
|
|
5696
|
+
for (const trigger of CLOUD_DATA_DELETE_TRIGGERS) await this._db.prepare(trigger.sql).run();
|
|
5567
5697
|
const criticalFailures = indexResults.filter((i) => i.critical && i.status === "failed");
|
|
5568
5698
|
if (criticalFailures.length > 0) {
|
|
5569
5699
|
const names = criticalFailures.map((i) => i.name).join(", ");
|
|
@@ -5587,7 +5717,7 @@ var D1Adapter = class {
|
|
|
5587
5717
|
* 构变了而老部署没跑过 initSchema 时,cron 会每分钟静默挂在缺的那一列上,
|
|
5588
5718
|
* 界面上一切正常——这个方法就是让宿主查得出来。
|
|
5589
5719
|
*
|
|
5590
|
-
* @returns {Promise<{ tables: Record<string, string[]>, indexes: string[] }>}
|
|
5720
|
+
* @returns {Promise<{ tables: Record<string, string[]>, indexes: string[], triggers: string[] }>}
|
|
5591
5721
|
*/
|
|
5592
5722
|
async describeSchema() {
|
|
5593
5723
|
const tableRes = await this._db.prepare(
|
|
@@ -5604,7 +5734,8 @@ var D1Adapter = class {
|
|
|
5604
5734
|
const indexRes = await this._db.prepare(
|
|
5605
5735
|
`SELECT name FROM sqlite_master WHERE type = 'index' AND name IS NOT NULL`
|
|
5606
5736
|
).all();
|
|
5607
|
-
|
|
5737
|
+
const triggerRes = await this._db.prepare("SELECT name FROM sqlite_master WHERE type = 'trigger'").all();
|
|
5738
|
+
return { tables, indexes: (indexRes.results || []).map((row) => row.name), triggers: (triggerRes.results || []).map((row) => row.name) };
|
|
5608
5739
|
}
|
|
5609
5740
|
async dropSchema() {
|
|
5610
5741
|
await this._db.prepare("DROP TABLE IF EXISTS scheduled_messages").run();
|
|
@@ -5612,7 +5743,7 @@ var D1Adapter = class {
|
|
|
5612
5743
|
await this._db.prepare("DROP TABLE IF EXISTS push_subscriptions").run();
|
|
5613
5744
|
await this._db.prepare("DROP TABLE IF EXISTS llm_credentials").run();
|
|
5614
5745
|
await this._db.prepare("DROP TABLE IF EXISTS message_outbox").run();
|
|
5615
|
-
for (const table of ["cloud_data_record_chunks", "cloud_data_records", "cloud_data_owners", "cloud_resource_metadata", "cloud_guard_assertions"]) {
|
|
5746
|
+
for (const table of ["cloud_data_work", "cloud_data_maintenance", "cloud_data_record_chunks", "cloud_data_records", "cloud_data_owners", "cloud_resource_metadata", "cloud_guard_assertions"]) {
|
|
5616
5747
|
await this._db.prepare(`DROP TABLE IF EXISTS ${table}`).run();
|
|
5617
5748
|
}
|
|
5618
5749
|
}
|
|
@@ -5716,7 +5847,7 @@ var D1Adapter = class {
|
|
|
5716
5847
|
).bind(...values);
|
|
5717
5848
|
const ownerUser = cloudGuard ? await this._db.prepare("SELECT user_id FROM scheduled_messages WHERE id=?").bind(taskId).first() : null;
|
|
5718
5849
|
if (cloudGuard && !ownerUser) return null;
|
|
5719
|
-
await this._cloudBatch([statement], _optionalChain([ownerUser, 'optionalAccess',
|
|
5850
|
+
await this._cloudBatch([statement], _optionalChain([ownerUser, 'optionalAccess', _50 => _50.user_id]), [cloudGuard]);
|
|
5720
5851
|
return this._db.prepare("SELECT * FROM scheduled_messages WHERE id = ?").bind(taskId).first();
|
|
5721
5852
|
}
|
|
5722
5853
|
/**
|
|
@@ -5841,7 +5972,7 @@ var D1Adapter = class {
|
|
|
5841
5972
|
).bind(...values);
|
|
5842
5973
|
const ownerUser = cloudGuard ? await this._db.prepare("SELECT user_id FROM scheduled_messages WHERE id=?").bind(taskId).first() : null;
|
|
5843
5974
|
if (cloudGuard && !ownerUser) return false;
|
|
5844
|
-
const [res] = await this._cloudBatch([statement], _optionalChain([ownerUser, 'optionalAccess',
|
|
5975
|
+
const [res] = await this._cloudBatch([statement], _optionalChain([ownerUser, 'optionalAccess', _51 => _51.user_id]), [cloudGuard]);
|
|
5845
5976
|
return (res.meta.changes || 0) > 0;
|
|
5846
5977
|
}
|
|
5847
5978
|
/**
|
|
@@ -5860,7 +5991,7 @@ var D1Adapter = class {
|
|
|
5860
5991
|
).bind(this._iso(leaseUntil), taskId);
|
|
5861
5992
|
const ownerUser = cloudGuard ? await this._db.prepare("SELECT user_id FROM scheduled_messages WHERE id=?").bind(taskId).first() : null;
|
|
5862
5993
|
if (cloudGuard && !ownerUser) return false;
|
|
5863
|
-
const [res] = await this._cloudBatch([statement], _optionalChain([ownerUser, 'optionalAccess',
|
|
5994
|
+
const [res] = await this._cloudBatch([statement], _optionalChain([ownerUser, 'optionalAccess', _52 => _52.user_id]), [cloudGuard]);
|
|
5864
5995
|
return (res.meta.changes || 0) > 0;
|
|
5865
5996
|
}
|
|
5866
5997
|
async listTasks(userId, opts = {}) {
|
|
@@ -5890,7 +6021,8 @@ var D1Adapter = class {
|
|
|
5890
6021
|
const cutoff = new Date(Date.now() - safeDays * 24 * 60 * 60 * 1e3).toISOString();
|
|
5891
6022
|
const res = await this._db.prepare(
|
|
5892
6023
|
`DELETE FROM scheduled_messages
|
|
5893
|
-
WHERE
|
|
6024
|
+
WHERE rowid IN (SELECT rowid FROM scheduled_messages
|
|
6025
|
+
WHERE status IN ('sent', 'failed') AND updated_at < ? LIMIT 100)`
|
|
5894
6026
|
).bind(cutoff).run();
|
|
5895
6027
|
return res.meta.changes || 0;
|
|
5896
6028
|
}
|
|
@@ -6020,7 +6152,7 @@ var D1Adapter = class {
|
|
|
6020
6152
|
result.cleanupOutcomes = probeIndexes.map((probeAt) => {
|
|
6021
6153
|
if (probeAt === null) return null;
|
|
6022
6154
|
const row = results[probeAt] && Array.isArray(results[probeAt].results) ? results[probeAt].results[0] : null;
|
|
6023
|
-
return Number(_nullishCoalesce(_optionalChain([row, 'optionalAccess',
|
|
6155
|
+
return Number(_nullishCoalesce(_optionalChain([row, 'optionalAccess', _53 => _53.n]), () => ( 0))) === 0;
|
|
6024
6156
|
});
|
|
6025
6157
|
}
|
|
6026
6158
|
return result;
|
|
@@ -6056,7 +6188,7 @@ var D1Adapter = class {
|
|
|
6056
6188
|
*/
|
|
6057
6189
|
async cleanupClientState(targets = []) {
|
|
6058
6190
|
if (!Array.isArray(targets) || targets.length === 0) return 0;
|
|
6059
|
-
const SQL = "DELETE FROM client_state WHERE namespace = ? AND updated_at < ?";
|
|
6191
|
+
const SQL = "DELETE FROM client_state WHERE rowid IN (SELECT rowid FROM client_state WHERE namespace = ? AND updated_at < ? LIMIT 100)";
|
|
6060
6192
|
const statements = targets.map(
|
|
6061
6193
|
(target) => this._db.prepare(SQL).bind(target.namespace, target.updatedBefore)
|
|
6062
6194
|
);
|
|
@@ -6552,13 +6684,13 @@ var D1Adapter = class {
|
|
|
6552
6684
|
let deleted = 0;
|
|
6553
6685
|
if (Number.isFinite(ackedBeforeMs)) {
|
|
6554
6686
|
const res = await this._db.prepare(
|
|
6555
|
-
"DELETE FROM message_outbox WHERE acked_at IS NOT NULL AND acked_at < ?"
|
|
6687
|
+
"DELETE FROM message_outbox WHERE rowid IN (SELECT rowid FROM message_outbox WHERE acked_at IS NOT NULL AND acked_at < ? LIMIT 100)"
|
|
6556
6688
|
).bind(ackedBeforeMs).run();
|
|
6557
6689
|
deleted += res.meta.changes || 0;
|
|
6558
6690
|
}
|
|
6559
6691
|
if (Number.isFinite(allBeforeMs)) {
|
|
6560
6692
|
const res = await this._db.prepare(
|
|
6561
|
-
"DELETE FROM message_outbox WHERE created_at < ?"
|
|
6693
|
+
"DELETE FROM message_outbox WHERE rowid IN (SELECT rowid FROM message_outbox WHERE created_at < ? LIMIT 100)"
|
|
6562
6694
|
).bind(allBeforeMs).run();
|
|
6563
6695
|
deleted += res.meta.changes || 0;
|
|
6564
6696
|
}
|
|
@@ -6879,7 +7011,7 @@ function createClientStateNamespacesHandler(ctx) {
|
|
|
6879
7011
|
}
|
|
6880
7012
|
|
|
6881
7013
|
// src/server/lib/version.js
|
|
6882
|
-
var SERVER_VERSION = true ? "2.6.0-next.
|
|
7014
|
+
var SERVER_VERSION = true ? "2.6.0-next.35" : "0.0.0-dev";
|
|
6883
7015
|
|
|
6884
7016
|
// src/server/handlers/capabilities.js
|
|
6885
7017
|
var SERVER_FEATURES = Object.freeze([
|
|
@@ -7114,8 +7246,8 @@ async function buildCloudDataInventory({
|
|
|
7114
7246
|
});
|
|
7115
7247
|
}
|
|
7116
7248
|
}
|
|
7117
|
-
const owner = safeOwner(_optionalChain([stored, 'optionalAccess',
|
|
7118
|
-
const kind = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([stored, 'optionalAccess',
|
|
7249
|
+
const owner = safeOwner(_optionalChain([stored, 'optionalAccess', _54 => _54.owner])) || safeOwner(_optionalChain([payload, 'optionalAccess', _55 => _55.__cloudOwnerGuard, 'optionalAccess', _56 => _56.owner])) || safeOwner(_optionalChain([payload, 'optionalAccess', _57 => _57.metadata, 'optionalAccess', _58 => _58.cloudOwner])) || safeOwner(_optionalChain([payload, 'optionalAccess', _59 => _59.metadata, 'optionalAccess', _60 => _60.owner])) || safeOwner(_optionalChain([payload, 'optionalAccess', _61 => _61.owner])) || safeOwner(_optionalChain([task, 'optionalAccess', _62 => _62.__cloudOwnerGuard, 'optionalAccess', _63 => _63.owner])) || safeOwner(_optionalChain([task, 'optionalAccess', _64 => _64.metadata, 'optionalAccess', _65 => _65.cloudOwner])) || safeOwner(_optionalChain([task, 'optionalAccess', _66 => _66.metadata, 'optionalAccess', _67 => _67.owner])) || safeOwner(_optionalChain([task, 'optionalAccess', _68 => _68.owner])) || safeOwner(_optionalChain([resolved, 'optionalAccess', _69 => _69.owner]));
|
|
7250
|
+
const kind = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([stored, 'optionalAccess', _70 => _70.kind]), () => ( _optionalChain([payload, 'optionalAccess', _71 => _71.metadata, 'optionalAccess', _72 => _72.kind]))), () => ( _optionalChain([payload, 'optionalAccess', _73 => _73.kind]))), () => ( _optionalChain([resolved, 'optionalAccess', _74 => _74.kind]))), () => ( null));
|
|
7119
7251
|
const times = rows.map((row) => timestamp(_nullishCoalesce(row.updated_at, () => ( row.created_at)))).filter((time) => time !== null);
|
|
7120
7252
|
const byteSize = rows.reduce(
|
|
7121
7253
|
(sum, row) => sum + encoder.encode(
|
|
@@ -7258,7 +7390,7 @@ async function buildCloudDataInventory({
|
|
|
7258
7390
|
const ownerLabels = /* @__PURE__ */ new Map();
|
|
7259
7391
|
for (const { resource } of entries) {
|
|
7260
7392
|
const owner = resource.owner;
|
|
7261
|
-
if (!_optionalChain([owner, 'optionalAccess',
|
|
7393
|
+
if (!_optionalChain([owner, 'optionalAccess', _75 => _75.label, 'optionalAccess', _76 => _76.trim, 'call', _77 => _77()])) continue;
|
|
7262
7394
|
const identity = JSON.stringify([owner.type, owner.id]);
|
|
7263
7395
|
const current = ownerLabels.get(identity);
|
|
7264
7396
|
if (!current || (_nullishCoalesce(resource.updatedAt, () => ( 0))) > current.updatedAt) {
|
|
@@ -7270,7 +7402,7 @@ async function buildCloudDataInventory({
|
|
|
7270
7402
|
}
|
|
7271
7403
|
for (const { resource } of entries) {
|
|
7272
7404
|
const owner = resource.owner;
|
|
7273
|
-
if (!owner || _optionalChain([owner, 'access',
|
|
7405
|
+
if (!owner || _optionalChain([owner, 'access', _78 => _78.label, 'optionalAccess', _79 => _79.trim, 'call', _80 => _80()])) continue;
|
|
7274
7406
|
const known = ownerLabels.get(JSON.stringify([owner.type, owner.id]));
|
|
7275
7407
|
if (known) resource.owner = { ...owner, label: known.label };
|
|
7276
7408
|
}
|
|
@@ -7298,9 +7430,18 @@ async function cloudInventory(ctx, db, userId, userKey) {
|
|
|
7298
7430
|
db,
|
|
7299
7431
|
userId,
|
|
7300
7432
|
userKey,
|
|
7301
|
-
resolveOwner: _optionalChain([ctx, 'access',
|
|
7433
|
+
resolveOwner: _optionalChain([ctx, 'access', _81 => _81.cloudData, 'optionalAccess', _82 => _82.resolveOwner])
|
|
7302
7434
|
});
|
|
7303
7435
|
}
|
|
7436
|
+
function operationWork(operation) {
|
|
7437
|
+
if (["pending", "running"].includes(operation.status)) {
|
|
7438
|
+
return { nextRunAt: Number(operation.nextAttemptAt) || 0, expiresAt: null };
|
|
7439
|
+
}
|
|
7440
|
+
if (["completed", "failed"].includes(operation.status)) {
|
|
7441
|
+
return { nextRunAt: null, expiresAt: Number(operation.updatedAt) + 30 * 864e5 };
|
|
7442
|
+
}
|
|
7443
|
+
return { nextRunAt: null, expiresAt: null };
|
|
7444
|
+
}
|
|
7304
7445
|
async function save(db, userId, key, kind, value, options) {
|
|
7305
7446
|
return db.putCloudDataRecord(
|
|
7306
7447
|
userId,
|
|
@@ -7313,7 +7454,7 @@ async function save(db, userId, key, kind, value, options) {
|
|
|
7313
7454
|
}),
|
|
7314
7455
|
key
|
|
7315
7456
|
),
|
|
7316
|
-
options
|
|
7457
|
+
{ ...options, ...kind === "operation" ? { work: operationWork(value) } : {} }
|
|
7317
7458
|
);
|
|
7318
7459
|
}
|
|
7319
7460
|
async function readCloudRecord(db, userId, key, kind, id) {
|
|
@@ -7346,7 +7487,7 @@ async function makeCleanupPlan(ctx, db, userId, key, input) {
|
|
|
7346
7487
|
throw cloudError("INVALID_CLEANUP_SELECTION", "\u8BF7\u9009\u62E9\u81F3\u5C11\u4E00\u9879\u8D44\u6E90");
|
|
7347
7488
|
if (types !== void 0 && (!Array.isArray(types) || !types.length || types.some((type) => !CLOUD_RESOURCE_TYPES.includes(type))))
|
|
7348
7489
|
throw cloudError("INVALID_CLEANUP_SELECTION", "\u8D44\u6E90\u7C7B\u522B\u65E0\u6548");
|
|
7349
|
-
if (mode === "purge" && !owner && !_optionalChain([resourceIds, 'optionalAccess',
|
|
7490
|
+
if (mode === "purge" && !owner && !_optionalChain([resourceIds, 'optionalAccess', _83 => _83.length]))
|
|
7350
7491
|
throw cloudError("INVALID_CLEANUP_SELECTION", "\u6E05\u7406\u9700\u8981\u660E\u786E\u8D44\u6E90\u6216\u5F52\u5C5E");
|
|
7351
7492
|
if (mode === "retire-owner" && (resourceIds || types))
|
|
7352
7493
|
throw cloudError("INVALID_CLEANUP_SELECTION", "\u5F7B\u5E95\u79FB\u9664\u4E0D\u80FD\u9650\u5236\u8D44\u6E90\u7C7B\u522B");
|
|
@@ -7675,33 +7816,65 @@ async function advanceCleanup(ctx, db, userId, key, operation) {
|
|
|
7675
7816
|
}
|
|
7676
7817
|
return operation;
|
|
7677
7818
|
}
|
|
7819
|
+
async function repairLegacyWorkIndex(ctx) {
|
|
7820
|
+
const db = ctx.db;
|
|
7821
|
+
if (typeof db.getCloudMaintenanceBatch !== "function") return;
|
|
7822
|
+
const name = "management-work-v1";
|
|
7823
|
+
const batch = await db.getCloudMaintenanceBatch(name, "cloud_data_records", 100);
|
|
7824
|
+
if (batch.completed) return;
|
|
7825
|
+
for (const row of batch.rows) {
|
|
7826
|
+
let work;
|
|
7827
|
+
if (["inventory", "plan"].includes(row.kind)) {
|
|
7828
|
+
work = { nextRunAt: null, expiresAt: row.updated_at + 36e5 };
|
|
7829
|
+
} else if (row.kind === "operation") {
|
|
7830
|
+
try {
|
|
7831
|
+
const record = await db.readCloudMaintenanceRecord(row);
|
|
7832
|
+
const key = await deriveUserEncryptionKey(row.user_id, ctx.masterKey);
|
|
7833
|
+
work = operationWork(JSON.parse(await decryptFromStorage(record.data, key)));
|
|
7834
|
+
} catch (e11) {
|
|
7835
|
+
console.warn("[amsg] Legacy cleanup operation could not be indexed");
|
|
7836
|
+
continue;
|
|
7837
|
+
}
|
|
7838
|
+
} else continue;
|
|
7839
|
+
await db.indexCloudDataRecordWork(row.user_id, row.kind, row.id, work, row.write_token);
|
|
7840
|
+
}
|
|
7841
|
+
const cursor = _nullishCoalesce(_optionalChain([batch, 'access', _84 => _84.rows, 'access', _85 => _85.at, 'call', _86 => _86(-1), 'optionalAccess', _87 => _87.maintenance_rowid]), () => ( batch.upperBound));
|
|
7842
|
+
await db.finishCloudMaintenanceBatch(name, cursor, batch.rows.length < 100 || cursor >= batch.upperBound);
|
|
7843
|
+
}
|
|
7678
7844
|
async function resumeCloudDataCleanups(ctx) {
|
|
7679
7845
|
const db = ctx.db;
|
|
7680
|
-
if (!_optionalChain([db, 'optionalAccess',
|
|
7681
|
-
|
|
7682
|
-
|
|
7683
|
-
|
|
7684
|
-
await db.
|
|
7685
|
-
let processed = 0;
|
|
7846
|
+
if (!_optionalChain([db, 'optionalAccess', _88 => _88.cloudDataManagement])) return;
|
|
7847
|
+
await repairLegacyWorkIndex(ctx);
|
|
7848
|
+
if (typeof db.repairCloudResourceMetadata === "function") await db.repairCloudResourceMetadata(100);
|
|
7849
|
+
if (typeof db.cleanupExpiredCloudDataRecords === "function") await db.cleanupExpiredCloudDataRecords(Date.now(), 100);
|
|
7850
|
+
const rows = typeof db.listDueCloudDataOperations === "function" ? await db.listDueCloudDataOperations(Date.now(), 25) : await db.listCloudDataRecordsAcrossUsers("operation");
|
|
7686
7851
|
for (const row of rows) {
|
|
7687
7852
|
try {
|
|
7688
7853
|
const key = await deriveUserEncryptionKey(row.userId, ctx.masterKey);
|
|
7689
7854
|
const operation = JSON.parse(await decryptFromStorage(row.data, key));
|
|
7690
|
-
if (["completed", "failed"].includes(operation.status) && operation.updatedAt < Date.now() - 30 * 864e5) {
|
|
7691
|
-
await db.deleteCloudDataRecord(row.userId, "operation", operation.id);
|
|
7692
|
-
continue;
|
|
7693
|
-
}
|
|
7694
7855
|
if (["pending", "running"].includes(operation.status)) {
|
|
7695
7856
|
await advanceCleanup(ctx, db, row.userId, key, operation);
|
|
7696
|
-
if (++processed >= 100) break;
|
|
7697
7857
|
}
|
|
7698
|
-
} catch (
|
|
7858
|
+
} catch (e12) {
|
|
7699
7859
|
console.warn("[amsg] A cloud cleanup operation could not be resumed");
|
|
7700
7860
|
}
|
|
7701
7861
|
}
|
|
7702
7862
|
}
|
|
7703
7863
|
|
|
7704
7864
|
// src/server/handlers/cloud-data.js
|
|
7865
|
+
function inventorySummary(inventory) {
|
|
7866
|
+
const resources = inventory.entries.map((entry) => entry.resource);
|
|
7867
|
+
return {
|
|
7868
|
+
total: resources.length,
|
|
7869
|
+
counts: CLOUD_RESOURCE_TYPES.map((type) => ({
|
|
7870
|
+
type,
|
|
7871
|
+
count: resources.filter((resource) => resource.type === type).length,
|
|
7872
|
+
byteSize: resources.filter((resource) => resource.type === type).reduce((sum, resource) => sum + (resource.byteSize || 0), 0)
|
|
7873
|
+
})),
|
|
7874
|
+
complete: inventory.complete,
|
|
7875
|
+
gaps: inventory.gaps
|
|
7876
|
+
};
|
|
7877
|
+
}
|
|
7705
7878
|
function createCloudDataHandler(ctx) {
|
|
7706
7879
|
async function run(url, headers, body, method) {
|
|
7707
7880
|
const tenant = await ctx.tenantManager.resolveTenant(headers);
|
|
@@ -7734,7 +7907,7 @@ function createCloudDataHandler(ctx) {
|
|
|
7734
7907
|
if (!parsed.ok) throw cloudError("INVALID_PAYLOAD", "\u8BF7\u6C42\u683C\u5F0F\u65E0\u6548");
|
|
7735
7908
|
try {
|
|
7736
7909
|
input = await decryptPayload(parsed.data, key);
|
|
7737
|
-
} catch (
|
|
7910
|
+
} catch (e13) {
|
|
7738
7911
|
throw cloudError("DECRYPTION_FAILED", "\u8BF7\u6C42\u89E3\u5BC6\u5931\u8D25");
|
|
7739
7912
|
}
|
|
7740
7913
|
if (!input || typeof input !== "object" || Array.isArray(input))
|
|
@@ -7748,17 +7921,7 @@ function createCloudDataHandler(ctx) {
|
|
|
7748
7921
|
const filter = { ownerType, ownerId, type };
|
|
7749
7922
|
if (path.endsWith("/summary")) {
|
|
7750
7923
|
const inventory = await cloudInventory(ctx, db, userId, key);
|
|
7751
|
-
|
|
7752
|
-
data = {
|
|
7753
|
-
total: resources.length,
|
|
7754
|
-
counts: CLOUD_RESOURCE_TYPES.map((type2) => ({
|
|
7755
|
-
type: type2,
|
|
7756
|
-
count: resources.filter((r) => r.type === type2).length,
|
|
7757
|
-
byteSize: resources.filter((r) => r.type === type2).reduce((sum, r) => sum + (r.byteSize || 0), 0)
|
|
7758
|
-
})),
|
|
7759
|
-
complete: inventory.complete,
|
|
7760
|
-
gaps: inventory.gaps
|
|
7761
|
-
};
|
|
7924
|
+
data = inventorySummary(inventory);
|
|
7762
7925
|
} else {
|
|
7763
7926
|
const limit = Number(params.get("limit") || 50);
|
|
7764
7927
|
if (!Number.isInteger(limit) || limit < 1 || limit > 200)
|
|
@@ -7790,9 +7953,10 @@ function createCloudDataHandler(ctx) {
|
|
|
7790
7953
|
snapshot = {
|
|
7791
7954
|
id: crypto.randomUUID(),
|
|
7792
7955
|
filter,
|
|
7956
|
+
summary: inventorySummary(inventory),
|
|
7793
7957
|
expiresAt: Date.now() + 15 * 60 * 1e3,
|
|
7794
7958
|
resources: inventory.entries.map((e) => e.resource).filter(
|
|
7795
|
-
(r) => (!type || r.type === type) && (!ownerId || _optionalChain([r, 'access',
|
|
7959
|
+
(r) => (!type || r.type === type) && (!ownerId || _optionalChain([r, 'access', _89 => _89.owner, 'optionalAccess', _90 => _90.type]) === ownerType && r.owner.id === ownerId)
|
|
7796
7960
|
),
|
|
7797
7961
|
complete: inventory.complete,
|
|
7798
7962
|
gaps: inventory.gaps
|
|
@@ -7806,6 +7970,7 @@ function createCloudDataHandler(ctx) {
|
|
|
7806
7970
|
}
|
|
7807
7971
|
data = {
|
|
7808
7972
|
resources: snapshot.resources.slice(offset, offset + limit),
|
|
7973
|
+
...snapshot.summary ? { summary: snapshot.summary } : {},
|
|
7809
7974
|
nextCursor: offset + limit < snapshot.resources.length ? `${snapshot.id}:${offset + limit}` : null,
|
|
7810
7975
|
complete: snapshot.complete,
|
|
7811
7976
|
gaps: snapshot.gaps
|
|
@@ -7826,7 +7991,7 @@ function createCloudDataHandler(ctx) {
|
|
|
7826
7991
|
JSON.parse(await decryptFromStorage(row.data, key))
|
|
7827
7992
|
)
|
|
7828
7993
|
);
|
|
7829
|
-
} catch (
|
|
7994
|
+
} catch (e14) {
|
|
7830
7995
|
gaps.push({
|
|
7831
7996
|
source: "operation",
|
|
7832
7997
|
code: "UNREADABLE_OPERATION",
|
|
@@ -7874,7 +8039,7 @@ function createCloudDataHandler(ctx) {
|
|
|
7874
8039
|
const rows = await db.listCloudDataRecords(userId, "operation");
|
|
7875
8040
|
for (const row of rows) {
|
|
7876
8041
|
const op = JSON.parse(await decryptFromStorage(row.data, key));
|
|
7877
|
-
if (op.mode === "retire-owner" && _optionalChain([op, 'access',
|
|
8042
|
+
if (op.mode === "retire-owner" && _optionalChain([op, 'access', _91 => _91.owner, 'optionalAccess', _92 => _92.type]) === owner.type && _optionalChain([op, 'access', _93 => _93.owner, 'optionalAccess', _94 => _94.id]) === owner.id && ["pending", "running"].includes(op.status))
|
|
7878
8043
|
throw cloudError(
|
|
7879
8044
|
"CLOUD_CLEANUP_IN_PROGRESS",
|
|
7880
8045
|
"\u6E05\u7406\u5B8C\u6210\u540E\u624D\u80FD\u91CD\u65B0\u542F\u7528",
|
|
@@ -8092,7 +8257,7 @@ function createSingleUserServer(config) {
|
|
|
8092
8257
|
if (!config.masterKey) throw new Error("[amsg-server single-user] config.masterKey is required");
|
|
8093
8258
|
const vapid = config.vapid || {};
|
|
8094
8259
|
const tenantManager = createSingleUserContextManager({
|
|
8095
|
-
db: createCloudGuardedAdapter(config.db, { masterKey: config.masterKey, resolveOwner: _optionalChain([config, 'access',
|
|
8260
|
+
db: createCloudGuardedAdapter(config.db, { masterKey: config.masterKey, resolveOwner: _optionalChain([config, 'access', _95 => _95.cloudData, 'optionalAccess', _96 => _96.resolveOwner]) }),
|
|
8096
8261
|
masterKey: config.masterKey,
|
|
8097
8262
|
serverToken: config.serverToken
|
|
8098
8263
|
});
|
|
@@ -8150,7 +8315,7 @@ function createSingleUserServer(config) {
|
|
|
8150
8315
|
}
|
|
8151
8316
|
|
|
8152
8317
|
// src/server/lib/schema-version.js
|
|
8153
|
-
var SCHEMA_VERSION = "2.6.0-cloud-data.
|
|
8318
|
+
var SCHEMA_VERSION = "2.6.0-cloud-data.2";
|
|
8154
8319
|
function requireIntrospection(db) {
|
|
8155
8320
|
if (!db || typeof db.describeSchema !== "function") {
|
|
8156
8321
|
throw new Error(
|
|
@@ -8178,6 +8343,10 @@ async function getSchemaVersion(db) {
|
|
|
8178
8343
|
for (const index of SQLITE_REQUIRED_SCHEMA.indexes) {
|
|
8179
8344
|
if (!liveIndexes.has(index)) missing.push(`index:${index}`);
|
|
8180
8345
|
}
|
|
8346
|
+
const liveTriggers = new Set(_optionalChain([live, 'optionalAccess', _97 => _97.triggers]) || []);
|
|
8347
|
+
for (const name of SQLITE_REQUIRED_SCHEMA.triggers) {
|
|
8348
|
+
if (!liveTriggers.has(name)) missing.push(`trigger:${name}`);
|
|
8349
|
+
}
|
|
8181
8350
|
const ok = missing.length === 0;
|
|
8182
8351
|
return { current: ok ? SCHEMA_VERSION : null, required: SCHEMA_VERSION, ok, missing };
|
|
8183
8352
|
}
|
package/dist/cloudflare.cjs
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
var
|
|
31
|
+
var _chunkUG5ZNM5Jcjs = require('./chunk-UG5ZNM5J.cjs');
|
|
32
32
|
require('./chunk-7NMQFTDJ.cjs');
|
|
33
33
|
|
|
34
34
|
|
|
@@ -60,4 +60,4 @@ require('./chunk-7NMQFTDJ.cjs');
|
|
|
60
60
|
|
|
61
61
|
|
|
62
62
|
|
|
63
|
-
exports.DEFAULT_MAX_DELIVERY_RETRIES =
|
|
63
|
+
exports.DEFAULT_MAX_DELIVERY_RETRIES = _chunkUG5ZNM5Jcjs.DEFAULT_MAX_DELIVERY_RETRIES; exports.DEFAULT_MAX_REQUEST_BODY_BYTES = _chunkUG5ZNM5Jcjs.DEFAULT_MAX_REQUEST_BODY_BYTES; exports.MAX_DEFER_AFTER_MS = _chunkUG5ZNM5Jcjs.MAX_DEFER_AFTER_MS; exports.MAX_PUSH_PAYLOAD_BYTES = _chunkUG5ZNM5Jcjs.MAX_PUSH_PAYLOAD_BYTES; exports.NonRetryableError = _chunkUG5ZNM5Jcjs.NonRetryableError; exports.PUSH_ENVELOPE_RESERVED_BYTES = _chunkUG5ZNM5Jcjs.PUSH_ENVELOPE_RESERVED_BYTES; exports.SCHEMA_VERSION = _chunkUG5ZNM5Jcjs.SCHEMA_VERSION; exports.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES = _chunkUG5ZNM5Jcjs.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES; exports.WEB_PUSH_MAX_BODY_BYTES = _chunkUG5ZNM5Jcjs.WEB_PUSH_MAX_BODY_BYTES; exports.advanceOccurrence = _chunkUG5ZNM5Jcjs.advanceOccurrence; exports.createD1Adapter = _chunkUG5ZNM5Jcjs.createD1Adapter; exports.createSingleUserCloudflareWorker = _chunkUG5ZNM5Jcjs.createSingleUserCloudflareWorker; exports.createSingleUserServer = _chunkUG5ZNM5Jcjs.createSingleUserServer; exports.createWebCryptoWebPush = _chunkUG5ZNM5Jcjs.createWebCryptoWebPush; exports.decryptFromStorage = _chunkUG5ZNM5Jcjs.decryptFromStorage; exports.decryptPayload = _chunkUG5ZNM5Jcjs.decryptPayload; exports.deriveUserEncryptionKey = _chunkUG5ZNM5Jcjs.deriveUserEncryptionKey; exports.encryptForStorage = _chunkUG5ZNM5Jcjs.encryptForStorage; exports.ensureSchema = _chunkUG5ZNM5Jcjs.ensureSchema; exports.getSchemaVersion = _chunkUG5ZNM5Jcjs.getSchemaVersion; exports.isNonRetryableError = _chunkUG5ZNM5Jcjs.isNonRetryableError; exports.isValidTimeZoneId = _chunkUG5ZNM5Jcjs.isValidTimeZoneId; exports.measurePushPayload = _chunkUG5ZNM5Jcjs.measurePushPayload; exports.nextFutureOccurrence = _chunkUG5ZNM5Jcjs.nextFutureOccurrence; exports.planNextOccurrence = _chunkUG5ZNM5Jcjs.planNextOccurrence; exports.readRequestBody = _chunkUG5ZNM5Jcjs.readRequestBody; exports.runScheduledTick = _chunkUG5ZNM5Jcjs.runScheduledTick; exports.runTask = _chunkUG5ZNM5Jcjs.runTask; exports.summarizeErrorCause = _chunkUG5ZNM5Jcjs.summarizeErrorCause;
|