deepspace 0.16.0 → 0.18.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 +247 -1
- package/README.md +18 -41
- package/dist/cli.js +1499 -1327
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +4 -157
- package/dist/index.js +248 -326
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +4 -137
- package/dist/server.js +3 -412
- package/dist/server.js.map +1 -1
- package/dist/worker.d.ts +5 -210
- package/dist/worker.js +3 -419
- package/dist/worker.js.map +1 -1
- package/features/documents/src/LibrarySidebar.tsx +6 -8
- package/features/documents/src/editor/useDocEditor.ts +3 -8
- package/features/landing/feature.json +1 -1
- package/features/messaging/src/components/chat/MessageItem.tsx +83 -34
- package/features/messaging/src/hooks/useChatChannel.ts +2 -8
- package/package.json +2 -2
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)) {
|
|
@@ -1809,6 +1786,8 @@ function parseServerError(error) {
|
|
|
1809
1786
|
// src/client/storage/record-socket.ts
|
|
1810
1787
|
var WS_CONNECTING = 0;
|
|
1811
1788
|
var WS_OPEN = 1;
|
|
1789
|
+
var PING_EVERY_MS = 15e3;
|
|
1790
|
+
var PONG_TIMEOUT_MS = 3e4;
|
|
1812
1791
|
var RecordSocket = class {
|
|
1813
1792
|
constructor(config) {
|
|
1814
1793
|
this.config = config;
|
|
@@ -1824,6 +1803,14 @@ var RecordSocket = class {
|
|
|
1824
1803
|
pendingRequests = /* @__PURE__ */ new Map();
|
|
1825
1804
|
reconnectAttempt = 0;
|
|
1826
1805
|
reconnectTimeout = null;
|
|
1806
|
+
heartbeat = null;
|
|
1807
|
+
/** Any inbound frame proves the peer is answering. */
|
|
1808
|
+
lastInboundAt = 0;
|
|
1809
|
+
/** Monotonic time of the one probe awaiting an inbound answer. */
|
|
1810
|
+
outstandingPingAt = null;
|
|
1811
|
+
/** Monotonic time of the prior heartbeat callback. A long gap means the
|
|
1812
|
+
* scheduler was suspended, so a pre-suspension probe cannot be judged. */
|
|
1813
|
+
lastHeartbeatCheckAt = 0;
|
|
1827
1814
|
// Bumped by connect() (on entry) and disconnect()/destroy(). connect()
|
|
1828
1815
|
// captures it before awaiting the auth token and re-checks after; a
|
|
1829
1816
|
// mismatch means a teardown (or a newer connect) raced in during the
|
|
@@ -1872,10 +1859,12 @@ var RecordSocket = class {
|
|
|
1872
1859
|
ws.onopen = () => {
|
|
1873
1860
|
config.log?.("connected", config.roomId);
|
|
1874
1861
|
config.listeners.onStatus("connected");
|
|
1862
|
+
this.startHeartbeat(ws);
|
|
1875
1863
|
this.resubscribeAll(ws);
|
|
1876
1864
|
};
|
|
1877
1865
|
ws.onmessage = (event) => this.handleMessage(event);
|
|
1878
1866
|
ws.onclose = () => {
|
|
1867
|
+
this.stopHeartbeat();
|
|
1879
1868
|
config.log?.("disconnected", config.roomId);
|
|
1880
1869
|
config.listeners.onStatus("disconnected");
|
|
1881
1870
|
config.listeners.onReady(false);
|
|
@@ -1930,8 +1919,48 @@ var RecordSocket = class {
|
|
|
1930
1919
|
this.reconnectTimeout = null;
|
|
1931
1920
|
}
|
|
1932
1921
|
}
|
|
1922
|
+
/**
|
|
1923
|
+
* Turn a peer that stopped answering into a `close` event. That is the whole
|
|
1924
|
+
* job — `onclose` already reports 'disconnected', marks every query stale,
|
|
1925
|
+
* and reconnects with backoff. Without this it is never called, because
|
|
1926
|
+
* nothing about the connection is actually broken.
|
|
1927
|
+
*/
|
|
1928
|
+
startHeartbeat(ws) {
|
|
1929
|
+
this.stopHeartbeat();
|
|
1930
|
+
this.lastInboundAt = performance.now();
|
|
1931
|
+
this.lastHeartbeatCheckAt = this.lastInboundAt;
|
|
1932
|
+
this.outstandingPingAt = null;
|
|
1933
|
+
this.heartbeat = setInterval(() => {
|
|
1934
|
+
if (ws.readyState !== WS_OPEN) return;
|
|
1935
|
+
const now = performance.now();
|
|
1936
|
+
const callbackGap = now - this.lastHeartbeatCheckAt;
|
|
1937
|
+
this.lastHeartbeatCheckAt = now;
|
|
1938
|
+
if (this.outstandingPingAt !== null) {
|
|
1939
|
+
if (now - this.outstandingPingAt >= PONG_TIMEOUT_MS) {
|
|
1940
|
+
if (callbackGap >= PONG_TIMEOUT_MS) {
|
|
1941
|
+
ws.send("ping");
|
|
1942
|
+
this.outstandingPingAt = now;
|
|
1943
|
+
} else {
|
|
1944
|
+
ws.close();
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
return;
|
|
1948
|
+
}
|
|
1949
|
+
if (now - this.lastInboundAt >= PING_EVERY_MS) {
|
|
1950
|
+
ws.send("ping");
|
|
1951
|
+
this.outstandingPingAt = now;
|
|
1952
|
+
}
|
|
1953
|
+
}, PING_EVERY_MS);
|
|
1954
|
+
}
|
|
1955
|
+
stopHeartbeat() {
|
|
1956
|
+
if (this.heartbeat) clearInterval(this.heartbeat);
|
|
1957
|
+
this.heartbeat = null;
|
|
1958
|
+
this.outstandingPingAt = null;
|
|
1959
|
+
this.lastHeartbeatCheckAt = 0;
|
|
1960
|
+
}
|
|
1933
1961
|
/** Close without firing onclose — prevents the zombie-reconnect. */
|
|
1934
1962
|
teardownSocket() {
|
|
1963
|
+
this.stopHeartbeat();
|
|
1935
1964
|
const ws = this.ws;
|
|
1936
1965
|
if (!ws) return;
|
|
1937
1966
|
this.config.log?.("closing", this.config.roomId);
|
|
@@ -2000,6 +2029,9 @@ var RecordSocket = class {
|
|
|
2000
2029
|
}
|
|
2001
2030
|
}
|
|
2002
2031
|
handleMessage(event) {
|
|
2032
|
+
this.lastInboundAt = performance.now();
|
|
2033
|
+
this.outstandingPingAt = null;
|
|
2034
|
+
if (event.data === "pong") return;
|
|
2003
2035
|
if (event.data instanceof ArrayBuffer) {
|
|
2004
2036
|
this.binaryHandlers.forEach((h) => h(event.data));
|
|
2005
2037
|
return;
|
|
@@ -2973,123 +3005,15 @@ function useYjsRoom(docId, fieldName) {
|
|
|
2973
3005
|
return { doc, awareness, text, setText, synced, canWrite, writeAuthResolved };
|
|
2974
3006
|
}
|
|
2975
3007
|
|
|
2976
|
-
// src/client/storage/hooks/
|
|
3008
|
+
// src/client/storage/hooks/useCanvas.ts
|
|
2977
3009
|
import { useState as useState8, useEffect as useEffect11, useCallback as useCallback10, useRef as useRef9 } from "react";
|
|
2978
|
-
function
|
|
2979
|
-
const [
|
|
2980
|
-
const [
|
|
2981
|
-
const [players, setPlayers] = useState8([]);
|
|
2982
|
-
const [running, setRunning] = useState8(false);
|
|
3010
|
+
function useCanvas(roomId) {
|
|
3011
|
+
const [shapes, setShapes] = useState8([]);
|
|
3012
|
+
const [viewports, setViewports] = useState8([]);
|
|
2983
3013
|
const [connected, setConnected] = useState8(false);
|
|
2984
3014
|
const [canWrite, setCanWrite] = useState8(false);
|
|
2985
3015
|
const wsRef = useRef9(null);
|
|
2986
3016
|
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
3017
|
let ws = null;
|
|
3094
3018
|
let reconnectTimer = null;
|
|
3095
3019
|
let alive = true;
|
|
@@ -3183,7 +3107,7 @@ function useCanvas(roomId) {
|
|
|
3183
3107
|
wsRef.current = null;
|
|
3184
3108
|
};
|
|
3185
3109
|
}, [roomId]);
|
|
3186
|
-
const sendBuilt =
|
|
3110
|
+
const sendBuilt = useCallback10(
|
|
3187
3111
|
(message) => {
|
|
3188
3112
|
const ws = wsRef.current;
|
|
3189
3113
|
if (!ws || ws.readyState !== WebSocket.OPEN) return;
|
|
@@ -3191,51 +3115,51 @@ function useCanvas(roomId) {
|
|
|
3191
3115
|
},
|
|
3192
3116
|
[]
|
|
3193
3117
|
);
|
|
3194
|
-
const sendWrite =
|
|
3118
|
+
const sendWrite = useCallback10(
|
|
3195
3119
|
(message) => {
|
|
3196
3120
|
if (!canWrite) return;
|
|
3197
3121
|
sendBuilt(message);
|
|
3198
3122
|
},
|
|
3199
3123
|
[sendBuilt, canWrite]
|
|
3200
3124
|
);
|
|
3201
|
-
const addShape =
|
|
3125
|
+
const addShape = useCallback10(
|
|
3202
3126
|
(shape) => sendWrite(clientBuild.canvasAdd(shape)),
|
|
3203
3127
|
[sendWrite]
|
|
3204
3128
|
);
|
|
3205
|
-
const moveShape =
|
|
3129
|
+
const moveShape = useCallback10(
|
|
3206
3130
|
(shapeId, x, y) => sendWrite(clientBuild.canvasMove(shapeId, x, y)),
|
|
3207
3131
|
[sendWrite]
|
|
3208
3132
|
);
|
|
3209
|
-
const resizeShape =
|
|
3133
|
+
const resizeShape = useCallback10(
|
|
3210
3134
|
(shapeId, width, height, x, y) => sendWrite(clientBuild.canvasResize(shapeId, width, height, x, y)),
|
|
3211
3135
|
[sendWrite]
|
|
3212
3136
|
);
|
|
3213
|
-
const deleteShape =
|
|
3137
|
+
const deleteShape = useCallback10(
|
|
3214
3138
|
(shapeId) => sendWrite(clientBuild.canvasDelete(shapeId)),
|
|
3215
3139
|
[sendWrite]
|
|
3216
3140
|
);
|
|
3217
|
-
const updateShape =
|
|
3141
|
+
const updateShape = useCallback10(
|
|
3218
3142
|
(shapeId, props) => sendWrite(clientBuild.canvasUpdate(shapeId, props)),
|
|
3219
3143
|
[sendWrite]
|
|
3220
3144
|
);
|
|
3221
|
-
const setViewport =
|
|
3145
|
+
const setViewport = useCallback10(
|
|
3222
3146
|
(viewport) => sendBuilt(clientBuild.canvasViewport(viewport)),
|
|
3223
3147
|
[sendBuilt]
|
|
3224
3148
|
);
|
|
3225
|
-
const undo =
|
|
3226
|
-
const redo =
|
|
3149
|
+
const undo = useCallback10(() => sendWrite(clientBuild.canvasUndo()), [sendWrite]);
|
|
3150
|
+
const redo = useCallback10(() => sendWrite(clientBuild.canvasRedo()), [sendWrite]);
|
|
3227
3151
|
return { shapes, viewports, connected, canWrite, addShape, moveShape, resizeShape, deleteShape, updateShape, setViewport, undo, redo };
|
|
3228
3152
|
}
|
|
3229
3153
|
|
|
3230
3154
|
// src/client/storage/hooks/useCronMonitor.ts
|
|
3231
|
-
import { useState as
|
|
3155
|
+
import { useState as useState9, useEffect as useEffect12, useCallback as useCallback11, useRef as useRef10 } from "react";
|
|
3232
3156
|
function useCronMonitor(roomId) {
|
|
3233
|
-
const [tasks, setTasks] =
|
|
3234
|
-
const [history, setHistory] =
|
|
3235
|
-
const [connected, setConnected] =
|
|
3236
|
-
const [canWrite, setCanWrite] =
|
|
3237
|
-
const wsRef =
|
|
3238
|
-
|
|
3157
|
+
const [tasks, setTasks] = useState9([]);
|
|
3158
|
+
const [history, setHistory] = useState9([]);
|
|
3159
|
+
const [connected, setConnected] = useState9(false);
|
|
3160
|
+
const [canWrite, setCanWrite] = useState9(false);
|
|
3161
|
+
const wsRef = useRef10(null);
|
|
3162
|
+
useEffect12(() => {
|
|
3239
3163
|
let ws = null;
|
|
3240
3164
|
let reconnectTimer = null;
|
|
3241
3165
|
let alive = true;
|
|
@@ -3282,7 +3206,7 @@ function useCronMonitor(roomId) {
|
|
|
3282
3206
|
wsRef.current = null;
|
|
3283
3207
|
};
|
|
3284
3208
|
}, [roomId]);
|
|
3285
|
-
const sendWrite =
|
|
3209
|
+
const sendWrite = useCallback11(
|
|
3286
3210
|
(message) => {
|
|
3287
3211
|
if (!canWrite) return;
|
|
3288
3212
|
const ws = wsRef.current;
|
|
@@ -3291,15 +3215,15 @@ function useCronMonitor(roomId) {
|
|
|
3291
3215
|
},
|
|
3292
3216
|
[canWrite]
|
|
3293
3217
|
);
|
|
3294
|
-
const trigger =
|
|
3218
|
+
const trigger = useCallback11(
|
|
3295
3219
|
(taskName) => sendWrite(clientBuild.cronTrigger(taskName)),
|
|
3296
3220
|
[sendWrite]
|
|
3297
3221
|
);
|
|
3298
|
-
const pause =
|
|
3222
|
+
const pause = useCallback11(
|
|
3299
3223
|
(taskName) => sendWrite(clientBuild.cronPause(taskName)),
|
|
3300
3224
|
[sendWrite]
|
|
3301
3225
|
);
|
|
3302
|
-
const resume =
|
|
3226
|
+
const resume = useCallback11(
|
|
3303
3227
|
(taskName) => sendWrite(clientBuild.cronResume(taskName)),
|
|
3304
3228
|
[sendWrite]
|
|
3305
3229
|
);
|
|
@@ -3307,14 +3231,14 @@ function useCronMonitor(roomId) {
|
|
|
3307
3231
|
}
|
|
3308
3232
|
|
|
3309
3233
|
// src/client/storage/hooks/useJobs.ts
|
|
3310
|
-
import { useState as
|
|
3234
|
+
import { useState as useState10, useEffect as useEffect13, useCallback as useCallback12, useRef as useRef11 } from "react";
|
|
3311
3235
|
var ENQUEUE_TIMEOUT_MS = 1e4;
|
|
3312
3236
|
function useJobs(roomId) {
|
|
3313
|
-
const [jobs, setJobs] =
|
|
3314
|
-
const [connected, setConnected] =
|
|
3315
|
-
const wsRef =
|
|
3316
|
-
const pendingEnqueueRef =
|
|
3317
|
-
|
|
3237
|
+
const [jobs, setJobs] = useState10([]);
|
|
3238
|
+
const [connected, setConnected] = useState10(false);
|
|
3239
|
+
const wsRef = useRef11(null);
|
|
3240
|
+
const pendingEnqueueRef = useRef11(/* @__PURE__ */ new Map());
|
|
3241
|
+
useEffect13(() => {
|
|
3318
3242
|
let ws = null;
|
|
3319
3243
|
let reconnectTimer = null;
|
|
3320
3244
|
let alive = true;
|
|
@@ -3382,7 +3306,7 @@ function useJobs(roomId) {
|
|
|
3382
3306
|
wsRef.current = null;
|
|
3383
3307
|
};
|
|
3384
3308
|
}, [roomId]);
|
|
3385
|
-
const enqueue =
|
|
3309
|
+
const enqueue = useCallback12(
|
|
3386
3310
|
(type, payload, options) => {
|
|
3387
3311
|
return new Promise((resolve, reject) => {
|
|
3388
3312
|
const ws = wsRef.current;
|
|
@@ -3413,7 +3337,7 @@ function useJobs(roomId) {
|
|
|
3413
3337
|
},
|
|
3414
3338
|
[]
|
|
3415
3339
|
);
|
|
3416
|
-
const sendBuilt =
|
|
3340
|
+
const sendBuilt = useCallback12(
|
|
3417
3341
|
(message) => {
|
|
3418
3342
|
const ws = wsRef.current;
|
|
3419
3343
|
if (!ws || ws.readyState !== WebSocket.OPEN) return;
|
|
@@ -3421,15 +3345,15 @@ function useJobs(roomId) {
|
|
|
3421
3345
|
},
|
|
3422
3346
|
[]
|
|
3423
3347
|
);
|
|
3424
|
-
const getJob =
|
|
3348
|
+
const getJob = useCallback12(
|
|
3425
3349
|
(jobId) => jobs.find((j) => j.id === jobId),
|
|
3426
3350
|
[jobs]
|
|
3427
3351
|
);
|
|
3428
|
-
const cancel =
|
|
3352
|
+
const cancel = useCallback12(
|
|
3429
3353
|
(jobId) => sendBuilt(clientBuild.jobCancel(jobId)),
|
|
3430
3354
|
[sendBuilt]
|
|
3431
3355
|
);
|
|
3432
|
-
const retry =
|
|
3356
|
+
const retry = useCallback12(
|
|
3433
3357
|
(jobId) => sendBuilt(clientBuild.jobRetry(jobId)),
|
|
3434
3358
|
[sendBuilt]
|
|
3435
3359
|
);
|
|
@@ -3437,12 +3361,12 @@ function useJobs(roomId) {
|
|
|
3437
3361
|
}
|
|
3438
3362
|
|
|
3439
3363
|
// src/client/storage/hooks/usePresenceRoom.ts
|
|
3440
|
-
import { useState as
|
|
3364
|
+
import { useState as useState11, useEffect as useEffect14, useCallback as useCallback13, useRef as useRef12 } from "react";
|
|
3441
3365
|
function usePresenceRoom(scopeId) {
|
|
3442
|
-
const [peers, setPeers] =
|
|
3443
|
-
const [connected, setConnected] =
|
|
3444
|
-
const wsRef =
|
|
3445
|
-
|
|
3366
|
+
const [peers, setPeers] = useState11([]);
|
|
3367
|
+
const [connected, setConnected] = useState11(false);
|
|
3368
|
+
const wsRef = useRef12(null);
|
|
3369
|
+
useEffect14(() => {
|
|
3446
3370
|
let ws = null;
|
|
3447
3371
|
let reconnectTimer = null;
|
|
3448
3372
|
let alive = true;
|
|
@@ -3503,7 +3427,7 @@ function usePresenceRoom(scopeId) {
|
|
|
3503
3427
|
wsRef.current = null;
|
|
3504
3428
|
};
|
|
3505
3429
|
}, [scopeId]);
|
|
3506
|
-
const updateState =
|
|
3430
|
+
const updateState = useCallback13((state) => {
|
|
3507
3431
|
const ws = wsRef.current;
|
|
3508
3432
|
if (!ws || ws.readyState !== WebSocket.OPEN) return;
|
|
3509
3433
|
ws.send(encode(clientBuild.presenceUpdate(state)));
|
|
@@ -3519,7 +3443,7 @@ function toConnectionStatus(queryStatus) {
|
|
|
3519
3443
|
}
|
|
3520
3444
|
|
|
3521
3445
|
// src/client/storage/useR2Files.ts
|
|
3522
|
-
import { useCallback as
|
|
3446
|
+
import { useCallback as useCallback14, useState as useState12, useMemo as useMemo11 } from "react";
|
|
3523
3447
|
|
|
3524
3448
|
// src/shared/app-files.ts
|
|
3525
3449
|
var MAX_APP_FILE_BYTES = 1024 * 1024 * 1024;
|
|
@@ -3659,21 +3583,21 @@ async function uploadInParts(file, name, scopeParams, authHeaders, onProgress) {
|
|
|
3659
3583
|
}
|
|
3660
3584
|
}
|
|
3661
3585
|
function useR2Files(options) {
|
|
3662
|
-
const [isUploading, setIsUploading] =
|
|
3586
|
+
const [isUploading, setIsUploading] = useState12(false);
|
|
3663
3587
|
const scope = options?.scope ?? "self";
|
|
3664
3588
|
const scopeParams = useMemo11(() => {
|
|
3665
3589
|
const params = new URLSearchParams();
|
|
3666
3590
|
params.set("scope", scope);
|
|
3667
3591
|
return params.toString();
|
|
3668
3592
|
}, [scope]);
|
|
3669
|
-
const authHeaders =
|
|
3593
|
+
const authHeaders = useCallback14(async () => {
|
|
3670
3594
|
const token = await getAuthToken();
|
|
3671
3595
|
if (token) {
|
|
3672
3596
|
return { Authorization: `Bearer ${token}` };
|
|
3673
3597
|
}
|
|
3674
3598
|
return {};
|
|
3675
3599
|
}, []);
|
|
3676
|
-
const upload =
|
|
3600
|
+
const upload = useCallback14(
|
|
3677
3601
|
async (file, name, options2) => {
|
|
3678
3602
|
setIsUploading(true);
|
|
3679
3603
|
try {
|
|
@@ -3702,7 +3626,7 @@ function useR2Files(options) {
|
|
|
3702
3626
|
},
|
|
3703
3627
|
[scopeParams, authHeaders]
|
|
3704
3628
|
);
|
|
3705
|
-
const uploadBase64 =
|
|
3629
|
+
const uploadBase64 = useCallback14(
|
|
3706
3630
|
async (base64Data, name, mimeType) => {
|
|
3707
3631
|
setIsUploading(true);
|
|
3708
3632
|
try {
|
|
@@ -3726,7 +3650,7 @@ function useR2Files(options) {
|
|
|
3726
3650
|
},
|
|
3727
3651
|
[scopeParams, authHeaders]
|
|
3728
3652
|
);
|
|
3729
|
-
const deleteFile =
|
|
3653
|
+
const deleteFile = useCallback14(
|
|
3730
3654
|
async (fileOrKey) => {
|
|
3731
3655
|
const { key } = resolveFile(fileOrKey);
|
|
3732
3656
|
try {
|
|
@@ -3742,7 +3666,7 @@ function useR2Files(options) {
|
|
|
3742
3666
|
},
|
|
3743
3667
|
[scopeParams, authHeaders]
|
|
3744
3668
|
);
|
|
3745
|
-
const list =
|
|
3669
|
+
const list = useCallback14(
|
|
3746
3670
|
async (prefix) => {
|
|
3747
3671
|
try {
|
|
3748
3672
|
const headers = await authHeaders();
|
|
@@ -3757,7 +3681,7 @@ function useR2Files(options) {
|
|
|
3757
3681
|
},
|
|
3758
3682
|
[scopeParams, authHeaders]
|
|
3759
3683
|
);
|
|
3760
|
-
const downloadFile =
|
|
3684
|
+
const downloadFile = useCallback14(
|
|
3761
3685
|
async (fileOrKey, fileName) => {
|
|
3762
3686
|
const { key, name: infoName } = resolveFile(fileOrKey);
|
|
3763
3687
|
try {
|
|
@@ -3787,7 +3711,7 @@ function useR2Files(options) {
|
|
|
3787
3711
|
},
|
|
3788
3712
|
[scopeParams, authHeaders]
|
|
3789
3713
|
);
|
|
3790
|
-
const readFile =
|
|
3714
|
+
const readFile = useCallback14(
|
|
3791
3715
|
async (fileOrKey) => {
|
|
3792
3716
|
const { key } = resolveFile(fileOrKey);
|
|
3793
3717
|
const headers = await authHeaders();
|
|
@@ -3800,7 +3724,7 @@ function useR2Files(options) {
|
|
|
3800
3724
|
},
|
|
3801
3725
|
[scopeParams, authHeaders]
|
|
3802
3726
|
);
|
|
3803
|
-
const getUrl =
|
|
3727
|
+
const getUrl = useCallback14(
|
|
3804
3728
|
(fileOrKey) => {
|
|
3805
3729
|
const { key } = resolveFile(fileOrKey);
|
|
3806
3730
|
return `/api/files/${encodeKeyPath(key)}?${scopeParams}`;
|
|
@@ -3846,7 +3770,7 @@ function getUserColor(userId, palette = DEFAULT_USER_COLORS) {
|
|
|
3846
3770
|
}
|
|
3847
3771
|
|
|
3848
3772
|
// src/client/messaging/useMessages.ts
|
|
3849
|
-
import { useCallback as
|
|
3773
|
+
import { useCallback as useCallback15, useMemo as useMemo12 } from "react";
|
|
3850
3774
|
function useMessages(channelId, options) {
|
|
3851
3775
|
const where = useMemo12(() => {
|
|
3852
3776
|
if (!channelId) return { channelId: "__none__" };
|
|
@@ -3863,7 +3787,7 @@ function useMessages(channelId, options) {
|
|
|
3863
3787
|
orderDir: "asc"
|
|
3864
3788
|
});
|
|
3865
3789
|
const { create, put, remove: removeMutation } = useMutations("messages");
|
|
3866
|
-
const send =
|
|
3790
|
+
const send = useCallback15(
|
|
3867
3791
|
(content, parentMessageId) => {
|
|
3868
3792
|
if (!channelId || !user) return;
|
|
3869
3793
|
const data = { channelId, content, authorId: user.id, edited: false };
|
|
@@ -3872,19 +3796,19 @@ function useMessages(channelId, options) {
|
|
|
3872
3796
|
},
|
|
3873
3797
|
[channelId, user, create]
|
|
3874
3798
|
);
|
|
3875
|
-
const edit =
|
|
3799
|
+
const edit = useCallback15(
|
|
3876
3800
|
(messageId, newContent) => {
|
|
3877
3801
|
put(messageId, { content: newContent, edited: true });
|
|
3878
3802
|
},
|
|
3879
3803
|
[put]
|
|
3880
3804
|
);
|
|
3881
|
-
const remove =
|
|
3805
|
+
const remove = useCallback15(
|
|
3882
3806
|
(messageId) => {
|
|
3883
3807
|
removeMutation(messageId);
|
|
3884
3808
|
},
|
|
3885
3809
|
[removeMutation]
|
|
3886
3810
|
);
|
|
3887
|
-
const softDelete =
|
|
3811
|
+
const softDelete = useCallback15(
|
|
3888
3812
|
(messageId) => {
|
|
3889
3813
|
put(messageId, { deleted: true });
|
|
3890
3814
|
},
|
|
@@ -3902,7 +3826,7 @@ function useMessages(channelId, options) {
|
|
|
3902
3826
|
}
|
|
3903
3827
|
|
|
3904
3828
|
// src/client/messaging/useChannels.ts
|
|
3905
|
-
import { useCallback as
|
|
3829
|
+
import { useCallback as useCallback16 } from "react";
|
|
3906
3830
|
function useChannels() {
|
|
3907
3831
|
const { user } = useUser();
|
|
3908
3832
|
const { records, status, error } = useQuery("channels", {
|
|
@@ -3910,7 +3834,7 @@ function useChannels() {
|
|
|
3910
3834
|
orderDir: "asc"
|
|
3911
3835
|
});
|
|
3912
3836
|
const { create: createMutation, put, remove } = useMutations("channels");
|
|
3913
|
-
const create =
|
|
3837
|
+
const create = useCallback16(
|
|
3914
3838
|
(data) => {
|
|
3915
3839
|
return createMutation({
|
|
3916
3840
|
name: data.name,
|
|
@@ -3922,13 +3846,13 @@ function useChannels() {
|
|
|
3922
3846
|
},
|
|
3923
3847
|
[user, createMutation]
|
|
3924
3848
|
);
|
|
3925
|
-
const archive =
|
|
3849
|
+
const archive = useCallback16(
|
|
3926
3850
|
(channelId) => {
|
|
3927
3851
|
put(channelId, { archived: true });
|
|
3928
3852
|
},
|
|
3929
3853
|
[put]
|
|
3930
3854
|
);
|
|
3931
|
-
const update =
|
|
3855
|
+
const update = useCallback16(
|
|
3932
3856
|
(channelId, data) => {
|
|
3933
3857
|
put(channelId, data);
|
|
3934
3858
|
},
|
|
@@ -3946,14 +3870,14 @@ function useChannels() {
|
|
|
3946
3870
|
}
|
|
3947
3871
|
|
|
3948
3872
|
// src/client/messaging/useReactions.ts
|
|
3949
|
-
import { useCallback as
|
|
3873
|
+
import { useCallback as useCallback17 } from "react";
|
|
3950
3874
|
function useReactions(channelId) {
|
|
3951
3875
|
const { user } = useUser();
|
|
3952
3876
|
const { records, status, error } = useQuery("reactions", {
|
|
3953
3877
|
where: channelId ? { channelId } : { channelId: "__none__" }
|
|
3954
3878
|
});
|
|
3955
3879
|
const { create, remove: removeMutation } = useMutations("reactions");
|
|
3956
|
-
const getReactionsForMessage =
|
|
3880
|
+
const getReactionsForMessage = useCallback17(
|
|
3957
3881
|
(messageId) => {
|
|
3958
3882
|
const messageReactions = records.filter((r) => r.data.messageId === messageId);
|
|
3959
3883
|
const grouped = /* @__PURE__ */ new Map();
|
|
@@ -3970,7 +3894,7 @@ function useReactions(channelId) {
|
|
|
3970
3894
|
},
|
|
3971
3895
|
[records, user]
|
|
3972
3896
|
);
|
|
3973
|
-
const toggle =
|
|
3897
|
+
const toggle = useCallback17(
|
|
3974
3898
|
(messageId, emoji) => {
|
|
3975
3899
|
if (!channelId || !user) return;
|
|
3976
3900
|
const existing = records.find(
|
|
@@ -3988,20 +3912,20 @@ function useReactions(channelId) {
|
|
|
3988
3912
|
}
|
|
3989
3913
|
|
|
3990
3914
|
// src/client/messaging/useChannelMembers.ts
|
|
3991
|
-
import { useCallback as
|
|
3915
|
+
import { useCallback as useCallback18 } from "react";
|
|
3992
3916
|
function useChannelMembers(channelId) {
|
|
3993
3917
|
const { user } = useUser();
|
|
3994
3918
|
const { records, status, error } = useQuery("channel-members", {
|
|
3995
3919
|
where: channelId ? { channelId } : { channelId: "__none__" }
|
|
3996
3920
|
});
|
|
3997
3921
|
const { create, remove: removeMutation } = useMutations("channel-members");
|
|
3998
|
-
const join =
|
|
3922
|
+
const join = useCallback18(() => {
|
|
3999
3923
|
if (!channelId || !user) return;
|
|
4000
3924
|
const existing = records.find((r) => r.data.userId === user.id);
|
|
4001
3925
|
if (existing) return;
|
|
4002
3926
|
create({ channelId, userId: user.id, joinedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
4003
3927
|
}, [channelId, user, records, create]);
|
|
4004
|
-
const leave =
|
|
3928
|
+
const leave = useCallback18(() => {
|
|
4005
3929
|
if (!channelId || !user) return;
|
|
4006
3930
|
const membership = records.find((r) => r.data.userId === user.id);
|
|
4007
3931
|
if (membership) removeMutation(membership.recordId);
|
|
@@ -4011,14 +3935,14 @@ function useChannelMembers(channelId) {
|
|
|
4011
3935
|
}
|
|
4012
3936
|
|
|
4013
3937
|
// src/client/messaging/useReadReceipts.ts
|
|
4014
|
-
import { useCallback as
|
|
3938
|
+
import { useCallback as useCallback19 } from "react";
|
|
4015
3939
|
function useReadReceipts() {
|
|
4016
3940
|
const { user } = useUser();
|
|
4017
3941
|
const { records, status, error } = useQuery("read-receipts", {
|
|
4018
3942
|
where: user ? { userId: user.id } : { userId: "__none__" }
|
|
4019
3943
|
});
|
|
4020
3944
|
const { create, put } = useMutations("read-receipts");
|
|
4021
|
-
const markAsRead =
|
|
3945
|
+
const markAsRead = useCallback19(
|
|
4022
3946
|
(channelId) => {
|
|
4023
3947
|
if (!user) return;
|
|
4024
3948
|
const existing = records.find((r) => r.data.channelId === channelId);
|
|
@@ -4031,7 +3955,7 @@ function useReadReceipts() {
|
|
|
4031
3955
|
},
|
|
4032
3956
|
[user, records, create, put]
|
|
4033
3957
|
);
|
|
4034
|
-
const getUnreadCount =
|
|
3958
|
+
const getUnreadCount = useCallback19(
|
|
4035
3959
|
(channelId, messages) => {
|
|
4036
3960
|
const receipt = records.find((r) => r.data.channelId === channelId);
|
|
4037
3961
|
if (!receipt) return messages.length;
|
|
@@ -4044,7 +3968,7 @@ function useReadReceipts() {
|
|
|
4044
3968
|
}
|
|
4045
3969
|
|
|
4046
3970
|
// src/client/messaging/useConversation.ts
|
|
4047
|
-
import { useCallback as
|
|
3971
|
+
import { useCallback as useCallback20, useMemo as useMemo13 } from "react";
|
|
4048
3972
|
function useConversation(opts) {
|
|
4049
3973
|
const { user } = useUser();
|
|
4050
3974
|
const { ready } = useRecordContext();
|
|
@@ -4053,7 +3977,7 @@ function useConversation(opts) {
|
|
|
4053
3977
|
const { records: members } = useQuery("conv_members");
|
|
4054
3978
|
const messageMut = useMutations("conv_messages");
|
|
4055
3979
|
const reactionMut = useMutations("conv_reactions");
|
|
4056
|
-
const send =
|
|
3980
|
+
const send = useCallback20(
|
|
4057
3981
|
(content, parentMessageId, messageType, metadata) => {
|
|
4058
3982
|
messageMut.create({
|
|
4059
3983
|
Content: content,
|
|
@@ -4068,7 +3992,7 @@ function useConversation(opts) {
|
|
|
4068
3992
|
// 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
|
|
4069
3993
|
[messageMut, user?.id, opts?.onMessageSent]
|
|
4070
3994
|
);
|
|
4071
|
-
const edit =
|
|
3995
|
+
const edit = useCallback20(
|
|
4072
3996
|
(recordId, content) => {
|
|
4073
3997
|
const existing = allMessages.find((m) => m.recordId === recordId);
|
|
4074
3998
|
if (!existing) return;
|
|
@@ -4076,7 +4000,7 @@ function useConversation(opts) {
|
|
|
4076
4000
|
},
|
|
4077
4001
|
[messageMut, allMessages]
|
|
4078
4002
|
);
|
|
4079
|
-
const remove =
|
|
4003
|
+
const remove = useCallback20(
|
|
4080
4004
|
(recordId) => {
|
|
4081
4005
|
const existing = allMessages.find((m) => m.recordId === recordId);
|
|
4082
4006
|
if (!existing) return;
|
|
@@ -4089,7 +4013,7 @@ function useConversation(opts) {
|
|
|
4089
4013
|
},
|
|
4090
4014
|
[messageMut, allMessages]
|
|
4091
4015
|
);
|
|
4092
|
-
const toggleReaction =
|
|
4016
|
+
const toggleReaction = useCallback20(
|
|
4093
4017
|
(messageId, emoji) => {
|
|
4094
4018
|
const existing = allReactions.find(
|
|
4095
4019
|
(r) => r.data.MessageId === messageId && r.data.Emoji === emoji && r.data.UserId === user?.id
|
|
@@ -4222,7 +4146,7 @@ function parseMessageMetadata(raw) {
|
|
|
4222
4146
|
}
|
|
4223
4147
|
|
|
4224
4148
|
// src/client/directory/useConversations.ts
|
|
4225
|
-
import { useCallback as
|
|
4149
|
+
import { useCallback as useCallback21, useMemo as useMemo14, useRef as useRef13 } from "react";
|
|
4226
4150
|
var defaultConvFields = {
|
|
4227
4151
|
Visibility: "public",
|
|
4228
4152
|
Status: "active",
|
|
@@ -4237,7 +4161,7 @@ function useConversations() {
|
|
|
4237
4161
|
const stateMut = useMutations("conversation_state");
|
|
4238
4162
|
const { user } = useUser();
|
|
4239
4163
|
const ready = status === "ready";
|
|
4240
|
-
const recentCreationsRef =
|
|
4164
|
+
const recentCreationsRef = useRef13(/* @__PURE__ */ new Map());
|
|
4241
4165
|
for (const [id] of recentCreationsRef.current) {
|
|
4242
4166
|
if (conversations.find((c) => c.recordId === id)) {
|
|
4243
4167
|
recentCreationsRef.current.delete(id);
|
|
@@ -4259,13 +4183,13 @@ function useConversations() {
|
|
|
4259
4183
|
() => new Set(stateRecords.filter((r) => r.data.Archived).map((r) => r.data.ConversationId)),
|
|
4260
4184
|
[stateRecords]
|
|
4261
4185
|
);
|
|
4262
|
-
const getConversationState =
|
|
4186
|
+
const getConversationState = useCallback21(
|
|
4263
4187
|
(conversationId) => {
|
|
4264
4188
|
return stateRecords.find((r) => r.data.ConversationId === conversationId)?.data;
|
|
4265
4189
|
},
|
|
4266
4190
|
[stateRecords]
|
|
4267
4191
|
);
|
|
4268
|
-
const createChannel =
|
|
4192
|
+
const createChannel = useCallback21(
|
|
4269
4193
|
async (name, description) => {
|
|
4270
4194
|
const existing = conversations.find((r) => r.data.Name === name && r.data.Type !== "dm");
|
|
4271
4195
|
if (existing) return existing.recordId;
|
|
@@ -4285,7 +4209,7 @@ function useConversations() {
|
|
|
4285
4209
|
},
|
|
4286
4210
|
[create, user?.id, conversations]
|
|
4287
4211
|
);
|
|
4288
|
-
const createDM =
|
|
4212
|
+
const createDM = useCallback21(
|
|
4289
4213
|
async (otherUserId) => {
|
|
4290
4214
|
if (!user?.id) return null;
|
|
4291
4215
|
const hash = [user.id, otherUserId].sort().join(":");
|
|
@@ -4313,7 +4237,7 @@ function useConversations() {
|
|
|
4313
4237
|
},
|
|
4314
4238
|
[create, user?.id, conversations]
|
|
4315
4239
|
);
|
|
4316
|
-
const createGroupDM =
|
|
4240
|
+
const createGroupDM = useCallback21(
|
|
4317
4241
|
async (participantIds) => {
|
|
4318
4242
|
if (!user?.id) return null;
|
|
4319
4243
|
const allIds = [.../* @__PURE__ */ new Set([user.id, ...participantIds])];
|
|
@@ -4343,14 +4267,14 @@ function useConversations() {
|
|
|
4343
4267
|
},
|
|
4344
4268
|
[create, user?.id, conversations]
|
|
4345
4269
|
);
|
|
4346
|
-
const lookupByName =
|
|
4270
|
+
const lookupByName = useCallback21(
|
|
4347
4271
|
(name) => {
|
|
4348
4272
|
const found = conversations.find((r) => r.data.Name === name);
|
|
4349
4273
|
return found?.recordId ?? null;
|
|
4350
4274
|
},
|
|
4351
4275
|
[conversations]
|
|
4352
4276
|
);
|
|
4353
|
-
const updateLastMessage =
|
|
4277
|
+
const updateLastMessage = useCallback21(
|
|
4354
4278
|
(conversationId, preview, authorId) => {
|
|
4355
4279
|
const conv = conversations.find((c) => c.recordId === conversationId);
|
|
4356
4280
|
const baseData = conv?.data ?? recentCreationsRef.current.get(conversationId);
|
|
@@ -4369,7 +4293,7 @@ function useConversations() {
|
|
|
4369
4293
|
},
|
|
4370
4294
|
[put, conversations]
|
|
4371
4295
|
);
|
|
4372
|
-
const upsertState =
|
|
4296
|
+
const upsertState = useCallback21(
|
|
4373
4297
|
(conversationId, partial) => {
|
|
4374
4298
|
if (!user?.id) return;
|
|
4375
4299
|
const existing = stateRecords.find(
|
|
@@ -4391,7 +4315,7 @@ function useConversations() {
|
|
|
4391
4315
|
},
|
|
4392
4316
|
[stateMut, stateRecords, user?.id]
|
|
4393
4317
|
);
|
|
4394
|
-
const markRead =
|
|
4318
|
+
const markRead = useCallback21(
|
|
4395
4319
|
(conversationId) => {
|
|
4396
4320
|
const conv = conversations.find((c) => c.recordId === conversationId);
|
|
4397
4321
|
const msgCount = conv?.data.MessageCount ?? recentCreationsRef.current.get(conversationId)?.MessageCount ?? 0;
|
|
@@ -4402,32 +4326,32 @@ function useConversations() {
|
|
|
4402
4326
|
},
|
|
4403
4327
|
[upsertState, conversations]
|
|
4404
4328
|
);
|
|
4405
|
-
const toggleStar =
|
|
4329
|
+
const toggleStar = useCallback21(
|
|
4406
4330
|
(conversationId) => {
|
|
4407
4331
|
const isStarred = starredSet.has(conversationId);
|
|
4408
4332
|
upsertState(conversationId, { Starred: isStarred ? 0 : 1 });
|
|
4409
4333
|
},
|
|
4410
4334
|
[upsertState, starredSet]
|
|
4411
4335
|
);
|
|
4412
|
-
const setArchived =
|
|
4336
|
+
const setArchived = useCallback21(
|
|
4413
4337
|
(conversationId, archived) => {
|
|
4414
4338
|
upsertState(conversationId, { Archived: archived ? 1 : 0 });
|
|
4415
4339
|
},
|
|
4416
4340
|
[upsertState]
|
|
4417
4341
|
);
|
|
4418
|
-
const setTrashed =
|
|
4342
|
+
const setTrashed = useCallback21(
|
|
4419
4343
|
(conversationId, trashed) => {
|
|
4420
4344
|
upsertState(conversationId, { Trashed: trashed ? 1 : 0 });
|
|
4421
4345
|
},
|
|
4422
4346
|
[upsertState]
|
|
4423
4347
|
);
|
|
4424
|
-
const setLabels =
|
|
4348
|
+
const setLabels = useCallback21(
|
|
4425
4349
|
(conversationId, labels) => {
|
|
4426
4350
|
upsertState(conversationId, { Labels: JSON.stringify(labels) });
|
|
4427
4351
|
},
|
|
4428
4352
|
[upsertState]
|
|
4429
4353
|
);
|
|
4430
|
-
const setFolder =
|
|
4354
|
+
const setFolder = useCallback21(
|
|
4431
4355
|
(conversationId, folder) => {
|
|
4432
4356
|
upsertState(conversationId, { Folder: folder });
|
|
4433
4357
|
},
|
|
@@ -4457,7 +4381,7 @@ function useConversations() {
|
|
|
4457
4381
|
}
|
|
4458
4382
|
|
|
4459
4383
|
// src/client/directory/useCommunities.ts
|
|
4460
|
-
import { useCallback as
|
|
4384
|
+
import { useCallback as useCallback22, useMemo as useMemo15 } from "react";
|
|
4461
4385
|
function useCommunities() {
|
|
4462
4386
|
const { records: communities, status } = useQuery("communities");
|
|
4463
4387
|
const communityMut = useMutations("communities");
|
|
@@ -4480,7 +4404,7 @@ function useCommunities() {
|
|
|
4480
4404
|
),
|
|
4481
4405
|
[memberships, user?.id]
|
|
4482
4406
|
);
|
|
4483
|
-
const createCommunity =
|
|
4407
|
+
const createCommunity = useCallback22(
|
|
4484
4408
|
async (name, opts) => {
|
|
4485
4409
|
const existing = communities.find((c) => c.data.Name === name);
|
|
4486
4410
|
if (existing) return existing.recordId;
|
|
@@ -4499,7 +4423,7 @@ function useCommunities() {
|
|
|
4499
4423
|
},
|
|
4500
4424
|
[communityMut, user?.id, communities]
|
|
4501
4425
|
);
|
|
4502
|
-
const updateCommunity =
|
|
4426
|
+
const updateCommunity = useCallback22(
|
|
4503
4427
|
(communityId, updates) => {
|
|
4504
4428
|
const existing = communities.find((c) => c.recordId === communityId);
|
|
4505
4429
|
if (!existing) return;
|
|
@@ -4507,7 +4431,7 @@ function useCommunities() {
|
|
|
4507
4431
|
},
|
|
4508
4432
|
[communityMut, communities]
|
|
4509
4433
|
);
|
|
4510
|
-
const joinCommunity =
|
|
4434
|
+
const joinCommunity = useCallback22(
|
|
4511
4435
|
async (communityId, userName) => {
|
|
4512
4436
|
if (!user?.id) return null;
|
|
4513
4437
|
const existing = memberships.find(
|
|
@@ -4525,7 +4449,7 @@ function useCommunities() {
|
|
|
4525
4449
|
},
|
|
4526
4450
|
[membershipMut, memberships, user?.id]
|
|
4527
4451
|
);
|
|
4528
|
-
const leaveCommunity =
|
|
4452
|
+
const leaveCommunity = useCallback22(
|
|
4529
4453
|
(communityId) => {
|
|
4530
4454
|
if (!user?.id) return;
|
|
4531
4455
|
const membership = memberships.find(
|
|
@@ -4537,13 +4461,13 @@ function useCommunities() {
|
|
|
4537
4461
|
},
|
|
4538
4462
|
[membershipMut, memberships, user?.id]
|
|
4539
4463
|
);
|
|
4540
|
-
const getMembersOf =
|
|
4464
|
+
const getMembersOf = useCallback22(
|
|
4541
4465
|
(communityId) => {
|
|
4542
4466
|
return membershipMap.get(communityId) ?? [];
|
|
4543
4467
|
},
|
|
4544
4468
|
[membershipMap]
|
|
4545
4469
|
);
|
|
4546
|
-
const lookupByName =
|
|
4470
|
+
const lookupByName = useCallback22(
|
|
4547
4471
|
(name) => {
|
|
4548
4472
|
const found = communities.find((c) => c.data.Name === name);
|
|
4549
4473
|
return found?.recordId ?? null;
|
|
@@ -4565,14 +4489,14 @@ function useCommunities() {
|
|
|
4565
4489
|
}
|
|
4566
4490
|
|
|
4567
4491
|
// src/client/directory/usePosts.ts
|
|
4568
|
-
import { useCallback as
|
|
4492
|
+
import { useCallback as useCallback23 } from "react";
|
|
4569
4493
|
function usePosts(opts) {
|
|
4570
4494
|
const { records: allPosts, status } = useQuery("posts");
|
|
4571
4495
|
const postMut = useMutations("posts");
|
|
4572
4496
|
const { user } = useUser();
|
|
4573
4497
|
const ready = status === "ready";
|
|
4574
4498
|
const posts = opts?.communityId ? allPosts.filter((p) => p.data.CommunityId === opts.communityId) : allPosts;
|
|
4575
|
-
const createPost =
|
|
4499
|
+
const createPost = useCallback23(
|
|
4576
4500
|
async (data) => {
|
|
4577
4501
|
const recordId = await postMut.create({
|
|
4578
4502
|
Title: data.title,
|
|
@@ -4590,7 +4514,7 @@ function usePosts(opts) {
|
|
|
4590
4514
|
},
|
|
4591
4515
|
[postMut, user?.id]
|
|
4592
4516
|
);
|
|
4593
|
-
const updatePost =
|
|
4517
|
+
const updatePost = useCallback23(
|
|
4594
4518
|
(postId, updates) => {
|
|
4595
4519
|
const existing = allPosts.find((p) => p.recordId === postId);
|
|
4596
4520
|
if (!existing) return;
|
|
@@ -4598,13 +4522,13 @@ function usePosts(opts) {
|
|
|
4598
4522
|
},
|
|
4599
4523
|
[postMut, allPosts]
|
|
4600
4524
|
);
|
|
4601
|
-
const deletePost =
|
|
4525
|
+
const deletePost = useCallback23(
|
|
4602
4526
|
(postId) => {
|
|
4603
4527
|
postMut.remove(postId);
|
|
4604
4528
|
},
|
|
4605
4529
|
[postMut]
|
|
4606
4530
|
);
|
|
4607
|
-
const setConversationId =
|
|
4531
|
+
const setConversationId = useCallback23(
|
|
4608
4532
|
(postId, conversationId) => {
|
|
4609
4533
|
updatePost(postId, { ConversationId: conversationId });
|
|
4610
4534
|
},
|
|
@@ -4621,7 +4545,7 @@ function usePosts(opts) {
|
|
|
4621
4545
|
}
|
|
4622
4546
|
|
|
4623
4547
|
// src/client/theme/DeepSpaceThemeProvider.tsx
|
|
4624
|
-
import { useEffect as
|
|
4548
|
+
import { useEffect as useEffect15 } from "react";
|
|
4625
4549
|
|
|
4626
4550
|
// src/client/theme/applyTheme.ts
|
|
4627
4551
|
function mix(color, pct, base = "transparent") {
|
|
@@ -4934,7 +4858,7 @@ function DeepSpaceThemeProvider({
|
|
|
4934
4858
|
children,
|
|
4935
4859
|
theme
|
|
4936
4860
|
}) {
|
|
4937
|
-
|
|
4861
|
+
useEffect15(() => {
|
|
4938
4862
|
const root = document.documentElement;
|
|
4939
4863
|
const config = theme ?? readThemeFromDOM(root);
|
|
4940
4864
|
applyDeepSpaceTheme(config, root);
|
|
@@ -4943,12 +4867,12 @@ function DeepSpaceThemeProvider({
|
|
|
4943
4867
|
}
|
|
4944
4868
|
|
|
4945
4869
|
// src/client/theme/useIsDarkTheme.ts
|
|
4946
|
-
import { useState as
|
|
4870
|
+
import { useState as useState13, useEffect as useEffect16 } from "react";
|
|
4947
4871
|
function useIsDarkTheme() {
|
|
4948
|
-
const [isDark, setIsDark] =
|
|
4872
|
+
const [isDark, setIsDark] = useState13(
|
|
4949
4873
|
() => typeof document === "undefined" || document.documentElement.dataset.uiTheme !== "light"
|
|
4950
4874
|
);
|
|
4951
|
-
|
|
4875
|
+
useEffect16(() => {
|
|
4952
4876
|
const update = () => {
|
|
4953
4877
|
setIsDark(document.documentElement.dataset.uiTheme !== "light");
|
|
4954
4878
|
};
|
|
@@ -4960,7 +4884,7 @@ function useIsDarkTheme() {
|
|
|
4960
4884
|
}
|
|
4961
4885
|
|
|
4962
4886
|
// src/client/platform/PlatformProvider.tsx
|
|
4963
|
-
import { createContext as createContext3, useContext as useContext5, useState as
|
|
4887
|
+
import { createContext as createContext3, useContext as useContext5, useState as useState14, useEffect as useEffect17, useRef as useRef14, useCallback as useCallback24 } from "react";
|
|
4964
4888
|
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
4965
4889
|
var PlatformContext = createContext3(null);
|
|
4966
4890
|
function usePlatform() {
|
|
@@ -4970,14 +4894,14 @@ function usePlatform() {
|
|
|
4970
4894
|
}
|
|
4971
4895
|
function useInbox() {
|
|
4972
4896
|
const { inbox, subscribeInbox } = usePlatform();
|
|
4973
|
-
|
|
4897
|
+
useEffect17(() => subscribeInbox(), [subscribeInbox]);
|
|
4974
4898
|
return inbox;
|
|
4975
4899
|
}
|
|
4976
4900
|
function PlatformProvider({ children }) {
|
|
4977
|
-
const [inbox, setInbox] =
|
|
4978
|
-
const inboxSubscribers =
|
|
4979
|
-
const [inboxActive, setInboxActive] =
|
|
4980
|
-
const subscribeInbox =
|
|
4901
|
+
const [inbox, setInbox] = useState14([]);
|
|
4902
|
+
const inboxSubscribers = useRef14(0);
|
|
4903
|
+
const [inboxActive, setInboxActive] = useState14(false);
|
|
4904
|
+
const subscribeInbox = useCallback24(() => {
|
|
4981
4905
|
inboxSubscribers.current++;
|
|
4982
4906
|
if (inboxSubscribers.current === 1) setInboxActive(true);
|
|
4983
4907
|
return () => {
|
|
@@ -4985,7 +4909,7 @@ function PlatformProvider({ children }) {
|
|
|
4985
4909
|
if (inboxSubscribers.current === 0) setInboxActive(false);
|
|
4986
4910
|
};
|
|
4987
4911
|
}, []);
|
|
4988
|
-
|
|
4912
|
+
useEffect17(() => {
|
|
4989
4913
|
if (!inboxActive) return;
|
|
4990
4914
|
let mounted = true;
|
|
4991
4915
|
let ws = null;
|
|
@@ -5046,7 +4970,7 @@ function PlatformProvider({ children }) {
|
|
|
5046
4970
|
setInbox([]);
|
|
5047
4971
|
};
|
|
5048
4972
|
}, [inboxActive]);
|
|
5049
|
-
const platformFetch =
|
|
4973
|
+
const platformFetch = useCallback24(async (path, init) => {
|
|
5050
4974
|
const token = await getAuthToken();
|
|
5051
4975
|
const headers = new Headers(init?.headers);
|
|
5052
4976
|
if (token) headers.set("Authorization", `Bearer ${token}`);
|
|
@@ -5057,28 +4981,28 @@ function PlatformProvider({ children }) {
|
|
|
5057
4981
|
}
|
|
5058
4982
|
|
|
5059
4983
|
// src/client/platform/usePlatformWS.ts
|
|
5060
|
-
import { useState as
|
|
4984
|
+
import { useState as useState15, useEffect as useEffect18, useRef as useRef15 } from "react";
|
|
5061
4985
|
var MAX_RECONNECT_DELAY = 1e4;
|
|
5062
4986
|
var BASE_RECONNECT_DELAY = 500;
|
|
5063
4987
|
function usePlatformWS(options) {
|
|
5064
4988
|
const { path, scopeId, initialState, onMessage } = options;
|
|
5065
|
-
const wsRef =
|
|
5066
|
-
const pingIntervalRef =
|
|
5067
|
-
const [state, setState] =
|
|
5068
|
-
const reconnectAttemptRef =
|
|
5069
|
-
const reconnectTimerRef =
|
|
5070
|
-
const mountedRef =
|
|
5071
|
-
const onMessageRef =
|
|
4989
|
+
const wsRef = useRef15(null);
|
|
4990
|
+
const pingIntervalRef = useRef15(null);
|
|
4991
|
+
const [state, setState] = useState15(initialState);
|
|
4992
|
+
const reconnectAttemptRef = useRef15(0);
|
|
4993
|
+
const reconnectTimerRef = useRef15(null);
|
|
4994
|
+
const mountedRef = useRef15(true);
|
|
4995
|
+
const onMessageRef = useRef15(onMessage);
|
|
5072
4996
|
onMessageRef.current = onMessage;
|
|
5073
|
-
const initialStateRef =
|
|
4997
|
+
const initialStateRef = useRef15(initialState);
|
|
5074
4998
|
initialStateRef.current = initialState;
|
|
5075
|
-
|
|
4999
|
+
useEffect18(() => {
|
|
5076
5000
|
mountedRef.current = true;
|
|
5077
5001
|
return () => {
|
|
5078
5002
|
mountedRef.current = false;
|
|
5079
5003
|
};
|
|
5080
5004
|
}, []);
|
|
5081
|
-
|
|
5005
|
+
useEffect18(() => {
|
|
5082
5006
|
if (!scopeId) return;
|
|
5083
5007
|
setState(initialStateRef.current);
|
|
5084
5008
|
reconnectAttemptRef.current = 0;
|
|
@@ -5137,7 +5061,7 @@ function usePlatformWS(options) {
|
|
|
5137
5061
|
wsRef.current = null;
|
|
5138
5062
|
};
|
|
5139
5063
|
}, [scopeId, path]);
|
|
5140
|
-
const send =
|
|
5064
|
+
const send = useRef15((msg) => {
|
|
5141
5065
|
wsRef.current?.send(JSON.stringify(msg));
|
|
5142
5066
|
}).current;
|
|
5143
5067
|
return { state, send };
|
|
@@ -5248,27 +5172,27 @@ var integration = {
|
|
|
5248
5172
|
};
|
|
5249
5173
|
|
|
5250
5174
|
// src/client/voice/useVoiceAgent.ts
|
|
5251
|
-
import { useCallback as
|
|
5175
|
+
import { useCallback as useCallback25, useEffect as useEffect19, useRef as useRef16, useState as useState16 } from "react";
|
|
5252
5176
|
var OPENAI_REALTIME_BASE = "https://api.openai.com/v1";
|
|
5253
5177
|
var ZERO_USAGE = { inputAudioTokens: 0, outputAudioTokens: 0, inputTextTokens: 0, outputTextTokens: 0 };
|
|
5254
5178
|
function useVoiceAgent(options = {}) {
|
|
5255
|
-
const [status, setStatus] =
|
|
5256
|
-
const [isMuted, setIsMuted] =
|
|
5257
|
-
const [isAgentSpeaking, setIsAgentSpeaking] =
|
|
5258
|
-
const [transcript, setTranscript] =
|
|
5259
|
-
const [error, setError] =
|
|
5260
|
-
const pcRef =
|
|
5261
|
-
const dcRef =
|
|
5262
|
-
const streamRef =
|
|
5263
|
-
const audioRef =
|
|
5264
|
-
const timerRef =
|
|
5265
|
-
const sessionIdRef =
|
|
5266
|
-
const liveStartRef =
|
|
5267
|
-
const settledRef =
|
|
5268
|
-
const usageRef =
|
|
5269
|
-
const optsRef =
|
|
5179
|
+
const [status, setStatus] = useState16("idle");
|
|
5180
|
+
const [isMuted, setIsMuted] = useState16(false);
|
|
5181
|
+
const [isAgentSpeaking, setIsAgentSpeaking] = useState16(false);
|
|
5182
|
+
const [transcript, setTranscript] = useState16([]);
|
|
5183
|
+
const [error, setError] = useState16(null);
|
|
5184
|
+
const pcRef = useRef16(null);
|
|
5185
|
+
const dcRef = useRef16(null);
|
|
5186
|
+
const streamRef = useRef16(null);
|
|
5187
|
+
const audioRef = useRef16(null);
|
|
5188
|
+
const timerRef = useRef16(null);
|
|
5189
|
+
const sessionIdRef = useRef16(null);
|
|
5190
|
+
const liveStartRef = useRef16(null);
|
|
5191
|
+
const settledRef = useRef16(false);
|
|
5192
|
+
const usageRef = useRef16({ ...ZERO_USAGE });
|
|
5193
|
+
const optsRef = useRef16(options);
|
|
5270
5194
|
optsRef.current = options;
|
|
5271
|
-
const settle =
|
|
5195
|
+
const settle = useCallback25(async () => {
|
|
5272
5196
|
const sessionId = sessionIdRef.current;
|
|
5273
5197
|
if (!sessionId || settledRef.current) return;
|
|
5274
5198
|
settledRef.current = true;
|
|
@@ -5282,7 +5206,7 @@ function useVoiceAgent(options = {}) {
|
|
|
5282
5206
|
} catch {
|
|
5283
5207
|
}
|
|
5284
5208
|
}, []);
|
|
5285
|
-
const cleanup =
|
|
5209
|
+
const cleanup = useCallback25(() => {
|
|
5286
5210
|
if (timerRef.current) {
|
|
5287
5211
|
clearTimeout(timerRef.current);
|
|
5288
5212
|
timerRef.current = null;
|
|
@@ -5306,13 +5230,13 @@ function useVoiceAgent(options = {}) {
|
|
|
5306
5230
|
streamRef.current = null;
|
|
5307
5231
|
audioRef.current = null;
|
|
5308
5232
|
}, []);
|
|
5309
|
-
const stop =
|
|
5233
|
+
const stop = useCallback25(async () => {
|
|
5310
5234
|
cleanup();
|
|
5311
5235
|
await settle();
|
|
5312
5236
|
setIsAgentSpeaking(false);
|
|
5313
5237
|
setStatus((s) => s === "error" ? s : "ended");
|
|
5314
5238
|
}, [cleanup, settle]);
|
|
5315
|
-
const appendTranscript =
|
|
5239
|
+
const appendTranscript = useCallback25((role, delta) => {
|
|
5316
5240
|
if (!delta) return;
|
|
5317
5241
|
setTranscript((prev) => {
|
|
5318
5242
|
const last = prev[prev.length - 1];
|
|
@@ -5320,7 +5244,7 @@ function useVoiceAgent(options = {}) {
|
|
|
5320
5244
|
return [...prev, { role, content: delta }];
|
|
5321
5245
|
});
|
|
5322
5246
|
}, []);
|
|
5323
|
-
const handleToolCall =
|
|
5247
|
+
const handleToolCall = useCallback25(async (item) => {
|
|
5324
5248
|
const onToolCall = optsRef.current.onToolCall;
|
|
5325
5249
|
let output = null;
|
|
5326
5250
|
if (onToolCall && item.name) {
|
|
@@ -5346,7 +5270,7 @@ function useVoiceAgent(options = {}) {
|
|
|
5346
5270
|
);
|
|
5347
5271
|
dc.send(JSON.stringify({ type: "response.create" }));
|
|
5348
5272
|
}, []);
|
|
5349
|
-
const handleEvent =
|
|
5273
|
+
const handleEvent = useCallback25(
|
|
5350
5274
|
(raw) => {
|
|
5351
5275
|
if (typeof raw !== "string") return;
|
|
5352
5276
|
let ev;
|
|
@@ -5386,7 +5310,7 @@ function useVoiceAgent(options = {}) {
|
|
|
5386
5310
|
},
|
|
5387
5311
|
[appendTranscript, handleToolCall]
|
|
5388
5312
|
);
|
|
5389
|
-
const start =
|
|
5313
|
+
const start = useCallback25(
|
|
5390
5314
|
async (overrides = {}) => {
|
|
5391
5315
|
if (sessionIdRef.current) {
|
|
5392
5316
|
cleanup();
|
|
@@ -5448,7 +5372,7 @@ function useVoiceAgent(options = {}) {
|
|
|
5448
5372
|
},
|
|
5449
5373
|
[cleanup, settle, stop, handleEvent]
|
|
5450
5374
|
);
|
|
5451
|
-
const toggleMute =
|
|
5375
|
+
const toggleMute = useCallback25(() => {
|
|
5452
5376
|
const stream = streamRef.current;
|
|
5453
5377
|
if (!stream) return;
|
|
5454
5378
|
setIsMuted((muted) => {
|
|
@@ -5457,7 +5381,7 @@ function useVoiceAgent(options = {}) {
|
|
|
5457
5381
|
return next;
|
|
5458
5382
|
});
|
|
5459
5383
|
}, []);
|
|
5460
|
-
|
|
5384
|
+
useEffect19(() => {
|
|
5461
5385
|
return () => {
|
|
5462
5386
|
cleanup();
|
|
5463
5387
|
void settle();
|
|
@@ -5545,7 +5469,7 @@ function decodeAiStreamChunk(chunk) {
|
|
|
5545
5469
|
}
|
|
5546
5470
|
|
|
5547
5471
|
// src/client/status.ts
|
|
5548
|
-
import { useCallback as
|
|
5472
|
+
import { useCallback as useCallback26, useEffect as useEffect20, useMemo as useMemo16, useRef as useRef17, useState as useState17 } from "react";
|
|
5549
5473
|
|
|
5550
5474
|
// src/client/status-core.ts
|
|
5551
5475
|
var ASYNC_RESOURCE_DEFAULTS = {
|
|
@@ -5629,7 +5553,7 @@ function useAsyncResource(fetcher, deps, options = {}) {
|
|
|
5629
5553
|
const retry = options.retry ?? ASYNC_RESOURCE_DEFAULTS.retry;
|
|
5630
5554
|
const retryDelayMs = options.retryDelayMs ?? ASYNC_RESOURCE_DEFAULTS.retryDelayMs;
|
|
5631
5555
|
const slowAfterMs = options.slowAfterMs ?? ASYNC_RESOURCE_DEFAULTS.slowAfterMs;
|
|
5632
|
-
const [state, setState] =
|
|
5556
|
+
const [state, setState] = useState17(() => ({
|
|
5633
5557
|
status: enabled ? "loading" : "idle",
|
|
5634
5558
|
data: options.initialData ?? null,
|
|
5635
5559
|
error: null,
|
|
@@ -5637,12 +5561,12 @@ function useAsyncResource(fetcher, deps, options = {}) {
|
|
|
5637
5561
|
isSlow: false,
|
|
5638
5562
|
retryCount: 0
|
|
5639
5563
|
}));
|
|
5640
|
-
const requestIdRef =
|
|
5641
|
-
const [reloadTick, setReloadTick] =
|
|
5642
|
-
const reload =
|
|
5564
|
+
const requestIdRef = useRef17(0);
|
|
5565
|
+
const [reloadTick, setReloadTick] = useState17(0);
|
|
5566
|
+
const reload = useCallback26(() => {
|
|
5643
5567
|
setReloadTick((tick) => tick + 1);
|
|
5644
5568
|
}, []);
|
|
5645
|
-
|
|
5569
|
+
useEffect20(() => {
|
|
5646
5570
|
if (!enabled) {
|
|
5647
5571
|
setState((prev) => ({ ...prev, status: "idle", isRefreshing: false, isSlow: false, retryCount: 0 }));
|
|
5648
5572
|
return;
|
|
@@ -5731,7 +5655,7 @@ function usePagedResource(fetchPage, deps, options = {}) {
|
|
|
5731
5655
|
const retryDelayMs = options.retryDelayMs ?? ASYNC_RESOURCE_DEFAULTS.retryDelayMs;
|
|
5732
5656
|
const maxRetryDelayMs = options.maxRetryDelayMs ?? 3e4;
|
|
5733
5657
|
const hasInitialItems = initialItems.length > 0;
|
|
5734
|
-
const [state, setState] =
|
|
5658
|
+
const [state, setState] = useState17(() => ({
|
|
5735
5659
|
status: enabled ? hasInitialItems ? "ready" : "loading" : "idle",
|
|
5736
5660
|
items: initialItems,
|
|
5737
5661
|
error: null,
|
|
@@ -5741,25 +5665,25 @@ function usePagedResource(fetchPage, deps, options = {}) {
|
|
|
5741
5665
|
isLoadingMore: false,
|
|
5742
5666
|
isRefreshing: false
|
|
5743
5667
|
}));
|
|
5744
|
-
const requestIdRef =
|
|
5745
|
-
const controllerRef =
|
|
5746
|
-
const loadingRef =
|
|
5747
|
-
const nextPageRef =
|
|
5748
|
-
const failedPageRef =
|
|
5749
|
-
const failureCountRef =
|
|
5750
|
-
const cooldownUntilRef =
|
|
5751
|
-
const autoRetryTimerRef =
|
|
5752
|
-
const clearAutoRetryTimer =
|
|
5668
|
+
const requestIdRef = useRef17(0);
|
|
5669
|
+
const controllerRef = useRef17(null);
|
|
5670
|
+
const loadingRef = useRef17(false);
|
|
5671
|
+
const nextPageRef = useRef17(hasInitialItems ? 2 : 1);
|
|
5672
|
+
const failedPageRef = useRef17(null);
|
|
5673
|
+
const failureCountRef = useRef17(0);
|
|
5674
|
+
const cooldownUntilRef = useRef17(0);
|
|
5675
|
+
const autoRetryTimerRef = useRef17(null);
|
|
5676
|
+
const clearAutoRetryTimer = useCallback26(() => {
|
|
5753
5677
|
if (autoRetryTimerRef.current) {
|
|
5754
5678
|
clearTimeout(autoRetryTimerRef.current);
|
|
5755
5679
|
autoRetryTimerRef.current = null;
|
|
5756
5680
|
}
|
|
5757
5681
|
}, []);
|
|
5758
|
-
const resetCooldown =
|
|
5682
|
+
const resetCooldown = useCallback26(() => {
|
|
5759
5683
|
failureCountRef.current = 0;
|
|
5760
5684
|
cooldownUntilRef.current = 0;
|
|
5761
5685
|
}, []);
|
|
5762
|
-
const setFailureCooldown =
|
|
5686
|
+
const setFailureCooldown = useCallback26(() => {
|
|
5763
5687
|
failureCountRef.current += 1;
|
|
5764
5688
|
const delay = getPagedResourceCooldownMs({
|
|
5765
5689
|
failureCount: failureCountRef.current,
|
|
@@ -5769,7 +5693,7 @@ function usePagedResource(fetchPage, deps, options = {}) {
|
|
|
5769
5693
|
cooldownUntilRef.current = Date.now() + delay;
|
|
5770
5694
|
return delay;
|
|
5771
5695
|
}, [maxRetryDelayMs, retryDelayMs]);
|
|
5772
|
-
const startLoad =
|
|
5696
|
+
const startLoad = useCallback26(async (page, mode) => {
|
|
5773
5697
|
if (!enabled || loadingRef.current) return;
|
|
5774
5698
|
if (mode === "auto" && !canAutoLoadPagedResource({
|
|
5775
5699
|
hasMore: true,
|
|
@@ -5849,21 +5773,21 @@ function usePagedResource(fetchPage, deps, options = {}) {
|
|
|
5849
5773
|
}
|
|
5850
5774
|
}
|
|
5851
5775
|
}, [autoRetryOnError, clearAutoRetryTimer, enabled, fetchPage, keepPreviousData, maxItemsPerPage, pageSize, resetCooldown, setFailureCooldown]);
|
|
5852
|
-
const loadMore =
|
|
5776
|
+
const loadMore = useCallback26(() => {
|
|
5853
5777
|
if (!state.hasMore || state.isLoadingInitial || state.isLoadingMore || state.isRefreshing) return;
|
|
5854
5778
|
void startLoad(nextPageRef.current, "auto");
|
|
5855
5779
|
}, [startLoad, state.hasMore, state.isLoadingInitial, state.isLoadingMore, state.isRefreshing]);
|
|
5856
|
-
const retry =
|
|
5780
|
+
const retry = useCallback26(() => {
|
|
5857
5781
|
const page = failedPageRef.current ?? nextPageRef.current;
|
|
5858
5782
|
void startLoad(page, "manual");
|
|
5859
5783
|
}, [startLoad]);
|
|
5860
|
-
const refresh =
|
|
5784
|
+
const refresh = useCallback26(() => {
|
|
5861
5785
|
failedPageRef.current = null;
|
|
5862
5786
|
resetCooldown();
|
|
5863
5787
|
nextPageRef.current = 1;
|
|
5864
5788
|
void startLoad(1, "refresh");
|
|
5865
5789
|
}, [resetCooldown, startLoad]);
|
|
5866
|
-
|
|
5790
|
+
useEffect20(() => {
|
|
5867
5791
|
requestIdRef.current += 1;
|
|
5868
5792
|
controllerRef.current?.abort();
|
|
5869
5793
|
clearAutoRetryTimer();
|
|
@@ -5900,7 +5824,7 @@ function usePagedResource(fetchPage, deps, options = {}) {
|
|
|
5900
5824
|
}
|
|
5901
5825
|
|
|
5902
5826
|
// src/client/subscriptions/useSubscription.ts
|
|
5903
|
-
import { useCallback as
|
|
5827
|
+
import { useCallback as useCallback27, useEffect as useEffect21, useState as useState18 } from "react";
|
|
5904
5828
|
|
|
5905
5829
|
// src/shared/subscription.ts
|
|
5906
5830
|
var ENTITLED_STATUSES = /* @__PURE__ */ new Set([
|
|
@@ -5931,7 +5855,7 @@ async function authedJson(path, init) {
|
|
|
5931
5855
|
return data;
|
|
5932
5856
|
}
|
|
5933
5857
|
function useSubscription() {
|
|
5934
|
-
const [state, setState] =
|
|
5858
|
+
const [state, setState] = useState18({
|
|
5935
5859
|
tier: "free",
|
|
5936
5860
|
status: "none",
|
|
5937
5861
|
interval: null,
|
|
@@ -5940,9 +5864,9 @@ function useSubscription() {
|
|
|
5940
5864
|
trialEndsAt: null,
|
|
5941
5865
|
plans: []
|
|
5942
5866
|
});
|
|
5943
|
-
const [isLoading, setLoading] =
|
|
5944
|
-
const [error, setError] =
|
|
5945
|
-
const refresh =
|
|
5867
|
+
const [isLoading, setLoading] = useState18(true);
|
|
5868
|
+
const [error, setError] = useState18(null);
|
|
5869
|
+
const refresh = useCallback27(async () => {
|
|
5946
5870
|
setLoading(true);
|
|
5947
5871
|
try {
|
|
5948
5872
|
const r = await authedJson("/_deepspace/subscriptions/me");
|
|
@@ -5962,15 +5886,15 @@ function useSubscription() {
|
|
|
5962
5886
|
setLoading(false);
|
|
5963
5887
|
}
|
|
5964
5888
|
}, []);
|
|
5965
|
-
|
|
5889
|
+
useEffect21(() => {
|
|
5966
5890
|
refresh();
|
|
5967
5891
|
}, [refresh]);
|
|
5968
5892
|
const entitled = isEntitled(state.tier, state.status);
|
|
5969
|
-
const hasTier =
|
|
5893
|
+
const hasTier = useCallback27(
|
|
5970
5894
|
(slug) => state.tier === slug && isEntitled(state.tier, state.status),
|
|
5971
5895
|
[state.tier, state.status]
|
|
5972
5896
|
);
|
|
5973
|
-
const isAtLeast =
|
|
5897
|
+
const isAtLeast = useCallback27(
|
|
5974
5898
|
(slug) => {
|
|
5975
5899
|
if (!isEntitled(state.tier, state.status)) return false;
|
|
5976
5900
|
const targetRank = state.plans.find((p) => p.slug === slug)?.rank;
|
|
@@ -5980,7 +5904,7 @@ function useSubscription() {
|
|
|
5980
5904
|
},
|
|
5981
5905
|
[state.plans, state.tier, state.status]
|
|
5982
5906
|
);
|
|
5983
|
-
const subscribe =
|
|
5907
|
+
const subscribe = useCallback27(
|
|
5984
5908
|
async (planSlug, opts) => {
|
|
5985
5909
|
const result = await authedJson("/_deepspace/subscriptions/checkout", {
|
|
5986
5910
|
method: "POST",
|
|
@@ -6000,7 +5924,7 @@ function useSubscription() {
|
|
|
6000
5924
|
},
|
|
6001
5925
|
[refresh]
|
|
6002
5926
|
);
|
|
6003
|
-
const openPortal =
|
|
5927
|
+
const openPortal = useCallback27(
|
|
6004
5928
|
async (returnUrl) => {
|
|
6005
5929
|
return authedJson("/_deepspace/subscriptions/portal", {
|
|
6006
5930
|
method: "POST",
|
|
@@ -6069,7 +5993,7 @@ function PricingTable(props) {
|
|
|
6069
5993
|
}
|
|
6070
5994
|
|
|
6071
5995
|
// src/client/charges/useCheckout.ts
|
|
6072
|
-
import { useCallback as
|
|
5996
|
+
import { useCallback as useCallback28, useEffect as useEffect22, useMemo as useMemo17, useState as useState19 } from "react";
|
|
6073
5997
|
async function authedJson2(path, init) {
|
|
6074
5998
|
const token = await getAuthToken();
|
|
6075
5999
|
const res = await fetch(path, {
|
|
@@ -6088,10 +6012,10 @@ async function authedJson2(path, init) {
|
|
|
6088
6012
|
return data;
|
|
6089
6013
|
}
|
|
6090
6014
|
function useCheckout(opts) {
|
|
6091
|
-
const [purchases, setPurchases] =
|
|
6092
|
-
const [isLoading, setLoading] =
|
|
6093
|
-
const [error, setError] =
|
|
6094
|
-
const refresh =
|
|
6015
|
+
const [purchases, setPurchases] = useState19([]);
|
|
6016
|
+
const [isLoading, setLoading] = useState19(true);
|
|
6017
|
+
const [error, setError] = useState19(null);
|
|
6018
|
+
const refresh = useCallback28(async () => {
|
|
6095
6019
|
setLoading(true);
|
|
6096
6020
|
try {
|
|
6097
6021
|
const r = await authedJson2(
|
|
@@ -6105,10 +6029,10 @@ function useCheckout(opts) {
|
|
|
6105
6029
|
setLoading(false);
|
|
6106
6030
|
}
|
|
6107
6031
|
}, []);
|
|
6108
|
-
|
|
6032
|
+
useEffect22(() => {
|
|
6109
6033
|
refresh();
|
|
6110
6034
|
}, [refresh]);
|
|
6111
|
-
const chargeOnce =
|
|
6035
|
+
const chargeOnce = useCallback28(
|
|
6112
6036
|
async (chargeOpts) => {
|
|
6113
6037
|
setError(null);
|
|
6114
6038
|
const common = {
|
|
@@ -6142,7 +6066,7 @@ function useCheckout(opts) {
|
|
|
6142
6066
|
},
|
|
6143
6067
|
[]
|
|
6144
6068
|
);
|
|
6145
|
-
const ownsProduct =
|
|
6069
|
+
const ownsProduct = useCallback28(
|
|
6146
6070
|
(productId) => purchases.some((p) => p.productId === productId),
|
|
6147
6071
|
[purchases]
|
|
6148
6072
|
);
|
|
@@ -6311,7 +6235,6 @@ export {
|
|
|
6311
6235
|
AuthGate,
|
|
6312
6236
|
AuthOverlay,
|
|
6313
6237
|
Awareness,
|
|
6314
|
-
CANONICAL_APP_IDENTITY_MIGRATION_ID,
|
|
6315
6238
|
DEEPSPACE_AGENT_PROFILES,
|
|
6316
6239
|
DEEPSPACE_AI_DEFAULTS,
|
|
6317
6240
|
DEEPSPACE_AI_MODELS,
|
|
@@ -6422,7 +6345,6 @@ export {
|
|
|
6422
6345
|
useConversations,
|
|
6423
6346
|
useCronMonitor,
|
|
6424
6347
|
useDisplayName,
|
|
6425
|
-
useGameRoom,
|
|
6426
6348
|
useInbox,
|
|
6427
6349
|
useIsDarkTheme,
|
|
6428
6350
|
useJobs,
|