deepspace 0.28.1 → 0.29.0
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/CHANGELOG.md +50 -0
- package/dist/{chunk-PVEUIQN4.js → chunk-ZWFH5HON.js} +2 -2
- package/dist/{chunk-PVEUIQN4.js.map → chunk-ZWFH5HON.js.map} +1 -1
- package/dist/cli.js +128 -81
- package/dist/cli.js.map +1 -1
- package/dist/documentation-client-core.js +1 -1
- package/dist/documentation-default-renderer.cjs +1 -1
- package/dist/documentation-react.js +1 -1
- package/dist/documentation-runtime.js +1 -1
- package/dist/documentation-server-core.js +1 -1
- package/dist/documentation.js +1 -1
- package/dist/documentation.js.map +1 -1
- package/dist/index.d.ts +56 -67
- package/dist/index.js +97 -129
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +0 -1
- package/dist/server.js +119 -31
- package/dist/server.js.map +1 -1
- package/dist/worker.d.ts +72 -90
- package/dist/worker.js +219 -143
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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}
|
|
4317
|
+
console.error(`Failed to load Yjs doc ${docKey}: ${loggableError(e)}`);
|
|
4232
4318
|
}
|
|
4233
4319
|
}
|
|
4234
4320
|
const saveDoc = () => {
|
|
@@ -5144,7 +5230,12 @@ async function executeTool(ctx, toolName, params, userId, userRole, skipUserRbac
|
|
|
5144
5230
|
case "user.current": {
|
|
5145
5231
|
if (!userId) return { success: false, error: "No userId provided" };
|
|
5146
5232
|
const user = getUser(ctx.sql, userId, ctx.schemaRegistry);
|
|
5147
|
-
if (!user)
|
|
5233
|
+
if (!user) {
|
|
5234
|
+
return {
|
|
5235
|
+
success: false,
|
|
5236
|
+
error: "No users row for this identity yet \u2014 it is created by signing in to the app in a browser. Tool access does not require one, so other tools keep working."
|
|
5237
|
+
};
|
|
5238
|
+
}
|
|
5148
5239
|
return { success: true, data: { user } };
|
|
5149
5240
|
}
|
|
5150
5241
|
// The same roster the socket's `user.list` returns, for the same caller.
|
|
@@ -5737,7 +5828,7 @@ var RecordRoom = class extends BaseRoom {
|
|
|
5737
5828
|
new Uint8Array(message)
|
|
5738
5829
|
);
|
|
5739
5830
|
} catch (e) {
|
|
5740
|
-
console.error(
|
|
5831
|
+
console.error(`[RecordRoom] Yjs binary message error: ${loggableError(e)}`);
|
|
5741
5832
|
}
|
|
5742
5833
|
return;
|
|
5743
5834
|
}
|
|
@@ -5747,7 +5838,9 @@ var RecordRoom = class extends BaseRoom {
|
|
|
5747
5838
|
} catch (e) {
|
|
5748
5839
|
const errMsg = e instanceof Error ? e.message : String(e);
|
|
5749
5840
|
const msgPreview = typeof message === "string" ? message.slice(0, 200) : "(non-string)";
|
|
5750
|
-
console.error(`[RecordRoom] Message handler error: ${
|
|
5841
|
+
console.error(`[RecordRoom] Message handler error: ${loggableError(e)}`, {
|
|
5842
|
+
message: msgPreview
|
|
5843
|
+
});
|
|
5751
5844
|
this.send(ws, { type: MSG.ERROR, payload: { error: `Invalid message: ${errMsg}` } });
|
|
5752
5845
|
}
|
|
5753
5846
|
}
|
|
@@ -5761,9 +5854,6 @@ var RecordRoom = class extends BaseRoom {
|
|
|
5761
5854
|
} catch {
|
|
5762
5855
|
}
|
|
5763
5856
|
}
|
|
5764
|
-
async webSocketError(_ws, error) {
|
|
5765
|
-
console.error(`[RecordRoom] webSocketError:`, error);
|
|
5766
|
-
}
|
|
5767
5857
|
// ============================================================================
|
|
5768
5858
|
// Message Routing
|
|
5769
5859
|
// ============================================================================
|
|
@@ -6891,8 +6981,7 @@ var CronRoom = class extends BaseRoom {
|
|
|
6891
6981
|
if (success) {
|
|
6892
6982
|
console.log(`[cron] ${taskName} ok ${durationMs}ms`);
|
|
6893
6983
|
} else {
|
|
6894
|
-
|
|
6895
|
-
console.error(`[cron] ${taskName} failed ${durationMs}ms: ${error}`, ...stack ? [stack] : []);
|
|
6984
|
+
console.error(`[cron] ${taskName} failed ${durationMs}ms: ${loggableError(thrown)}`);
|
|
6896
6985
|
}
|
|
6897
6986
|
this.sql.exec(
|
|
6898
6987
|
`INSERT INTO cron_history (task_name, started_at, completed_at, success, duration_ms, error, created_at)
|
|
@@ -7075,12 +7164,8 @@ var JobRoom = class extends BaseRoom {
|
|
|
7075
7164
|
next_run_at TEXT
|
|
7076
7165
|
)
|
|
7077
7166
|
`);
|
|
7078
|
-
this.sql.exec(
|
|
7079
|
-
|
|
7080
|
-
);
|
|
7081
|
-
this.sql.exec(
|
|
7082
|
-
`CREATE INDEX IF NOT EXISTS jobs_completed_at ON jobs (completed_at)`
|
|
7083
|
-
);
|
|
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)`);
|
|
7084
7169
|
this.recoverStuckRunning();
|
|
7085
7170
|
this.scheduleNextAlarm();
|
|
7086
7171
|
}
|
|
@@ -7348,8 +7433,7 @@ var JobRoom = class extends BaseRoom {
|
|
|
7348
7433
|
} catch (e) {
|
|
7349
7434
|
outcome = "failed";
|
|
7350
7435
|
errorMessage = e instanceof Error ? e.message : String(e);
|
|
7351
|
-
|
|
7352
|
-
console.error(`[jobs] ${row.type} (${row.id}) failed: ${errorMessage}`, ...stack ? [stack] : []);
|
|
7436
|
+
console.error(`[jobs] ${row.type} (${row.id}) failed: ${loggableError(e)}`);
|
|
7353
7437
|
} finally {
|
|
7354
7438
|
this.inFlight.delete(row.id);
|
|
7355
7439
|
}
|
|
@@ -8445,7 +8529,9 @@ function createDeepSpaceAuth(config) {
|
|
|
8445
8529
|
try {
|
|
8446
8530
|
return { clientId: apple.clientId, clientSecret: await generateAppleClientSecret(apple) };
|
|
8447
8531
|
} catch (err) {
|
|
8448
|
-
console.error(
|
|
8532
|
+
console.error(
|
|
8533
|
+
`[deepspace] failed to mint Apple client secret; Apple sign-in disabled: ${loggableError(err)}`
|
|
8534
|
+
);
|
|
8449
8535
|
return { clientId: apple.clientId, clientSecret: "" };
|
|
8450
8536
|
}
|
|
8451
8537
|
};
|
|
@@ -8520,7 +8606,9 @@ function buildDatabaseHooks(onUserCreated) {
|
|
|
8520
8606
|
ctx ? { request: ctx.request, headers: ctx.headers ?? void 0 } : null
|
|
8521
8607
|
);
|
|
8522
8608
|
} catch (err) {
|
|
8523
|
-
console.error(
|
|
8609
|
+
console.error(
|
|
8610
|
+
`[deepspace] onUserCreated hook failed (signup unaffected): ${loggableError(err)}`
|
|
8611
|
+
);
|
|
8524
8612
|
}
|
|
8525
8613
|
}
|
|
8526
8614
|
}
|