deepspace 0.28.2 → 0.29.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.
package/dist/server.d.ts CHANGED
@@ -2226,7 +2226,6 @@ declare class RecordRoom<E = Record<string, unknown>> extends BaseRoom<E> {
2226
2226
  protected onMessage(): void;
2227
2227
  webSocketMessage(ws: WebSocket, message: ArrayBuffer | string): Promise<void>;
2228
2228
  webSocketClose(ws: WebSocket, code: number, reason: string): Promise<void>;
2229
- webSocketError(_ws: WebSocket, error: unknown): Promise<void>;
2230
2229
  private handleRecordMessage;
2231
2230
  private handleListSchemas;
2232
2231
  private createHandlerContext;
package/dist/server.js CHANGED
@@ -211,6 +211,93 @@ var BUILT_IN_TOOLS = [
211
211
  }
212
212
  ];
213
213
 
214
+ // src/shared/log-events.ts
215
+ function loggableError(err) {
216
+ try {
217
+ return truncateLogText(renderError(err, 0));
218
+ } catch {
219
+ return tagOf(err);
220
+ }
221
+ }
222
+ function truncateLogText(s) {
223
+ if (s.length <= MAX_LOG_TEXT_LENGTH) return s;
224
+ let cut = MAX_LOG_TEXT_LENGTH - TRUNCATION_MARKER.length;
225
+ const last = s.charCodeAt(cut - 1);
226
+ if (last >= 55296 && last <= 56319) cut -= 1;
227
+ return s.slice(0, cut) + TRUNCATION_MARKER;
228
+ }
229
+ var MAX_LOG_TEXT_LENGTH = 8 * 1024;
230
+ var TRUNCATION_MARKER = "\u2026 [truncated]";
231
+ var MAX_CAUSE_DEPTH = 4;
232
+ function tagOf(err) {
233
+ try {
234
+ return Object.prototype.toString.call(err);
235
+ } catch {
236
+ return "[unloggable error]";
237
+ }
238
+ }
239
+ function renderError(err, depth) {
240
+ let isError;
241
+ try {
242
+ isError = err instanceof Error;
243
+ } catch {
244
+ return tagOf(err);
245
+ }
246
+ if (!isError) {
247
+ try {
248
+ return String(err).slice(0, MAX_LOG_TEXT_LENGTH + 1);
249
+ } catch {
250
+ return tagOf(err);
251
+ }
252
+ }
253
+ const e = err;
254
+ let out;
255
+ try {
256
+ const stack = typeof e.stack === "string" ? e.stack : void 0;
257
+ const head = (e.message ? `${e.name}: ${e.message}` : `${e.name}`).slice(
258
+ 0,
259
+ MAX_LOG_TEXT_LENGTH + 1
260
+ );
261
+ if (!stack) out = head;
262
+ else if (stack.startsWith(head)) out = stack.slice(0, MAX_LOG_TEXT_LENGTH + 1);
263
+ else out = `${head}
264
+ ${stack.slice(0, MAX_LOG_TEXT_LENGTH + 1)}`;
265
+ } catch {
266
+ return tagOf(err);
267
+ }
268
+ try {
269
+ if (e instanceof AggregateError && Array.isArray(e.errors)) {
270
+ if (depth < MAX_CAUSE_DEPTH) {
271
+ for (const sub of e.errors.slice(0, MAX_CAUSE_DEPTH)) {
272
+ if (out.length >= MAX_LOG_TEXT_LENGTH) return out + "\n\u2026 [cause chain truncated]";
273
+ out += `
274
+ caused by: ${renderError(sub, depth + 1)}`;
275
+ }
276
+ if (e.errors.length > MAX_CAUSE_DEPTH) {
277
+ out += `
278
+ \u2026 [${e.errors.length - MAX_CAUSE_DEPTH} more errors]`;
279
+ }
280
+ } else {
281
+ out += "\n\u2026 [cause chain truncated]";
282
+ }
283
+ }
284
+ const cause = e.cause;
285
+ if (cause != null) {
286
+ if (depth >= MAX_CAUSE_DEPTH) {
287
+ if (!out.endsWith("\u2026 [cause chain truncated]")) out += "\n\u2026 [cause chain truncated]";
288
+ } else if (out.length < MAX_LOG_TEXT_LENGTH) {
289
+ out += `
290
+ caused by: ${renderError(cause, depth + 1)}`;
291
+ } else {
292
+ out += "\n\u2026 [cause chain truncated]";
293
+ }
294
+ }
295
+ } catch {
296
+ out += "\n\u2026 [cause chain unrenderable]";
297
+ }
298
+ return out;
299
+ }
300
+
214
301
  // src/shared/app-files.ts
215
302
  var MAX_APP_FILE_BYTES = 1024 * 1024 * 1024;
216
303
  var MAX_UPLOAD_REQUEST_BYTES = 25 * 1024 * 1024;
@@ -380,7 +467,7 @@ async function measuredAllocationUsage(bucket, storage, prefixes, excludedMarker
380
467
  );
381
468
  if (budget.staleKeys.length > 0) {
382
469
  await bucket.delete(budget.staleKeys).catch((error) => {
383
- console.error("[files:quota] stale marker cleanup:", error);
470
+ console.error(`[files:quota] stale marker cleanup: ${loggableError(error)}`);
384
471
  });
385
472
  }
386
473
  return total;
@@ -440,7 +527,7 @@ async function markQuotaDirty(bucket, storage) {
440
527
  }
441
528
  console.error("[files:quota] could not mark summary reclaimable after concurrent writes");
442
529
  } catch (error) {
443
- console.error("[files:quota] could not mark summary reclaimable:", error);
530
+ console.error(`[files:quota] could not mark summary reclaimable: ${loggableError(error)}`);
444
531
  }
445
532
  }
446
533
  async function neutralizeMarker(bucket, markerKey) {
@@ -480,7 +567,7 @@ async function releaseQuotaMarker(bucket, storage, markerKey, summaryMayBeStale)
480
567
  }
481
568
  return true;
482
569
  } catch (error) {
483
- console.error("[files:quota] reservation cleanup:", error);
570
+ console.error(`[files:quota] reservation cleanup: ${loggableError(error)}`);
484
571
  return false;
485
572
  }
486
573
  }
@@ -510,7 +597,7 @@ async function readMultipartReservation(bucket, storage, reservationId) {
510
597
  try {
511
598
  object = await bucket.get(key);
512
599
  } catch (error) {
513
- console.error("[files:quota] reservation read:", error);
600
+ console.error(`[files:quota] reservation read: ${loggableError(error)}`);
514
601
  return "invalid";
515
602
  }
516
603
  if (!object) return null;
@@ -706,7 +793,7 @@ async function admitStorage(bucket, storage, incomingBytes, replacedBytes, marke
706
793
  }
707
794
  return { markerKey: effectiveMarker?.key ?? null };
708
795
  } catch (error) {
709
- console.error("[files:quota] admission:", error);
796
+ console.error(`[files:quota] admission: ${loggableError(error)}`);
710
797
  await releaseQuotaMarker(bucket, storage, markerKey, true);
711
798
  return quotaUnavailable(
712
799
  "The storage used by this account could not be verified. Retry shortly."
@@ -720,7 +807,7 @@ async function storageUsage(bucket, storage) {
720
807
  const current = await ensureQuotaSummary(bucket, storage, prefixes, "repairDirty");
721
808
  return current?.summary?.usedBytes ?? null;
722
809
  } catch (error) {
723
- console.error("[files:quota] usage:", error);
810
+ console.error(`[files:quota] usage: ${loggableError(error)}`);
724
811
  return null;
725
812
  }
726
813
  }
@@ -1306,7 +1393,7 @@ async function finishCompletedMultipart(bucket, session, reservation, object, au
1306
1393
  if (current?.etag === object.etag) await bucket.delete(session.key);
1307
1394
  remaining = await bucket.head(session.key);
1308
1395
  } catch (error) {
1309
- console.error("[files:multipart] invalid object cleanup:", error);
1396
+ console.error(`[files:multipart] invalid object cleanup: ${loggableError(error)}`);
1310
1397
  return quotaUnavailable("The invalid assembled file could not be removed. Retry completion.");
1311
1398
  }
1312
1399
  if (remaining?.etag === object.etag) {
@@ -2446,8 +2533,7 @@ async function prepareMessagesWithCompaction(messages, config, options) {
2446
2533
  };
2447
2534
  } catch (err) {
2448
2535
  console.error(
2449
- "prepareMessagesWithCompaction: summarizer failed, falling back to sliding window",
2450
- err
2536
+ `prepareMessagesWithCompaction: summarizer failed, falling back to sliding window: ${loggableError(err)}`
2451
2537
  );
2452
2538
  }
2453
2539
  } else {
@@ -3159,7 +3245,7 @@ var BaseRoom = class {
3159
3245
  try {
3160
3246
  await this.onBinaryMessage(ws, attachment, message);
3161
3247
  } catch (e) {
3162
- console.error(`[${this.constructor.name}] Binary message error:`, e);
3248
+ console.error(`[${this.constructor.name}] Binary message error: ${loggableError(e)}`);
3163
3249
  }
3164
3250
  }
3165
3251
  return;
@@ -3168,7 +3254,7 @@ var BaseRoom = class {
3168
3254
  const msg = JSON.parse(message);
3169
3255
  await this.onMessage(ws, attachment, msg);
3170
3256
  } catch (e) {
3171
- console.error(`[${this.constructor.name}] Message error:`, e);
3257
+ console.error(`[${this.constructor.name}] Message error: ${loggableError(e)}`);
3172
3258
  }
3173
3259
  }
3174
3260
  async webSocketClose(ws, _code, _reason) {
@@ -3181,7 +3267,7 @@ var BaseRoom = class {
3181
3267
  }
3182
3268
  }
3183
3269
  async webSocketError(_ws, error) {
3184
- console.error(`[${this.constructor.name}] webSocketError:`, error);
3270
+ console.error(`[${this.constructor.name}] webSocketError: ${loggableError(error)}`);
3185
3271
  }
3186
3272
  async alarm() {
3187
3273
  if (this.onAlarm) {
@@ -4228,7 +4314,7 @@ function getOrCreateYjsDoc(ctx, docKey) {
4228
4314
  try {
4229
4315
  Y2.applyUpdate(doc, new Uint8Array(row.state));
4230
4316
  } catch (e) {
4231
- console.error(`Failed to load Yjs doc ${docKey}:`, e);
4317
+ console.error(`Failed to load Yjs doc ${docKey}: ${loggableError(e)}`);
4232
4318
  }
4233
4319
  }
4234
4320
  const saveDoc = () => {
@@ -5742,7 +5828,7 @@ var RecordRoom = class extends BaseRoom {
5742
5828
  new Uint8Array(message)
5743
5829
  );
5744
5830
  } catch (e) {
5745
- console.error("[RecordRoom] Yjs binary message error:", e);
5831
+ console.error(`[RecordRoom] Yjs binary message error: ${loggableError(e)}`);
5746
5832
  }
5747
5833
  return;
5748
5834
  }
@@ -5752,7 +5838,9 @@ var RecordRoom = class extends BaseRoom {
5752
5838
  } catch (e) {
5753
5839
  const errMsg = e instanceof Error ? e.message : String(e);
5754
5840
  const msgPreview = typeof message === "string" ? message.slice(0, 200) : "(non-string)";
5755
- console.error(`[RecordRoom] Message handler error: ${errMsg}`, { message: msgPreview });
5841
+ console.error(`[RecordRoom] Message handler error: ${loggableError(e)}`, {
5842
+ message: msgPreview
5843
+ });
5756
5844
  this.send(ws, { type: MSG.ERROR, payload: { error: `Invalid message: ${errMsg}` } });
5757
5845
  }
5758
5846
  }
@@ -5766,9 +5854,6 @@ var RecordRoom = class extends BaseRoom {
5766
5854
  } catch {
5767
5855
  }
5768
5856
  }
5769
- async webSocketError(_ws, error) {
5770
- console.error(`[RecordRoom] webSocketError:`, error);
5771
- }
5772
5857
  // ============================================================================
5773
5858
  // Message Routing
5774
5859
  // ============================================================================
@@ -6896,8 +6981,7 @@ var CronRoom = class extends BaseRoom {
6896
6981
  if (success) {
6897
6982
  console.log(`[cron] ${taskName} ok ${durationMs}ms`);
6898
6983
  } else {
6899
- const stack = thrown instanceof Error ? thrown.stack : void 0;
6900
- console.error(`[cron] ${taskName} failed ${durationMs}ms: ${error}`, ...stack ? [stack] : []);
6984
+ console.error(`[cron] ${taskName} failed ${durationMs}ms: ${loggableError(thrown)}`);
6901
6985
  }
6902
6986
  this.sql.exec(
6903
6987
  `INSERT INTO cron_history (task_name, started_at, completed_at, success, duration_ms, error, created_at)
@@ -7080,12 +7164,8 @@ var JobRoom = class extends BaseRoom {
7080
7164
  next_run_at TEXT
7081
7165
  )
7082
7166
  `);
7083
- this.sql.exec(
7084
- `CREATE INDEX IF NOT EXISTS jobs_status_next_run ON jobs (status, next_run_at)`
7085
- );
7086
- this.sql.exec(
7087
- `CREATE INDEX IF NOT EXISTS jobs_completed_at ON jobs (completed_at)`
7088
- );
7167
+ this.sql.exec(`CREATE INDEX IF NOT EXISTS jobs_status_next_run ON jobs (status, next_run_at)`);
7168
+ this.sql.exec(`CREATE INDEX IF NOT EXISTS jobs_completed_at ON jobs (completed_at)`);
7089
7169
  this.recoverStuckRunning();
7090
7170
  this.scheduleNextAlarm();
7091
7171
  }
@@ -7353,8 +7433,7 @@ var JobRoom = class extends BaseRoom {
7353
7433
  } catch (e) {
7354
7434
  outcome = "failed";
7355
7435
  errorMessage = e instanceof Error ? e.message : String(e);
7356
- const stack = e instanceof Error ? e.stack : void 0;
7357
- console.error(`[jobs] ${row.type} (${row.id}) failed: ${errorMessage}`, ...stack ? [stack] : []);
7436
+ console.error(`[jobs] ${row.type} (${row.id}) failed: ${loggableError(e)}`);
7358
7437
  } finally {
7359
7438
  this.inFlight.delete(row.id);
7360
7439
  }
@@ -8450,7 +8529,9 @@ function createDeepSpaceAuth(config) {
8450
8529
  try {
8451
8530
  return { clientId: apple.clientId, clientSecret: await generateAppleClientSecret(apple) };
8452
8531
  } catch (err) {
8453
- console.error("[deepspace] failed to mint Apple client secret; Apple sign-in disabled", err);
8532
+ console.error(
8533
+ `[deepspace] failed to mint Apple client secret; Apple sign-in disabled: ${loggableError(err)}`
8534
+ );
8454
8535
  return { clientId: apple.clientId, clientSecret: "" };
8455
8536
  }
8456
8537
  };
@@ -8525,7 +8606,9 @@ function buildDatabaseHooks(onUserCreated) {
8525
8606
  ctx ? { request: ctx.request, headers: ctx.headers ?? void 0 } : null
8526
8607
  );
8527
8608
  } catch (err) {
8528
- console.error("[deepspace] onUserCreated hook failed (signup unaffected)", err);
8609
+ console.error(
8610
+ `[deepspace] onUserCreated hook failed (signup unaffected): ${loggableError(err)}`
8611
+ );
8529
8612
  }
8530
8613
  }
8531
8614
  }