deepspace 0.15.0 → 0.17.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/dist/index.js CHANGED
@@ -570,15 +570,6 @@ var MSG = {
570
570
  ACK: "records.ack",
571
571
  LIST_SCHEMAS: "records.list_schemas",
572
572
  RESUBSCRIBE: "records.resubscribe",
573
- // ---- GameRoom --------------------------------------------------------
574
- GAME_STATE: "game.state",
575
- GAME_INPUT: "game.input",
576
- GAME_PLAYER_JOIN: "game.player_join",
577
- GAME_PLAYER_LEAVE: "game.player_leave",
578
- GAME_PLAYER_READY: "game.player_ready",
579
- GAME_START: "game.start",
580
- GAME_END: "game.end",
581
- GAME_TICK: "game.tick",
582
573
  // ---- CanvasRoom ------------------------------------------------------
583
574
  CANVAS_SHAPES: "canvas.shapes",
584
575
  CANVAS_ADD: "canvas.add",
@@ -641,11 +632,6 @@ var clientBuild = {
641
632
  // Yjs
642
633
  yjsJoin: (collection, recordId, fieldName) => ({ type: MSG.YJS_JOIN, payload: { collection, recordId, fieldName } }),
643
634
  yjsLeave: (collection, recordId, fieldName) => ({ type: MSG.YJS_LEAVE, payload: { collection, recordId, fieldName } }),
644
- // Game
645
- gameInput: (action, data = {}) => ({ type: MSG.GAME_INPUT, payload: { action, data } }),
646
- gamePlayerReady: () => ({ type: MSG.GAME_PLAYER_READY, payload: EMPTY }),
647
- gameStart: () => ({ type: MSG.GAME_START, payload: EMPTY }),
648
- gameEnd: () => ({ type: MSG.GAME_END, payload: EMPTY }),
649
635
  // Canvas — `CANVAS_ADD` / `CANVAS_VIEWPORT` payloads are flat (the shape
650
636
  // or viewport object is the whole payload).
651
637
  canvasAdd: (shape) => ({ type: MSG.CANVAS_ADD, payload: shape }),
@@ -697,14 +683,6 @@ var serverBuild = {
697
683
  type: MSG.YJS_JOIN,
698
684
  payload: { collection, recordId, fieldName, canWrite }
699
685
  }),
700
- // Game
701
- gameState: (state, tick, players, running) => ({ type: MSG.GAME_STATE, payload: { state, tick, players, running } }),
702
- gameTick: (state, tick) => ({ type: MSG.GAME_TICK, payload: { state, tick } }),
703
- gameStart: (state, tick) => ({ type: MSG.GAME_START, payload: { state, tick } }),
704
- gameEnd: (state, tick) => ({ type: MSG.GAME_END, payload: { state, tick } }),
705
- gamePlayerJoin: (player) => ({ type: MSG.GAME_PLAYER_JOIN, payload: { player } }),
706
- gamePlayerLeave: (userId) => ({ type: MSG.GAME_PLAYER_LEAVE, payload: { userId } }),
707
- gamePlayerReady: (userId) => ({ type: MSG.GAME_PLAYER_READY, payload: { userId } }),
708
686
  // Canvas
709
687
  canvasShapes: (shapes, viewports) => ({ type: MSG.CANVAS_SHAPES, payload: { shapes, viewports } }),
710
688
  canvasAdd: (shape) => ({ type: MSG.CANVAS_ADD, payload: { shape } }),
@@ -770,7 +748,6 @@ function encode(message) {
770
748
  // src/shared/protocol/app-migrations.ts
771
749
  var APP_MIGRATION_ID_RE = /^[a-z0-9][a-z0-9._-]{0,127}$/;
772
750
  var MAX_APP_MIGRATION_IDS = 256;
773
- var CANONICAL_APP_IDENTITY_MIGRATION_ID = "2026-08-canonical-app-identity-wire";
774
751
  var WORKER_OWNED_NOT_FOUND_MIGRATION_ID = "2026-08-worker-owned-not-found";
775
752
  function validateAppMigrationIds(value) {
776
753
  if (!Array.isArray(value)) {
@@ -2973,123 +2950,15 @@ function useYjsRoom(docId, fieldName) {
2973
2950
  return { doc, awareness, text, setText, synced, canWrite, writeAuthResolved };
2974
2951
  }
2975
2952
 
2976
- // src/client/storage/hooks/useGameRoom.ts
2953
+ // src/client/storage/hooks/useCanvas.ts
2977
2954
  import { useState as useState8, useEffect as useEffect11, useCallback as useCallback10, useRef as useRef9 } from "react";
2978
- function useGameRoom(roomId) {
2979
- const [gameState, setGameState] = useState8({});
2980
- const [tick, setTick] = useState8(0);
2981
- const [players, setPlayers] = useState8([]);
2982
- const [running, setRunning] = useState8(false);
2955
+ function useCanvas(roomId) {
2956
+ const [shapes, setShapes] = useState8([]);
2957
+ const [viewports, setViewports] = useState8([]);
2983
2958
  const [connected, setConnected] = useState8(false);
2984
2959
  const [canWrite, setCanWrite] = useState8(false);
2985
2960
  const wsRef = useRef9(null);
2986
2961
  useEffect11(() => {
2987
- let ws = null;
2988
- let reconnectTimer = null;
2989
- let alive = true;
2990
- const connect = async () => {
2991
- if (!alive) return;
2992
- const token = await getAuthToken();
2993
- const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
2994
- const baseUrl = `${protocol}//${window.location.host}`;
2995
- const url = new URL(`/ws/game/${encodeURIComponent(roomId)}`, baseUrl);
2996
- if (token) url.searchParams.set("token", token);
2997
- wsLog("connecting", `game:${roomId}`);
2998
- ws = new WebSocket(url.toString());
2999
- wsRef.current = ws;
3000
- ws.onopen = () => {
3001
- wsLog("connected", `game:${roomId}`);
3002
- setConnected(true);
3003
- };
3004
- ws.onmessage = (event) => {
3005
- dispatch(event.data, {
3006
- [MSG.AUTH]: (p) => {
3007
- setCanWrite(p.canWrite);
3008
- },
3009
- [MSG.GAME_STATE]: (p) => {
3010
- setGameState(p.state);
3011
- setTick(p.tick);
3012
- setPlayers(p.players);
3013
- setRunning(p.running);
3014
- },
3015
- [MSG.GAME_TICK]: (p) => {
3016
- setGameState(p.state);
3017
- setTick(p.tick);
3018
- },
3019
- [MSG.GAME_PLAYER_JOIN]: (p) => {
3020
- const player = p.player;
3021
- setPlayers((prev) => [...prev.filter((x) => x.userId !== player.userId), player]);
3022
- },
3023
- [MSG.GAME_PLAYER_LEAVE]: (p) => {
3024
- setPlayers((prev) => prev.filter((x) => x.userId !== p.userId));
3025
- },
3026
- [MSG.GAME_PLAYER_READY]: (p) => {
3027
- setPlayers(
3028
- (prev) => prev.map((x) => x.userId === p.userId ? { ...x, ready: true } : x)
3029
- );
3030
- },
3031
- [MSG.GAME_START]: (p) => {
3032
- setRunning(true);
3033
- setGameState(p.state);
3034
- setTick(p.tick);
3035
- },
3036
- [MSG.GAME_END]: (p) => {
3037
- setRunning(false);
3038
- setGameState(p.state);
3039
- }
3040
- });
3041
- };
3042
- ws.onclose = () => {
3043
- wsLog("disconnected", `game:${roomId}`);
3044
- wsRef.current = null;
3045
- setConnected(false);
3046
- setCanWrite(false);
3047
- if (alive) reconnectTimer = setTimeout(connect, 1e3);
3048
- };
3049
- ws.onerror = () => ws?.close();
3050
- };
3051
- connect();
3052
- return () => {
3053
- wsLog("closing", `game:${roomId}`);
3054
- alive = false;
3055
- if (reconnectTimer) clearTimeout(reconnectTimer);
3056
- if (ws) {
3057
- ws.onclose = null;
3058
- ws.onmessage = null;
3059
- ws.onerror = null;
3060
- ws.close();
3061
- }
3062
- wsRef.current = null;
3063
- };
3064
- }, [roomId]);
3065
- const send = useCallback10(
3066
- (message) => {
3067
- if (!canWrite) return;
3068
- const ws = wsRef.current;
3069
- if (!ws || ws.readyState !== WebSocket.OPEN) return;
3070
- ws.send(encode(message));
3071
- },
3072
- [canWrite]
3073
- );
3074
- const sendInput = useCallback10(
3075
- (action, data = {}) => send(clientBuild.gameInput(action, data)),
3076
- [send]
3077
- );
3078
- const setReady = useCallback10(() => send(clientBuild.gamePlayerReady()), [send]);
3079
- const startGame = useCallback10(() => send(clientBuild.gameStart()), [send]);
3080
- const endGame = useCallback10(() => send(clientBuild.gameEnd()), [send]);
3081
- return { state: gameState, tick, players, running, connected, canWrite, sendInput, setReady, startGame, endGame };
3082
- }
3083
-
3084
- // src/client/storage/hooks/useCanvas.ts
3085
- import { useState as useState9, useEffect as useEffect12, useCallback as useCallback11, useRef as useRef10 } from "react";
3086
- function useCanvas(roomId) {
3087
- const [shapes, setShapes] = useState9([]);
3088
- const [viewports, setViewports] = useState9([]);
3089
- const [connected, setConnected] = useState9(false);
3090
- const [canWrite, setCanWrite] = useState9(false);
3091
- const wsRef = useRef10(null);
3092
- useEffect12(() => {
3093
2962
  let ws = null;
3094
2963
  let reconnectTimer = null;
3095
2964
  let alive = true;
@@ -3183,7 +3052,7 @@ function useCanvas(roomId) {
3183
3052
  wsRef.current = null;
3184
3053
  };
3185
3054
  }, [roomId]);
3186
- const sendBuilt = useCallback11(
3055
+ const sendBuilt = useCallback10(
3187
3056
  (message) => {
3188
3057
  const ws = wsRef.current;
3189
3058
  if (!ws || ws.readyState !== WebSocket.OPEN) return;
@@ -3191,51 +3060,51 @@ function useCanvas(roomId) {
3191
3060
  },
3192
3061
  []
3193
3062
  );
3194
- const sendWrite = useCallback11(
3063
+ const sendWrite = useCallback10(
3195
3064
  (message) => {
3196
3065
  if (!canWrite) return;
3197
3066
  sendBuilt(message);
3198
3067
  },
3199
3068
  [sendBuilt, canWrite]
3200
3069
  );
3201
- const addShape = useCallback11(
3070
+ const addShape = useCallback10(
3202
3071
  (shape) => sendWrite(clientBuild.canvasAdd(shape)),
3203
3072
  [sendWrite]
3204
3073
  );
3205
- const moveShape = useCallback11(
3074
+ const moveShape = useCallback10(
3206
3075
  (shapeId, x, y) => sendWrite(clientBuild.canvasMove(shapeId, x, y)),
3207
3076
  [sendWrite]
3208
3077
  );
3209
- const resizeShape = useCallback11(
3078
+ const resizeShape = useCallback10(
3210
3079
  (shapeId, width, height, x, y) => sendWrite(clientBuild.canvasResize(shapeId, width, height, x, y)),
3211
3080
  [sendWrite]
3212
3081
  );
3213
- const deleteShape = useCallback11(
3082
+ const deleteShape = useCallback10(
3214
3083
  (shapeId) => sendWrite(clientBuild.canvasDelete(shapeId)),
3215
3084
  [sendWrite]
3216
3085
  );
3217
- const updateShape = useCallback11(
3086
+ const updateShape = useCallback10(
3218
3087
  (shapeId, props) => sendWrite(clientBuild.canvasUpdate(shapeId, props)),
3219
3088
  [sendWrite]
3220
3089
  );
3221
- const setViewport = useCallback11(
3090
+ const setViewport = useCallback10(
3222
3091
  (viewport) => sendBuilt(clientBuild.canvasViewport(viewport)),
3223
3092
  [sendBuilt]
3224
3093
  );
3225
- const undo = useCallback11(() => sendWrite(clientBuild.canvasUndo()), [sendWrite]);
3226
- const redo = useCallback11(() => sendWrite(clientBuild.canvasRedo()), [sendWrite]);
3094
+ const undo = useCallback10(() => sendWrite(clientBuild.canvasUndo()), [sendWrite]);
3095
+ const redo = useCallback10(() => sendWrite(clientBuild.canvasRedo()), [sendWrite]);
3227
3096
  return { shapes, viewports, connected, canWrite, addShape, moveShape, resizeShape, deleteShape, updateShape, setViewport, undo, redo };
3228
3097
  }
3229
3098
 
3230
3099
  // src/client/storage/hooks/useCronMonitor.ts
3231
- import { useState as useState10, useEffect as useEffect13, useCallback as useCallback12, useRef as useRef11 } from "react";
3100
+ import { useState as useState9, useEffect as useEffect12, useCallback as useCallback11, useRef as useRef10 } from "react";
3232
3101
  function useCronMonitor(roomId) {
3233
- const [tasks, setTasks] = useState10([]);
3234
- const [history, setHistory] = useState10([]);
3235
- const [connected, setConnected] = useState10(false);
3236
- const [canWrite, setCanWrite] = useState10(false);
3237
- const wsRef = useRef11(null);
3238
- useEffect13(() => {
3102
+ const [tasks, setTasks] = useState9([]);
3103
+ const [history, setHistory] = useState9([]);
3104
+ const [connected, setConnected] = useState9(false);
3105
+ const [canWrite, setCanWrite] = useState9(false);
3106
+ const wsRef = useRef10(null);
3107
+ useEffect12(() => {
3239
3108
  let ws = null;
3240
3109
  let reconnectTimer = null;
3241
3110
  let alive = true;
@@ -3282,7 +3151,7 @@ function useCronMonitor(roomId) {
3282
3151
  wsRef.current = null;
3283
3152
  };
3284
3153
  }, [roomId]);
3285
- const sendWrite = useCallback12(
3154
+ const sendWrite = useCallback11(
3286
3155
  (message) => {
3287
3156
  if (!canWrite) return;
3288
3157
  const ws = wsRef.current;
@@ -3291,15 +3160,15 @@ function useCronMonitor(roomId) {
3291
3160
  },
3292
3161
  [canWrite]
3293
3162
  );
3294
- const trigger = useCallback12(
3163
+ const trigger = useCallback11(
3295
3164
  (taskName) => sendWrite(clientBuild.cronTrigger(taskName)),
3296
3165
  [sendWrite]
3297
3166
  );
3298
- const pause = useCallback12(
3167
+ const pause = useCallback11(
3299
3168
  (taskName) => sendWrite(clientBuild.cronPause(taskName)),
3300
3169
  [sendWrite]
3301
3170
  );
3302
- const resume = useCallback12(
3171
+ const resume = useCallback11(
3303
3172
  (taskName) => sendWrite(clientBuild.cronResume(taskName)),
3304
3173
  [sendWrite]
3305
3174
  );
@@ -3307,14 +3176,14 @@ function useCronMonitor(roomId) {
3307
3176
  }
3308
3177
 
3309
3178
  // src/client/storage/hooks/useJobs.ts
3310
- import { useState as useState11, useEffect as useEffect14, useCallback as useCallback13, useRef as useRef12 } from "react";
3179
+ import { useState as useState10, useEffect as useEffect13, useCallback as useCallback12, useRef as useRef11 } from "react";
3311
3180
  var ENQUEUE_TIMEOUT_MS = 1e4;
3312
3181
  function useJobs(roomId) {
3313
- const [jobs, setJobs] = useState11([]);
3314
- const [connected, setConnected] = useState11(false);
3315
- const wsRef = useRef12(null);
3316
- const pendingEnqueueRef = useRef12(/* @__PURE__ */ new Map());
3317
- useEffect14(() => {
3182
+ const [jobs, setJobs] = useState10([]);
3183
+ const [connected, setConnected] = useState10(false);
3184
+ const wsRef = useRef11(null);
3185
+ const pendingEnqueueRef = useRef11(/* @__PURE__ */ new Map());
3186
+ useEffect13(() => {
3318
3187
  let ws = null;
3319
3188
  let reconnectTimer = null;
3320
3189
  let alive = true;
@@ -3382,7 +3251,7 @@ function useJobs(roomId) {
3382
3251
  wsRef.current = null;
3383
3252
  };
3384
3253
  }, [roomId]);
3385
- const enqueue = useCallback13(
3254
+ const enqueue = useCallback12(
3386
3255
  (type, payload, options) => {
3387
3256
  return new Promise((resolve, reject) => {
3388
3257
  const ws = wsRef.current;
@@ -3413,7 +3282,7 @@ function useJobs(roomId) {
3413
3282
  },
3414
3283
  []
3415
3284
  );
3416
- const sendBuilt = useCallback13(
3285
+ const sendBuilt = useCallback12(
3417
3286
  (message) => {
3418
3287
  const ws = wsRef.current;
3419
3288
  if (!ws || ws.readyState !== WebSocket.OPEN) return;
@@ -3421,15 +3290,15 @@ function useJobs(roomId) {
3421
3290
  },
3422
3291
  []
3423
3292
  );
3424
- const getJob = useCallback13(
3293
+ const getJob = useCallback12(
3425
3294
  (jobId) => jobs.find((j) => j.id === jobId),
3426
3295
  [jobs]
3427
3296
  );
3428
- const cancel = useCallback13(
3297
+ const cancel = useCallback12(
3429
3298
  (jobId) => sendBuilt(clientBuild.jobCancel(jobId)),
3430
3299
  [sendBuilt]
3431
3300
  );
3432
- const retry = useCallback13(
3301
+ const retry = useCallback12(
3433
3302
  (jobId) => sendBuilt(clientBuild.jobRetry(jobId)),
3434
3303
  [sendBuilt]
3435
3304
  );
@@ -3437,12 +3306,12 @@ function useJobs(roomId) {
3437
3306
  }
3438
3307
 
3439
3308
  // src/client/storage/hooks/usePresenceRoom.ts
3440
- import { useState as useState12, useEffect as useEffect15, useCallback as useCallback14, useRef as useRef13 } from "react";
3309
+ import { useState as useState11, useEffect as useEffect14, useCallback as useCallback13, useRef as useRef12 } from "react";
3441
3310
  function usePresenceRoom(scopeId) {
3442
- const [peers, setPeers] = useState12([]);
3443
- const [connected, setConnected] = useState12(false);
3444
- const wsRef = useRef13(null);
3445
- useEffect15(() => {
3311
+ const [peers, setPeers] = useState11([]);
3312
+ const [connected, setConnected] = useState11(false);
3313
+ const wsRef = useRef12(null);
3314
+ useEffect14(() => {
3446
3315
  let ws = null;
3447
3316
  let reconnectTimer = null;
3448
3317
  let alive = true;
@@ -3503,7 +3372,7 @@ function usePresenceRoom(scopeId) {
3503
3372
  wsRef.current = null;
3504
3373
  };
3505
3374
  }, [scopeId]);
3506
- const updateState = useCallback14((state) => {
3375
+ const updateState = useCallback13((state) => {
3507
3376
  const ws = wsRef.current;
3508
3377
  if (!ws || ws.readyState !== WebSocket.OPEN) return;
3509
3378
  ws.send(encode(clientBuild.presenceUpdate(state)));
@@ -3519,7 +3388,7 @@ function toConnectionStatus(queryStatus) {
3519
3388
  }
3520
3389
 
3521
3390
  // src/client/storage/useR2Files.ts
3522
- import { useCallback as useCallback15, useState as useState13, useMemo as useMemo11 } from "react";
3391
+ import { useCallback as useCallback14, useState as useState12, useMemo as useMemo11 } from "react";
3523
3392
 
3524
3393
  // src/shared/app-files.ts
3525
3394
  var MAX_APP_FILE_BYTES = 1024 * 1024 * 1024;
@@ -3538,13 +3407,21 @@ function planUploadParts(totalBytes, partSize) {
3538
3407
  }
3539
3408
  return parts;
3540
3409
  }
3541
- var APP_STORAGE_LIMIT_BYTES = {
3410
+ var GIB = 1024 * 1024 * 1024;
3411
+ var ACCOUNT_STORAGE_LIMIT_BYTES = {
3542
3412
  test: 0,
3543
- free: 128 * 1024 * 1024,
3544
- starter: 512 * 1024 * 1024,
3545
- premium: 2 * 1024 * 1024 * 1024,
3546
- admin: 10 * 1024 * 1024 * 1024
3413
+ free: 1 * GIB,
3414
+ starter: 10 * GIB,
3415
+ premium: 30 * GIB,
3416
+ admin: 100 * GIB
3547
3417
  };
3418
+ function storageLimitForTier(tier) {
3419
+ if (tier && Object.hasOwn(ACCOUNT_STORAGE_LIMIT_BYTES, tier)) {
3420
+ return ACCOUNT_STORAGE_LIMIT_BYTES[tier];
3421
+ }
3422
+ return ACCOUNT_STORAGE_LIMIT_BYTES.free;
3423
+ }
3424
+ var REPO_STORE_LIMIT_BYTES = 256 * 1024 * 1024;
3548
3425
  var MAX_DEPLOY_ASSET_FILE_BYTES = 25 * 1024 * 1024;
3549
3426
  function formatBytes(bytes) {
3550
3427
  if (bytes >= 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GiB`;
@@ -3651,21 +3528,21 @@ async function uploadInParts(file, name, scopeParams, authHeaders, onProgress) {
3651
3528
  }
3652
3529
  }
3653
3530
  function useR2Files(options) {
3654
- const [isUploading, setIsUploading] = useState13(false);
3531
+ const [isUploading, setIsUploading] = useState12(false);
3655
3532
  const scope = options?.scope ?? "self";
3656
3533
  const scopeParams = useMemo11(() => {
3657
3534
  const params = new URLSearchParams();
3658
3535
  params.set("scope", scope);
3659
3536
  return params.toString();
3660
3537
  }, [scope]);
3661
- const authHeaders = useCallback15(async () => {
3538
+ const authHeaders = useCallback14(async () => {
3662
3539
  const token = await getAuthToken();
3663
3540
  if (token) {
3664
3541
  return { Authorization: `Bearer ${token}` };
3665
3542
  }
3666
3543
  return {};
3667
3544
  }, []);
3668
- const upload = useCallback15(
3545
+ const upload = useCallback14(
3669
3546
  async (file, name, options2) => {
3670
3547
  setIsUploading(true);
3671
3548
  try {
@@ -3694,7 +3571,7 @@ function useR2Files(options) {
3694
3571
  },
3695
3572
  [scopeParams, authHeaders]
3696
3573
  );
3697
- const uploadBase64 = useCallback15(
3574
+ const uploadBase64 = useCallback14(
3698
3575
  async (base64Data, name, mimeType) => {
3699
3576
  setIsUploading(true);
3700
3577
  try {
@@ -3718,7 +3595,7 @@ function useR2Files(options) {
3718
3595
  },
3719
3596
  [scopeParams, authHeaders]
3720
3597
  );
3721
- const deleteFile = useCallback15(
3598
+ const deleteFile = useCallback14(
3722
3599
  async (fileOrKey) => {
3723
3600
  const { key } = resolveFile(fileOrKey);
3724
3601
  try {
@@ -3734,7 +3611,7 @@ function useR2Files(options) {
3734
3611
  },
3735
3612
  [scopeParams, authHeaders]
3736
3613
  );
3737
- const list = useCallback15(
3614
+ const list = useCallback14(
3738
3615
  async (prefix) => {
3739
3616
  try {
3740
3617
  const headers = await authHeaders();
@@ -3749,7 +3626,7 @@ function useR2Files(options) {
3749
3626
  },
3750
3627
  [scopeParams, authHeaders]
3751
3628
  );
3752
- const downloadFile = useCallback15(
3629
+ const downloadFile = useCallback14(
3753
3630
  async (fileOrKey, fileName) => {
3754
3631
  const { key, name: infoName } = resolveFile(fileOrKey);
3755
3632
  try {
@@ -3779,7 +3656,7 @@ function useR2Files(options) {
3779
3656
  },
3780
3657
  [scopeParams, authHeaders]
3781
3658
  );
3782
- const readFile = useCallback15(
3659
+ const readFile = useCallback14(
3783
3660
  async (fileOrKey) => {
3784
3661
  const { key } = resolveFile(fileOrKey);
3785
3662
  const headers = await authHeaders();
@@ -3792,7 +3669,7 @@ function useR2Files(options) {
3792
3669
  },
3793
3670
  [scopeParams, authHeaders]
3794
3671
  );
3795
- const getUrl = useCallback15(
3672
+ const getUrl = useCallback14(
3796
3673
  (fileOrKey) => {
3797
3674
  const { key } = resolveFile(fileOrKey);
3798
3675
  return `/api/files/${encodeKeyPath(key)}?${scopeParams}`;
@@ -3838,7 +3715,7 @@ function getUserColor(userId, palette = DEFAULT_USER_COLORS) {
3838
3715
  }
3839
3716
 
3840
3717
  // src/client/messaging/useMessages.ts
3841
- import { useCallback as useCallback16, useMemo as useMemo12 } from "react";
3718
+ import { useCallback as useCallback15, useMemo as useMemo12 } from "react";
3842
3719
  function useMessages(channelId, options) {
3843
3720
  const where = useMemo12(() => {
3844
3721
  if (!channelId) return { channelId: "__none__" };
@@ -3855,7 +3732,7 @@ function useMessages(channelId, options) {
3855
3732
  orderDir: "asc"
3856
3733
  });
3857
3734
  const { create, put, remove: removeMutation } = useMutations("messages");
3858
- const send = useCallback16(
3735
+ const send = useCallback15(
3859
3736
  (content, parentMessageId) => {
3860
3737
  if (!channelId || !user) return;
3861
3738
  const data = { channelId, content, authorId: user.id, edited: false };
@@ -3864,19 +3741,19 @@ function useMessages(channelId, options) {
3864
3741
  },
3865
3742
  [channelId, user, create]
3866
3743
  );
3867
- const edit = useCallback16(
3744
+ const edit = useCallback15(
3868
3745
  (messageId, newContent) => {
3869
3746
  put(messageId, { content: newContent, edited: true });
3870
3747
  },
3871
3748
  [put]
3872
3749
  );
3873
- const remove = useCallback16(
3750
+ const remove = useCallback15(
3874
3751
  (messageId) => {
3875
3752
  removeMutation(messageId);
3876
3753
  },
3877
3754
  [removeMutation]
3878
3755
  );
3879
- const softDelete = useCallback16(
3756
+ const softDelete = useCallback15(
3880
3757
  (messageId) => {
3881
3758
  put(messageId, { deleted: true });
3882
3759
  },
@@ -3894,7 +3771,7 @@ function useMessages(channelId, options) {
3894
3771
  }
3895
3772
 
3896
3773
  // src/client/messaging/useChannels.ts
3897
- import { useCallback as useCallback17 } from "react";
3774
+ import { useCallback as useCallback16 } from "react";
3898
3775
  function useChannels() {
3899
3776
  const { user } = useUser();
3900
3777
  const { records, status, error } = useQuery("channels", {
@@ -3902,7 +3779,7 @@ function useChannels() {
3902
3779
  orderDir: "asc"
3903
3780
  });
3904
3781
  const { create: createMutation, put, remove } = useMutations("channels");
3905
- const create = useCallback17(
3782
+ const create = useCallback16(
3906
3783
  (data) => {
3907
3784
  return createMutation({
3908
3785
  name: data.name,
@@ -3914,13 +3791,13 @@ function useChannels() {
3914
3791
  },
3915
3792
  [user, createMutation]
3916
3793
  );
3917
- const archive = useCallback17(
3794
+ const archive = useCallback16(
3918
3795
  (channelId) => {
3919
3796
  put(channelId, { archived: true });
3920
3797
  },
3921
3798
  [put]
3922
3799
  );
3923
- const update = useCallback17(
3800
+ const update = useCallback16(
3924
3801
  (channelId, data) => {
3925
3802
  put(channelId, data);
3926
3803
  },
@@ -3938,14 +3815,14 @@ function useChannels() {
3938
3815
  }
3939
3816
 
3940
3817
  // src/client/messaging/useReactions.ts
3941
- import { useCallback as useCallback18 } from "react";
3818
+ import { useCallback as useCallback17 } from "react";
3942
3819
  function useReactions(channelId) {
3943
3820
  const { user } = useUser();
3944
3821
  const { records, status, error } = useQuery("reactions", {
3945
3822
  where: channelId ? { channelId } : { channelId: "__none__" }
3946
3823
  });
3947
3824
  const { create, remove: removeMutation } = useMutations("reactions");
3948
- const getReactionsForMessage = useCallback18(
3825
+ const getReactionsForMessage = useCallback17(
3949
3826
  (messageId) => {
3950
3827
  const messageReactions = records.filter((r) => r.data.messageId === messageId);
3951
3828
  const grouped = /* @__PURE__ */ new Map();
@@ -3962,7 +3839,7 @@ function useReactions(channelId) {
3962
3839
  },
3963
3840
  [records, user]
3964
3841
  );
3965
- const toggle = useCallback18(
3842
+ const toggle = useCallback17(
3966
3843
  (messageId, emoji) => {
3967
3844
  if (!channelId || !user) return;
3968
3845
  const existing = records.find(
@@ -3980,20 +3857,20 @@ function useReactions(channelId) {
3980
3857
  }
3981
3858
 
3982
3859
  // src/client/messaging/useChannelMembers.ts
3983
- import { useCallback as useCallback19 } from "react";
3860
+ import { useCallback as useCallback18 } from "react";
3984
3861
  function useChannelMembers(channelId) {
3985
3862
  const { user } = useUser();
3986
3863
  const { records, status, error } = useQuery("channel-members", {
3987
3864
  where: channelId ? { channelId } : { channelId: "__none__" }
3988
3865
  });
3989
3866
  const { create, remove: removeMutation } = useMutations("channel-members");
3990
- const join = useCallback19(() => {
3867
+ const join = useCallback18(() => {
3991
3868
  if (!channelId || !user) return;
3992
3869
  const existing = records.find((r) => r.data.userId === user.id);
3993
3870
  if (existing) return;
3994
3871
  create({ channelId, userId: user.id, joinedAt: (/* @__PURE__ */ new Date()).toISOString() });
3995
3872
  }, [channelId, user, records, create]);
3996
- const leave = useCallback19(() => {
3873
+ const leave = useCallback18(() => {
3997
3874
  if (!channelId || !user) return;
3998
3875
  const membership = records.find((r) => r.data.userId === user.id);
3999
3876
  if (membership) removeMutation(membership.recordId);
@@ -4003,14 +3880,14 @@ function useChannelMembers(channelId) {
4003
3880
  }
4004
3881
 
4005
3882
  // src/client/messaging/useReadReceipts.ts
4006
- import { useCallback as useCallback20 } from "react";
3883
+ import { useCallback as useCallback19 } from "react";
4007
3884
  function useReadReceipts() {
4008
3885
  const { user } = useUser();
4009
3886
  const { records, status, error } = useQuery("read-receipts", {
4010
3887
  where: user ? { userId: user.id } : { userId: "__none__" }
4011
3888
  });
4012
3889
  const { create, put } = useMutations("read-receipts");
4013
- const markAsRead = useCallback20(
3890
+ const markAsRead = useCallback19(
4014
3891
  (channelId) => {
4015
3892
  if (!user) return;
4016
3893
  const existing = records.find((r) => r.data.channelId === channelId);
@@ -4023,7 +3900,7 @@ function useReadReceipts() {
4023
3900
  },
4024
3901
  [user, records, create, put]
4025
3902
  );
4026
- const getUnreadCount = useCallback20(
3903
+ const getUnreadCount = useCallback19(
4027
3904
  (channelId, messages) => {
4028
3905
  const receipt = records.find((r) => r.data.channelId === channelId);
4029
3906
  if (!receipt) return messages.length;
@@ -4036,7 +3913,7 @@ function useReadReceipts() {
4036
3913
  }
4037
3914
 
4038
3915
  // src/client/messaging/useConversation.ts
4039
- import { useCallback as useCallback21, useMemo as useMemo13 } from "react";
3916
+ import { useCallback as useCallback20, useMemo as useMemo13 } from "react";
4040
3917
  function useConversation(opts) {
4041
3918
  const { user } = useUser();
4042
3919
  const { ready } = useRecordContext();
@@ -4045,7 +3922,7 @@ function useConversation(opts) {
4045
3922
  const { records: members } = useQuery("conv_members");
4046
3923
  const messageMut = useMutations("conv_messages");
4047
3924
  const reactionMut = useMutations("conv_reactions");
4048
- const send = useCallback21(
3925
+ const send = useCallback20(
4049
3926
  (content, parentMessageId, messageType, metadata) => {
4050
3927
  messageMut.create({
4051
3928
  Content: content,
@@ -4060,7 +3937,7 @@ function useConversation(opts) {
4060
3937
  // eslint-disable-next-line react-hooks/exhaustive-deps -- depend on the precise opts?.onMessageSent callback, not the whole opts object, to avoid recreating send when unrelated opts fields change
4061
3938
  [messageMut, user?.id, opts?.onMessageSent]
4062
3939
  );
4063
- const edit = useCallback21(
3940
+ const edit = useCallback20(
4064
3941
  (recordId, content) => {
4065
3942
  const existing = allMessages.find((m) => m.recordId === recordId);
4066
3943
  if (!existing) return;
@@ -4068,7 +3945,7 @@ function useConversation(opts) {
4068
3945
  },
4069
3946
  [messageMut, allMessages]
4070
3947
  );
4071
- const remove = useCallback21(
3948
+ const remove = useCallback20(
4072
3949
  (recordId) => {
4073
3950
  const existing = allMessages.find((m) => m.recordId === recordId);
4074
3951
  if (!existing) return;
@@ -4081,7 +3958,7 @@ function useConversation(opts) {
4081
3958
  },
4082
3959
  [messageMut, allMessages]
4083
3960
  );
4084
- const toggleReaction = useCallback21(
3961
+ const toggleReaction = useCallback20(
4085
3962
  (messageId, emoji) => {
4086
3963
  const existing = allReactions.find(
4087
3964
  (r) => r.data.MessageId === messageId && r.data.Emoji === emoji && r.data.UserId === user?.id
@@ -4214,7 +4091,7 @@ function parseMessageMetadata(raw) {
4214
4091
  }
4215
4092
 
4216
4093
  // src/client/directory/useConversations.ts
4217
- import { useCallback as useCallback22, useMemo as useMemo14, useRef as useRef14 } from "react";
4094
+ import { useCallback as useCallback21, useMemo as useMemo14, useRef as useRef13 } from "react";
4218
4095
  var defaultConvFields = {
4219
4096
  Visibility: "public",
4220
4097
  Status: "active",
@@ -4229,7 +4106,7 @@ function useConversations() {
4229
4106
  const stateMut = useMutations("conversation_state");
4230
4107
  const { user } = useUser();
4231
4108
  const ready = status === "ready";
4232
- const recentCreationsRef = useRef14(/* @__PURE__ */ new Map());
4109
+ const recentCreationsRef = useRef13(/* @__PURE__ */ new Map());
4233
4110
  for (const [id] of recentCreationsRef.current) {
4234
4111
  if (conversations.find((c) => c.recordId === id)) {
4235
4112
  recentCreationsRef.current.delete(id);
@@ -4251,13 +4128,13 @@ function useConversations() {
4251
4128
  () => new Set(stateRecords.filter((r) => r.data.Archived).map((r) => r.data.ConversationId)),
4252
4129
  [stateRecords]
4253
4130
  );
4254
- const getConversationState = useCallback22(
4131
+ const getConversationState = useCallback21(
4255
4132
  (conversationId) => {
4256
4133
  return stateRecords.find((r) => r.data.ConversationId === conversationId)?.data;
4257
4134
  },
4258
4135
  [stateRecords]
4259
4136
  );
4260
- const createChannel = useCallback22(
4137
+ const createChannel = useCallback21(
4261
4138
  async (name, description) => {
4262
4139
  const existing = conversations.find((r) => r.data.Name === name && r.data.Type !== "dm");
4263
4140
  if (existing) return existing.recordId;
@@ -4277,7 +4154,7 @@ function useConversations() {
4277
4154
  },
4278
4155
  [create, user?.id, conversations]
4279
4156
  );
4280
- const createDM = useCallback22(
4157
+ const createDM = useCallback21(
4281
4158
  async (otherUserId) => {
4282
4159
  if (!user?.id) return null;
4283
4160
  const hash = [user.id, otherUserId].sort().join(":");
@@ -4305,7 +4182,7 @@ function useConversations() {
4305
4182
  },
4306
4183
  [create, user?.id, conversations]
4307
4184
  );
4308
- const createGroupDM = useCallback22(
4185
+ const createGroupDM = useCallback21(
4309
4186
  async (participantIds) => {
4310
4187
  if (!user?.id) return null;
4311
4188
  const allIds = [.../* @__PURE__ */ new Set([user.id, ...participantIds])];
@@ -4335,14 +4212,14 @@ function useConversations() {
4335
4212
  },
4336
4213
  [create, user?.id, conversations]
4337
4214
  );
4338
- const lookupByName = useCallback22(
4215
+ const lookupByName = useCallback21(
4339
4216
  (name) => {
4340
4217
  const found = conversations.find((r) => r.data.Name === name);
4341
4218
  return found?.recordId ?? null;
4342
4219
  },
4343
4220
  [conversations]
4344
4221
  );
4345
- const updateLastMessage = useCallback22(
4222
+ const updateLastMessage = useCallback21(
4346
4223
  (conversationId, preview, authorId) => {
4347
4224
  const conv = conversations.find((c) => c.recordId === conversationId);
4348
4225
  const baseData = conv?.data ?? recentCreationsRef.current.get(conversationId);
@@ -4361,7 +4238,7 @@ function useConversations() {
4361
4238
  },
4362
4239
  [put, conversations]
4363
4240
  );
4364
- const upsertState = useCallback22(
4241
+ const upsertState = useCallback21(
4365
4242
  (conversationId, partial) => {
4366
4243
  if (!user?.id) return;
4367
4244
  const existing = stateRecords.find(
@@ -4383,7 +4260,7 @@ function useConversations() {
4383
4260
  },
4384
4261
  [stateMut, stateRecords, user?.id]
4385
4262
  );
4386
- const markRead = useCallback22(
4263
+ const markRead = useCallback21(
4387
4264
  (conversationId) => {
4388
4265
  const conv = conversations.find((c) => c.recordId === conversationId);
4389
4266
  const msgCount = conv?.data.MessageCount ?? recentCreationsRef.current.get(conversationId)?.MessageCount ?? 0;
@@ -4394,32 +4271,32 @@ function useConversations() {
4394
4271
  },
4395
4272
  [upsertState, conversations]
4396
4273
  );
4397
- const toggleStar = useCallback22(
4274
+ const toggleStar = useCallback21(
4398
4275
  (conversationId) => {
4399
4276
  const isStarred = starredSet.has(conversationId);
4400
4277
  upsertState(conversationId, { Starred: isStarred ? 0 : 1 });
4401
4278
  },
4402
4279
  [upsertState, starredSet]
4403
4280
  );
4404
- const setArchived = useCallback22(
4281
+ const setArchived = useCallback21(
4405
4282
  (conversationId, archived) => {
4406
4283
  upsertState(conversationId, { Archived: archived ? 1 : 0 });
4407
4284
  },
4408
4285
  [upsertState]
4409
4286
  );
4410
- const setTrashed = useCallback22(
4287
+ const setTrashed = useCallback21(
4411
4288
  (conversationId, trashed) => {
4412
4289
  upsertState(conversationId, { Trashed: trashed ? 1 : 0 });
4413
4290
  },
4414
4291
  [upsertState]
4415
4292
  );
4416
- const setLabels = useCallback22(
4293
+ const setLabels = useCallback21(
4417
4294
  (conversationId, labels) => {
4418
4295
  upsertState(conversationId, { Labels: JSON.stringify(labels) });
4419
4296
  },
4420
4297
  [upsertState]
4421
4298
  );
4422
- const setFolder = useCallback22(
4299
+ const setFolder = useCallback21(
4423
4300
  (conversationId, folder) => {
4424
4301
  upsertState(conversationId, { Folder: folder });
4425
4302
  },
@@ -4449,7 +4326,7 @@ function useConversations() {
4449
4326
  }
4450
4327
 
4451
4328
  // src/client/directory/useCommunities.ts
4452
- import { useCallback as useCallback23, useMemo as useMemo15 } from "react";
4329
+ import { useCallback as useCallback22, useMemo as useMemo15 } from "react";
4453
4330
  function useCommunities() {
4454
4331
  const { records: communities, status } = useQuery("communities");
4455
4332
  const communityMut = useMutations("communities");
@@ -4472,7 +4349,7 @@ function useCommunities() {
4472
4349
  ),
4473
4350
  [memberships, user?.id]
4474
4351
  );
4475
- const createCommunity = useCallback23(
4352
+ const createCommunity = useCallback22(
4476
4353
  async (name, opts) => {
4477
4354
  const existing = communities.find((c) => c.data.Name === name);
4478
4355
  if (existing) return existing.recordId;
@@ -4491,7 +4368,7 @@ function useCommunities() {
4491
4368
  },
4492
4369
  [communityMut, user?.id, communities]
4493
4370
  );
4494
- const updateCommunity = useCallback23(
4371
+ const updateCommunity = useCallback22(
4495
4372
  (communityId, updates) => {
4496
4373
  const existing = communities.find((c) => c.recordId === communityId);
4497
4374
  if (!existing) return;
@@ -4499,7 +4376,7 @@ function useCommunities() {
4499
4376
  },
4500
4377
  [communityMut, communities]
4501
4378
  );
4502
- const joinCommunity = useCallback23(
4379
+ const joinCommunity = useCallback22(
4503
4380
  async (communityId, userName) => {
4504
4381
  if (!user?.id) return null;
4505
4382
  const existing = memberships.find(
@@ -4517,7 +4394,7 @@ function useCommunities() {
4517
4394
  },
4518
4395
  [membershipMut, memberships, user?.id]
4519
4396
  );
4520
- const leaveCommunity = useCallback23(
4397
+ const leaveCommunity = useCallback22(
4521
4398
  (communityId) => {
4522
4399
  if (!user?.id) return;
4523
4400
  const membership = memberships.find(
@@ -4529,13 +4406,13 @@ function useCommunities() {
4529
4406
  },
4530
4407
  [membershipMut, memberships, user?.id]
4531
4408
  );
4532
- const getMembersOf = useCallback23(
4409
+ const getMembersOf = useCallback22(
4533
4410
  (communityId) => {
4534
4411
  return membershipMap.get(communityId) ?? [];
4535
4412
  },
4536
4413
  [membershipMap]
4537
4414
  );
4538
- const lookupByName = useCallback23(
4415
+ const lookupByName = useCallback22(
4539
4416
  (name) => {
4540
4417
  const found = communities.find((c) => c.data.Name === name);
4541
4418
  return found?.recordId ?? null;
@@ -4557,14 +4434,14 @@ function useCommunities() {
4557
4434
  }
4558
4435
 
4559
4436
  // src/client/directory/usePosts.ts
4560
- import { useCallback as useCallback24 } from "react";
4437
+ import { useCallback as useCallback23 } from "react";
4561
4438
  function usePosts(opts) {
4562
4439
  const { records: allPosts, status } = useQuery("posts");
4563
4440
  const postMut = useMutations("posts");
4564
4441
  const { user } = useUser();
4565
4442
  const ready = status === "ready";
4566
4443
  const posts = opts?.communityId ? allPosts.filter((p) => p.data.CommunityId === opts.communityId) : allPosts;
4567
- const createPost = useCallback24(
4444
+ const createPost = useCallback23(
4568
4445
  async (data) => {
4569
4446
  const recordId = await postMut.create({
4570
4447
  Title: data.title,
@@ -4582,7 +4459,7 @@ function usePosts(opts) {
4582
4459
  },
4583
4460
  [postMut, user?.id]
4584
4461
  );
4585
- const updatePost = useCallback24(
4462
+ const updatePost = useCallback23(
4586
4463
  (postId, updates) => {
4587
4464
  const existing = allPosts.find((p) => p.recordId === postId);
4588
4465
  if (!existing) return;
@@ -4590,13 +4467,13 @@ function usePosts(opts) {
4590
4467
  },
4591
4468
  [postMut, allPosts]
4592
4469
  );
4593
- const deletePost = useCallback24(
4470
+ const deletePost = useCallback23(
4594
4471
  (postId) => {
4595
4472
  postMut.remove(postId);
4596
4473
  },
4597
4474
  [postMut]
4598
4475
  );
4599
- const setConversationId = useCallback24(
4476
+ const setConversationId = useCallback23(
4600
4477
  (postId, conversationId) => {
4601
4478
  updatePost(postId, { ConversationId: conversationId });
4602
4479
  },
@@ -4613,7 +4490,7 @@ function usePosts(opts) {
4613
4490
  }
4614
4491
 
4615
4492
  // src/client/theme/DeepSpaceThemeProvider.tsx
4616
- import { useEffect as useEffect16 } from "react";
4493
+ import { useEffect as useEffect15 } from "react";
4617
4494
 
4618
4495
  // src/client/theme/applyTheme.ts
4619
4496
  function mix(color, pct, base = "transparent") {
@@ -4926,7 +4803,7 @@ function DeepSpaceThemeProvider({
4926
4803
  children,
4927
4804
  theme
4928
4805
  }) {
4929
- useEffect16(() => {
4806
+ useEffect15(() => {
4930
4807
  const root = document.documentElement;
4931
4808
  const config = theme ?? readThemeFromDOM(root);
4932
4809
  applyDeepSpaceTheme(config, root);
@@ -4935,12 +4812,12 @@ function DeepSpaceThemeProvider({
4935
4812
  }
4936
4813
 
4937
4814
  // src/client/theme/useIsDarkTheme.ts
4938
- import { useState as useState14, useEffect as useEffect17 } from "react";
4815
+ import { useState as useState13, useEffect as useEffect16 } from "react";
4939
4816
  function useIsDarkTheme() {
4940
- const [isDark, setIsDark] = useState14(
4817
+ const [isDark, setIsDark] = useState13(
4941
4818
  () => typeof document === "undefined" || document.documentElement.dataset.uiTheme !== "light"
4942
4819
  );
4943
- useEffect17(() => {
4820
+ useEffect16(() => {
4944
4821
  const update = () => {
4945
4822
  setIsDark(document.documentElement.dataset.uiTheme !== "light");
4946
4823
  };
@@ -4952,7 +4829,7 @@ function useIsDarkTheme() {
4952
4829
  }
4953
4830
 
4954
4831
  // src/client/platform/PlatformProvider.tsx
4955
- import { createContext as createContext3, useContext as useContext5, useState as useState15, useEffect as useEffect18, useRef as useRef15, useCallback as useCallback25 } from "react";
4832
+ import { createContext as createContext3, useContext as useContext5, useState as useState14, useEffect as useEffect17, useRef as useRef14, useCallback as useCallback24 } from "react";
4956
4833
  import { jsx as jsx9 } from "react/jsx-runtime";
4957
4834
  var PlatformContext = createContext3(null);
4958
4835
  function usePlatform() {
@@ -4962,14 +4839,14 @@ function usePlatform() {
4962
4839
  }
4963
4840
  function useInbox() {
4964
4841
  const { inbox, subscribeInbox } = usePlatform();
4965
- useEffect18(() => subscribeInbox(), [subscribeInbox]);
4842
+ useEffect17(() => subscribeInbox(), [subscribeInbox]);
4966
4843
  return inbox;
4967
4844
  }
4968
4845
  function PlatformProvider({ children }) {
4969
- const [inbox, setInbox] = useState15([]);
4970
- const inboxSubscribers = useRef15(0);
4971
- const [inboxActive, setInboxActive] = useState15(false);
4972
- const subscribeInbox = useCallback25(() => {
4846
+ const [inbox, setInbox] = useState14([]);
4847
+ const inboxSubscribers = useRef14(0);
4848
+ const [inboxActive, setInboxActive] = useState14(false);
4849
+ const subscribeInbox = useCallback24(() => {
4973
4850
  inboxSubscribers.current++;
4974
4851
  if (inboxSubscribers.current === 1) setInboxActive(true);
4975
4852
  return () => {
@@ -4977,7 +4854,7 @@ function PlatformProvider({ children }) {
4977
4854
  if (inboxSubscribers.current === 0) setInboxActive(false);
4978
4855
  };
4979
4856
  }, []);
4980
- useEffect18(() => {
4857
+ useEffect17(() => {
4981
4858
  if (!inboxActive) return;
4982
4859
  let mounted = true;
4983
4860
  let ws = null;
@@ -5038,7 +4915,7 @@ function PlatformProvider({ children }) {
5038
4915
  setInbox([]);
5039
4916
  };
5040
4917
  }, [inboxActive]);
5041
- const platformFetch = useCallback25(async (path, init) => {
4918
+ const platformFetch = useCallback24(async (path, init) => {
5042
4919
  const token = await getAuthToken();
5043
4920
  const headers = new Headers(init?.headers);
5044
4921
  if (token) headers.set("Authorization", `Bearer ${token}`);
@@ -5049,28 +4926,28 @@ function PlatformProvider({ children }) {
5049
4926
  }
5050
4927
 
5051
4928
  // src/client/platform/usePlatformWS.ts
5052
- import { useState as useState16, useEffect as useEffect19, useRef as useRef16 } from "react";
4929
+ import { useState as useState15, useEffect as useEffect18, useRef as useRef15 } from "react";
5053
4930
  var MAX_RECONNECT_DELAY = 1e4;
5054
4931
  var BASE_RECONNECT_DELAY = 500;
5055
4932
  function usePlatformWS(options) {
5056
4933
  const { path, scopeId, initialState, onMessage } = options;
5057
- const wsRef = useRef16(null);
5058
- const pingIntervalRef = useRef16(null);
5059
- const [state, setState] = useState16(initialState);
5060
- const reconnectAttemptRef = useRef16(0);
5061
- const reconnectTimerRef = useRef16(null);
5062
- const mountedRef = useRef16(true);
5063
- const onMessageRef = useRef16(onMessage);
4934
+ const wsRef = useRef15(null);
4935
+ const pingIntervalRef = useRef15(null);
4936
+ const [state, setState] = useState15(initialState);
4937
+ const reconnectAttemptRef = useRef15(0);
4938
+ const reconnectTimerRef = useRef15(null);
4939
+ const mountedRef = useRef15(true);
4940
+ const onMessageRef = useRef15(onMessage);
5064
4941
  onMessageRef.current = onMessage;
5065
- const initialStateRef = useRef16(initialState);
4942
+ const initialStateRef = useRef15(initialState);
5066
4943
  initialStateRef.current = initialState;
5067
- useEffect19(() => {
4944
+ useEffect18(() => {
5068
4945
  mountedRef.current = true;
5069
4946
  return () => {
5070
4947
  mountedRef.current = false;
5071
4948
  };
5072
4949
  }, []);
5073
- useEffect19(() => {
4950
+ useEffect18(() => {
5074
4951
  if (!scopeId) return;
5075
4952
  setState(initialStateRef.current);
5076
4953
  reconnectAttemptRef.current = 0;
@@ -5129,7 +5006,7 @@ function usePlatformWS(options) {
5129
5006
  wsRef.current = null;
5130
5007
  };
5131
5008
  }, [scopeId, path]);
5132
- const send = useRef16((msg) => {
5009
+ const send = useRef15((msg) => {
5133
5010
  wsRef.current?.send(JSON.stringify(msg));
5134
5011
  }).current;
5135
5012
  return { state, send };
@@ -5240,27 +5117,27 @@ var integration = {
5240
5117
  };
5241
5118
 
5242
5119
  // src/client/voice/useVoiceAgent.ts
5243
- import { useCallback as useCallback26, useEffect as useEffect20, useRef as useRef17, useState as useState17 } from "react";
5120
+ import { useCallback as useCallback25, useEffect as useEffect19, useRef as useRef16, useState as useState16 } from "react";
5244
5121
  var OPENAI_REALTIME_BASE = "https://api.openai.com/v1";
5245
5122
  var ZERO_USAGE = { inputAudioTokens: 0, outputAudioTokens: 0, inputTextTokens: 0, outputTextTokens: 0 };
5246
5123
  function useVoiceAgent(options = {}) {
5247
- const [status, setStatus] = useState17("idle");
5248
- const [isMuted, setIsMuted] = useState17(false);
5249
- const [isAgentSpeaking, setIsAgentSpeaking] = useState17(false);
5250
- const [transcript, setTranscript] = useState17([]);
5251
- const [error, setError] = useState17(null);
5252
- const pcRef = useRef17(null);
5253
- const dcRef = useRef17(null);
5254
- const streamRef = useRef17(null);
5255
- const audioRef = useRef17(null);
5256
- const timerRef = useRef17(null);
5257
- const sessionIdRef = useRef17(null);
5258
- const liveStartRef = useRef17(null);
5259
- const settledRef = useRef17(false);
5260
- const usageRef = useRef17({ ...ZERO_USAGE });
5261
- const optsRef = useRef17(options);
5124
+ const [status, setStatus] = useState16("idle");
5125
+ const [isMuted, setIsMuted] = useState16(false);
5126
+ const [isAgentSpeaking, setIsAgentSpeaking] = useState16(false);
5127
+ const [transcript, setTranscript] = useState16([]);
5128
+ const [error, setError] = useState16(null);
5129
+ const pcRef = useRef16(null);
5130
+ const dcRef = useRef16(null);
5131
+ const streamRef = useRef16(null);
5132
+ const audioRef = useRef16(null);
5133
+ const timerRef = useRef16(null);
5134
+ const sessionIdRef = useRef16(null);
5135
+ const liveStartRef = useRef16(null);
5136
+ const settledRef = useRef16(false);
5137
+ const usageRef = useRef16({ ...ZERO_USAGE });
5138
+ const optsRef = useRef16(options);
5262
5139
  optsRef.current = options;
5263
- const settle = useCallback26(async () => {
5140
+ const settle = useCallback25(async () => {
5264
5141
  const sessionId = sessionIdRef.current;
5265
5142
  if (!sessionId || settledRef.current) return;
5266
5143
  settledRef.current = true;
@@ -5274,7 +5151,7 @@ function useVoiceAgent(options = {}) {
5274
5151
  } catch {
5275
5152
  }
5276
5153
  }, []);
5277
- const cleanup = useCallback26(() => {
5154
+ const cleanup = useCallback25(() => {
5278
5155
  if (timerRef.current) {
5279
5156
  clearTimeout(timerRef.current);
5280
5157
  timerRef.current = null;
@@ -5298,13 +5175,13 @@ function useVoiceAgent(options = {}) {
5298
5175
  streamRef.current = null;
5299
5176
  audioRef.current = null;
5300
5177
  }, []);
5301
- const stop = useCallback26(async () => {
5178
+ const stop = useCallback25(async () => {
5302
5179
  cleanup();
5303
5180
  await settle();
5304
5181
  setIsAgentSpeaking(false);
5305
5182
  setStatus((s) => s === "error" ? s : "ended");
5306
5183
  }, [cleanup, settle]);
5307
- const appendTranscript = useCallback26((role, delta) => {
5184
+ const appendTranscript = useCallback25((role, delta) => {
5308
5185
  if (!delta) return;
5309
5186
  setTranscript((prev) => {
5310
5187
  const last = prev[prev.length - 1];
@@ -5312,7 +5189,7 @@ function useVoiceAgent(options = {}) {
5312
5189
  return [...prev, { role, content: delta }];
5313
5190
  });
5314
5191
  }, []);
5315
- const handleToolCall = useCallback26(async (item) => {
5192
+ const handleToolCall = useCallback25(async (item) => {
5316
5193
  const onToolCall = optsRef.current.onToolCall;
5317
5194
  let output = null;
5318
5195
  if (onToolCall && item.name) {
@@ -5338,7 +5215,7 @@ function useVoiceAgent(options = {}) {
5338
5215
  );
5339
5216
  dc.send(JSON.stringify({ type: "response.create" }));
5340
5217
  }, []);
5341
- const handleEvent = useCallback26(
5218
+ const handleEvent = useCallback25(
5342
5219
  (raw) => {
5343
5220
  if (typeof raw !== "string") return;
5344
5221
  let ev;
@@ -5378,7 +5255,7 @@ function useVoiceAgent(options = {}) {
5378
5255
  },
5379
5256
  [appendTranscript, handleToolCall]
5380
5257
  );
5381
- const start = useCallback26(
5258
+ const start = useCallback25(
5382
5259
  async (overrides = {}) => {
5383
5260
  if (sessionIdRef.current) {
5384
5261
  cleanup();
@@ -5440,7 +5317,7 @@ function useVoiceAgent(options = {}) {
5440
5317
  },
5441
5318
  [cleanup, settle, stop, handleEvent]
5442
5319
  );
5443
- const toggleMute = useCallback26(() => {
5320
+ const toggleMute = useCallback25(() => {
5444
5321
  const stream = streamRef.current;
5445
5322
  if (!stream) return;
5446
5323
  setIsMuted((muted) => {
@@ -5449,7 +5326,7 @@ function useVoiceAgent(options = {}) {
5449
5326
  return next;
5450
5327
  });
5451
5328
  }, []);
5452
- useEffect20(() => {
5329
+ useEffect19(() => {
5453
5330
  return () => {
5454
5331
  cleanup();
5455
5332
  void settle();
@@ -5537,7 +5414,7 @@ function decodeAiStreamChunk(chunk) {
5537
5414
  }
5538
5415
 
5539
5416
  // src/client/status.ts
5540
- import { useCallback as useCallback27, useEffect as useEffect21, useMemo as useMemo16, useRef as useRef18, useState as useState18 } from "react";
5417
+ import { useCallback as useCallback26, useEffect as useEffect20, useMemo as useMemo16, useRef as useRef17, useState as useState17 } from "react";
5541
5418
 
5542
5419
  // src/client/status-core.ts
5543
5420
  var ASYNC_RESOURCE_DEFAULTS = {
@@ -5621,7 +5498,7 @@ function useAsyncResource(fetcher, deps, options = {}) {
5621
5498
  const retry = options.retry ?? ASYNC_RESOURCE_DEFAULTS.retry;
5622
5499
  const retryDelayMs = options.retryDelayMs ?? ASYNC_RESOURCE_DEFAULTS.retryDelayMs;
5623
5500
  const slowAfterMs = options.slowAfterMs ?? ASYNC_RESOURCE_DEFAULTS.slowAfterMs;
5624
- const [state, setState] = useState18(() => ({
5501
+ const [state, setState] = useState17(() => ({
5625
5502
  status: enabled ? "loading" : "idle",
5626
5503
  data: options.initialData ?? null,
5627
5504
  error: null,
@@ -5629,12 +5506,12 @@ function useAsyncResource(fetcher, deps, options = {}) {
5629
5506
  isSlow: false,
5630
5507
  retryCount: 0
5631
5508
  }));
5632
- const requestIdRef = useRef18(0);
5633
- const [reloadTick, setReloadTick] = useState18(0);
5634
- const reload = useCallback27(() => {
5509
+ const requestIdRef = useRef17(0);
5510
+ const [reloadTick, setReloadTick] = useState17(0);
5511
+ const reload = useCallback26(() => {
5635
5512
  setReloadTick((tick) => tick + 1);
5636
5513
  }, []);
5637
- useEffect21(() => {
5514
+ useEffect20(() => {
5638
5515
  if (!enabled) {
5639
5516
  setState((prev) => ({ ...prev, status: "idle", isRefreshing: false, isSlow: false, retryCount: 0 }));
5640
5517
  return;
@@ -5723,7 +5600,7 @@ function usePagedResource(fetchPage, deps, options = {}) {
5723
5600
  const retryDelayMs = options.retryDelayMs ?? ASYNC_RESOURCE_DEFAULTS.retryDelayMs;
5724
5601
  const maxRetryDelayMs = options.maxRetryDelayMs ?? 3e4;
5725
5602
  const hasInitialItems = initialItems.length > 0;
5726
- const [state, setState] = useState18(() => ({
5603
+ const [state, setState] = useState17(() => ({
5727
5604
  status: enabled ? hasInitialItems ? "ready" : "loading" : "idle",
5728
5605
  items: initialItems,
5729
5606
  error: null,
@@ -5733,25 +5610,25 @@ function usePagedResource(fetchPage, deps, options = {}) {
5733
5610
  isLoadingMore: false,
5734
5611
  isRefreshing: false
5735
5612
  }));
5736
- const requestIdRef = useRef18(0);
5737
- const controllerRef = useRef18(null);
5738
- const loadingRef = useRef18(false);
5739
- const nextPageRef = useRef18(hasInitialItems ? 2 : 1);
5740
- const failedPageRef = useRef18(null);
5741
- const failureCountRef = useRef18(0);
5742
- const cooldownUntilRef = useRef18(0);
5743
- const autoRetryTimerRef = useRef18(null);
5744
- const clearAutoRetryTimer = useCallback27(() => {
5613
+ const requestIdRef = useRef17(0);
5614
+ const controllerRef = useRef17(null);
5615
+ const loadingRef = useRef17(false);
5616
+ const nextPageRef = useRef17(hasInitialItems ? 2 : 1);
5617
+ const failedPageRef = useRef17(null);
5618
+ const failureCountRef = useRef17(0);
5619
+ const cooldownUntilRef = useRef17(0);
5620
+ const autoRetryTimerRef = useRef17(null);
5621
+ const clearAutoRetryTimer = useCallback26(() => {
5745
5622
  if (autoRetryTimerRef.current) {
5746
5623
  clearTimeout(autoRetryTimerRef.current);
5747
5624
  autoRetryTimerRef.current = null;
5748
5625
  }
5749
5626
  }, []);
5750
- const resetCooldown = useCallback27(() => {
5627
+ const resetCooldown = useCallback26(() => {
5751
5628
  failureCountRef.current = 0;
5752
5629
  cooldownUntilRef.current = 0;
5753
5630
  }, []);
5754
- const setFailureCooldown = useCallback27(() => {
5631
+ const setFailureCooldown = useCallback26(() => {
5755
5632
  failureCountRef.current += 1;
5756
5633
  const delay = getPagedResourceCooldownMs({
5757
5634
  failureCount: failureCountRef.current,
@@ -5761,7 +5638,7 @@ function usePagedResource(fetchPage, deps, options = {}) {
5761
5638
  cooldownUntilRef.current = Date.now() + delay;
5762
5639
  return delay;
5763
5640
  }, [maxRetryDelayMs, retryDelayMs]);
5764
- const startLoad = useCallback27(async (page, mode) => {
5641
+ const startLoad = useCallback26(async (page, mode) => {
5765
5642
  if (!enabled || loadingRef.current) return;
5766
5643
  if (mode === "auto" && !canAutoLoadPagedResource({
5767
5644
  hasMore: true,
@@ -5841,21 +5718,21 @@ function usePagedResource(fetchPage, deps, options = {}) {
5841
5718
  }
5842
5719
  }
5843
5720
  }, [autoRetryOnError, clearAutoRetryTimer, enabled, fetchPage, keepPreviousData, maxItemsPerPage, pageSize, resetCooldown, setFailureCooldown]);
5844
- const loadMore = useCallback27(() => {
5721
+ const loadMore = useCallback26(() => {
5845
5722
  if (!state.hasMore || state.isLoadingInitial || state.isLoadingMore || state.isRefreshing) return;
5846
5723
  void startLoad(nextPageRef.current, "auto");
5847
5724
  }, [startLoad, state.hasMore, state.isLoadingInitial, state.isLoadingMore, state.isRefreshing]);
5848
- const retry = useCallback27(() => {
5725
+ const retry = useCallback26(() => {
5849
5726
  const page = failedPageRef.current ?? nextPageRef.current;
5850
5727
  void startLoad(page, "manual");
5851
5728
  }, [startLoad]);
5852
- const refresh = useCallback27(() => {
5729
+ const refresh = useCallback26(() => {
5853
5730
  failedPageRef.current = null;
5854
5731
  resetCooldown();
5855
5732
  nextPageRef.current = 1;
5856
5733
  void startLoad(1, "refresh");
5857
5734
  }, [resetCooldown, startLoad]);
5858
- useEffect21(() => {
5735
+ useEffect20(() => {
5859
5736
  requestIdRef.current += 1;
5860
5737
  controllerRef.current?.abort();
5861
5738
  clearAutoRetryTimer();
@@ -5892,7 +5769,7 @@ function usePagedResource(fetchPage, deps, options = {}) {
5892
5769
  }
5893
5770
 
5894
5771
  // src/client/subscriptions/useSubscription.ts
5895
- import { useCallback as useCallback28, useEffect as useEffect22, useState as useState19 } from "react";
5772
+ import { useCallback as useCallback27, useEffect as useEffect21, useState as useState18 } from "react";
5896
5773
 
5897
5774
  // src/shared/subscription.ts
5898
5775
  var ENTITLED_STATUSES = /* @__PURE__ */ new Set([
@@ -5923,7 +5800,7 @@ async function authedJson(path, init) {
5923
5800
  return data;
5924
5801
  }
5925
5802
  function useSubscription() {
5926
- const [state, setState] = useState19({
5803
+ const [state, setState] = useState18({
5927
5804
  tier: "free",
5928
5805
  status: "none",
5929
5806
  interval: null,
@@ -5932,9 +5809,9 @@ function useSubscription() {
5932
5809
  trialEndsAt: null,
5933
5810
  plans: []
5934
5811
  });
5935
- const [isLoading, setLoading] = useState19(true);
5936
- const [error, setError] = useState19(null);
5937
- const refresh = useCallback28(async () => {
5812
+ const [isLoading, setLoading] = useState18(true);
5813
+ const [error, setError] = useState18(null);
5814
+ const refresh = useCallback27(async () => {
5938
5815
  setLoading(true);
5939
5816
  try {
5940
5817
  const r = await authedJson("/_deepspace/subscriptions/me");
@@ -5954,15 +5831,15 @@ function useSubscription() {
5954
5831
  setLoading(false);
5955
5832
  }
5956
5833
  }, []);
5957
- useEffect22(() => {
5834
+ useEffect21(() => {
5958
5835
  refresh();
5959
5836
  }, [refresh]);
5960
5837
  const entitled = isEntitled(state.tier, state.status);
5961
- const hasTier = useCallback28(
5838
+ const hasTier = useCallback27(
5962
5839
  (slug) => state.tier === slug && isEntitled(state.tier, state.status),
5963
5840
  [state.tier, state.status]
5964
5841
  );
5965
- const isAtLeast = useCallback28(
5842
+ const isAtLeast = useCallback27(
5966
5843
  (slug) => {
5967
5844
  if (!isEntitled(state.tier, state.status)) return false;
5968
5845
  const targetRank = state.plans.find((p) => p.slug === slug)?.rank;
@@ -5972,7 +5849,7 @@ function useSubscription() {
5972
5849
  },
5973
5850
  [state.plans, state.tier, state.status]
5974
5851
  );
5975
- const subscribe = useCallback28(
5852
+ const subscribe = useCallback27(
5976
5853
  async (planSlug, opts) => {
5977
5854
  const result = await authedJson("/_deepspace/subscriptions/checkout", {
5978
5855
  method: "POST",
@@ -5992,7 +5869,7 @@ function useSubscription() {
5992
5869
  },
5993
5870
  [refresh]
5994
5871
  );
5995
- const openPortal = useCallback28(
5872
+ const openPortal = useCallback27(
5996
5873
  async (returnUrl) => {
5997
5874
  return authedJson("/_deepspace/subscriptions/portal", {
5998
5875
  method: "POST",
@@ -6061,7 +5938,7 @@ function PricingTable(props) {
6061
5938
  }
6062
5939
 
6063
5940
  // src/client/charges/useCheckout.ts
6064
- import { useCallback as useCallback29, useEffect as useEffect23, useMemo as useMemo17, useState as useState20 } from "react";
5941
+ import { useCallback as useCallback28, useEffect as useEffect22, useMemo as useMemo17, useState as useState19 } from "react";
6065
5942
  async function authedJson2(path, init) {
6066
5943
  const token = await getAuthToken();
6067
5944
  const res = await fetch(path, {
@@ -6080,10 +5957,10 @@ async function authedJson2(path, init) {
6080
5957
  return data;
6081
5958
  }
6082
5959
  function useCheckout(opts) {
6083
- const [purchases, setPurchases] = useState20([]);
6084
- const [isLoading, setLoading] = useState20(true);
6085
- const [error, setError] = useState20(null);
6086
- const refresh = useCallback29(async () => {
5960
+ const [purchases, setPurchases] = useState19([]);
5961
+ const [isLoading, setLoading] = useState19(true);
5962
+ const [error, setError] = useState19(null);
5963
+ const refresh = useCallback28(async () => {
6087
5964
  setLoading(true);
6088
5965
  try {
6089
5966
  const r = await authedJson2(
@@ -6097,10 +5974,10 @@ function useCheckout(opts) {
6097
5974
  setLoading(false);
6098
5975
  }
6099
5976
  }, []);
6100
- useEffect23(() => {
5977
+ useEffect22(() => {
6101
5978
  refresh();
6102
5979
  }, [refresh]);
6103
- const chargeOnce = useCallback29(
5980
+ const chargeOnce = useCallback28(
6104
5981
  async (chargeOpts) => {
6105
5982
  setError(null);
6106
5983
  const common = {
@@ -6134,7 +6011,7 @@ function useCheckout(opts) {
6134
6011
  },
6135
6012
  []
6136
6013
  );
6137
- const ownsProduct = useCallback29(
6014
+ const ownsProduct = useCallback28(
6138
6015
  (productId) => purchases.some((p) => p.productId === productId),
6139
6016
  [purchases]
6140
6017
  );
@@ -6297,12 +6174,12 @@ var APP_LOG_EVENT_KEYS = [
6297
6174
  "exception"
6298
6175
  ];
6299
6176
  export {
6177
+ ACCOUNT_STORAGE_LIMIT_BYTES,
6300
6178
  APP_LOG_EVENT_KEYS,
6301
6179
  ASYNC_RESOURCE_DEFAULTS,
6302
6180
  AuthGate,
6303
6181
  AuthOverlay,
6304
6182
  Awareness,
6305
- CANONICAL_APP_IDENTITY_MIGRATION_ID,
6306
6183
  DEEPSPACE_AGENT_PROFILES,
6307
6184
  DEEPSPACE_AI_DEFAULTS,
6308
6185
  DEEPSPACE_AI_MODELS,
@@ -6355,6 +6232,7 @@ export {
6355
6232
  encodeSyncStep1,
6356
6233
  encodeSyncStep2,
6357
6234
  encodeUpdate,
6235
+ formatBytes,
6358
6236
  formatFileSize,
6359
6237
  formatFullTimestamp,
6360
6238
  formatMessageTime,
@@ -6395,6 +6273,7 @@ export {
6395
6273
  shouldGroupMessages,
6396
6274
  signIn,
6397
6275
  signOut,
6276
+ storageLimitForTier,
6398
6277
  toConnectionStatus,
6399
6278
  toUint8Array,
6400
6279
  useAsyncResource,
@@ -6411,7 +6290,6 @@ export {
6411
6290
  useConversations,
6412
6291
  useCronMonitor,
6413
6292
  useDisplayName,
6414
- useGameRoom,
6415
6293
  useInbox,
6416
6294
  useIsDarkTheme,
6417
6295
  useJobs,