deepspace 0.6.1 → 0.6.2
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 +17 -0
- package/dist/cli.js +149 -68
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +53 -1
- package/dist/server.js +86 -1
- package/dist/server.js.map +1 -1
- package/dist/worker.d.ts +53 -1
- package/dist/worker.js +86 -1
- package/dist/worker.js.map +1 -1
- package/features/ai-chat/src/ChatPanel.tsx +14 -12
- package/package.json +1 -1
package/dist/server.d.ts
CHANGED
|
@@ -615,7 +615,7 @@ declare function createDeepSpaceAI(env: DeepSpaceAIEnv, provider: Provider, opti
|
|
|
615
615
|
* const jwt = c.req.header('Authorization')!.slice(7)
|
|
616
616
|
* const tools = await composioTools(c.env, { toolkit: 'gmail', authToken: jwt })
|
|
617
617
|
* const ai = createDeepSpaceAI(c.env, 'anthropic', { authToken: jwt })
|
|
618
|
-
* const result = streamText({ model: ai('claude-sonnet-
|
|
618
|
+
* const result = streamText({ model: ai('claude-sonnet-5'), prompt, tools })
|
|
619
619
|
*
|
|
620
620
|
* Merge with your own tools: `tools: { ...buildTools(executor), ...composio }`.
|
|
621
621
|
*/
|
|
@@ -1373,6 +1373,8 @@ type ServerMessage = BaseMessage<typeof MSG.QUERY_RESULT, {
|
|
|
1373
1373
|
* - Raw SQLite access via this.sql
|
|
1374
1374
|
* - Broadcast helpers: broadcast(), sendTo()
|
|
1375
1375
|
* - HTTP fetch handler with WebSocket upgrade detection
|
|
1376
|
+
* - Internal control-plane endpoint: POST /internal/disconnect-sockets
|
|
1377
|
+
* (force every client to reconnect and resync after out-of-band writes)
|
|
1376
1378
|
*
|
|
1377
1379
|
* Subclasses implement lifecycle hooks:
|
|
1378
1380
|
* onConnect, onMessage, onBinaryMessage, onDisconnect, onRequest, onAlarm
|
|
@@ -1392,6 +1394,21 @@ declare abstract class BaseRoom<E = Record<string, unknown>> {
|
|
|
1392
1394
|
protected sql: SqlStorage;
|
|
1393
1395
|
constructor(state: DurableObjectState, env: unknown);
|
|
1394
1396
|
fetch(request: Request): Promise<Response>;
|
|
1397
|
+
/**
|
|
1398
|
+
* Handle built-in `/internal/*` control-plane routes shared by every room
|
|
1399
|
+
* type. Returns a `Response` if the request was an internal route, or `null`
|
|
1400
|
+
* to let the caller continue normal dispatch.
|
|
1401
|
+
*
|
|
1402
|
+
* Currently:
|
|
1403
|
+
* - `POST /internal/disconnect-sockets` — close every live WebSocket so
|
|
1404
|
+
* clients reconnect and resync. Optional JSON body `{ code?, reason? }`
|
|
1405
|
+
* overrides the defaults (1012 / 'state-refresh'). Responds with
|
|
1406
|
+
* `{ success: true, closed: <n> }`.
|
|
1407
|
+
*
|
|
1408
|
+
* See the security note on `fetch()`: this path is only reachable via DO
|
|
1409
|
+
* stub fetch from the app worker, never from the public internet.
|
|
1410
|
+
*/
|
|
1411
|
+
protected handleInternalRequest(request: Request, url: URL): Promise<Response | null>;
|
|
1395
1412
|
private handleWebSocketUpgrade;
|
|
1396
1413
|
webSocketMessage(ws: WebSocket, message: ArrayBuffer | string): Promise<void>;
|
|
1397
1414
|
webSocketClose(ws: WebSocket, _code: number, _reason: string): Promise<void>;
|
|
@@ -1430,6 +1447,33 @@ declare abstract class BaseRoom<E = Record<string, unknown>> {
|
|
|
1430
1447
|
* Get all connected WebSockets.
|
|
1431
1448
|
*/
|
|
1432
1449
|
protected getWebSockets(): WebSocket[];
|
|
1450
|
+
/**
|
|
1451
|
+
* Force every connected client to reconnect and resync by closing all live
|
|
1452
|
+
* WebSockets. Returns the number of sockets closed.
|
|
1453
|
+
*
|
|
1454
|
+
* Use this after an **out-of-band, server-side write** to the room's records
|
|
1455
|
+
* — an admin import route, a migration script, a cron job, or a server
|
|
1456
|
+
* action — that connected clients have no way to learn about. Without it, a
|
|
1457
|
+
* browser tab holding stale in-memory state keeps operating on (and may
|
|
1458
|
+
* autosave over) data that changed underneath it. Closing the socket makes
|
|
1459
|
+
* the client SDK reconnect and pull fresh query results.
|
|
1460
|
+
*
|
|
1461
|
+
* The default close code is 1012 ("service restart") with reason
|
|
1462
|
+
* 'state-refresh'. The DeepSpace client treats *any* close as a reconnect
|
|
1463
|
+
* trigger (it does not special-case clean/1000 closes), so on reconnect it
|
|
1464
|
+
* re-subscribes every active query and receives fresh `QUERY_RESULT`s —
|
|
1465
|
+
* `useQuery` consumers see the new data without re-subscribing.
|
|
1466
|
+
*
|
|
1467
|
+
* Each close is guarded so one already-closing socket can't abort the sweep.
|
|
1468
|
+
*
|
|
1469
|
+
* @param options.code WebSocket close code (default 1012).
|
|
1470
|
+
* @param options.reason WebSocket close reason (default 'state-refresh').
|
|
1471
|
+
* @returns the number of sockets that were closed.
|
|
1472
|
+
*/
|
|
1473
|
+
disconnectAllSockets(options?: {
|
|
1474
|
+
code?: number;
|
|
1475
|
+
reason?: string;
|
|
1476
|
+
}): number;
|
|
1433
1477
|
/**
|
|
1434
1478
|
* Get the user attachment for a WebSocket.
|
|
1435
1479
|
*/
|
|
@@ -1751,6 +1795,14 @@ declare class RecordRoom<E = Record<string, unknown>> extends BaseRoom<E> {
|
|
|
1751
1795
|
* truthy value on the worker to opt in). Off by default.
|
|
1752
1796
|
*/
|
|
1753
1797
|
private get perfLogEnabled();
|
|
1798
|
+
/**
|
|
1799
|
+
* The HTTP debug API (`/api/debug/*`) runs arbitrary SQL and role changes
|
|
1800
|
+
* with no auth of its own, so it is gated here at the DO's single ingress.
|
|
1801
|
+
* Off unless a deployment opts in with `ALLOW_DEBUG_ROUTES=true`
|
|
1802
|
+
* (`deepspace dev`/`test` set it automatically). Deployments holding shared
|
|
1803
|
+
* data override this to always return false.
|
|
1804
|
+
*/
|
|
1805
|
+
protected get debugRoutesEnabled(): boolean;
|
|
1754
1806
|
constructor(state: DurableObjectState, env: unknown, schemas?: CollectionSchema[], config?: RecordRoomConfig);
|
|
1755
1807
|
private getPermissionContext;
|
|
1756
1808
|
fetch(request: Request): Promise<Response>;
|
package/dist/server.js
CHANGED
|
@@ -1287,6 +1287,8 @@ var BaseRoom = class {
|
|
|
1287
1287
|
// ==========================================================================
|
|
1288
1288
|
async fetch(request) {
|
|
1289
1289
|
const url = new URL(request.url);
|
|
1290
|
+
const internal = await this.handleInternalRequest(request, url);
|
|
1291
|
+
if (internal) return internal;
|
|
1290
1292
|
if (request.headers.get("Upgrade") === "websocket") {
|
|
1291
1293
|
return this.handleWebSocketUpgrade(request, url);
|
|
1292
1294
|
}
|
|
@@ -1296,6 +1298,36 @@ var BaseRoom = class {
|
|
|
1296
1298
|
return new Response("Not Found", { status: 404 });
|
|
1297
1299
|
}
|
|
1298
1300
|
// ==========================================================================
|
|
1301
|
+
// Internal Control-Plane Endpoints
|
|
1302
|
+
// ==========================================================================
|
|
1303
|
+
/**
|
|
1304
|
+
* Handle built-in `/internal/*` control-plane routes shared by every room
|
|
1305
|
+
* type. Returns a `Response` if the request was an internal route, or `null`
|
|
1306
|
+
* to let the caller continue normal dispatch.
|
|
1307
|
+
*
|
|
1308
|
+
* Currently:
|
|
1309
|
+
* - `POST /internal/disconnect-sockets` — close every live WebSocket so
|
|
1310
|
+
* clients reconnect and resync. Optional JSON body `{ code?, reason? }`
|
|
1311
|
+
* overrides the defaults (1012 / 'state-refresh'). Responds with
|
|
1312
|
+
* `{ success: true, closed: <n> }`.
|
|
1313
|
+
*
|
|
1314
|
+
* See the security note on `fetch()`: this path is only reachable via DO
|
|
1315
|
+
* stub fetch from the app worker, never from the public internet.
|
|
1316
|
+
*/
|
|
1317
|
+
async handleInternalRequest(request, url) {
|
|
1318
|
+
if (request.method === "POST" && url.pathname === "/internal/disconnect-sockets") {
|
|
1319
|
+
let options;
|
|
1320
|
+
try {
|
|
1321
|
+
const text = await request.text();
|
|
1322
|
+
if (text) options = JSON.parse(text);
|
|
1323
|
+
} catch {
|
|
1324
|
+
}
|
|
1325
|
+
const closed = this.disconnectAllSockets(options);
|
|
1326
|
+
return Response.json({ success: true, closed });
|
|
1327
|
+
}
|
|
1328
|
+
return null;
|
|
1329
|
+
}
|
|
1330
|
+
// ==========================================================================
|
|
1299
1331
|
// WebSocket Connection
|
|
1300
1332
|
// ==========================================================================
|
|
1301
1333
|
async handleWebSocketUpgrade(request, url) {
|
|
@@ -1382,6 +1414,42 @@ var BaseRoom = class {
|
|
|
1382
1414
|
getWebSockets() {
|
|
1383
1415
|
return this.state.getWebSockets();
|
|
1384
1416
|
}
|
|
1417
|
+
/**
|
|
1418
|
+
* Force every connected client to reconnect and resync by closing all live
|
|
1419
|
+
* WebSockets. Returns the number of sockets closed.
|
|
1420
|
+
*
|
|
1421
|
+
* Use this after an **out-of-band, server-side write** to the room's records
|
|
1422
|
+
* — an admin import route, a migration script, a cron job, or a server
|
|
1423
|
+
* action — that connected clients have no way to learn about. Without it, a
|
|
1424
|
+
* browser tab holding stale in-memory state keeps operating on (and may
|
|
1425
|
+
* autosave over) data that changed underneath it. Closing the socket makes
|
|
1426
|
+
* the client SDK reconnect and pull fresh query results.
|
|
1427
|
+
*
|
|
1428
|
+
* The default close code is 1012 ("service restart") with reason
|
|
1429
|
+
* 'state-refresh'. The DeepSpace client treats *any* close as a reconnect
|
|
1430
|
+
* trigger (it does not special-case clean/1000 closes), so on reconnect it
|
|
1431
|
+
* re-subscribes every active query and receives fresh `QUERY_RESULT`s —
|
|
1432
|
+
* `useQuery` consumers see the new data without re-subscribing.
|
|
1433
|
+
*
|
|
1434
|
+
* Each close is guarded so one already-closing socket can't abort the sweep.
|
|
1435
|
+
*
|
|
1436
|
+
* @param options.code WebSocket close code (default 1012).
|
|
1437
|
+
* @param options.reason WebSocket close reason (default 'state-refresh').
|
|
1438
|
+
* @returns the number of sockets that were closed.
|
|
1439
|
+
*/
|
|
1440
|
+
disconnectAllSockets(options) {
|
|
1441
|
+
const code = options?.code ?? 1012;
|
|
1442
|
+
const reason = options?.reason ?? "state-refresh";
|
|
1443
|
+
let closed = 0;
|
|
1444
|
+
for (const ws of this.state.getWebSockets()) {
|
|
1445
|
+
try {
|
|
1446
|
+
ws.close(code, reason);
|
|
1447
|
+
closed++;
|
|
1448
|
+
} catch {
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
return closed;
|
|
1452
|
+
}
|
|
1385
1453
|
/**
|
|
1386
1454
|
* Get the user attachment for a WebSocket.
|
|
1387
1455
|
*/
|
|
@@ -3481,6 +3549,16 @@ var RecordRoom = class extends BaseRoom {
|
|
|
3481
3549
|
get perfLogEnabled() {
|
|
3482
3550
|
return !!this.env?.DEEPSPACE_DO_PERF;
|
|
3483
3551
|
}
|
|
3552
|
+
/**
|
|
3553
|
+
* The HTTP debug API (`/api/debug/*`) runs arbitrary SQL and role changes
|
|
3554
|
+
* with no auth of its own, so it is gated here at the DO's single ingress.
|
|
3555
|
+
* Off unless a deployment opts in with `ALLOW_DEBUG_ROUTES=true`
|
|
3556
|
+
* (`deepspace dev`/`test` set it automatically). Deployments holding shared
|
|
3557
|
+
* data override this to always return false.
|
|
3558
|
+
*/
|
|
3559
|
+
get debugRoutesEnabled() {
|
|
3560
|
+
return this.env?.ALLOW_DEBUG_ROUTES === "true";
|
|
3561
|
+
}
|
|
3484
3562
|
constructor(state, env, schemas = [], config = {}) {
|
|
3485
3563
|
super(state, env);
|
|
3486
3564
|
this.schemaRegistry = new SchemaRegistry([
|
|
@@ -3516,14 +3594,21 @@ var RecordRoom = class extends BaseRoom {
|
|
|
3516
3594
|
// HTTP Entry Point (overrides BaseRoom.fetch)
|
|
3517
3595
|
// ============================================================================
|
|
3518
3596
|
async fetch(request) {
|
|
3597
|
+
const url = new URL(request.url);
|
|
3598
|
+
if (url.pathname.startsWith("/internal/")) {
|
|
3599
|
+
const internal = await this.handleInternalRequest(request, url);
|
|
3600
|
+
if (internal) return internal;
|
|
3601
|
+
}
|
|
3519
3602
|
const fetchStart = Date.now();
|
|
3520
3603
|
const isColdStart = this.freshConstruct;
|
|
3521
3604
|
const needsInit = !this.initPromise;
|
|
3522
3605
|
this.freshConstruct = false;
|
|
3523
3606
|
await this.ensureInitialized();
|
|
3524
3607
|
const initMs = Date.now() - fetchStart;
|
|
3525
|
-
const url = new URL(request.url);
|
|
3526
3608
|
if (url.pathname.startsWith("/api/")) {
|
|
3609
|
+
if (url.pathname.startsWith("/api/debug/") && !this.debugRoutesEnabled) {
|
|
3610
|
+
return new Response("Not Found", { status: 404 });
|
|
3611
|
+
}
|
|
3527
3612
|
return handleApiRequest(this.createHandlerContext(), request, url);
|
|
3528
3613
|
}
|
|
3529
3614
|
if (request.headers.get("Upgrade") === "websocket") {
|