@rei-standard/amsg-server 3.1.0-next.0 → 3.1.0-next.1

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.
@@ -57,6 +57,7 @@ export class D1Adapter {
57
57
  };
58
58
  _cloudBatch(statements: any, userId: any, guards?: any[], metadata?: Map<any, any>): Promise<any[]>;
59
59
  getCloudResourceMetadata(userId: any, resourceKey: any): Promise<any>;
60
+ getOutboxPayload(userId: any, messageId: any): Promise<any>;
60
61
  listCloudResourceRows(userId: any): Promise<{
61
62
  gaps: any[];
62
63
  }>;
@@ -148,6 +149,10 @@ export class D1Adapter {
148
149
  updatedAt: any;
149
150
  }>;
150
151
  isCloudOwnerGuardValid(userId: any, guard: any): Promise<boolean>;
152
+ _rowSnapshotMatch(spec: any, row: any): {
153
+ predicate: string;
154
+ values: any[];
155
+ };
151
156
  /** Delete only the exact physical snapshot; no untrusted SQL identifiers. */
152
157
  deleteCloudResourceRows(userId: any, locators: any, { operationId, leaseToken }?: {}): Promise<{
153
158
  deleted: number;
@@ -147,14 +147,33 @@ var _amsgshared = require('@rei-standard/amsg-shared');
147
147
  // src/server/lib/encryption.js
148
148
  var base64ToBytes = _amsgshared.base64UrlToBytes;
149
149
  var TAG_LENGTH_BYTES = 16;
150
+ var AES_KEY_CACHE_MAX = 128;
151
+ var aesKeyCache = /* @__PURE__ */ new Map();
150
152
  function importAesKey(hexKey, usage) {
151
- return globalThis.crypto.subtle.importKey(
152
- "raw",
153
- _amsgshared.hexToBytes.call(void 0, hexKey),
154
- { name: "AES-GCM" },
155
- false,
156
- [usage]
157
- );
153
+ const cacheKey = `${usage}:${hexKey}`;
154
+ const cached = aesKeyCache.get(cacheKey);
155
+ if (cached) return cached;
156
+ let promise;
157
+ try {
158
+ promise = globalThis.crypto.subtle.importKey(
159
+ "raw",
160
+ _amsgshared.hexToBytes.call(void 0, hexKey),
161
+ { name: "AES-GCM" },
162
+ false,
163
+ [usage]
164
+ ).catch((err6) => {
165
+ aesKeyCache.delete(cacheKey);
166
+ throw err6;
167
+ });
168
+ } catch (err6) {
169
+ return Promise.reject(err6);
170
+ }
171
+ if (aesKeyCache.size >= AES_KEY_CACHE_MAX) {
172
+ const oldest = aesKeyCache.keys().next().value;
173
+ if (oldest !== void 0) aesKeyCache.delete(oldest);
174
+ }
175
+ aesKeyCache.set(cacheKey, promise);
176
+ return promise;
158
177
  }
159
178
  async function aesGcmSeal(hexKey, iv, plaintextBytes) {
160
179
  const key = await importAesKey(hexKey, "encrypt");
@@ -5451,12 +5470,37 @@ var D1Adapter = class {
5451
5470
  const row = await this._db.prepare("SELECT encrypted_value FROM cloud_resource_metadata WHERE user_id=? AND resource_key=?").bind(userId, resourceKey).first();
5452
5471
  return _nullishCoalesce(_optionalChain([row, 'optionalAccess', _52 => _52.encrypted_value]), () => ( null));
5453
5472
  }
5473
+ async getOutboxPayload(userId, messageId) {
5474
+ const row = await this._db.prepare(
5475
+ "SELECT payload FROM message_outbox WHERE user_id = ? AND message_id = ? LIMIT 1"
5476
+ ).bind(userId, messageId).first();
5477
+ return _nullishCoalesce(_optionalChain([row, 'optionalAccess', _53 => _53.payload]), () => ( null));
5478
+ }
5454
5479
  async listCloudResourceRows(userId) {
5455
- const tables = { task: "scheduled_messages", state: "client_state", credential: "llm_credentials", outbox: "message_outbox", subscription: "push_subscriptions", metadata: "cloud_resource_metadata" };
5480
+ const queries = {
5481
+ task: "SELECT * FROM scheduled_messages WHERE user_id = ?",
5482
+ state: `SELECT user_id, namespace, key,
5483
+ CASE WHEN LENGTH(value) <= 1024 THEN value ELSE NULL END AS value,
5484
+ LENGTH(CAST(value AS BLOB)) AS byte_size,
5485
+ substr(value, 1, 128) AS value_prefix,
5486
+ CASE WHEN LENGTH(value) > 128 THEN substr(value, -64) ELSE '' END AS value_suffix,
5487
+ updated_at
5488
+ FROM client_state WHERE user_id = ?`,
5489
+ credential: "SELECT * FROM llm_credentials WHERE user_id = ?",
5490
+ outbox: `SELECT id, user_id, message_id, task_uuid, session_id, message_index, total_messages,
5491
+ CASE WHEN LENGTH(payload) <= 1024 THEN payload ELSE NULL END AS payload,
5492
+ LENGTH(CAST(payload AS BLOB)) AS byte_size,
5493
+ substr(payload, 1, 128) AS payload_prefix,
5494
+ CASE WHEN LENGTH(payload) > 128 THEN substr(payload, -64) ELSE '' END AS payload_suffix,
5495
+ created_at, delivered_at, acked_at
5496
+ FROM message_outbox WHERE user_id = ?`,
5497
+ subscription: "SELECT * FROM push_subscriptions WHERE user_id = ?",
5498
+ metadata: "SELECT * FROM cloud_resource_metadata WHERE user_id = ?"
5499
+ };
5456
5500
  const result = { gaps: [] };
5457
- await Promise.all(Object.entries(tables).map(async ([type, table]) => {
5501
+ await Promise.all(Object.entries(queries).map(async ([type, sql]) => {
5458
5502
  try {
5459
- const response = await this._db.prepare(`SELECT * FROM ${table} WHERE user_id = ?`).bind(userId).all();
5503
+ const response = await this._db.prepare(sql).bind(userId).all();
5460
5504
  result[type] = response.results || [];
5461
5505
  } catch (e4) {
5462
5506
  result[type] = [];
@@ -5521,7 +5565,10 @@ var D1Adapter = class {
5521
5565
  if (idempotencyKey) {
5522
5566
  return this._cloudRecord(await this._db.prepare(`SELECT * FROM cloud_data_records WHERE user_id=? AND kind=? AND idempotency_key=?`).bind(userId, kind, idempotencyKey).first());
5523
5567
  }
5524
- return this.getCloudDataRecord(userId, kind, id);
5568
+ if (createOnly) {
5569
+ return this.getCloudDataRecord(userId, kind, id);
5570
+ }
5571
+ return { id, userId, kind, data, updatedAt: now };
5525
5572
  }
5526
5573
  async getCloudDataRecord(userId, kind, id) {
5527
5574
  return this._cloudRecord(await this._db.prepare("SELECT * FROM cloud_data_records WHERE user_id=? AND kind=? AND id=?").bind(userId, kind, id).first());
@@ -5654,7 +5701,7 @@ var D1Adapter = class {
5654
5701
  const name = "metadata-sidecars-v1";
5655
5702
  const batch = await this.getCloudMaintenanceBatch(name, "cloud_resource_metadata", limit);
5656
5703
  if (batch.completed) return;
5657
- const cursor = _nullishCoalesce(_optionalChain([batch, 'access', _53 => _53.rows, 'access', _54 => _54.at, 'call', _55 => _55(-1), 'optionalAccess', _56 => _56.maintenance_rowid]), () => ( batch.upperBound));
5704
+ const cursor = _nullishCoalesce(_optionalChain([batch, 'access', _54 => _54.rows, 'access', _55 => _55.at, 'call', _56 => _56(-1), 'optionalAccess', _57 => _57.maintenance_rowid]), () => ( batch.upperBound));
5658
5705
  if (batch.rows.length) await this.cleanupCloudResourceMetadata(null, { after: batch.cursor, through: cursor });
5659
5706
  await this.finishCloudMaintenanceBatch(name, cursor, batch.rows.length < limit || cursor >= batch.upperBound);
5660
5707
  }
@@ -5728,7 +5775,30 @@ var D1Adapter = class {
5728
5775
  if (!guard) return true;
5729
5776
  const condition = this._cloudGuardPredicate(userId, guard);
5730
5777
  const row = await this._db.prepare(`SELECT ${condition.sql} AS valid`).bind(...condition.args).first();
5731
- return !!_optionalChain([row, 'optionalAccess', _57 => _57.valid]);
5778
+ return !!_optionalChain([row, 'optionalAccess', _58 => _58.valid]);
5779
+ }
5780
+ _rowSnapshotMatch(spec, row) {
5781
+ const clauses = [];
5782
+ const args = [];
5783
+ for (const column of spec.columns) {
5784
+ if (!Object.hasOwn(row, column)) continue;
5785
+ if ((column === "value" || column === "payload") && row[column] === null && typeof row.byte_size === "number") {
5786
+ clauses.push(
5787
+ `LENGTH(CAST(${column} AS BLOB)) IS ?`,
5788
+ `substr(${column}, 1, 128) IS ?`,
5789
+ `(CASE WHEN LENGTH(${column}) > 128 THEN substr(${column}, -64) ELSE '' END) IS ?`
5790
+ );
5791
+ args.push(
5792
+ row.byte_size,
5793
+ _nullishCoalesce(row[`${column}_prefix`], () => ( null)),
5794
+ _nullishCoalesce(row[`${column}_suffix`], () => ( ""))
5795
+ );
5796
+ } else {
5797
+ clauses.push(`${column} IS ?`);
5798
+ args.push(row[column]);
5799
+ }
5800
+ }
5801
+ return { predicate: clauses.join(" AND "), values: args };
5732
5802
  }
5733
5803
  /** Delete only the exact physical snapshot; no untrusted SQL identifiers. */
5734
5804
  async deleteCloudResourceRows(userId, locators, { operationId, leaseToken } = {}) {
@@ -5777,9 +5847,7 @@ var D1Adapter = class {
5777
5847
  ).bind(userId, namespace, key, "amsg-chunks" + namespace, key + "", key + " ", identities));
5778
5848
  }
5779
5849
  for (const row of locator.rows) {
5780
- const columns = spec.columns.filter((column) => Object.hasOwn(row, column));
5781
- const predicate = columns.map((column) => `${column} IS ?`).join(" AND ");
5782
- const values = columns.map((column) => row[column]);
5850
+ const { predicate, values } = this._rowSnapshotMatch(spec, row);
5783
5851
  const identity = spec.keys.map((column) => `${column} IS ?`).join(" AND ");
5784
5852
  statements.push(this._db.prepare(
5785
5853
  `INSERT INTO cloud_guard_assertions (allowed)
@@ -5788,8 +5856,8 @@ var D1Adapter = class {
5788
5856
  ).bind(...spec.keys.map((column) => row[column]), ...values));
5789
5857
  }
5790
5858
  for (const row of locator.rows) {
5791
- const columns = spec.columns.filter((column) => Object.hasOwn(row, column));
5792
- statements.push(this._db.prepare(`DELETE FROM ${spec.table} WHERE ${columns.map((column) => `${column} IS ?`).join(" AND ")}`).bind(...columns.map((column) => row[column])));
5859
+ const { predicate, values } = this._rowSnapshotMatch(spec, row);
5860
+ statements.push(this._db.prepare(`DELETE FROM ${spec.table} WHERE ${predicate}`).bind(...values));
5793
5861
  }
5794
5862
  if (locator.metadataKey) statements.push(this._db.prepare("DELETE FROM cloud_resource_metadata WHERE user_id=? AND resource_key=?").bind(userId, locator.metadataKey));
5795
5863
  try {
@@ -5981,7 +6049,7 @@ var D1Adapter = class {
5981
6049
  ).bind(...values);
5982
6050
  const ownerUser = cloudGuard ? await this._db.prepare("SELECT user_id FROM scheduled_messages WHERE id=?").bind(taskId).first() : null;
5983
6051
  if (cloudGuard && !ownerUser) return null;
5984
- await this._cloudBatch([statement], _optionalChain([ownerUser, 'optionalAccess', _58 => _58.user_id]), [cloudGuard]);
6052
+ await this._cloudBatch([statement], _optionalChain([ownerUser, 'optionalAccess', _59 => _59.user_id]), [cloudGuard]);
5985
6053
  return this._db.prepare("SELECT * FROM scheduled_messages WHERE id = ?").bind(taskId).first();
5986
6054
  }
5987
6055
  /**
@@ -6106,7 +6174,7 @@ var D1Adapter = class {
6106
6174
  ).bind(...values);
6107
6175
  const ownerUser = cloudGuard ? await this._db.prepare("SELECT user_id FROM scheduled_messages WHERE id=?").bind(taskId).first() : null;
6108
6176
  if (cloudGuard && !ownerUser) return false;
6109
- const [res] = await this._cloudBatch([statement], _optionalChain([ownerUser, 'optionalAccess', _59 => _59.user_id]), [cloudGuard]);
6177
+ const [res] = await this._cloudBatch([statement], _optionalChain([ownerUser, 'optionalAccess', _60 => _60.user_id]), [cloudGuard]);
6110
6178
  return (res.meta.changes || 0) > 0;
6111
6179
  }
6112
6180
  /**
@@ -6125,7 +6193,7 @@ var D1Adapter = class {
6125
6193
  ).bind(this._iso(leaseUntil), taskId);
6126
6194
  const ownerUser = cloudGuard ? await this._db.prepare("SELECT user_id FROM scheduled_messages WHERE id=?").bind(taskId).first() : null;
6127
6195
  if (cloudGuard && !ownerUser) return false;
6128
- const [res] = await this._cloudBatch([statement], _optionalChain([ownerUser, 'optionalAccess', _60 => _60.user_id]), [cloudGuard]);
6196
+ const [res] = await this._cloudBatch([statement], _optionalChain([ownerUser, 'optionalAccess', _61 => _61.user_id]), [cloudGuard]);
6129
6197
  return (res.meta.changes || 0) > 0;
6130
6198
  }
6131
6199
  async listTasks(userId, opts = {}) {
@@ -6286,7 +6354,7 @@ var D1Adapter = class {
6286
6354
  result.cleanupOutcomes = probeIndexes.map((probeAt) => {
6287
6355
  if (probeAt === null) return null;
6288
6356
  const row = results[probeAt] && Array.isArray(results[probeAt].results) ? results[probeAt].results[0] : null;
6289
- return Number(_nullishCoalesce(_optionalChain([row, 'optionalAccess', _61 => _61.n]), () => ( 0))) === 0;
6357
+ return Number(_nullishCoalesce(_optionalChain([row, 'optionalAccess', _62 => _62.n]), () => ( 0))) === 0;
6290
6358
  });
6291
6359
  }
6292
6360
  return result;
@@ -7160,7 +7228,7 @@ function createClientStateNamespacesHandler(ctx) {
7160
7228
  }
7161
7229
 
7162
7230
  // src/server/lib/version.js
7163
- var SERVER_VERSION = true ? "3.1.0-next.0" : "0.0.0-dev";
7231
+ var SERVER_VERSION = true ? "3.1.0-next.1" : "0.0.0-dev";
7164
7232
 
7165
7233
  // src/server/handlers/capabilities.js
7166
7234
  var SERVER_FEATURES = Object.freeze([
@@ -7328,6 +7396,39 @@ function objectOrText(value) {
7328
7396
  return value;
7329
7397
  }
7330
7398
  }
7399
+ function utf8ByteLength(text) {
7400
+ if (typeof text !== "string" || text.length === 0) return 0;
7401
+ return /[^\x00-\x7f]/.test(text) ? encoder.encode(text).length : text.length;
7402
+ }
7403
+ function rowByteSize(row) {
7404
+ if (typeof row.byte_size === "number") return row.byte_size;
7405
+ return utf8ByteLength(
7406
+ String(
7407
+ _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(row.value, () => ( row.encrypted_payload)), () => ( row.encrypted_value)), () => ( row.payload)), () => ( row.subscription)), () => ( ""))
7408
+ )
7409
+ );
7410
+ }
7411
+ var STORAGE_PREFIX_RE = /^[0-9a-f]{32}:[0-9a-f]{24,32}:[0-9a-f]*$/i;
7412
+ var HEX_RE = /^[0-9a-f]*$/i;
7413
+ function isValidStorageCiphertext(fullText, prefix, suffix, byteSize) {
7414
+ if (typeof fullText === "string") {
7415
+ if (!STORAGE_PREFIX_RE.test(fullText)) return false;
7416
+ const secondColon = fullText.indexOf(":", 33);
7417
+ return secondColon > 32 && (fullText.length - secondColon - 1) % 2 === 0;
7418
+ }
7419
+ if (typeof prefix === "string" && typeof byteSize === "number") {
7420
+ if (!STORAGE_PREFIX_RE.test(prefix)) return false;
7421
+ if (typeof suffix === "string" && !HEX_RE.test(suffix)) return false;
7422
+ const secondColon = prefix.indexOf(":", 33);
7423
+ return secondColon > 32 && (byteSize - secondColon - 1) % 2 === 0;
7424
+ }
7425
+ return false;
7426
+ }
7427
+ function hasCompleteStoredMetadata(stored) {
7428
+ return Boolean(
7429
+ stored && safeOwner(stored.owner) !== null && typeof stored.kind === "string" && stored.kind.length > 0
7430
+ );
7431
+ }
7331
7432
  async function buildCloudDataInventory({
7332
7433
  db,
7333
7434
  userId,
@@ -7340,6 +7441,20 @@ async function buildCloudDataInventory({
7340
7441
  const metadata = new Map(
7341
7442
  (raw.metadata || []).map((row) => [row.resource_key, row.encrypted_value])
7342
7443
  );
7444
+ const readStoredMetadata = async (metadataKey) => {
7445
+ const encryptedMetadata = metadata.get(metadataKey) || null;
7446
+ if (!encryptedMetadata) {
7447
+ return { encryptedMetadata: null, stored: null, unreadable: false };
7448
+ }
7449
+ try {
7450
+ const stored = JSON.parse(
7451
+ await decryptFromStorage(encryptedMetadata, userKey)
7452
+ );
7453
+ return { encryptedMetadata, stored, unreadable: false };
7454
+ } catch (e6) {
7455
+ return { encryptedMetadata, stored: null, unreadable: true };
7456
+ }
7457
+ };
7343
7458
  const taskPayloads = /* @__PURE__ */ new Map();
7344
7459
  const taskByUuid = /* @__PURE__ */ new Map();
7345
7460
  for (const row of raw.task || []) {
@@ -7349,7 +7464,7 @@ async function buildCloudDataInventory({
7349
7464
  );
7350
7465
  taskPayloads.set(row.id, payload);
7351
7466
  if (row.uuid) taskByUuid.set(row.uuid, payload);
7352
- } catch (e6) {
7467
+ } catch (e7) {
7353
7468
  }
7354
7469
  }
7355
7470
  const tasks = (raw.task || []).filter((row) => taskPayloads.has(row.id)).map((row) => ({ ...taskPayloads.get(row.id), uuid: row.uuid }));
@@ -7364,23 +7479,19 @@ async function buildCloudDataInventory({
7364
7479
  status = null,
7365
7480
  namespace,
7366
7481
  key,
7367
- credId
7482
+ credId,
7483
+ metadataInfo
7368
7484
  }) => {
7369
7485
  const metadataKey = JSON.stringify([type, ...identity]);
7370
7486
  const id = await cloudDataHash(JSON.stringify([userId, metadataKey]));
7371
- let stored = null;
7372
- const encryptedMetadata = metadata.get(metadataKey);
7373
- if (encryptedMetadata) {
7374
- try {
7375
- stored = JSON.parse(
7376
- await decryptFromStorage(encryptedMetadata, userKey)
7377
- );
7378
- } catch (e7) {
7379
- unreadable = true;
7380
- }
7381
- }
7487
+ const {
7488
+ encryptedMetadata,
7489
+ stored,
7490
+ unreadable: metadataUnreadable
7491
+ } = await _asyncNullishCoalesce(metadataInfo, async () => ( await readStoredMetadata(metadataKey)));
7492
+ if (metadataUnreadable) unreadable = true;
7382
7493
  let resolved = null;
7383
- if (resolveOwner) {
7494
+ if (resolveOwner && !hasCompleteStoredMetadata(stored)) {
7384
7495
  try {
7385
7496
  resolved = await resolveOwner({
7386
7497
  type,
@@ -7400,17 +7511,10 @@ async function buildCloudDataInventory({
7400
7511
  });
7401
7512
  }
7402
7513
  }
7403
- const owner = safeOwner(_optionalChain([stored, 'optionalAccess', _62 => _62.owner])) || safeOwner(_optionalChain([payload, 'optionalAccess', _63 => _63.__cloudOwnerGuard, 'optionalAccess', _64 => _64.owner])) || safeOwner(_optionalChain([payload, 'optionalAccess', _65 => _65.metadata, 'optionalAccess', _66 => _66.cloudOwner])) || safeOwner(_optionalChain([payload, 'optionalAccess', _67 => _67.metadata, 'optionalAccess', _68 => _68.owner])) || safeOwner(_optionalChain([payload, 'optionalAccess', _69 => _69.owner])) || safeOwner(_optionalChain([task, 'optionalAccess', _70 => _70.__cloudOwnerGuard, 'optionalAccess', _71 => _71.owner])) || safeOwner(_optionalChain([task, 'optionalAccess', _72 => _72.metadata, 'optionalAccess', _73 => _73.cloudOwner])) || safeOwner(_optionalChain([task, 'optionalAccess', _74 => _74.metadata, 'optionalAccess', _75 => _75.owner])) || safeOwner(_optionalChain([task, 'optionalAccess', _76 => _76.owner])) || safeOwner(_optionalChain([resolved, 'optionalAccess', _77 => _77.owner]));
7404
- const kind = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([stored, 'optionalAccess', _78 => _78.kind]), () => ( _optionalChain([payload, 'optionalAccess', _79 => _79.metadata, 'optionalAccess', _80 => _80.kind]))), () => ( _optionalChain([payload, 'optionalAccess', _81 => _81.kind]))), () => ( _optionalChain([resolved, 'optionalAccess', _82 => _82.kind]))), () => ( null));
7514
+ const owner = safeOwner(_optionalChain([stored, 'optionalAccess', _63 => _63.owner])) || safeOwner(_optionalChain([payload, 'optionalAccess', _64 => _64.__cloudOwnerGuard, 'optionalAccess', _65 => _65.owner])) || safeOwner(_optionalChain([payload, 'optionalAccess', _66 => _66.metadata, 'optionalAccess', _67 => _67.cloudOwner])) || safeOwner(_optionalChain([payload, 'optionalAccess', _68 => _68.metadata, 'optionalAccess', _69 => _69.owner])) || safeOwner(_optionalChain([payload, 'optionalAccess', _70 => _70.owner])) || safeOwner(_optionalChain([task, 'optionalAccess', _71 => _71.__cloudOwnerGuard, 'optionalAccess', _72 => _72.owner])) || safeOwner(_optionalChain([task, 'optionalAccess', _73 => _73.metadata, 'optionalAccess', _74 => _74.cloudOwner])) || safeOwner(_optionalChain([task, 'optionalAccess', _75 => _75.metadata, 'optionalAccess', _76 => _76.owner])) || safeOwner(_optionalChain([task, 'optionalAccess', _77 => _77.owner])) || safeOwner(_optionalChain([resolved, 'optionalAccess', _78 => _78.owner]));
7515
+ const kind = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([stored, 'optionalAccess', _79 => _79.kind]), () => ( _optionalChain([payload, 'optionalAccess', _80 => _80.metadata, 'optionalAccess', _81 => _81.kind]))), () => ( _optionalChain([payload, 'optionalAccess', _82 => _82.kind]))), () => ( _optionalChain([resolved, 'optionalAccess', _83 => _83.kind]))), () => ( null));
7405
7516
  const times = rows.map((row) => timestamp(_nullishCoalesce(row.updated_at, () => ( row.created_at)))).filter((time) => time !== null);
7406
- const byteSize = rows.reduce(
7407
- (sum, row) => sum + encoder.encode(
7408
- String(
7409
- _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_nullishCoalesce(row.value, () => ( row.encrypted_payload)), () => ( row.encrypted_value)), () => ( row.payload)), () => ( row.subscription)), () => ( ""))
7410
- )
7411
- ).length,
7412
- 0
7413
- );
7517
+ const byteSize = rows.reduce((sum, row) => sum + rowByteSize(row), 0);
7414
7518
  const label = type === "state" ? `${namespace}/${key}` : type === "credential" ? credId : type === "task" ? rows[0].uuid || `task row ${rows[0].id}` : type === "outbox" ? rows[0].message_id : "Web Push subscription";
7415
7519
  entries.push({
7416
7520
  resource: {
@@ -7465,22 +7569,75 @@ async function buildCloudDataInventory({
7465
7569
  const slices = chunks.get(group) || [];
7466
7570
  chunks.delete(group);
7467
7571
  const rows = [row, ...slices.sort((a, b) => a.key.localeCompare(b.key))];
7468
- let value, unreadable = false;
7572
+ const metadataKey = JSON.stringify(["state", row.namespace, row.key]);
7573
+ const metadataInfo = await readStoredMetadata(metadataKey);
7574
+ const skipFullDecrypt = !metadataInfo.unreadable && hasCompleteStoredMetadata(metadataInfo.stored);
7575
+ let value, unreadable = metadataInfo.unreadable;
7469
7576
  try {
7470
- const count = parseChunkedRootCount(row.value);
7471
- if (count === null) value = await decryptFromStorage(row.value, userKey);
7472
- else {
7577
+ const rootMarker = _nullishCoalesce(_nullishCoalesce(row.value, () => ( row.value_prefix)), () => ( ""));
7578
+ const count = parseChunkedRootCount(rootMarker);
7579
+ if (count === null) {
7580
+ if (typeof row.value === "string" && (!skipFullDecrypt || row.value.length <= 1024)) {
7581
+ value = await decryptFromStorage(row.value, userKey);
7582
+ } else if (skipFullDecrypt) {
7583
+ if (!isValidStorageCiphertext(
7584
+ row.value,
7585
+ row.value_prefix,
7586
+ row.value_suffix,
7587
+ row.byte_size
7588
+ )) {
7589
+ throw new Error("Invalid state ciphertext");
7590
+ }
7591
+ } else {
7592
+ const fetched = typeof db.getClientState === "function" ? await db.getClientState(userId, row.namespace, { key: row.key }) : [];
7593
+ const rawValue = _optionalChain([fetched, 'optionalAccess', _84 => _84[0], 'optionalAccess', _85 => _85.value]);
7594
+ if (typeof rawValue !== "string") {
7595
+ throw new Error("Missing state value");
7596
+ }
7597
+ value = await decryptFromStorage(rawValue, userKey);
7598
+ }
7599
+ } else {
7473
7600
  if (count > slices.length) throw new Error("Missing state chunks");
7474
- const parts = [];
7601
+ const sliceByKey = new Map(
7602
+ slices.map((candidate) => [candidate.key, candidate])
7603
+ );
7604
+ const orderedSlices = [];
7475
7605
  for (let i = 0; i < count; i++) {
7476
- const slice = slices.find(
7477
- (candidate) => candidate.key === chunkKeyFor(row.key, i)
7478
- );
7606
+ const slice = sliceByKey.get(chunkKeyFor(row.key, i));
7479
7607
  if (!slice || slice.updated_at !== row.updated_at)
7480
7608
  throw new Error("Mismatched state chunks");
7481
- parts.push(await decryptFromStorage(slice.value, userKey));
7609
+ if (!isValidStorageCiphertext(
7610
+ slice.value,
7611
+ slice.value_prefix,
7612
+ slice.value_suffix,
7613
+ slice.byte_size
7614
+ )) {
7615
+ throw new Error("Corrupt state chunk");
7616
+ }
7617
+ orderedSlices.push(slice);
7618
+ }
7619
+ if (!skipFullDecrypt) {
7620
+ let fetchedByKey = null;
7621
+ if (orderedSlices.some((slice) => typeof slice.value !== "string")) {
7622
+ const fetchedSlices = typeof db.getClientState === "function" ? await db.getClientState(
7623
+ userId,
7624
+ CHUNK_NAMESPACE_PREFIX + row.namespace,
7625
+ { keyPrefix: `${row.key}` }
7626
+ ) : [];
7627
+ fetchedByKey = new Map(
7628
+ fetchedSlices.map((candidate) => [candidate.key, candidate.value])
7629
+ );
7630
+ }
7631
+ const parts = [];
7632
+ for (const slice of orderedSlices) {
7633
+ const rawSliceValue = typeof slice.value === "string" ? slice.value : _optionalChain([fetchedByKey, 'optionalAccess', _86 => _86.get, 'call', _87 => _87(slice.key)]);
7634
+ if (typeof rawSliceValue !== "string") {
7635
+ throw new Error("Missing state chunk value");
7636
+ }
7637
+ parts.push(await decryptFromStorage(rawSliceValue, userKey));
7638
+ }
7639
+ value = parts.join("");
7482
7640
  }
7483
- value = parts.join("");
7484
7641
  }
7485
7642
  } catch (e9) {
7486
7643
  unreadable = true;
@@ -7493,7 +7650,8 @@ async function buildCloudDataInventory({
7493
7650
  rows,
7494
7651
  value,
7495
7652
  unreadable,
7496
- status: null
7653
+ status: null,
7654
+ metadataInfo
7497
7655
  });
7498
7656
  }
7499
7657
  for (const [group, rows] of chunks) {
@@ -7517,9 +7675,29 @@ async function buildCloudDataInventory({
7517
7675
  });
7518
7676
  }
7519
7677
  for (const row of raw.outbox || []) {
7520
- let payload, unreadable = false;
7678
+ const metadataKey = JSON.stringify(["outbox", row.message_id]);
7679
+ const metadataInfo = await readStoredMetadata(metadataKey);
7680
+ const skipFullDecrypt = !metadataInfo.unreadable && hasCompleteStoredMetadata(metadataInfo.stored);
7681
+ let payload, unreadable = metadataInfo.unreadable;
7521
7682
  try {
7522
- payload = objectOrText(await decryptFromStorage(row.payload, userKey));
7683
+ if (typeof row.payload === "string" && (!skipFullDecrypt || row.payload.length <= 1024)) {
7684
+ payload = objectOrText(await decryptFromStorage(row.payload, userKey));
7685
+ } else if (skipFullDecrypt) {
7686
+ if (!isValidStorageCiphertext(
7687
+ row.payload,
7688
+ row.payload_prefix,
7689
+ row.payload_suffix,
7690
+ row.byte_size
7691
+ )) {
7692
+ throw new Error("Invalid outbox ciphertext");
7693
+ }
7694
+ } else {
7695
+ const rawPayload = typeof db.getOutboxPayload === "function" ? await db.getOutboxPayload(userId, row.message_id) : null;
7696
+ if (typeof rawPayload !== "string") {
7697
+ throw new Error("Missing outbox payload");
7698
+ }
7699
+ payload = objectOrText(await decryptFromStorage(rawPayload, userKey));
7700
+ }
7523
7701
  } catch (e10) {
7524
7702
  unreadable = true;
7525
7703
  }
@@ -7530,7 +7708,8 @@ async function buildCloudDataInventory({
7530
7708
  payload,
7531
7709
  task: taskByUuid.get(row.task_uuid),
7532
7710
  unreadable,
7533
- status: row.acked_at != null ? "acked" : row.delivered_at != null ? "delivered" : "pending"
7711
+ status: row.acked_at != null ? "acked" : row.delivered_at != null ? "delivered" : "pending",
7712
+ metadataInfo
7534
7713
  });
7535
7714
  }
7536
7715
  for (const row of raw.subscription || []) {
@@ -7544,7 +7723,7 @@ async function buildCloudDataInventory({
7544
7723
  const ownerLabels = /* @__PURE__ */ new Map();
7545
7724
  for (const { resource } of entries) {
7546
7725
  const owner = resource.owner;
7547
- if (!_optionalChain([owner, 'optionalAccess', _83 => _83.label, 'optionalAccess', _84 => _84.trim, 'call', _85 => _85()])) continue;
7726
+ if (!_optionalChain([owner, 'optionalAccess', _88 => _88.label, 'optionalAccess', _89 => _89.trim, 'call', _90 => _90()])) continue;
7548
7727
  const identity = JSON.stringify([owner.type, owner.id]);
7549
7728
  const current = ownerLabels.get(identity);
7550
7729
  if (!current || (_nullishCoalesce(resource.updatedAt, () => ( 0))) > current.updatedAt) {
@@ -7556,7 +7735,7 @@ async function buildCloudDataInventory({
7556
7735
  }
7557
7736
  for (const { resource } of entries) {
7558
7737
  const owner = resource.owner;
7559
- if (!owner || _optionalChain([owner, 'access', _86 => _86.label, 'optionalAccess', _87 => _87.trim, 'call', _88 => _88()])) continue;
7738
+ if (!owner || _optionalChain([owner, 'access', _91 => _91.label, 'optionalAccess', _92 => _92.trim, 'call', _93 => _93()])) continue;
7560
7739
  const known = ownerLabels.get(JSON.stringify([owner.type, owner.id]));
7561
7740
  if (known) resource.owner = { ...owner, label: known.label };
7562
7741
  }
@@ -7584,7 +7763,7 @@ async function cloudInventory(ctx, db, userId, userKey) {
7584
7763
  db,
7585
7764
  userId,
7586
7765
  userKey,
7587
- resolveOwner: _optionalChain([ctx, 'access', _89 => _89.cloudData, 'optionalAccess', _90 => _90.resolveOwner])
7766
+ resolveOwner: _optionalChain([ctx, 'access', _94 => _94.cloudData, 'optionalAccess', _95 => _95.resolveOwner])
7588
7767
  });
7589
7768
  }
7590
7769
  function operationWork(operation) {
@@ -7641,7 +7820,7 @@ async function makeCleanupPlan(ctx, db, userId, key, input) {
7641
7820
  throw cloudError("INVALID_CLEANUP_SELECTION", "\u8BF7\u9009\u62E9\u81F3\u5C11\u4E00\u9879\u8D44\u6E90");
7642
7821
  if (types !== void 0 && (!Array.isArray(types) || !types.length || types.some((type) => !CLOUD_RESOURCE_TYPES.includes(type))))
7643
7822
  throw cloudError("INVALID_CLEANUP_SELECTION", "\u8D44\u6E90\u7C7B\u522B\u65E0\u6548");
7644
- if (mode === "purge" && !owner && !_optionalChain([resourceIds, 'optionalAccess', _91 => _91.length]))
7823
+ if (mode === "purge" && !owner && !_optionalChain([resourceIds, 'optionalAccess', _96 => _96.length]))
7645
7824
  throw cloudError("INVALID_CLEANUP_SELECTION", "\u6E05\u7406\u9700\u8981\u660E\u786E\u8D44\u6E90\u6216\u5F52\u5C5E");
7646
7825
  if (mode === "retire-owner" && (resourceIds || types))
7647
7826
  throw cloudError("INVALID_CLEANUP_SELECTION", "\u5F7B\u5E95\u79FB\u9664\u4E0D\u80FD\u9650\u5236\u8D44\u6E90\u7C7B\u522B");
@@ -7653,10 +7832,12 @@ async function makeCleanupPlan(ctx, db, userId, key, input) {
7653
7832
  "\u4E91\u7AEF\u6E05\u5355\u4E0D\u5B8C\u6574\uFF0C\u6682\u4E0D\u80FD\u751F\u6210\u6E05\u7406\u8BA1\u5212",
7654
7833
  409
7655
7834
  );
7835
+ const resourceIdSet = resourceIds ? new Set(resourceIds) : null;
7836
+ const typeSet = types ? new Set(types) : null;
7656
7837
  const entries = inventory.entries.filter(
7657
- (e) => (!owner || ownerEquals(e.resource.owner, owner)) && (!resourceIds || resourceIds.includes(e.resource.id)) && (!types || types.includes(e.resource.type))
7838
+ (e) => (!owner || ownerEquals(e.resource.owner, owner)) && (!resourceIdSet || resourceIdSet.has(e.resource.id)) && (!typeSet || typeSet.has(e.resource.type))
7658
7839
  );
7659
- if (resourceIds && new Set(resourceIds).size !== entries.length)
7840
+ if (resourceIdSet && resourceIdSet.size !== entries.length)
7660
7841
  throw cloudError(
7661
7842
  "CLOUD_RESOURCE_NOT_FOUND",
7662
7843
  "\u90E8\u5206\u9009\u4E2D\u8D44\u6E90\u4E0D\u5B58\u5728\u6216\u4E0D\u5C5E\u4E8E\u5F53\u524D\u8303\u56F4",
@@ -7814,6 +7995,7 @@ async function advanceCleanup(ctx, db, userId, key, operation) {
7814
7995
  if (operation.status === "completed" || operation.status === "failed")
7815
7996
  return operation;
7816
7997
  operation.status = "running";
7998
+ let retirementInventory = null;
7817
7999
  if (operation.mode === "retire-owner") {
7818
8000
  if (operation.fencedGeneration == null) {
7819
8001
  const state = await db.setCloudOwnerActive(
@@ -7841,6 +8023,7 @@ async function advanceCleanup(ctx, db, userId, key, operation) {
7841
8023
  "\u65E0\u6CD5\u786E\u8BA4\u5F85\u6E05\u7406\u8D44\u6E90",
7842
8024
  503
7843
8025
  );
8026
+ retirementInventory = inventory;
7844
8027
  const known = new Set(operation.knownResourceIds || []);
7845
8028
  operation.knownResourceVersions ||= {};
7846
8029
  operation.entries = inventory.entries.filter((entry) => {
@@ -7867,7 +8050,7 @@ async function advanceCleanup(ctx, db, userId, key, operation) {
7867
8050
  ).length;
7868
8051
  await save(db, userId, key, "operation", operation, { leaseToken });
7869
8052
  }
7870
- const beforeBatch = await cloudInventory(ctx, db, userId, key);
8053
+ const beforeBatch = await _asyncNullishCoalesce(retirementInventory, async () => ( await cloudInventory(ctx, db, userId, key)));
7871
8054
  if (!beforeBatch.complete)
7872
8055
  throw cloudError("CLOUD_INVENTORY_INCOMPLETE", "\u65E0\u6CD5\u786E\u8BA4\u5F85\u6E05\u7406\u8D44\u6E90", 503);
7873
8056
  const currentById = new Map(
@@ -7905,7 +8088,6 @@ async function advanceCleanup(ctx, db, userId, key, operation) {
7905
8088
  delete entry.locator;
7906
8089
  operation.cursor++;
7907
8090
  operation.updatedAt = Date.now();
7908
- await save(db, userId, key, "operation", operation, { leaseToken });
7909
8091
  }
7910
8092
  await renewLease();
7911
8093
  const current = await cloudInventory(ctx, db, userId, key);
@@ -7916,8 +8098,9 @@ async function advanceCleanup(ctx, db, userId, key, operation) {
7916
8098
  503
7917
8099
  );
7918
8100
  const selected = new Set(operation.entries.map((e) => e.resource.id));
8101
+ const knownIds = new Set(operation.knownResourceIds || []);
7919
8102
  const remaining = current.entries.filter(
7920
- (e) => operation.mode === "retire-owner" ? ownerEquals(e.resource.owner, operation.owner) || (operation.knownResourceIds || []).includes(e.resource.id) : selected.has(e.resource.id)
8103
+ (e) => operation.mode === "retire-owner" ? ownerEquals(e.resource.owner, operation.owner) || knownIds.has(e.resource.id) : selected.has(e.resource.id)
7921
8104
  );
7922
8105
  for (const count of operation.counts)
7923
8106
  count.remaining = remaining.filter(
@@ -8006,12 +8189,12 @@ async function repairLegacyWorkIndex(ctx) {
8006
8189
  entries.push({ userId: row.user_id, kind: row.kind, id: row.id, work, writeToken: row.write_token });
8007
8190
  }
8008
8191
  await db.indexCloudDataRecordWorkBatch(entries);
8009
- const cursor = _nullishCoalesce(_optionalChain([batch, 'access', _92 => _92.rows, 'access', _93 => _93.at, 'call', _94 => _94(-1), 'optionalAccess', _95 => _95.maintenance_rowid]), () => ( batch.upperBound));
8192
+ const cursor = _nullishCoalesce(_optionalChain([batch, 'access', _97 => _97.rows, 'access', _98 => _98.at, 'call', _99 => _99(-1), 'optionalAccess', _100 => _100.maintenance_rowid]), () => ( batch.upperBound));
8010
8193
  await db.finishCloudMaintenanceBatch(name, cursor, batch.rows.length < 100 || cursor >= batch.upperBound);
8011
8194
  }
8012
8195
  async function resumeCloudDataCleanups(ctx) {
8013
8196
  const db = ctx.db;
8014
- if (!_optionalChain([db, 'optionalAccess', _96 => _96.cloudDataManagement])) return;
8197
+ if (!_optionalChain([db, 'optionalAccess', _101 => _101.cloudDataManagement])) return;
8015
8198
  const indexed = WORK_INDEX_METHODS.every((method) => typeof db[method] === "function");
8016
8199
  let rows;
8017
8200
  if (indexed) {
@@ -8043,7 +8226,7 @@ async function resumeCloudDataCleanups(ctx) {
8043
8226
  }
8044
8227
  } catch (error) {
8045
8228
  console.warn("[amsg] A cloud cleanup operation could not be resumed");
8046
- if (!indexed || _optionalChain([error, 'optionalAccess', _97 => _97.code]) === "CLOUD_LEASE_LOST") continue;
8229
+ if (!indexed || _optionalChain([error, 'optionalAccess', _102 => _102.code]) === "CLOUD_LEASE_LOST") continue;
8047
8230
  await db.rescheduleCloudDataRecordWork(
8048
8231
  row.userId,
8049
8232
  "operation",
@@ -8151,7 +8334,7 @@ function createCloudDataHandler(ctx) {
8151
8334
  summary: inventorySummary(inventory),
8152
8335
  expiresAt: Date.now() + 15 * 60 * 1e3,
8153
8336
  resources: inventory.entries.map((e) => e.resource).filter(
8154
- (r) => (!type || r.type === type) && (!ownerId || _optionalChain([r, 'access', _98 => _98.owner, 'optionalAccess', _99 => _99.type]) === ownerType && r.owner.id === ownerId)
8337
+ (r) => (!type || r.type === type) && (!ownerId || _optionalChain([r, 'access', _103 => _103.owner, 'optionalAccess', _104 => _104.type]) === ownerType && r.owner.id === ownerId)
8155
8338
  ),
8156
8339
  complete: inventory.complete,
8157
8340
  gaps: inventory.gaps
@@ -8234,7 +8417,7 @@ function createCloudDataHandler(ctx) {
8234
8417
  const rows = await db.listCloudDataRecords(userId, "operation");
8235
8418
  for (const row of rows) {
8236
8419
  const op = JSON.parse(await decryptFromStorage(row.data, key));
8237
- if (op.mode === "retire-owner" && _optionalChain([op, 'access', _100 => _100.owner, 'optionalAccess', _101 => _101.type]) === owner.type && _optionalChain([op, 'access', _102 => _102.owner, 'optionalAccess', _103 => _103.id]) === owner.id && ["pending", "running"].includes(op.status))
8420
+ if (op.mode === "retire-owner" && _optionalChain([op, 'access', _105 => _105.owner, 'optionalAccess', _106 => _106.type]) === owner.type && _optionalChain([op, 'access', _107 => _107.owner, 'optionalAccess', _108 => _108.id]) === owner.id && ["pending", "running"].includes(op.status))
8238
8421
  throw cloudError(
8239
8422
  "CLOUD_CLEANUP_IN_PROGRESS",
8240
8423
  "\u6E05\u7406\u5B8C\u6210\u540E\u624D\u80FD\u91CD\u65B0\u542F\u7528",
@@ -8452,7 +8635,7 @@ function createSingleUserServer(config) {
8452
8635
  if (!config.masterKey) throw new Error("[amsg-server single-user] config.masterKey is required");
8453
8636
  const vapid = config.vapid || {};
8454
8637
  const tenantManager = createSingleUserContextManager({
8455
- db: createCloudGuardedAdapter(config.db, { masterKey: config.masterKey, resolveOwner: _optionalChain([config, 'access', _104 => _104.cloudData, 'optionalAccess', _105 => _105.resolveOwner]) }),
8638
+ db: createCloudGuardedAdapter(config.db, { masterKey: config.masterKey, resolveOwner: _optionalChain([config, 'access', _109 => _109.cloudData, 'optionalAccess', _110 => _110.resolveOwner]) }),
8456
8639
  masterKey: config.masterKey,
8457
8640
  serverToken: config.serverToken
8458
8641
  });
@@ -8538,7 +8721,7 @@ async function getSchemaVersion(db) {
8538
8721
  for (const index of SQLITE_REQUIRED_SCHEMA.indexes) {
8539
8722
  if (!liveIndexes.has(index)) missing.push(`index:${index}`);
8540
8723
  }
8541
- if (Array.isArray(_optionalChain([live, 'optionalAccess', _106 => _106.triggers]))) {
8724
+ if (Array.isArray(_optionalChain([live, 'optionalAccess', _111 => _111.triggers]))) {
8542
8725
  const liveTriggers = new Set(live.triggers);
8543
8726
  for (const name of SQLITE_REQUIRED_SCHEMA.triggers) {
8544
8727
  if (!liveTriggers.has(name)) missing.push(`trigger:${name}`);
@@ -147,14 +147,33 @@ import {
147
147
  // src/server/lib/encryption.js
148
148
  var base64ToBytes = base64UrlToBytes;
149
149
  var TAG_LENGTH_BYTES = 16;
150
+ var AES_KEY_CACHE_MAX = 128;
151
+ var aesKeyCache = /* @__PURE__ */ new Map();
150
152
  function importAesKey(hexKey, usage) {
151
- return globalThis.crypto.subtle.importKey(
152
- "raw",
153
- hexToBytes(hexKey),
154
- { name: "AES-GCM" },
155
- false,
156
- [usage]
157
- );
153
+ const cacheKey = `${usage}:${hexKey}`;
154
+ const cached = aesKeyCache.get(cacheKey);
155
+ if (cached) return cached;
156
+ let promise;
157
+ try {
158
+ promise = globalThis.crypto.subtle.importKey(
159
+ "raw",
160
+ hexToBytes(hexKey),
161
+ { name: "AES-GCM" },
162
+ false,
163
+ [usage]
164
+ ).catch((err6) => {
165
+ aesKeyCache.delete(cacheKey);
166
+ throw err6;
167
+ });
168
+ } catch (err6) {
169
+ return Promise.reject(err6);
170
+ }
171
+ if (aesKeyCache.size >= AES_KEY_CACHE_MAX) {
172
+ const oldest = aesKeyCache.keys().next().value;
173
+ if (oldest !== void 0) aesKeyCache.delete(oldest);
174
+ }
175
+ aesKeyCache.set(cacheKey, promise);
176
+ return promise;
158
177
  }
159
178
  async function aesGcmSeal(hexKey, iv, plaintextBytes) {
160
179
  const key = await importAesKey(hexKey, "encrypt");
@@ -5451,12 +5470,37 @@ var D1Adapter = class {
5451
5470
  const row = await this._db.prepare("SELECT encrypted_value FROM cloud_resource_metadata WHERE user_id=? AND resource_key=?").bind(userId, resourceKey).first();
5452
5471
  return row?.encrypted_value ?? null;
5453
5472
  }
5473
+ async getOutboxPayload(userId, messageId) {
5474
+ const row = await this._db.prepare(
5475
+ "SELECT payload FROM message_outbox WHERE user_id = ? AND message_id = ? LIMIT 1"
5476
+ ).bind(userId, messageId).first();
5477
+ return row?.payload ?? null;
5478
+ }
5454
5479
  async listCloudResourceRows(userId) {
5455
- const tables = { task: "scheduled_messages", state: "client_state", credential: "llm_credentials", outbox: "message_outbox", subscription: "push_subscriptions", metadata: "cloud_resource_metadata" };
5480
+ const queries = {
5481
+ task: "SELECT * FROM scheduled_messages WHERE user_id = ?",
5482
+ state: `SELECT user_id, namespace, key,
5483
+ CASE WHEN LENGTH(value) <= 1024 THEN value ELSE NULL END AS value,
5484
+ LENGTH(CAST(value AS BLOB)) AS byte_size,
5485
+ substr(value, 1, 128) AS value_prefix,
5486
+ CASE WHEN LENGTH(value) > 128 THEN substr(value, -64) ELSE '' END AS value_suffix,
5487
+ updated_at
5488
+ FROM client_state WHERE user_id = ?`,
5489
+ credential: "SELECT * FROM llm_credentials WHERE user_id = ?",
5490
+ outbox: `SELECT id, user_id, message_id, task_uuid, session_id, message_index, total_messages,
5491
+ CASE WHEN LENGTH(payload) <= 1024 THEN payload ELSE NULL END AS payload,
5492
+ LENGTH(CAST(payload AS BLOB)) AS byte_size,
5493
+ substr(payload, 1, 128) AS payload_prefix,
5494
+ CASE WHEN LENGTH(payload) > 128 THEN substr(payload, -64) ELSE '' END AS payload_suffix,
5495
+ created_at, delivered_at, acked_at
5496
+ FROM message_outbox WHERE user_id = ?`,
5497
+ subscription: "SELECT * FROM push_subscriptions WHERE user_id = ?",
5498
+ metadata: "SELECT * FROM cloud_resource_metadata WHERE user_id = ?"
5499
+ };
5456
5500
  const result = { gaps: [] };
5457
- await Promise.all(Object.entries(tables).map(async ([type, table]) => {
5501
+ await Promise.all(Object.entries(queries).map(async ([type, sql]) => {
5458
5502
  try {
5459
- const response = await this._db.prepare(`SELECT * FROM ${table} WHERE user_id = ?`).bind(userId).all();
5503
+ const response = await this._db.prepare(sql).bind(userId).all();
5460
5504
  result[type] = response.results || [];
5461
5505
  } catch {
5462
5506
  result[type] = [];
@@ -5521,7 +5565,10 @@ var D1Adapter = class {
5521
5565
  if (idempotencyKey) {
5522
5566
  return this._cloudRecord(await this._db.prepare(`SELECT * FROM cloud_data_records WHERE user_id=? AND kind=? AND idempotency_key=?`).bind(userId, kind, idempotencyKey).first());
5523
5567
  }
5524
- return this.getCloudDataRecord(userId, kind, id);
5568
+ if (createOnly) {
5569
+ return this.getCloudDataRecord(userId, kind, id);
5570
+ }
5571
+ return { id, userId, kind, data, updatedAt: now };
5525
5572
  }
5526
5573
  async getCloudDataRecord(userId, kind, id) {
5527
5574
  return this._cloudRecord(await this._db.prepare("SELECT * FROM cloud_data_records WHERE user_id=? AND kind=? AND id=?").bind(userId, kind, id).first());
@@ -5730,6 +5777,29 @@ var D1Adapter = class {
5730
5777
  const row = await this._db.prepare(`SELECT ${condition.sql} AS valid`).bind(...condition.args).first();
5731
5778
  return !!row?.valid;
5732
5779
  }
5780
+ _rowSnapshotMatch(spec, row) {
5781
+ const clauses = [];
5782
+ const args = [];
5783
+ for (const column of spec.columns) {
5784
+ if (!Object.hasOwn(row, column)) continue;
5785
+ if ((column === "value" || column === "payload") && row[column] === null && typeof row.byte_size === "number") {
5786
+ clauses.push(
5787
+ `LENGTH(CAST(${column} AS BLOB)) IS ?`,
5788
+ `substr(${column}, 1, 128) IS ?`,
5789
+ `(CASE WHEN LENGTH(${column}) > 128 THEN substr(${column}, -64) ELSE '' END) IS ?`
5790
+ );
5791
+ args.push(
5792
+ row.byte_size,
5793
+ row[`${column}_prefix`] ?? null,
5794
+ row[`${column}_suffix`] ?? ""
5795
+ );
5796
+ } else {
5797
+ clauses.push(`${column} IS ?`);
5798
+ args.push(row[column]);
5799
+ }
5800
+ }
5801
+ return { predicate: clauses.join(" AND "), values: args };
5802
+ }
5733
5803
  /** Delete only the exact physical snapshot; no untrusted SQL identifiers. */
5734
5804
  async deleteCloudResourceRows(userId, locators, { operationId, leaseToken } = {}) {
5735
5805
  const specs = {
@@ -5777,9 +5847,7 @@ var D1Adapter = class {
5777
5847
  ).bind(userId, namespace, key, "amsg-chunks" + namespace, key + "", key + " ", identities));
5778
5848
  }
5779
5849
  for (const row of locator.rows) {
5780
- const columns = spec.columns.filter((column) => Object.hasOwn(row, column));
5781
- const predicate = columns.map((column) => `${column} IS ?`).join(" AND ");
5782
- const values = columns.map((column) => row[column]);
5850
+ const { predicate, values } = this._rowSnapshotMatch(spec, row);
5783
5851
  const identity = spec.keys.map((column) => `${column} IS ?`).join(" AND ");
5784
5852
  statements.push(this._db.prepare(
5785
5853
  `INSERT INTO cloud_guard_assertions (allowed)
@@ -5788,8 +5856,8 @@ var D1Adapter = class {
5788
5856
  ).bind(...spec.keys.map((column) => row[column]), ...values));
5789
5857
  }
5790
5858
  for (const row of locator.rows) {
5791
- const columns = spec.columns.filter((column) => Object.hasOwn(row, column));
5792
- statements.push(this._db.prepare(`DELETE FROM ${spec.table} WHERE ${columns.map((column) => `${column} IS ?`).join(" AND ")}`).bind(...columns.map((column) => row[column])));
5859
+ const { predicate, values } = this._rowSnapshotMatch(spec, row);
5860
+ statements.push(this._db.prepare(`DELETE FROM ${spec.table} WHERE ${predicate}`).bind(...values));
5793
5861
  }
5794
5862
  if (locator.metadataKey) statements.push(this._db.prepare("DELETE FROM cloud_resource_metadata WHERE user_id=? AND resource_key=?").bind(userId, locator.metadataKey));
5795
5863
  try {
@@ -7160,7 +7228,7 @@ function createClientStateNamespacesHandler(ctx) {
7160
7228
  }
7161
7229
 
7162
7230
  // src/server/lib/version.js
7163
- var SERVER_VERSION = true ? "3.1.0-next.0" : "0.0.0-dev";
7231
+ var SERVER_VERSION = true ? "3.1.0-next.1" : "0.0.0-dev";
7164
7232
 
7165
7233
  // src/server/handlers/capabilities.js
7166
7234
  var SERVER_FEATURES = Object.freeze([
@@ -7328,6 +7396,39 @@ function objectOrText(value) {
7328
7396
  return value;
7329
7397
  }
7330
7398
  }
7399
+ function utf8ByteLength(text) {
7400
+ if (typeof text !== "string" || text.length === 0) return 0;
7401
+ return /[^\x00-\x7f]/.test(text) ? encoder.encode(text).length : text.length;
7402
+ }
7403
+ function rowByteSize(row) {
7404
+ if (typeof row.byte_size === "number") return row.byte_size;
7405
+ return utf8ByteLength(
7406
+ String(
7407
+ row.value ?? row.encrypted_payload ?? row.encrypted_value ?? row.payload ?? row.subscription ?? ""
7408
+ )
7409
+ );
7410
+ }
7411
+ var STORAGE_PREFIX_RE = /^[0-9a-f]{32}:[0-9a-f]{24,32}:[0-9a-f]*$/i;
7412
+ var HEX_RE = /^[0-9a-f]*$/i;
7413
+ function isValidStorageCiphertext(fullText, prefix, suffix, byteSize) {
7414
+ if (typeof fullText === "string") {
7415
+ if (!STORAGE_PREFIX_RE.test(fullText)) return false;
7416
+ const secondColon = fullText.indexOf(":", 33);
7417
+ return secondColon > 32 && (fullText.length - secondColon - 1) % 2 === 0;
7418
+ }
7419
+ if (typeof prefix === "string" && typeof byteSize === "number") {
7420
+ if (!STORAGE_PREFIX_RE.test(prefix)) return false;
7421
+ if (typeof suffix === "string" && !HEX_RE.test(suffix)) return false;
7422
+ const secondColon = prefix.indexOf(":", 33);
7423
+ return secondColon > 32 && (byteSize - secondColon - 1) % 2 === 0;
7424
+ }
7425
+ return false;
7426
+ }
7427
+ function hasCompleteStoredMetadata(stored) {
7428
+ return Boolean(
7429
+ stored && safeOwner(stored.owner) !== null && typeof stored.kind === "string" && stored.kind.length > 0
7430
+ );
7431
+ }
7331
7432
  async function buildCloudDataInventory({
7332
7433
  db,
7333
7434
  userId,
@@ -7340,6 +7441,20 @@ async function buildCloudDataInventory({
7340
7441
  const metadata = new Map(
7341
7442
  (raw.metadata || []).map((row) => [row.resource_key, row.encrypted_value])
7342
7443
  );
7444
+ const readStoredMetadata = async (metadataKey) => {
7445
+ const encryptedMetadata = metadata.get(metadataKey) || null;
7446
+ if (!encryptedMetadata) {
7447
+ return { encryptedMetadata: null, stored: null, unreadable: false };
7448
+ }
7449
+ try {
7450
+ const stored = JSON.parse(
7451
+ await decryptFromStorage(encryptedMetadata, userKey)
7452
+ );
7453
+ return { encryptedMetadata, stored, unreadable: false };
7454
+ } catch {
7455
+ return { encryptedMetadata, stored: null, unreadable: true };
7456
+ }
7457
+ };
7343
7458
  const taskPayloads = /* @__PURE__ */ new Map();
7344
7459
  const taskByUuid = /* @__PURE__ */ new Map();
7345
7460
  for (const row of raw.task || []) {
@@ -7364,23 +7479,19 @@ async function buildCloudDataInventory({
7364
7479
  status = null,
7365
7480
  namespace,
7366
7481
  key,
7367
- credId
7482
+ credId,
7483
+ metadataInfo
7368
7484
  }) => {
7369
7485
  const metadataKey = JSON.stringify([type, ...identity]);
7370
7486
  const id = await cloudDataHash(JSON.stringify([userId, metadataKey]));
7371
- let stored = null;
7372
- const encryptedMetadata = metadata.get(metadataKey);
7373
- if (encryptedMetadata) {
7374
- try {
7375
- stored = JSON.parse(
7376
- await decryptFromStorage(encryptedMetadata, userKey)
7377
- );
7378
- } catch {
7379
- unreadable = true;
7380
- }
7381
- }
7487
+ const {
7488
+ encryptedMetadata,
7489
+ stored,
7490
+ unreadable: metadataUnreadable
7491
+ } = metadataInfo ?? await readStoredMetadata(metadataKey);
7492
+ if (metadataUnreadable) unreadable = true;
7382
7493
  let resolved = null;
7383
- if (resolveOwner) {
7494
+ if (resolveOwner && !hasCompleteStoredMetadata(stored)) {
7384
7495
  try {
7385
7496
  resolved = await resolveOwner({
7386
7497
  type,
@@ -7403,14 +7514,7 @@ async function buildCloudDataInventory({
7403
7514
  const owner = safeOwner(stored?.owner) || safeOwner(payload?.__cloudOwnerGuard?.owner) || safeOwner(payload?.metadata?.cloudOwner) || safeOwner(payload?.metadata?.owner) || safeOwner(payload?.owner) || safeOwner(task?.__cloudOwnerGuard?.owner) || safeOwner(task?.metadata?.cloudOwner) || safeOwner(task?.metadata?.owner) || safeOwner(task?.owner) || safeOwner(resolved?.owner);
7404
7515
  const kind = stored?.kind ?? payload?.metadata?.kind ?? payload?.kind ?? resolved?.kind ?? null;
7405
7516
  const times = rows.map((row) => timestamp(row.updated_at ?? row.created_at)).filter((time) => time !== null);
7406
- const byteSize = rows.reduce(
7407
- (sum, row) => sum + encoder.encode(
7408
- String(
7409
- row.value ?? row.encrypted_payload ?? row.encrypted_value ?? row.payload ?? row.subscription ?? ""
7410
- )
7411
- ).length,
7412
- 0
7413
- );
7517
+ const byteSize = rows.reduce((sum, row) => sum + rowByteSize(row), 0);
7414
7518
  const label = type === "state" ? `${namespace}/${key}` : type === "credential" ? credId : type === "task" ? rows[0].uuid || `task row ${rows[0].id}` : type === "outbox" ? rows[0].message_id : "Web Push subscription";
7415
7519
  entries.push({
7416
7520
  resource: {
@@ -7465,22 +7569,75 @@ async function buildCloudDataInventory({
7465
7569
  const slices = chunks.get(group) || [];
7466
7570
  chunks.delete(group);
7467
7571
  const rows = [row, ...slices.sort((a, b) => a.key.localeCompare(b.key))];
7468
- let value, unreadable = false;
7572
+ const metadataKey = JSON.stringify(["state", row.namespace, row.key]);
7573
+ const metadataInfo = await readStoredMetadata(metadataKey);
7574
+ const skipFullDecrypt = !metadataInfo.unreadable && hasCompleteStoredMetadata(metadataInfo.stored);
7575
+ let value, unreadable = metadataInfo.unreadable;
7469
7576
  try {
7470
- const count = parseChunkedRootCount(row.value);
7471
- if (count === null) value = await decryptFromStorage(row.value, userKey);
7472
- else {
7577
+ const rootMarker = row.value ?? row.value_prefix ?? "";
7578
+ const count = parseChunkedRootCount(rootMarker);
7579
+ if (count === null) {
7580
+ if (typeof row.value === "string" && (!skipFullDecrypt || row.value.length <= 1024)) {
7581
+ value = await decryptFromStorage(row.value, userKey);
7582
+ } else if (skipFullDecrypt) {
7583
+ if (!isValidStorageCiphertext(
7584
+ row.value,
7585
+ row.value_prefix,
7586
+ row.value_suffix,
7587
+ row.byte_size
7588
+ )) {
7589
+ throw new Error("Invalid state ciphertext");
7590
+ }
7591
+ } else {
7592
+ const fetched = typeof db.getClientState === "function" ? await db.getClientState(userId, row.namespace, { key: row.key }) : [];
7593
+ const rawValue = fetched?.[0]?.value;
7594
+ if (typeof rawValue !== "string") {
7595
+ throw new Error("Missing state value");
7596
+ }
7597
+ value = await decryptFromStorage(rawValue, userKey);
7598
+ }
7599
+ } else {
7473
7600
  if (count > slices.length) throw new Error("Missing state chunks");
7474
- const parts = [];
7601
+ const sliceByKey = new Map(
7602
+ slices.map((candidate) => [candidate.key, candidate])
7603
+ );
7604
+ const orderedSlices = [];
7475
7605
  for (let i = 0; i < count; i++) {
7476
- const slice = slices.find(
7477
- (candidate) => candidate.key === chunkKeyFor(row.key, i)
7478
- );
7606
+ const slice = sliceByKey.get(chunkKeyFor(row.key, i));
7479
7607
  if (!slice || slice.updated_at !== row.updated_at)
7480
7608
  throw new Error("Mismatched state chunks");
7481
- parts.push(await decryptFromStorage(slice.value, userKey));
7609
+ if (!isValidStorageCiphertext(
7610
+ slice.value,
7611
+ slice.value_prefix,
7612
+ slice.value_suffix,
7613
+ slice.byte_size
7614
+ )) {
7615
+ throw new Error("Corrupt state chunk");
7616
+ }
7617
+ orderedSlices.push(slice);
7618
+ }
7619
+ if (!skipFullDecrypt) {
7620
+ let fetchedByKey = null;
7621
+ if (orderedSlices.some((slice) => typeof slice.value !== "string")) {
7622
+ const fetchedSlices = typeof db.getClientState === "function" ? await db.getClientState(
7623
+ userId,
7624
+ CHUNK_NAMESPACE_PREFIX + row.namespace,
7625
+ { keyPrefix: `${row.key}` }
7626
+ ) : [];
7627
+ fetchedByKey = new Map(
7628
+ fetchedSlices.map((candidate) => [candidate.key, candidate.value])
7629
+ );
7630
+ }
7631
+ const parts = [];
7632
+ for (const slice of orderedSlices) {
7633
+ const rawSliceValue = typeof slice.value === "string" ? slice.value : fetchedByKey?.get(slice.key);
7634
+ if (typeof rawSliceValue !== "string") {
7635
+ throw new Error("Missing state chunk value");
7636
+ }
7637
+ parts.push(await decryptFromStorage(rawSliceValue, userKey));
7638
+ }
7639
+ value = parts.join("");
7482
7640
  }
7483
- value = parts.join("");
7484
7641
  }
7485
7642
  } catch {
7486
7643
  unreadable = true;
@@ -7493,7 +7650,8 @@ async function buildCloudDataInventory({
7493
7650
  rows,
7494
7651
  value,
7495
7652
  unreadable,
7496
- status: null
7653
+ status: null,
7654
+ metadataInfo
7497
7655
  });
7498
7656
  }
7499
7657
  for (const [group, rows] of chunks) {
@@ -7517,9 +7675,29 @@ async function buildCloudDataInventory({
7517
7675
  });
7518
7676
  }
7519
7677
  for (const row of raw.outbox || []) {
7520
- let payload, unreadable = false;
7678
+ const metadataKey = JSON.stringify(["outbox", row.message_id]);
7679
+ const metadataInfo = await readStoredMetadata(metadataKey);
7680
+ const skipFullDecrypt = !metadataInfo.unreadable && hasCompleteStoredMetadata(metadataInfo.stored);
7681
+ let payload, unreadable = metadataInfo.unreadable;
7521
7682
  try {
7522
- payload = objectOrText(await decryptFromStorage(row.payload, userKey));
7683
+ if (typeof row.payload === "string" && (!skipFullDecrypt || row.payload.length <= 1024)) {
7684
+ payload = objectOrText(await decryptFromStorage(row.payload, userKey));
7685
+ } else if (skipFullDecrypt) {
7686
+ if (!isValidStorageCiphertext(
7687
+ row.payload,
7688
+ row.payload_prefix,
7689
+ row.payload_suffix,
7690
+ row.byte_size
7691
+ )) {
7692
+ throw new Error("Invalid outbox ciphertext");
7693
+ }
7694
+ } else {
7695
+ const rawPayload = typeof db.getOutboxPayload === "function" ? await db.getOutboxPayload(userId, row.message_id) : null;
7696
+ if (typeof rawPayload !== "string") {
7697
+ throw new Error("Missing outbox payload");
7698
+ }
7699
+ payload = objectOrText(await decryptFromStorage(rawPayload, userKey));
7700
+ }
7523
7701
  } catch {
7524
7702
  unreadable = true;
7525
7703
  }
@@ -7530,7 +7708,8 @@ async function buildCloudDataInventory({
7530
7708
  payload,
7531
7709
  task: taskByUuid.get(row.task_uuid),
7532
7710
  unreadable,
7533
- status: row.acked_at != null ? "acked" : row.delivered_at != null ? "delivered" : "pending"
7711
+ status: row.acked_at != null ? "acked" : row.delivered_at != null ? "delivered" : "pending",
7712
+ metadataInfo
7534
7713
  });
7535
7714
  }
7536
7715
  for (const row of raw.subscription || []) {
@@ -7653,10 +7832,12 @@ async function makeCleanupPlan(ctx, db, userId, key, input) {
7653
7832
  "\u4E91\u7AEF\u6E05\u5355\u4E0D\u5B8C\u6574\uFF0C\u6682\u4E0D\u80FD\u751F\u6210\u6E05\u7406\u8BA1\u5212",
7654
7833
  409
7655
7834
  );
7835
+ const resourceIdSet = resourceIds ? new Set(resourceIds) : null;
7836
+ const typeSet = types ? new Set(types) : null;
7656
7837
  const entries = inventory.entries.filter(
7657
- (e) => (!owner || ownerEquals(e.resource.owner, owner)) && (!resourceIds || resourceIds.includes(e.resource.id)) && (!types || types.includes(e.resource.type))
7838
+ (e) => (!owner || ownerEquals(e.resource.owner, owner)) && (!resourceIdSet || resourceIdSet.has(e.resource.id)) && (!typeSet || typeSet.has(e.resource.type))
7658
7839
  );
7659
- if (resourceIds && new Set(resourceIds).size !== entries.length)
7840
+ if (resourceIdSet && resourceIdSet.size !== entries.length)
7660
7841
  throw cloudError(
7661
7842
  "CLOUD_RESOURCE_NOT_FOUND",
7662
7843
  "\u90E8\u5206\u9009\u4E2D\u8D44\u6E90\u4E0D\u5B58\u5728\u6216\u4E0D\u5C5E\u4E8E\u5F53\u524D\u8303\u56F4",
@@ -7814,6 +7995,7 @@ async function advanceCleanup(ctx, db, userId, key, operation) {
7814
7995
  if (operation.status === "completed" || operation.status === "failed")
7815
7996
  return operation;
7816
7997
  operation.status = "running";
7998
+ let retirementInventory = null;
7817
7999
  if (operation.mode === "retire-owner") {
7818
8000
  if (operation.fencedGeneration == null) {
7819
8001
  const state = await db.setCloudOwnerActive(
@@ -7841,6 +8023,7 @@ async function advanceCleanup(ctx, db, userId, key, operation) {
7841
8023
  "\u65E0\u6CD5\u786E\u8BA4\u5F85\u6E05\u7406\u8D44\u6E90",
7842
8024
  503
7843
8025
  );
8026
+ retirementInventory = inventory;
7844
8027
  const known = new Set(operation.knownResourceIds || []);
7845
8028
  operation.knownResourceVersions ||= {};
7846
8029
  operation.entries = inventory.entries.filter((entry) => {
@@ -7867,7 +8050,7 @@ async function advanceCleanup(ctx, db, userId, key, operation) {
7867
8050
  ).length;
7868
8051
  await save(db, userId, key, "operation", operation, { leaseToken });
7869
8052
  }
7870
- const beforeBatch = await cloudInventory(ctx, db, userId, key);
8053
+ const beforeBatch = retirementInventory ?? await cloudInventory(ctx, db, userId, key);
7871
8054
  if (!beforeBatch.complete)
7872
8055
  throw cloudError("CLOUD_INVENTORY_INCOMPLETE", "\u65E0\u6CD5\u786E\u8BA4\u5F85\u6E05\u7406\u8D44\u6E90", 503);
7873
8056
  const currentById = new Map(
@@ -7905,7 +8088,6 @@ async function advanceCleanup(ctx, db, userId, key, operation) {
7905
8088
  delete entry.locator;
7906
8089
  operation.cursor++;
7907
8090
  operation.updatedAt = Date.now();
7908
- await save(db, userId, key, "operation", operation, { leaseToken });
7909
8091
  }
7910
8092
  await renewLease();
7911
8093
  const current = await cloudInventory(ctx, db, userId, key);
@@ -7916,8 +8098,9 @@ async function advanceCleanup(ctx, db, userId, key, operation) {
7916
8098
  503
7917
8099
  );
7918
8100
  const selected = new Set(operation.entries.map((e) => e.resource.id));
8101
+ const knownIds = new Set(operation.knownResourceIds || []);
7919
8102
  const remaining = current.entries.filter(
7920
- (e) => operation.mode === "retire-owner" ? ownerEquals(e.resource.owner, operation.owner) || (operation.knownResourceIds || []).includes(e.resource.id) : selected.has(e.resource.id)
8103
+ (e) => operation.mode === "retire-owner" ? ownerEquals(e.resource.owner, operation.owner) || knownIds.has(e.resource.id) : selected.has(e.resource.id)
7921
8104
  );
7922
8105
  for (const count of operation.counts)
7923
8106
  count.remaining = remaining.filter(
@@ -29,7 +29,7 @@
29
29
 
30
30
 
31
31
 
32
- var _chunk3NIYNYZYcjs = require('./chunk-3NIYNYZY.cjs');
32
+ var _chunkD4SKSCIYcjs = require('./chunk-D4SKSCIY.cjs');
33
33
  require('./chunk-7NMQFTDJ.cjs');
34
34
 
35
35
 
@@ -62,4 +62,4 @@ require('./chunk-7NMQFTDJ.cjs');
62
62
 
63
63
 
64
64
 
65
- exports.DEFAULT_MAX_DELIVERY_RETRIES = _chunk3NIYNYZYcjs.DEFAULT_MAX_DELIVERY_RETRIES; exports.DEFAULT_MAX_REQUEST_BODY_BYTES = _chunk3NIYNYZYcjs.DEFAULT_MAX_REQUEST_BODY_BYTES; exports.MAX_DEFER_AFTER_MS = _chunk3NIYNYZYcjs.MAX_DEFER_AFTER_MS; exports.MAX_PUSH_PAYLOAD_BYTES = _chunk3NIYNYZYcjs.MAX_PUSH_PAYLOAD_BYTES; exports.NonRetryableError = _chunk3NIYNYZYcjs.NonRetryableError; exports.PUSH_ENVELOPE_RESERVED_BYTES = _chunk3NIYNYZYcjs.PUSH_ENVELOPE_RESERVED_BYTES; exports.SCHEMA_VERSION = _chunk3NIYNYZYcjs.SCHEMA_VERSION; exports.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES = _chunk3NIYNYZYcjs.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES; exports.WEB_PUSH_MAX_BODY_BYTES = _chunk3NIYNYZYcjs.WEB_PUSH_MAX_BODY_BYTES; exports.advanceOccurrence = _chunk3NIYNYZYcjs.advanceOccurrence; exports.createD1Adapter = _chunk3NIYNYZYcjs.createD1Adapter; exports.createSingleUserCloudflareWorker = _chunk3NIYNYZYcjs.createSingleUserCloudflareWorker; exports.createSingleUserServer = _chunk3NIYNYZYcjs.createSingleUserServer; exports.createWebCryptoWebPush = _chunk3NIYNYZYcjs.createWebCryptoWebPush; exports.decryptFromStorage = _chunk3NIYNYZYcjs.decryptFromStorage; exports.decryptPayload = _chunk3NIYNYZYcjs.decryptPayload; exports.deriveUserEncryptionKey = _chunk3NIYNYZYcjs.deriveUserEncryptionKey; exports.encryptForStorage = _chunk3NIYNYZYcjs.encryptForStorage; exports.encryptPayload = _chunk3NIYNYZYcjs.encryptPayload; exports.ensureSchema = _chunk3NIYNYZYcjs.ensureSchema; exports.getSchemaVersion = _chunk3NIYNYZYcjs.getSchemaVersion; exports.isNonRetryableError = _chunk3NIYNYZYcjs.isNonRetryableError; exports.isValidTimeZoneId = _chunk3NIYNYZYcjs.isValidTimeZoneId; exports.measurePushPayload = _chunk3NIYNYZYcjs.measurePushPayload; exports.nextFutureOccurrence = _chunk3NIYNYZYcjs.nextFutureOccurrence; exports.planNextOccurrence = _chunk3NIYNYZYcjs.planNextOccurrence; exports.readRequestBody = _chunk3NIYNYZYcjs.readRequestBody; exports.runScheduledTick = _chunk3NIYNYZYcjs.runScheduledTick; exports.runTask = _chunk3NIYNYZYcjs.runTask; exports.summarizeErrorCause = _chunk3NIYNYZYcjs.summarizeErrorCause;
65
+ exports.DEFAULT_MAX_DELIVERY_RETRIES = _chunkD4SKSCIYcjs.DEFAULT_MAX_DELIVERY_RETRIES; exports.DEFAULT_MAX_REQUEST_BODY_BYTES = _chunkD4SKSCIYcjs.DEFAULT_MAX_REQUEST_BODY_BYTES; exports.MAX_DEFER_AFTER_MS = _chunkD4SKSCIYcjs.MAX_DEFER_AFTER_MS; exports.MAX_PUSH_PAYLOAD_BYTES = _chunkD4SKSCIYcjs.MAX_PUSH_PAYLOAD_BYTES; exports.NonRetryableError = _chunkD4SKSCIYcjs.NonRetryableError; exports.PUSH_ENVELOPE_RESERVED_BYTES = _chunkD4SKSCIYcjs.PUSH_ENVELOPE_RESERVED_BYTES; exports.SCHEMA_VERSION = _chunkD4SKSCIYcjs.SCHEMA_VERSION; exports.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES = _chunkD4SKSCIYcjs.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES; exports.WEB_PUSH_MAX_BODY_BYTES = _chunkD4SKSCIYcjs.WEB_PUSH_MAX_BODY_BYTES; exports.advanceOccurrence = _chunkD4SKSCIYcjs.advanceOccurrence; exports.createD1Adapter = _chunkD4SKSCIYcjs.createD1Adapter; exports.createSingleUserCloudflareWorker = _chunkD4SKSCIYcjs.createSingleUserCloudflareWorker; exports.createSingleUserServer = _chunkD4SKSCIYcjs.createSingleUserServer; exports.createWebCryptoWebPush = _chunkD4SKSCIYcjs.createWebCryptoWebPush; exports.decryptFromStorage = _chunkD4SKSCIYcjs.decryptFromStorage; exports.decryptPayload = _chunkD4SKSCIYcjs.decryptPayload; exports.deriveUserEncryptionKey = _chunkD4SKSCIYcjs.deriveUserEncryptionKey; exports.encryptForStorage = _chunkD4SKSCIYcjs.encryptForStorage; exports.encryptPayload = _chunkD4SKSCIYcjs.encryptPayload; exports.ensureSchema = _chunkD4SKSCIYcjs.ensureSchema; exports.getSchemaVersion = _chunkD4SKSCIYcjs.getSchemaVersion; exports.isNonRetryableError = _chunkD4SKSCIYcjs.isNonRetryableError; exports.isValidTimeZoneId = _chunkD4SKSCIYcjs.isValidTimeZoneId; exports.measurePushPayload = _chunkD4SKSCIYcjs.measurePushPayload; exports.nextFutureOccurrence = _chunkD4SKSCIYcjs.nextFutureOccurrence; exports.planNextOccurrence = _chunkD4SKSCIYcjs.planNextOccurrence; exports.readRequestBody = _chunkD4SKSCIYcjs.readRequestBody; exports.runScheduledTick = _chunkD4SKSCIYcjs.runScheduledTick; exports.runTask = _chunkD4SKSCIYcjs.runTask; exports.summarizeErrorCause = _chunkD4SKSCIYcjs.summarizeErrorCause;
@@ -29,7 +29,7 @@ import {
29
29
  runScheduledTick,
30
30
  runTask,
31
31
  summarizeErrorCause
32
- } from "./chunk-6TCZEACV.mjs";
32
+ } from "./chunk-EIM3PKFY.mjs";
33
33
  import "./chunk-GN44PST5.mjs";
34
34
  export {
35
35
  DEFAULT_MAX_DELIVERY_RETRIES,
package/dist/index.cjs CHANGED
@@ -74,7 +74,7 @@
74
74
 
75
75
 
76
76
 
77
- var _chunk3NIYNYZYcjs = require('./chunk-3NIYNYZY.cjs');
77
+ var _chunkD4SKSCIYcjs = require('./chunk-D4SKSCIY.cjs');
78
78
  require('./chunk-7NMQFTDJ.cjs');
79
79
 
80
80
  // src/server/adapters/factory.js
@@ -108,7 +108,7 @@ async function createAdapter(config) {
108
108
  // src/server/handlers/init-tenant.js
109
109
  function createInitTenantHandler(ctx) {
110
110
  async function POST(headers, body) {
111
- const initSecret = _chunk3NIYNYZYcjs.getHeader.call(void 0, headers, "x-init-secret");
111
+ const initSecret = _chunkD4SKSCIYcjs.getHeader.call(void 0, headers, "x-init-secret");
112
112
  if (ctx.tenant.initSecret && initSecret !== ctx.tenant.initSecret) {
113
113
  return {
114
114
  status: 401,
@@ -121,7 +121,7 @@ function createInitTenantHandler(ctx) {
121
121
  }
122
122
  };
123
123
  }
124
- const parsed = _chunk3NIYNYZYcjs.parseJsonBody.call(void 0, body);
124
+ const parsed = _chunkD4SKSCIYcjs.parseJsonBody.call(void 0, body);
125
125
  if (!parsed.ok) {
126
126
  return {
127
127
  status: 400,
@@ -135,7 +135,7 @@ function createInitTenantHandler(ctx) {
135
135
  const tenantId = payload.tenantId || void 0;
136
136
  const driver = payload.driver;
137
137
  const databaseUrl = payload.databaseUrl || payload.connectionString;
138
- if (tenantId && !_chunk3NIYNYZYcjs.isValidUUIDv4.call(void 0, tenantId)) {
138
+ if (tenantId && !_chunkD4SKSCIYcjs.isValidUUIDv4.call(void 0, tenantId)) {
139
139
  return {
140
140
  status: 400,
141
141
  body: {
@@ -255,7 +255,7 @@ function createSendNotificationsHandler(ctx) {
255
255
  }
256
256
  };
257
257
  }
258
- const data = await _chunk3NIYNYZYcjs.runScheduledTick.call(void 0, { ...ctx, db, masterKey });
258
+ const data = await _chunkD4SKSCIYcjs.runScheduledTick.call(void 0, { ...ctx, db, masterKey });
259
259
  return { status: 200, body: { success: true, data } };
260
260
  }
261
261
  return { POST };
@@ -277,16 +277,16 @@ function encryptConfig(config, kekBuffer) {
277
277
  const plaintext = Buffer.from(JSON.stringify(config), "utf8");
278
278
  const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
279
279
  const authTag = cipher.getAuthTag();
280
- return `v1.${_chunk3NIYNYZYcjs.bytesToBase64Url.call(void 0, iv)}.${_chunk3NIYNYZYcjs.bytesToBase64Url.call(void 0, authTag)}.${_chunk3NIYNYZYcjs.bytesToBase64Url.call(void 0, ciphertext)}`;
280
+ return `v1.${_chunkD4SKSCIYcjs.bytesToBase64Url.call(void 0, iv)}.${_chunkD4SKSCIYcjs.bytesToBase64Url.call(void 0, authTag)}.${_chunkD4SKSCIYcjs.bytesToBase64Url.call(void 0, ciphertext)}`;
281
281
  }
282
282
  function decryptConfig(encrypted, kekBuffer) {
283
283
  const parts = String(encrypted || "").split(".");
284
284
  if (parts.length !== 4 || parts[0] !== "v1") {
285
285
  throw new Error("INVALID_TENANT_CONFIG");
286
286
  }
287
- const iv = _chunk3NIYNYZYcjs.base64UrlToBytes.call(void 0, parts[1]);
288
- const authTag = _chunk3NIYNYZYcjs.base64UrlToBytes.call(void 0, parts[2]);
289
- const ciphertext = _chunk3NIYNYZYcjs.base64UrlToBytes.call(void 0, parts[3]);
287
+ const iv = _chunkD4SKSCIYcjs.base64UrlToBytes.call(void 0, parts[1]);
288
+ const authTag = _chunkD4SKSCIYcjs.base64UrlToBytes.call(void 0, parts[2]);
289
+ const ciphertext = _chunkD4SKSCIYcjs.base64UrlToBytes.call(void 0, parts[3]);
290
290
  const decipher = _crypto.createDecipheriv.call(void 0, "aes-256-gcm", kekBuffer, iv);
291
291
  decipher.setAuthTag(authTag);
292
292
  const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
@@ -354,7 +354,7 @@ function createTenantBlobStore(options) {
354
354
  // src/server/tenant/token.js
355
355
 
356
356
  function sign(input, secret) {
357
- return _chunk3NIYNYZYcjs.bytesToBase64Url.call(void 0, _crypto.createHmac.call(void 0, "sha256", secret).update(input).digest());
357
+ return _chunkD4SKSCIYcjs.bytesToBase64Url.call(void 0, _crypto.createHmac.call(void 0, "sha256", secret).update(input).digest());
358
358
  }
359
359
  function nowEpochSeconds() {
360
360
  return Math.floor(Date.now() / 1e3);
@@ -370,8 +370,8 @@ function createTenantToken(params, secret) {
370
370
  v: 1
371
371
  };
372
372
  const header = { alg: "HS256", typ: "JWT" };
373
- const encodedHeader = _chunk3NIYNYZYcjs.bytesToBase64Url.call(void 0, _chunk3NIYNYZYcjs.utf8.call(void 0, JSON.stringify(header)));
374
- const encodedPayload = _chunk3NIYNYZYcjs.bytesToBase64Url.call(void 0, _chunk3NIYNYZYcjs.utf8.call(void 0, JSON.stringify(payload)));
373
+ const encodedHeader = _chunkD4SKSCIYcjs.bytesToBase64Url.call(void 0, _chunkD4SKSCIYcjs.utf8.call(void 0, JSON.stringify(header)));
374
+ const encodedPayload = _chunkD4SKSCIYcjs.bytesToBase64Url.call(void 0, _chunkD4SKSCIYcjs.utf8.call(void 0, JSON.stringify(payload)));
375
375
  const signingInput = `${encodedHeader}.${encodedPayload}`;
376
376
  const signature = sign(signingInput, secret);
377
377
  return `${signingInput}.${signature}`;
@@ -390,17 +390,17 @@ function verifyTenantToken(token, secret, options = {}) {
390
390
  let receivedBytes;
391
391
  let expectedBytes;
392
392
  try {
393
- receivedBytes = _chunk3NIYNYZYcjs.base64UrlToBytes.call(void 0, receivedSignature);
394
- expectedBytes = _chunk3NIYNYZYcjs.base64UrlToBytes.call(void 0, expectedSignature);
393
+ receivedBytes = _chunkD4SKSCIYcjs.base64UrlToBytes.call(void 0, receivedSignature);
394
+ expectedBytes = _chunkD4SKSCIYcjs.base64UrlToBytes.call(void 0, expectedSignature);
395
395
  } catch (e) {
396
396
  throw new Error("INVALID_TENANT_AUTH");
397
397
  }
398
- if (!_chunk3NIYNYZYcjs.timingSafeEqualBytes.call(void 0, receivedBytes, expectedBytes)) {
398
+ if (!_chunkD4SKSCIYcjs.timingSafeEqualBytes.call(void 0, receivedBytes, expectedBytes)) {
399
399
  throw new Error("INVALID_TENANT_AUTH");
400
400
  }
401
401
  let payload;
402
402
  try {
403
- payload = JSON.parse(_chunk3NIYNYZYcjs.utf8Decode.call(void 0, _chunk3NIYNYZYcjs.base64UrlToBytes.call(void 0, encodedPayload)));
403
+ payload = JSON.parse(_chunkD4SKSCIYcjs.utf8Decode.call(void 0, _chunkD4SKSCIYcjs.base64UrlToBytes.call(void 0, encodedPayload)));
404
404
  } catch (e2) {
405
405
  throw new Error("INVALID_TENANT_AUTH");
406
406
  }
@@ -628,15 +628,15 @@ async function createReiServer(config) {
628
628
  return {
629
629
  handlers: {
630
630
  initTenant: createInitTenantHandler(ctx),
631
- getUserKey: _chunk3NIYNYZYcjs.createGetUserKeyHandler.call(void 0, ctx),
632
- scheduleMessage: _chunk3NIYNYZYcjs.createScheduleMessageHandler.call(void 0, ctx),
631
+ getUserKey: _chunkD4SKSCIYcjs.createGetUserKeyHandler.call(void 0, ctx),
632
+ scheduleMessage: _chunkD4SKSCIYcjs.createScheduleMessageHandler.call(void 0, ctx),
633
633
  sendNotifications: createSendNotificationsHandler(ctx),
634
- updateMessage: _chunk3NIYNYZYcjs.createUpdateMessageHandler.call(void 0, ctx),
635
- cancelMessage: _chunk3NIYNYZYcjs.createCancelMessageHandler.call(void 0, ctx),
636
- messages: _chunk3NIYNYZYcjs.createMessagesHandler.call(void 0, ctx),
637
- getMessage: _chunk3NIYNYZYcjs.createGetMessageHandler.call(void 0, ctx),
638
- pushSubscription: _chunk3NIYNYZYcjs.createPushSubscriptionHandler.call(void 0, ctx),
639
- llmCredentials: _chunk3NIYNYZYcjs.createLlmCredentialsHandler.call(void 0, ctx)
634
+ updateMessage: _chunkD4SKSCIYcjs.createUpdateMessageHandler.call(void 0, ctx),
635
+ cancelMessage: _chunkD4SKSCIYcjs.createCancelMessageHandler.call(void 0, ctx),
636
+ messages: _chunkD4SKSCIYcjs.createMessagesHandler.call(void 0, ctx),
637
+ getMessage: _chunkD4SKSCIYcjs.createGetMessageHandler.call(void 0, ctx),
638
+ pushSubscription: _chunkD4SKSCIYcjs.createPushSubscriptionHandler.call(void 0, ctx),
639
+ llmCredentials: _chunkD4SKSCIYcjs.createLlmCredentialsHandler.call(void 0, ctx)
640
640
  }
641
641
  };
642
642
  }
@@ -705,4 +705,4 @@ async function createReiServer(config) {
705
705
 
706
706
 
707
707
 
708
- exports.CORS_ALLOW_HEADERS = _chunk3NIYNYZYcjs.CORS_ALLOW_HEADERS; exports.CORS_ALLOW_METHODS = _chunk3NIYNYZYcjs.CORS_ALLOW_METHODS; exports.CRED_ID_MAX_LENGTH = _chunk3NIYNYZYcjs.CRED_ID_MAX_LENGTH; exports.CRED_PUT_BATCH_MAX = _chunk3NIYNYZYcjs.CRED_PUT_BATCH_MAX; exports.CRED_REFS_MAX_ENTRIES = _chunk3NIYNYZYcjs.CRED_REFS_MAX_ENTRIES; exports.CRED_ROWS_PER_USER_MAX = _chunk3NIYNYZYcjs.CRED_ROWS_PER_USER_MAX; exports.DEFAULT_CLAIM_LEASE_MS = _chunk3NIYNYZYcjs.DEFAULT_CLAIM_LEASE_MS; exports.DEFAULT_HEARTBEAT_LEASE_TTL_MS = _chunk3NIYNYZYcjs.DEFAULT_HEARTBEAT_LEASE_TTL_MS; exports.DEFAULT_LEASE_HEARTBEAT_MS = _chunk3NIYNYZYcjs.DEFAULT_LEASE_HEARTBEAT_MS; exports.DEFAULT_MAX_DELIVERY_RETRIES = _chunk3NIYNYZYcjs.DEFAULT_MAX_DELIVERY_RETRIES; exports.DEFAULT_MAX_REQUEST_BODY_BYTES = _chunk3NIYNYZYcjs.DEFAULT_MAX_REQUEST_BODY_BYTES; exports.DEFAULT_MAX_SCHEDULED_TASKS_PER_FIRE = _chunk3NIYNYZYcjs.DEFAULT_MAX_SCHEDULED_TASKS_PER_FIRE; exports.DEFAULT_MAX_TOOL_ITERATIONS = _chunk3NIYNYZYcjs.DEFAULT_MAX_TOOL_ITERATIONS; exports.DEFAULT_TOTAL_TIMEOUT_MS = _chunk3NIYNYZYcjs.DEFAULT_TOTAL_TIMEOUT_MS; exports.DeploymentConfigError = _chunk3NIYNYZYcjs.DeploymentConfigError; exports.MAX_DEFER_AFTER_MS = _chunk3NIYNYZYcjs.MAX_DEFER_AFTER_MS; exports.MAX_PUSH_PAYLOAD_BYTES = _chunk3NIYNYZYcjs.MAX_PUSH_PAYLOAD_BYTES; exports.MAX_TASK_PAYLOAD_BYTES = _chunk3NIYNYZYcjs.MAX_TASK_PAYLOAD_BYTES; exports.MIN_SCHEDULE_LEAD_MS = _chunk3NIYNYZYcjs.MIN_SCHEDULE_LEAD_MS; exports.NonRetryableError = _chunk3NIYNYZYcjs.NonRetryableError; exports.PUSH_ENVELOPE_RESERVED_BYTES = _chunk3NIYNYZYcjs.PUSH_ENVELOPE_RESERVED_BYTES; exports.SCHEMA_VERSION = _chunk3NIYNYZYcjs.SCHEMA_VERSION; exports.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES = _chunk3NIYNYZYcjs.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES; exports.WEB_PUSH_MAX_BODY_BYTES = _chunk3NIYNYZYcjs.WEB_PUSH_MAX_BODY_BYTES; exports.advanceOccurrence = _chunk3NIYNYZYcjs.advanceOccurrence; exports.createAdapter = createAdapter; exports.createD1Adapter = _chunk3NIYNYZYcjs.createD1Adapter; exports.createReiServer = createReiServer; exports.createSingleUserCloudflareWorker = _chunk3NIYNYZYcjs.createSingleUserCloudflareWorker; exports.createSingleUserServer = _chunk3NIYNYZYcjs.createSingleUserServer; exports.createTenantToken = createTenantToken; exports.createWebCryptoWebPush = _chunk3NIYNYZYcjs.createWebCryptoWebPush; exports.decryptFromStorage = _chunk3NIYNYZYcjs.decryptFromStorage; exports.decryptPayload = _chunk3NIYNYZYcjs.decryptPayload; exports.deriveUserEncryptionKey = _chunk3NIYNYZYcjs.deriveUserEncryptionKey; exports.encryptForStorage = _chunk3NIYNYZYcjs.encryptForStorage; exports.encryptPayload = _chunk3NIYNYZYcjs.encryptPayload; exports.ensureSchema = _chunk3NIYNYZYcjs.ensureSchema; exports.getSchemaVersion = _chunk3NIYNYZYcjs.getSchemaVersion; exports.hasChatCredRef = _chunk3NIYNYZYcjs.hasChatCredRef; exports.isNonRetryableError = _chunk3NIYNYZYcjs.isNonRetryableError; exports.isValidCredId = _chunk3NIYNYZYcjs.isValidCredId; exports.isValidISO8601 = _chunk3NIYNYZYcjs.isValidISO8601; exports.isValidTimeZoneId = _chunk3NIYNYZYcjs.isValidTimeZoneId; exports.isValidUUID = _chunk3NIYNYZYcjs.isValidUUID; exports.isValidUUIDv4 = _chunk3NIYNYZYcjs.isValidUUIDv4; exports.isValidUrl = _chunk3NIYNYZYcjs.isValidUrl; exports.measurePushPayload = _chunk3NIYNYZYcjs.measurePushPayload; exports.nextFutureOccurrence = _chunk3NIYNYZYcjs.nextFutureOccurrence; exports.planNextOccurrence = _chunk3NIYNYZYcjs.planNextOccurrence; exports.readRequestBody = _chunk3NIYNYZYcjs.readRequestBody; exports.resolveLlmCredential = _chunk3NIYNYZYcjs.resolveLlmCredential; exports.runScheduledTick = _chunk3NIYNYZYcjs.runScheduledTick; exports.runTask = _chunk3NIYNYZYcjs.runTask; exports.sanitizeErrorSummary = _chunk3NIYNYZYcjs.sanitizeErrorSummary; exports.summarizeErrorCause = _chunk3NIYNYZYcjs.summarizeErrorCause; exports.supportsLlmCredentialsStore = _chunk3NIYNYZYcjs.supportsLlmCredentialsStore; exports.validateAvatarUrl = _chunk3NIYNYZYcjs.validateAvatarUrl; exports.validateCredRefs = _chunk3NIYNYZYcjs.validateCredRefs; exports.validateCredValue = _chunk3NIYNYZYcjs.validateCredValue; exports.validateLlmMessagesArray = _chunk3NIYNYZYcjs.validateLlmMessagesArray; exports.validateScheduleMessagePayload = _chunk3NIYNYZYcjs.validateScheduleMessagePayload; exports.validateSplitPattern = _chunk3NIYNYZYcjs.validateSplitPattern; exports.verifyTenantToken = verifyTenantToken;
708
+ exports.CORS_ALLOW_HEADERS = _chunkD4SKSCIYcjs.CORS_ALLOW_HEADERS; exports.CORS_ALLOW_METHODS = _chunkD4SKSCIYcjs.CORS_ALLOW_METHODS; exports.CRED_ID_MAX_LENGTH = _chunkD4SKSCIYcjs.CRED_ID_MAX_LENGTH; exports.CRED_PUT_BATCH_MAX = _chunkD4SKSCIYcjs.CRED_PUT_BATCH_MAX; exports.CRED_REFS_MAX_ENTRIES = _chunkD4SKSCIYcjs.CRED_REFS_MAX_ENTRIES; exports.CRED_ROWS_PER_USER_MAX = _chunkD4SKSCIYcjs.CRED_ROWS_PER_USER_MAX; exports.DEFAULT_CLAIM_LEASE_MS = _chunkD4SKSCIYcjs.DEFAULT_CLAIM_LEASE_MS; exports.DEFAULT_HEARTBEAT_LEASE_TTL_MS = _chunkD4SKSCIYcjs.DEFAULT_HEARTBEAT_LEASE_TTL_MS; exports.DEFAULT_LEASE_HEARTBEAT_MS = _chunkD4SKSCIYcjs.DEFAULT_LEASE_HEARTBEAT_MS; exports.DEFAULT_MAX_DELIVERY_RETRIES = _chunkD4SKSCIYcjs.DEFAULT_MAX_DELIVERY_RETRIES; exports.DEFAULT_MAX_REQUEST_BODY_BYTES = _chunkD4SKSCIYcjs.DEFAULT_MAX_REQUEST_BODY_BYTES; exports.DEFAULT_MAX_SCHEDULED_TASKS_PER_FIRE = _chunkD4SKSCIYcjs.DEFAULT_MAX_SCHEDULED_TASKS_PER_FIRE; exports.DEFAULT_MAX_TOOL_ITERATIONS = _chunkD4SKSCIYcjs.DEFAULT_MAX_TOOL_ITERATIONS; exports.DEFAULT_TOTAL_TIMEOUT_MS = _chunkD4SKSCIYcjs.DEFAULT_TOTAL_TIMEOUT_MS; exports.DeploymentConfigError = _chunkD4SKSCIYcjs.DeploymentConfigError; exports.MAX_DEFER_AFTER_MS = _chunkD4SKSCIYcjs.MAX_DEFER_AFTER_MS; exports.MAX_PUSH_PAYLOAD_BYTES = _chunkD4SKSCIYcjs.MAX_PUSH_PAYLOAD_BYTES; exports.MAX_TASK_PAYLOAD_BYTES = _chunkD4SKSCIYcjs.MAX_TASK_PAYLOAD_BYTES; exports.MIN_SCHEDULE_LEAD_MS = _chunkD4SKSCIYcjs.MIN_SCHEDULE_LEAD_MS; exports.NonRetryableError = _chunkD4SKSCIYcjs.NonRetryableError; exports.PUSH_ENVELOPE_RESERVED_BYTES = _chunkD4SKSCIYcjs.PUSH_ENVELOPE_RESERVED_BYTES; exports.SCHEMA_VERSION = _chunkD4SKSCIYcjs.SCHEMA_VERSION; exports.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES = _chunkD4SKSCIYcjs.WEB_PUSH_ENCRYPTION_OVERHEAD_BYTES; exports.WEB_PUSH_MAX_BODY_BYTES = _chunkD4SKSCIYcjs.WEB_PUSH_MAX_BODY_BYTES; exports.advanceOccurrence = _chunkD4SKSCIYcjs.advanceOccurrence; exports.createAdapter = createAdapter; exports.createD1Adapter = _chunkD4SKSCIYcjs.createD1Adapter; exports.createReiServer = createReiServer; exports.createSingleUserCloudflareWorker = _chunkD4SKSCIYcjs.createSingleUserCloudflareWorker; exports.createSingleUserServer = _chunkD4SKSCIYcjs.createSingleUserServer; exports.createTenantToken = createTenantToken; exports.createWebCryptoWebPush = _chunkD4SKSCIYcjs.createWebCryptoWebPush; exports.decryptFromStorage = _chunkD4SKSCIYcjs.decryptFromStorage; exports.decryptPayload = _chunkD4SKSCIYcjs.decryptPayload; exports.deriveUserEncryptionKey = _chunkD4SKSCIYcjs.deriveUserEncryptionKey; exports.encryptForStorage = _chunkD4SKSCIYcjs.encryptForStorage; exports.encryptPayload = _chunkD4SKSCIYcjs.encryptPayload; exports.ensureSchema = _chunkD4SKSCIYcjs.ensureSchema; exports.getSchemaVersion = _chunkD4SKSCIYcjs.getSchemaVersion; exports.hasChatCredRef = _chunkD4SKSCIYcjs.hasChatCredRef; exports.isNonRetryableError = _chunkD4SKSCIYcjs.isNonRetryableError; exports.isValidCredId = _chunkD4SKSCIYcjs.isValidCredId; exports.isValidISO8601 = _chunkD4SKSCIYcjs.isValidISO8601; exports.isValidTimeZoneId = _chunkD4SKSCIYcjs.isValidTimeZoneId; exports.isValidUUID = _chunkD4SKSCIYcjs.isValidUUID; exports.isValidUUIDv4 = _chunkD4SKSCIYcjs.isValidUUIDv4; exports.isValidUrl = _chunkD4SKSCIYcjs.isValidUrl; exports.measurePushPayload = _chunkD4SKSCIYcjs.measurePushPayload; exports.nextFutureOccurrence = _chunkD4SKSCIYcjs.nextFutureOccurrence; exports.planNextOccurrence = _chunkD4SKSCIYcjs.planNextOccurrence; exports.readRequestBody = _chunkD4SKSCIYcjs.readRequestBody; exports.resolveLlmCredential = _chunkD4SKSCIYcjs.resolveLlmCredential; exports.runScheduledTick = _chunkD4SKSCIYcjs.runScheduledTick; exports.runTask = _chunkD4SKSCIYcjs.runTask; exports.sanitizeErrorSummary = _chunkD4SKSCIYcjs.sanitizeErrorSummary; exports.summarizeErrorCause = _chunkD4SKSCIYcjs.summarizeErrorCause; exports.supportsLlmCredentialsStore = _chunkD4SKSCIYcjs.supportsLlmCredentialsStore; exports.validateAvatarUrl = _chunkD4SKSCIYcjs.validateAvatarUrl; exports.validateCredRefs = _chunkD4SKSCIYcjs.validateCredRefs; exports.validateCredValue = _chunkD4SKSCIYcjs.validateCredValue; exports.validateLlmMessagesArray = _chunkD4SKSCIYcjs.validateLlmMessagesArray; exports.validateScheduleMessagePayload = _chunkD4SKSCIYcjs.validateScheduleMessagePayload; exports.validateSplitPattern = _chunkD4SKSCIYcjs.validateSplitPattern; exports.verifyTenantToken = verifyTenantToken;
package/dist/index.mjs CHANGED
@@ -74,7 +74,7 @@ import {
74
74
  validateLlmMessagesArray,
75
75
  validateScheduleMessagePayload,
76
76
  validateSplitPattern
77
- } from "./chunk-6TCZEACV.mjs";
77
+ } from "./chunk-EIM3PKFY.mjs";
78
78
  import "./chunk-GN44PST5.mjs";
79
79
 
80
80
  // src/server/adapters/factory.js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rei-standard/amsg-server",
3
- "version": "3.1.0-next.0",
3
+ "version": "3.1.0-next.1",
4
4
  "description": "ReiStandard Active Messaging server SDK with pluggable database adapters. Three-axis push schema (messageKind / messageType / messageSubtype) from @rei-standard/amsg-shared. Auto-emits ReasoningPush when the LLM response carries reasoning_content.",
5
5
  "repository": {
6
6
  "type": "git",