deepspace 0.3.9 → 0.3.11
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/cli.js +96 -18
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +160 -1
- package/dist/index.js +283 -126
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +172 -2
- package/dist/server.js +581 -1
- package/dist/server.js.map +1 -1
- package/dist/worker.d.ts +252 -2
- package/dist/worker.js +588 -1
- package/dist/worker.js.map +1 -1
- package/features/admin-page/feature.json +29 -0
- package/features/admin-page/src/AdminPage.tsx +292 -0
- package/features/admin-page/src/admin-schema.ts +20 -0
- package/features/ai-chat/feature.json +41 -0
- package/features/ai-chat/src/AiChatPage.tsx +692 -0
- package/features/ai-chat/src/ChatPanel.tsx +1098 -0
- package/features/ai-chat/src/ai-chat-schema.ts +11 -0
- package/features/canvas/feature.json +45 -0
- package/features/canvas/src/CanvasEditorPage.tsx +87 -0
- package/features/canvas/src/CanvasListPage.tsx +202 -0
- package/features/canvas/src/canvas-schema.ts +33 -0
- package/features/canvas/src/components/CanvasToolbar.tsx +170 -0
- package/features/canvas/src/components/CanvasView.tsx +369 -0
- package/features/canvas/src/components/ShapeRenderer.tsx +114 -0
- package/features/cron/feature.json +33 -0
- package/features/cron/src/CronLogPage.tsx +100 -0
- package/features/cron/src/cron.ts +25 -0
- package/features/docs/feature.json +96 -0
- package/features/docs/src/DocsEditorPage.tsx +1012 -0
- package/features/docs/src/DocsListPage.tsx +951 -0
- package/features/docs/src/DocsOutlinePanel.tsx +68 -0
- package/features/docs/src/DocsPresence.tsx +138 -0
- package/features/docs/src/InviteDialog.tsx +336 -0
- package/features/docs/src/LibrarySidebar.tsx +464 -0
- package/features/docs/src/docs-favorites.ts +18 -0
- package/features/docs/src/docs-library-types.ts +15 -0
- package/features/docs/src/docs-schema.ts +80 -0
- package/features/docs/src/docs-ui.css +309 -0
- package/features/docs/src/editor/DocEditorSurface.tsx +257 -0
- package/features/docs/src/editor/DocsTiptapToolbar.tsx +560 -0
- package/features/docs/src/editor/useDocEditor.ts +206 -0
- package/features/docs/src/use-yjs-room-with-awareness.ts +285 -0
- package/features/file-attachments/feature.json +42 -0
- package/features/file-attachments/src/AttachmentsPage.tsx +864 -0
- package/features/file-attachments/src/attachments-constants.ts +9 -0
- package/features/file-attachments/src/attachments-schema.ts +45 -0
- package/features/file-attachments/src/useFilePreview.ts +471 -0
- package/features/file-attachments/src/useMimeTypeDetection.ts +138 -0
- package/features/file-manager/feature.json +24 -0
- package/features/file-manager/src/FileManagerPage.tsx +330 -0
- package/features/integration-test/feature.json +18 -0
- package/features/integration-test/src/IntegrationTestPage.tsx +423 -0
- package/features/integration-test/src/integration.spec.ts +42 -0
- package/features/items/feature.json +33 -0
- package/features/items/src/ItemsPage.tsx +325 -0
- package/features/items/src/items-constants.ts +10 -0
- package/features/items/src/items-schema.ts +27 -0
- package/features/kanban/feature.json +18 -0
- package/features/kanban/src/Kanban.tsx +283 -0
- package/features/landing/feature.json +62 -0
- package/features/landing/src/LandingPage.tsx +627 -0
- package/features/landing/src/primitives.tsx +389 -0
- package/features/landing/src/sections/FAQSection.tsx +110 -0
- package/features/landing/src/sections/FeaturesGridSection.tsx +311 -0
- package/features/landing/src/sections/HowItWorksSection.tsx +62 -0
- package/features/landing/src/sections/LogoCloudSection.tsx +58 -0
- package/features/landing/src/sections/ShowcaseSection.tsx +63 -0
- package/features/landing/src/sections/StatsSection.tsx +31 -0
- package/features/landing/src/sections/TeamSection.tsx +86 -0
- package/features/landing/src/sections/TestimonialsSection.tsx +68 -0
- package/features/landing/src/sections/VideoSection.tsx +71 -0
- package/features/leaderboard/feature.json +33 -0
- package/features/leaderboard/src/LeaderboardPage.tsx +372 -0
- package/features/leaderboard/src/leaderboard-constants.ts +21 -0
- package/features/leaderboard/src/leaderboard-schema.ts +36 -0
- package/features/messaging/feature.json +111 -0
- package/features/messaging/src/ChatMultiPage.tsx +300 -0
- package/features/messaging/src/ChatPage.tsx +75 -0
- package/features/messaging/src/components/chat/ChatHeader.tsx +76 -0
- package/features/messaging/src/components/chat/MessageActionSheet.tsx +168 -0
- package/features/messaging/src/components/chat/MessageInput.tsx +65 -0
- package/features/messaging/src/components/chat/MessageItem.tsx +352 -0
- package/features/messaging/src/components/chat/MessageList.tsx +248 -0
- package/features/messaging/src/components/chat/ReactionPicker.tsx +2 -0
- package/features/messaging/src/components/chat/ThreadPanel.tsx +107 -0
- package/features/messaging/src/components/chat/UserProfilePopover.tsx +158 -0
- package/features/messaging/src/components/chat-multi/AddMemberModal.tsx +188 -0
- package/features/messaging/src/components/chat-multi/BrowseGroupsModal.tsx +163 -0
- package/features/messaging/src/components/chat-multi/ChannelListItem.tsx +147 -0
- package/features/messaging/src/components/chat-multi/ChannelSettingsPanel.tsx +344 -0
- package/features/messaging/src/components/chat-multi/ChannelSidebar.tsx +460 -0
- package/features/messaging/src/components/chat-multi/CreateGroupModal.tsx +190 -0
- package/features/messaging/src/components/chat-multi/InvitationList.tsx +149 -0
- package/features/messaging/src/components/chat-multi/NewMessageModal.tsx +159 -0
- package/features/messaging/src/hooks/useChatChannel.ts +64 -0
- package/features/messaging/src/hooks/useLongPress.ts +74 -0
- package/features/messaging/src/hooks/useMultiChannel.ts +142 -0
- package/features/messaging/src/messaging-schema.ts +25 -0
- package/features/presence-test/feature.json +21 -0
- package/features/presence-test/src/PresenceTestPage.tsx +120 -0
- package/features/sidebar/feature.json +19 -0
- package/features/sidebar/src/AppSidebar.tsx +558 -0
- package/features/tasks/feature.json +33 -0
- package/features/tasks/src/TasksPage.tsx +598 -0
- package/features/tasks/src/tasks-constants.ts +43 -0
- package/features/tasks/src/tasks-schema.ts +56 -0
- package/features/testing/feature.json +49 -0
- package/features/testing/src/TestPage.tsx +145 -0
- package/features/testing/src/cpu-burn-action.ts +51 -0
- package/features/testing/src/subrequest-burn-action.ts +53 -0
- package/features/testing/src/test-schema.ts +23 -0
- package/features/topbar/feature.json +18 -0
- package/features/topbar/src/Topbar.tsx +353 -0
- package/features/tree/feature.json +26 -0
- package/features/tree/src/TreeSidebar.tsx +607 -0
- package/features/tree/src/tree-constants.ts +68 -0
- package/features/tree/src/tree-hooks.ts +258 -0
- package/package.json +4 -2
- package/scripts/add-feature.cjs +654 -0
package/dist/index.js
CHANGED
|
@@ -11,11 +11,11 @@ var DEV_CONFIG = {
|
|
|
11
11
|
};
|
|
12
12
|
var PROD_CONFIG = {
|
|
13
13
|
name: "prod",
|
|
14
|
-
apiUrl: "https://
|
|
15
|
-
platformWorkerUrl: "https://
|
|
16
|
-
authUrl: "https://
|
|
17
|
-
authSignInUrl: "https://deep.space/
|
|
18
|
-
authSignUpUrl: "https://deep.space/
|
|
14
|
+
apiUrl: "https://api-worker.deep.space",
|
|
15
|
+
platformWorkerUrl: "https://platform-worker.deep.space",
|
|
16
|
+
authUrl: "https://auth.deep.space",
|
|
17
|
+
authSignInUrl: "https://auth.deep.space/login/social",
|
|
18
|
+
authSignUpUrl: "https://auth.deep.space/login/social",
|
|
19
19
|
mainAppUrl: "https://deep.space",
|
|
20
20
|
dashboardUrl: "https://dashboard.deep.space"
|
|
21
21
|
};
|
|
@@ -440,6 +440,14 @@ var MSG = {
|
|
|
440
440
|
CRON_PAUSE: "cron.pause",
|
|
441
441
|
CRON_RESUME: "cron.resume",
|
|
442
442
|
CRON_STATUS: "cron.status",
|
|
443
|
+
// ---- JobRoom ---------------------------------------------------------
|
|
444
|
+
// Background-job queue with durable, alarm-driven execution. See
|
|
445
|
+
// server/rooms/job-room.ts. Clients enqueue and subscribe to updates;
|
|
446
|
+
// the room broadcasts JOB_UPDATE for every status transition.
|
|
447
|
+
JOB_ENQUEUE: "job.enqueue",
|
|
448
|
+
JOB_CANCEL: "job.cancel",
|
|
449
|
+
JOB_RETRY: "job.retry",
|
|
450
|
+
JOB_UPDATE: "job.update",
|
|
443
451
|
// ---- PresenceRoom ----------------------------------------------------
|
|
444
452
|
PRESENCE_SYNC: "presence.sync",
|
|
445
453
|
PRESENCE_JOIN: "presence.join",
|
|
@@ -496,6 +504,13 @@ var clientBuild = {
|
|
|
496
504
|
cronTrigger: (taskName) => ({ type: MSG.CRON_TRIGGER, payload: { taskName } }),
|
|
497
505
|
cronPause: (taskName) => ({ type: MSG.CRON_PAUSE, payload: { taskName } }),
|
|
498
506
|
cronResume: (taskName) => ({ type: MSG.CRON_RESUME, payload: { taskName } }),
|
|
507
|
+
// Jobs
|
|
508
|
+
jobEnqueue: (requestId, type, payload, maxAttempts) => ({
|
|
509
|
+
type: MSG.JOB_ENQUEUE,
|
|
510
|
+
payload: { requestId, type, payload, maxAttempts }
|
|
511
|
+
}),
|
|
512
|
+
jobCancel: (jobId) => ({ type: MSG.JOB_CANCEL, payload: { jobId } }),
|
|
513
|
+
jobRetry: (jobId) => ({ type: MSG.JOB_RETRY, payload: { jobId } }),
|
|
499
514
|
// Presence
|
|
500
515
|
presenceUpdate: (state) => ({ type: MSG.PRESENCE_UPDATE, payload: state }),
|
|
501
516
|
// Gateway
|
|
@@ -550,6 +565,17 @@ var serverBuild = {
|
|
|
550
565
|
cronTasks: (tasks) => ({ type: MSG.CRON_TASKS, payload: { tasks } }),
|
|
551
566
|
cronHistory: (history) => ({ type: MSG.CRON_HISTORY, payload: { history } }),
|
|
552
567
|
cronStatus: (tasks, recentHistory) => ({ type: MSG.CRON_STATUS, payload: { tasks, recentHistory } }),
|
|
568
|
+
// Jobs
|
|
569
|
+
jobSnapshot: (jobs) => ({ type: MSG.JOB_UPDATE, payload: { kind: "snapshot", jobs } }),
|
|
570
|
+
jobEnqueued: (job, requestId) => ({
|
|
571
|
+
type: MSG.JOB_UPDATE,
|
|
572
|
+
payload: { kind: "enqueued", job, requestId }
|
|
573
|
+
}),
|
|
574
|
+
jobProgress: (job) => ({ type: MSG.JOB_UPDATE, payload: { kind: "progress", job } }),
|
|
575
|
+
jobSucceeded: (job) => ({ type: MSG.JOB_UPDATE, payload: { kind: "succeeded", job } }),
|
|
576
|
+
jobFailed: (job) => ({ type: MSG.JOB_UPDATE, payload: { kind: "failed", job } }),
|
|
577
|
+
jobCanceled: (job) => ({ type: MSG.JOB_UPDATE, payload: { kind: "canceled", job } }),
|
|
578
|
+
jobRetried: (job) => ({ type: MSG.JOB_UPDATE, payload: { kind: "retried", job } }),
|
|
553
579
|
// Presence
|
|
554
580
|
presenceSync: (peers) => ({ type: MSG.PRESENCE_SYNC, payload: { peers } }),
|
|
555
581
|
presenceJoin: (peer) => ({ type: MSG.PRESENCE_JOIN, payload: { peer } }),
|
|
@@ -3128,13 +3154,143 @@ function useCronMonitor(roomId) {
|
|
|
3128
3154
|
return { tasks, history, connected, trigger, pause, resume };
|
|
3129
3155
|
}
|
|
3130
3156
|
|
|
3131
|
-
// src/client/storage/hooks/
|
|
3157
|
+
// src/client/storage/hooks/useJobs.ts
|
|
3132
3158
|
import { useState as useState11, useEffect as useEffect14, useCallback as useCallback13, useRef as useRef12 } from "react";
|
|
3133
|
-
|
|
3134
|
-
|
|
3159
|
+
var ENQUEUE_TIMEOUT_MS = 1e4;
|
|
3160
|
+
function useJobs(roomId) {
|
|
3161
|
+
const [jobs, setJobs] = useState11([]);
|
|
3135
3162
|
const [connected, setConnected] = useState11(false);
|
|
3136
3163
|
const wsRef = useRef12(null);
|
|
3164
|
+
const pendingEnqueueRef = useRef12(/* @__PURE__ */ new Map());
|
|
3137
3165
|
useEffect14(() => {
|
|
3166
|
+
let ws = null;
|
|
3167
|
+
let reconnectTimer = null;
|
|
3168
|
+
let alive = true;
|
|
3169
|
+
const upsert = (next) => {
|
|
3170
|
+
setJobs((prev) => {
|
|
3171
|
+
const idx = prev.findIndex((j) => j.id === next.id);
|
|
3172
|
+
if (idx === -1) return [next, ...prev];
|
|
3173
|
+
const copy = prev.slice();
|
|
3174
|
+
copy[idx] = next;
|
|
3175
|
+
return copy;
|
|
3176
|
+
});
|
|
3177
|
+
};
|
|
3178
|
+
const rejectAllPending = (err) => {
|
|
3179
|
+
for (const [id, pending] of pendingEnqueueRef.current.entries()) {
|
|
3180
|
+
clearTimeout(pending.timer);
|
|
3181
|
+
pending.reject(err);
|
|
3182
|
+
pendingEnqueueRef.current.delete(id);
|
|
3183
|
+
}
|
|
3184
|
+
};
|
|
3185
|
+
const connect = async () => {
|
|
3186
|
+
if (!alive) return;
|
|
3187
|
+
const token = await getAuthToken();
|
|
3188
|
+
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
|
|
3189
|
+
const baseUrl = `${protocol}//${window.location.host}`;
|
|
3190
|
+
const url = new URL(`/ws/jobs/${encodeURIComponent(roomId)}`, baseUrl);
|
|
3191
|
+
if (token) url.searchParams.set("token", token);
|
|
3192
|
+
ws = new WebSocket(url.toString());
|
|
3193
|
+
wsRef.current = ws;
|
|
3194
|
+
ws.onopen = () => setConnected(true);
|
|
3195
|
+
ws.onmessage = (event) => {
|
|
3196
|
+
dispatch(event.data, {
|
|
3197
|
+
[MSG.JOB_UPDATE]: (p) => {
|
|
3198
|
+
if (p.kind === "snapshot" && Array.isArray(p.jobs)) {
|
|
3199
|
+
setJobs(p.jobs);
|
|
3200
|
+
return;
|
|
3201
|
+
}
|
|
3202
|
+
const job = p.job;
|
|
3203
|
+
if (!job) return;
|
|
3204
|
+
upsert(job);
|
|
3205
|
+
if (p.kind === "enqueued" && typeof p.requestId === "string") {
|
|
3206
|
+
const pending = pendingEnqueueRef.current.get(p.requestId);
|
|
3207
|
+
if (pending) {
|
|
3208
|
+
clearTimeout(pending.timer);
|
|
3209
|
+
pendingEnqueueRef.current.delete(p.requestId);
|
|
3210
|
+
pending.resolve(job.id);
|
|
3211
|
+
}
|
|
3212
|
+
}
|
|
3213
|
+
}
|
|
3214
|
+
});
|
|
3215
|
+
};
|
|
3216
|
+
ws.onclose = () => {
|
|
3217
|
+
wsRef.current = null;
|
|
3218
|
+
setConnected(false);
|
|
3219
|
+
rejectAllPending(new Error("JobRoom WebSocket closed"));
|
|
3220
|
+
if (alive) reconnectTimer = setTimeout(connect, 1e3);
|
|
3221
|
+
};
|
|
3222
|
+
ws.onerror = () => ws?.close();
|
|
3223
|
+
};
|
|
3224
|
+
connect();
|
|
3225
|
+
return () => {
|
|
3226
|
+
alive = false;
|
|
3227
|
+
if (reconnectTimer) clearTimeout(reconnectTimer);
|
|
3228
|
+
rejectAllPending(new Error("useJobs unmounted"));
|
|
3229
|
+
ws?.close();
|
|
3230
|
+
wsRef.current = null;
|
|
3231
|
+
};
|
|
3232
|
+
}, [roomId]);
|
|
3233
|
+
const enqueue = useCallback13(
|
|
3234
|
+
(type, payload, options) => {
|
|
3235
|
+
return new Promise((resolve, reject) => {
|
|
3236
|
+
const ws = wsRef.current;
|
|
3237
|
+
if (!ws || ws.readyState !== WebSocket.OPEN) {
|
|
3238
|
+
reject(new Error("JobRoom WebSocket not connected"));
|
|
3239
|
+
return;
|
|
3240
|
+
}
|
|
3241
|
+
const requestId = crypto.randomUUID();
|
|
3242
|
+
const timer = setTimeout(() => {
|
|
3243
|
+
pendingEnqueueRef.current.delete(requestId);
|
|
3244
|
+
reject(
|
|
3245
|
+
new Error(
|
|
3246
|
+
`JobRoom enqueue timed out (no server ack within ${ENQUEUE_TIMEOUT_MS}ms)`
|
|
3247
|
+
)
|
|
3248
|
+
);
|
|
3249
|
+
}, ENQUEUE_TIMEOUT_MS);
|
|
3250
|
+
pendingEnqueueRef.current.set(requestId, { resolve, reject, timer });
|
|
3251
|
+
try {
|
|
3252
|
+
ws.send(
|
|
3253
|
+
encode(clientBuild.jobEnqueue(requestId, type, payload, options?.maxAttempts))
|
|
3254
|
+
);
|
|
3255
|
+
} catch (e) {
|
|
3256
|
+
clearTimeout(timer);
|
|
3257
|
+
pendingEnqueueRef.current.delete(requestId);
|
|
3258
|
+
reject(e instanceof Error ? e : new Error(String(e)));
|
|
3259
|
+
}
|
|
3260
|
+
});
|
|
3261
|
+
},
|
|
3262
|
+
[]
|
|
3263
|
+
);
|
|
3264
|
+
const sendBuilt = useCallback13(
|
|
3265
|
+
(message) => {
|
|
3266
|
+
const ws = wsRef.current;
|
|
3267
|
+
if (!ws || ws.readyState !== WebSocket.OPEN) return;
|
|
3268
|
+
ws.send(encode(message));
|
|
3269
|
+
},
|
|
3270
|
+
[]
|
|
3271
|
+
);
|
|
3272
|
+
const getJob = useCallback13(
|
|
3273
|
+
(jobId) => jobs.find((j) => j.id === jobId),
|
|
3274
|
+
[jobs]
|
|
3275
|
+
);
|
|
3276
|
+
const cancel = useCallback13(
|
|
3277
|
+
(jobId) => sendBuilt(clientBuild.jobCancel(jobId)),
|
|
3278
|
+
[sendBuilt]
|
|
3279
|
+
);
|
|
3280
|
+
const retry = useCallback13(
|
|
3281
|
+
(jobId) => sendBuilt(clientBuild.jobRetry(jobId)),
|
|
3282
|
+
[sendBuilt]
|
|
3283
|
+
);
|
|
3284
|
+
return { jobs, connected, enqueue, getJob, cancel, retry };
|
|
3285
|
+
}
|
|
3286
|
+
|
|
3287
|
+
// src/client/storage/hooks/usePresenceRoom.ts
|
|
3288
|
+
import { useState as useState12, useEffect as useEffect15, useCallback as useCallback14, useRef as useRef13 } from "react";
|
|
3289
|
+
function usePresenceRoom(scopeId) {
|
|
3290
|
+
const [peers, setPeers] = useState12([]);
|
|
3291
|
+
const [connected, setConnected] = useState12(false);
|
|
3292
|
+
const wsRef = useRef13(null);
|
|
3293
|
+
useEffect15(() => {
|
|
3138
3294
|
let ws = null;
|
|
3139
3295
|
let reconnectTimer = null;
|
|
3140
3296
|
let alive = true;
|
|
@@ -3195,7 +3351,7 @@ function usePresenceRoom(scopeId) {
|
|
|
3195
3351
|
wsRef.current = null;
|
|
3196
3352
|
};
|
|
3197
3353
|
}, [scopeId]);
|
|
3198
|
-
const updateState =
|
|
3354
|
+
const updateState = useCallback14((state) => {
|
|
3199
3355
|
const ws = wsRef.current;
|
|
3200
3356
|
if (!ws || ws.readyState !== WebSocket.OPEN) return;
|
|
3201
3357
|
ws.send(encode(clientBuild.presenceUpdate(state)));
|
|
@@ -3211,7 +3367,7 @@ function toConnectionStatus(queryStatus) {
|
|
|
3211
3367
|
}
|
|
3212
3368
|
|
|
3213
3369
|
// src/client/storage/useR2Files.ts
|
|
3214
|
-
import { useCallback as
|
|
3370
|
+
import { useCallback as useCallback15, useState as useState13, useMemo as useMemo10 } from "react";
|
|
3215
3371
|
function resolveFile(fileOrKey) {
|
|
3216
3372
|
if (typeof fileOrKey === "string") {
|
|
3217
3373
|
return { key: fileOrKey, name: void 0 };
|
|
@@ -3219,20 +3375,20 @@ function resolveFile(fileOrKey) {
|
|
|
3219
3375
|
return { key: fileOrKey.key, name: fileOrKey.originalName };
|
|
3220
3376
|
}
|
|
3221
3377
|
function useR2Files(options) {
|
|
3222
|
-
const [isUploading, setIsUploading] =
|
|
3378
|
+
const [isUploading, setIsUploading] = useState13(false);
|
|
3223
3379
|
const scopeParams = useMemo10(() => {
|
|
3224
3380
|
const params = new URLSearchParams();
|
|
3225
3381
|
params.set("scope", "self");
|
|
3226
3382
|
return params.toString();
|
|
3227
3383
|
}, []);
|
|
3228
|
-
const authHeaders =
|
|
3384
|
+
const authHeaders = useCallback15(async () => {
|
|
3229
3385
|
const token = await getAuthToken();
|
|
3230
3386
|
if (token) {
|
|
3231
3387
|
return { Authorization: `Bearer ${token}` };
|
|
3232
3388
|
}
|
|
3233
3389
|
return {};
|
|
3234
3390
|
}, []);
|
|
3235
|
-
const upload =
|
|
3391
|
+
const upload = useCallback15(async (file, name) => {
|
|
3236
3392
|
setIsUploading(true);
|
|
3237
3393
|
try {
|
|
3238
3394
|
const headers = await authHeaders();
|
|
@@ -3251,7 +3407,7 @@ function useR2Files(options) {
|
|
|
3251
3407
|
setIsUploading(false);
|
|
3252
3408
|
}
|
|
3253
3409
|
}, [scopeParams, authHeaders]);
|
|
3254
|
-
const uploadBase64 =
|
|
3410
|
+
const uploadBase64 = useCallback15(async (base64Data, name, mimeType) => {
|
|
3255
3411
|
setIsUploading(true);
|
|
3256
3412
|
try {
|
|
3257
3413
|
const headers = await authHeaders();
|
|
@@ -3267,7 +3423,7 @@ function useR2Files(options) {
|
|
|
3267
3423
|
setIsUploading(false);
|
|
3268
3424
|
}
|
|
3269
3425
|
}, [scopeParams, authHeaders]);
|
|
3270
|
-
const deleteFile =
|
|
3426
|
+
const deleteFile = useCallback15(async (fileOrKey) => {
|
|
3271
3427
|
const { key } = resolveFile(fileOrKey);
|
|
3272
3428
|
try {
|
|
3273
3429
|
const headers = await authHeaders();
|
|
@@ -3277,7 +3433,7 @@ function useR2Files(options) {
|
|
|
3277
3433
|
return { success: false, error: err instanceof Error ? err.message : "Delete failed" };
|
|
3278
3434
|
}
|
|
3279
3435
|
}, [scopeParams, authHeaders]);
|
|
3280
|
-
const list =
|
|
3436
|
+
const list = useCallback15(async (prefix) => {
|
|
3281
3437
|
try {
|
|
3282
3438
|
const headers = await authHeaders();
|
|
3283
3439
|
const params = new URLSearchParams(scopeParams);
|
|
@@ -3289,7 +3445,7 @@ function useR2Files(options) {
|
|
|
3289
3445
|
return [];
|
|
3290
3446
|
}
|
|
3291
3447
|
}, [scopeParams, authHeaders]);
|
|
3292
|
-
const downloadFile =
|
|
3448
|
+
const downloadFile = useCallback15(async (fileOrKey, fileName) => {
|
|
3293
3449
|
const { key, name: infoName } = resolveFile(fileOrKey);
|
|
3294
3450
|
try {
|
|
3295
3451
|
const headers = await authHeaders();
|
|
@@ -3316,7 +3472,7 @@ function useR2Files(options) {
|
|
|
3316
3472
|
return { success: false, error: err instanceof Error ? err.message : "Download failed" };
|
|
3317
3473
|
}
|
|
3318
3474
|
}, [scopeParams, authHeaders]);
|
|
3319
|
-
const readFile =
|
|
3475
|
+
const readFile = useCallback15(async (fileOrKey) => {
|
|
3320
3476
|
const { key } = resolveFile(fileOrKey);
|
|
3321
3477
|
const headers = await authHeaders();
|
|
3322
3478
|
const response = await fetch(`/api/files/${key}?${scopeParams}`, { headers });
|
|
@@ -3326,7 +3482,7 @@ function useR2Files(options) {
|
|
|
3326
3482
|
}
|
|
3327
3483
|
return response;
|
|
3328
3484
|
}, [scopeParams, authHeaders]);
|
|
3329
|
-
const getUrl =
|
|
3485
|
+
const getUrl = useCallback15((fileOrKey) => {
|
|
3330
3486
|
const { key } = resolveFile(fileOrKey);
|
|
3331
3487
|
return `/api/files/${key}?${scopeParams}`;
|
|
3332
3488
|
}, [scopeParams]);
|
|
@@ -3369,7 +3525,7 @@ function getUserColor(userId, palette = DEFAULT_USER_COLORS) {
|
|
|
3369
3525
|
}
|
|
3370
3526
|
|
|
3371
3527
|
// src/client/messaging/useMessages.ts
|
|
3372
|
-
import { useCallback as
|
|
3528
|
+
import { useCallback as useCallback16, useMemo as useMemo11 } from "react";
|
|
3373
3529
|
function useMessages(channelId, options) {
|
|
3374
3530
|
const where = useMemo11(() => {
|
|
3375
3531
|
if (!channelId) return { channelId: "__none__" };
|
|
@@ -3386,7 +3542,7 @@ function useMessages(channelId, options) {
|
|
|
3386
3542
|
orderDir: "asc"
|
|
3387
3543
|
});
|
|
3388
3544
|
const { create, put, remove: removeMutation } = useMutations("messages");
|
|
3389
|
-
const send =
|
|
3545
|
+
const send = useCallback16(
|
|
3390
3546
|
(content, parentMessageId) => {
|
|
3391
3547
|
if (!channelId || !user) return;
|
|
3392
3548
|
const data = { channelId, content, authorId: user.id, edited: false };
|
|
@@ -3395,19 +3551,19 @@ function useMessages(channelId, options) {
|
|
|
3395
3551
|
},
|
|
3396
3552
|
[channelId, create]
|
|
3397
3553
|
);
|
|
3398
|
-
const edit =
|
|
3554
|
+
const edit = useCallback16(
|
|
3399
3555
|
(messageId, newContent) => {
|
|
3400
3556
|
put(messageId, { content: newContent, edited: true });
|
|
3401
3557
|
},
|
|
3402
3558
|
[put]
|
|
3403
3559
|
);
|
|
3404
|
-
const remove =
|
|
3560
|
+
const remove = useCallback16(
|
|
3405
3561
|
(messageId) => {
|
|
3406
3562
|
removeMutation(messageId);
|
|
3407
3563
|
},
|
|
3408
3564
|
[removeMutation]
|
|
3409
3565
|
);
|
|
3410
|
-
const softDelete =
|
|
3566
|
+
const softDelete = useCallback16(
|
|
3411
3567
|
(messageId) => {
|
|
3412
3568
|
put(messageId, { deleted: true });
|
|
3413
3569
|
},
|
|
@@ -3417,7 +3573,7 @@ function useMessages(channelId, options) {
|
|
|
3417
3573
|
}
|
|
3418
3574
|
|
|
3419
3575
|
// src/client/messaging/useChannels.ts
|
|
3420
|
-
import { useCallback as
|
|
3576
|
+
import { useCallback as useCallback17 } from "react";
|
|
3421
3577
|
function useChannels() {
|
|
3422
3578
|
const { user } = useUser();
|
|
3423
3579
|
const { records, status, error } = useQuery("channels", {
|
|
@@ -3425,7 +3581,7 @@ function useChannels() {
|
|
|
3425
3581
|
orderDir: "asc"
|
|
3426
3582
|
});
|
|
3427
3583
|
const { create: createMutation, put, remove } = useMutations("channels");
|
|
3428
|
-
const create =
|
|
3584
|
+
const create = useCallback17(
|
|
3429
3585
|
(data) => {
|
|
3430
3586
|
return createMutation({
|
|
3431
3587
|
name: data.name,
|
|
@@ -3437,13 +3593,13 @@ function useChannels() {
|
|
|
3437
3593
|
},
|
|
3438
3594
|
[createMutation]
|
|
3439
3595
|
);
|
|
3440
|
-
const archive =
|
|
3596
|
+
const archive = useCallback17(
|
|
3441
3597
|
(channelId) => {
|
|
3442
3598
|
put(channelId, { archived: true });
|
|
3443
3599
|
},
|
|
3444
3600
|
[put]
|
|
3445
3601
|
);
|
|
3446
|
-
const update =
|
|
3602
|
+
const update = useCallback17(
|
|
3447
3603
|
(channelId, data) => {
|
|
3448
3604
|
put(channelId, data);
|
|
3449
3605
|
},
|
|
@@ -3453,14 +3609,14 @@ function useChannels() {
|
|
|
3453
3609
|
}
|
|
3454
3610
|
|
|
3455
3611
|
// src/client/messaging/useReactions.ts
|
|
3456
|
-
import { useCallback as
|
|
3612
|
+
import { useCallback as useCallback18 } from "react";
|
|
3457
3613
|
function useReactions(channelId) {
|
|
3458
3614
|
const { user } = useUser();
|
|
3459
3615
|
const { records, status, error } = useQuery("reactions", {
|
|
3460
3616
|
where: channelId ? { channelId } : { channelId: "__none__" }
|
|
3461
3617
|
});
|
|
3462
3618
|
const { create, remove: removeMutation } = useMutations("reactions");
|
|
3463
|
-
const getReactionsForMessage =
|
|
3619
|
+
const getReactionsForMessage = useCallback18(
|
|
3464
3620
|
(messageId) => {
|
|
3465
3621
|
const messageReactions = records.filter((r) => r.data.messageId === messageId);
|
|
3466
3622
|
const grouped = /* @__PURE__ */ new Map();
|
|
@@ -3477,7 +3633,7 @@ function useReactions(channelId) {
|
|
|
3477
3633
|
},
|
|
3478
3634
|
[records, user]
|
|
3479
3635
|
);
|
|
3480
|
-
const toggle =
|
|
3636
|
+
const toggle = useCallback18(
|
|
3481
3637
|
(messageId, emoji) => {
|
|
3482
3638
|
if (!channelId || !user) return;
|
|
3483
3639
|
const existing = records.find(
|
|
@@ -3495,20 +3651,20 @@ function useReactions(channelId) {
|
|
|
3495
3651
|
}
|
|
3496
3652
|
|
|
3497
3653
|
// src/client/messaging/useChannelMembers.ts
|
|
3498
|
-
import { useCallback as
|
|
3654
|
+
import { useCallback as useCallback19 } from "react";
|
|
3499
3655
|
function useChannelMembers(channelId) {
|
|
3500
3656
|
const { user } = useUser();
|
|
3501
3657
|
const { records, status, error } = useQuery("channel-members", {
|
|
3502
3658
|
where: channelId ? { channelId } : { channelId: "__none__" }
|
|
3503
3659
|
});
|
|
3504
3660
|
const { create, remove: removeMutation } = useMutations("channel-members");
|
|
3505
|
-
const join =
|
|
3661
|
+
const join = useCallback19(() => {
|
|
3506
3662
|
if (!channelId || !user) return;
|
|
3507
3663
|
const existing = records.find((r) => r.data.userId === user.id);
|
|
3508
3664
|
if (existing) return;
|
|
3509
3665
|
create({ channelId, userId: user.id, joinedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
3510
3666
|
}, [channelId, user, records, create]);
|
|
3511
|
-
const leave =
|
|
3667
|
+
const leave = useCallback19(() => {
|
|
3512
3668
|
if (!channelId || !user) return;
|
|
3513
3669
|
const membership = records.find((r) => r.data.userId === user.id);
|
|
3514
3670
|
if (membership) removeMutation(membership.recordId);
|
|
@@ -3518,14 +3674,14 @@ function useChannelMembers(channelId) {
|
|
|
3518
3674
|
}
|
|
3519
3675
|
|
|
3520
3676
|
// src/client/messaging/useReadReceipts.ts
|
|
3521
|
-
import { useCallback as
|
|
3677
|
+
import { useCallback as useCallback20 } from "react";
|
|
3522
3678
|
function useReadReceipts() {
|
|
3523
3679
|
const { user } = useUser();
|
|
3524
3680
|
const { records, status, error } = useQuery("read-receipts", {
|
|
3525
3681
|
where: user ? { userId: user.id } : { userId: "__none__" }
|
|
3526
3682
|
});
|
|
3527
3683
|
const { create, put } = useMutations("read-receipts");
|
|
3528
|
-
const markAsRead =
|
|
3684
|
+
const markAsRead = useCallback20(
|
|
3529
3685
|
(channelId) => {
|
|
3530
3686
|
if (!user) return;
|
|
3531
3687
|
const existing = records.find((r) => r.data.channelId === channelId);
|
|
@@ -3538,7 +3694,7 @@ function useReadReceipts() {
|
|
|
3538
3694
|
},
|
|
3539
3695
|
[user, records, create, put]
|
|
3540
3696
|
);
|
|
3541
|
-
const getUnreadCount =
|
|
3697
|
+
const getUnreadCount = useCallback20(
|
|
3542
3698
|
(channelId, messages) => {
|
|
3543
3699
|
const receipt = records.find((r) => r.data.channelId === channelId);
|
|
3544
3700
|
if (!receipt) return messages.length;
|
|
@@ -3551,7 +3707,7 @@ function useReadReceipts() {
|
|
|
3551
3707
|
}
|
|
3552
3708
|
|
|
3553
3709
|
// src/client/messaging/useConversation.ts
|
|
3554
|
-
import { useCallback as
|
|
3710
|
+
import { useCallback as useCallback21, useMemo as useMemo12 } from "react";
|
|
3555
3711
|
function useConversation(opts) {
|
|
3556
3712
|
const { user } = useUser();
|
|
3557
3713
|
const { ready } = useRecordContext();
|
|
@@ -3560,7 +3716,7 @@ function useConversation(opts) {
|
|
|
3560
3716
|
const { records: members } = useQuery("conv_members");
|
|
3561
3717
|
const messageMut = useMutations("conv_messages");
|
|
3562
3718
|
const reactionMut = useMutations("conv_reactions");
|
|
3563
|
-
const send =
|
|
3719
|
+
const send = useCallback21(
|
|
3564
3720
|
(content, parentMessageId, messageType, metadata) => {
|
|
3565
3721
|
messageMut.create({
|
|
3566
3722
|
Content: content,
|
|
@@ -3574,7 +3730,7 @@ function useConversation(opts) {
|
|
|
3574
3730
|
},
|
|
3575
3731
|
[messageMut, user?.id, opts?.onMessageSent]
|
|
3576
3732
|
);
|
|
3577
|
-
const edit =
|
|
3733
|
+
const edit = useCallback21(
|
|
3578
3734
|
(recordId, content) => {
|
|
3579
3735
|
const existing = allMessages.find((m) => m.recordId === recordId);
|
|
3580
3736
|
if (!existing) return;
|
|
@@ -3582,7 +3738,7 @@ function useConversation(opts) {
|
|
|
3582
3738
|
},
|
|
3583
3739
|
[messageMut, allMessages]
|
|
3584
3740
|
);
|
|
3585
|
-
const remove =
|
|
3741
|
+
const remove = useCallback21(
|
|
3586
3742
|
(recordId) => {
|
|
3587
3743
|
const existing = allMessages.find((m) => m.recordId === recordId);
|
|
3588
3744
|
if (!existing) return;
|
|
@@ -3595,7 +3751,7 @@ function useConversation(opts) {
|
|
|
3595
3751
|
},
|
|
3596
3752
|
[messageMut, allMessages]
|
|
3597
3753
|
);
|
|
3598
|
-
const toggleReaction =
|
|
3754
|
+
const toggleReaction = useCallback21(
|
|
3599
3755
|
(messageId, emoji) => {
|
|
3600
3756
|
const existing = allReactions.find(
|
|
3601
3757
|
(r) => r.data.MessageId === messageId && r.data.Emoji === emoji && r.data.UserId === user?.id
|
|
@@ -3728,7 +3884,7 @@ function parseMessageMetadata(raw) {
|
|
|
3728
3884
|
}
|
|
3729
3885
|
|
|
3730
3886
|
// src/client/directory/useConversations.ts
|
|
3731
|
-
import { useCallback as
|
|
3887
|
+
import { useCallback as useCallback22, useMemo as useMemo13, useRef as useRef14 } from "react";
|
|
3732
3888
|
function useConversations() {
|
|
3733
3889
|
const { records: conversations, status } = useQuery("conversations");
|
|
3734
3890
|
const { create, put } = useMutations("conversations");
|
|
@@ -3736,7 +3892,7 @@ function useConversations() {
|
|
|
3736
3892
|
const stateMut = useMutations("conversation_state");
|
|
3737
3893
|
const { user } = useUser();
|
|
3738
3894
|
const ready = status === "ready";
|
|
3739
|
-
const recentCreationsRef =
|
|
3895
|
+
const recentCreationsRef = useRef14(/* @__PURE__ */ new Map());
|
|
3740
3896
|
for (const [id] of recentCreationsRef.current) {
|
|
3741
3897
|
if (conversations.find((c) => c.recordId === id)) {
|
|
3742
3898
|
recentCreationsRef.current.delete(id);
|
|
@@ -3758,7 +3914,7 @@ function useConversations() {
|
|
|
3758
3914
|
() => new Set(stateRecords.filter((r) => r.data.Archived).map((r) => r.data.ConversationId)),
|
|
3759
3915
|
[stateRecords]
|
|
3760
3916
|
);
|
|
3761
|
-
const getConversationState =
|
|
3917
|
+
const getConversationState = useCallback22(
|
|
3762
3918
|
(conversationId) => {
|
|
3763
3919
|
return stateRecords.find((r) => r.data.ConversationId === conversationId)?.data;
|
|
3764
3920
|
},
|
|
@@ -3771,7 +3927,7 @@ function useConversations() {
|
|
|
3771
3927
|
LinkedRef: "",
|
|
3772
3928
|
MessageCount: 0
|
|
3773
3929
|
};
|
|
3774
|
-
const createChannel =
|
|
3930
|
+
const createChannel = useCallback22(
|
|
3775
3931
|
async (name, description) => {
|
|
3776
3932
|
const existing = conversations.find((r) => r.data.Name === name && r.data.Type !== "dm");
|
|
3777
3933
|
if (existing) return existing.recordId;
|
|
@@ -3791,7 +3947,7 @@ function useConversations() {
|
|
|
3791
3947
|
},
|
|
3792
3948
|
[create, user?.id, conversations]
|
|
3793
3949
|
);
|
|
3794
|
-
const createDM =
|
|
3950
|
+
const createDM = useCallback22(
|
|
3795
3951
|
async (otherUserId) => {
|
|
3796
3952
|
if (!user?.id) return null;
|
|
3797
3953
|
const hash = [user.id, otherUserId].sort().join(":");
|
|
@@ -3819,7 +3975,7 @@ function useConversations() {
|
|
|
3819
3975
|
},
|
|
3820
3976
|
[create, user?.id, conversations]
|
|
3821
3977
|
);
|
|
3822
|
-
const createGroupDM =
|
|
3978
|
+
const createGroupDM = useCallback22(
|
|
3823
3979
|
async (participantIds) => {
|
|
3824
3980
|
if (!user?.id) return null;
|
|
3825
3981
|
const allIds = [.../* @__PURE__ */ new Set([user.id, ...participantIds])];
|
|
@@ -3849,14 +4005,14 @@ function useConversations() {
|
|
|
3849
4005
|
},
|
|
3850
4006
|
[create, user?.id, conversations]
|
|
3851
4007
|
);
|
|
3852
|
-
const lookupByName =
|
|
4008
|
+
const lookupByName = useCallback22(
|
|
3853
4009
|
(name) => {
|
|
3854
4010
|
const found = conversations.find((r) => r.data.Name === name);
|
|
3855
4011
|
return found?.recordId ?? null;
|
|
3856
4012
|
},
|
|
3857
4013
|
[conversations]
|
|
3858
4014
|
);
|
|
3859
|
-
const updateLastMessage =
|
|
4015
|
+
const updateLastMessage = useCallback22(
|
|
3860
4016
|
(conversationId, preview, authorId) => {
|
|
3861
4017
|
const conv = conversations.find((c) => c.recordId === conversationId);
|
|
3862
4018
|
const baseData = conv?.data ?? recentCreationsRef.current.get(conversationId);
|
|
@@ -3875,7 +4031,7 @@ function useConversations() {
|
|
|
3875
4031
|
},
|
|
3876
4032
|
[put, conversations]
|
|
3877
4033
|
);
|
|
3878
|
-
const upsertState =
|
|
4034
|
+
const upsertState = useCallback22(
|
|
3879
4035
|
(conversationId, partial) => {
|
|
3880
4036
|
if (!user?.id) return;
|
|
3881
4037
|
const existing = stateRecords.find(
|
|
@@ -3897,7 +4053,7 @@ function useConversations() {
|
|
|
3897
4053
|
},
|
|
3898
4054
|
[stateMut, stateRecords, user?.id]
|
|
3899
4055
|
);
|
|
3900
|
-
const markRead =
|
|
4056
|
+
const markRead = useCallback22(
|
|
3901
4057
|
(conversationId) => {
|
|
3902
4058
|
const conv = conversations.find((c) => c.recordId === conversationId);
|
|
3903
4059
|
const msgCount = conv?.data.MessageCount ?? recentCreationsRef.current.get(conversationId)?.MessageCount ?? 0;
|
|
@@ -3908,32 +4064,32 @@ function useConversations() {
|
|
|
3908
4064
|
},
|
|
3909
4065
|
[upsertState, conversations]
|
|
3910
4066
|
);
|
|
3911
|
-
const toggleStar =
|
|
4067
|
+
const toggleStar = useCallback22(
|
|
3912
4068
|
(conversationId) => {
|
|
3913
4069
|
const isStarred = starredSet.has(conversationId);
|
|
3914
4070
|
upsertState(conversationId, { Starred: isStarred ? 0 : 1 });
|
|
3915
4071
|
},
|
|
3916
4072
|
[upsertState, starredSet]
|
|
3917
4073
|
);
|
|
3918
|
-
const setArchived =
|
|
4074
|
+
const setArchived = useCallback22(
|
|
3919
4075
|
(conversationId, archived) => {
|
|
3920
4076
|
upsertState(conversationId, { Archived: archived ? 1 : 0 });
|
|
3921
4077
|
},
|
|
3922
4078
|
[upsertState]
|
|
3923
4079
|
);
|
|
3924
|
-
const setTrashed =
|
|
4080
|
+
const setTrashed = useCallback22(
|
|
3925
4081
|
(conversationId, trashed) => {
|
|
3926
4082
|
upsertState(conversationId, { Trashed: trashed ? 1 : 0 });
|
|
3927
4083
|
},
|
|
3928
4084
|
[upsertState]
|
|
3929
4085
|
);
|
|
3930
|
-
const setLabels =
|
|
4086
|
+
const setLabels = useCallback22(
|
|
3931
4087
|
(conversationId, labels) => {
|
|
3932
4088
|
upsertState(conversationId, { Labels: JSON.stringify(labels) });
|
|
3933
4089
|
},
|
|
3934
4090
|
[upsertState]
|
|
3935
4091
|
);
|
|
3936
|
-
const setFolder =
|
|
4092
|
+
const setFolder = useCallback22(
|
|
3937
4093
|
(conversationId, folder) => {
|
|
3938
4094
|
upsertState(conversationId, { Folder: folder });
|
|
3939
4095
|
},
|
|
@@ -3963,7 +4119,7 @@ function useConversations() {
|
|
|
3963
4119
|
}
|
|
3964
4120
|
|
|
3965
4121
|
// src/client/directory/useCommunities.ts
|
|
3966
|
-
import { useCallback as
|
|
4122
|
+
import { useCallback as useCallback23, useMemo as useMemo14 } from "react";
|
|
3967
4123
|
function useCommunities() {
|
|
3968
4124
|
const { records: communities, status } = useQuery("communities");
|
|
3969
4125
|
const communityMut = useMutations("communities");
|
|
@@ -3986,7 +4142,7 @@ function useCommunities() {
|
|
|
3986
4142
|
),
|
|
3987
4143
|
[memberships, user?.id]
|
|
3988
4144
|
);
|
|
3989
|
-
const createCommunity =
|
|
4145
|
+
const createCommunity = useCallback23(
|
|
3990
4146
|
async (name, opts) => {
|
|
3991
4147
|
const existing = communities.find((c) => c.data.Name === name);
|
|
3992
4148
|
if (existing) return existing.recordId;
|
|
@@ -4005,7 +4161,7 @@ function useCommunities() {
|
|
|
4005
4161
|
},
|
|
4006
4162
|
[communityMut, user?.id, communities]
|
|
4007
4163
|
);
|
|
4008
|
-
const updateCommunity =
|
|
4164
|
+
const updateCommunity = useCallback23(
|
|
4009
4165
|
(communityId, updates) => {
|
|
4010
4166
|
const existing = communities.find((c) => c.recordId === communityId);
|
|
4011
4167
|
if (!existing) return;
|
|
@@ -4013,7 +4169,7 @@ function useCommunities() {
|
|
|
4013
4169
|
},
|
|
4014
4170
|
[communityMut, communities]
|
|
4015
4171
|
);
|
|
4016
|
-
const joinCommunity =
|
|
4172
|
+
const joinCommunity = useCallback23(
|
|
4017
4173
|
async (communityId, userName) => {
|
|
4018
4174
|
if (!user?.id) return null;
|
|
4019
4175
|
const existing = memberships.find(
|
|
@@ -4031,7 +4187,7 @@ function useCommunities() {
|
|
|
4031
4187
|
},
|
|
4032
4188
|
[membershipMut, memberships, user?.id]
|
|
4033
4189
|
);
|
|
4034
|
-
const leaveCommunity =
|
|
4190
|
+
const leaveCommunity = useCallback23(
|
|
4035
4191
|
(communityId) => {
|
|
4036
4192
|
if (!user?.id) return;
|
|
4037
4193
|
const membership = memberships.find(
|
|
@@ -4043,13 +4199,13 @@ function useCommunities() {
|
|
|
4043
4199
|
},
|
|
4044
4200
|
[membershipMut, memberships, user?.id]
|
|
4045
4201
|
);
|
|
4046
|
-
const getMembersOf =
|
|
4202
|
+
const getMembersOf = useCallback23(
|
|
4047
4203
|
(communityId) => {
|
|
4048
4204
|
return membershipMap.get(communityId) ?? [];
|
|
4049
4205
|
},
|
|
4050
4206
|
[membershipMap]
|
|
4051
4207
|
);
|
|
4052
|
-
const lookupByName =
|
|
4208
|
+
const lookupByName = useCallback23(
|
|
4053
4209
|
(name) => {
|
|
4054
4210
|
const found = communities.find((c) => c.data.Name === name);
|
|
4055
4211
|
return found?.recordId ?? null;
|
|
@@ -4071,14 +4227,14 @@ function useCommunities() {
|
|
|
4071
4227
|
}
|
|
4072
4228
|
|
|
4073
4229
|
// src/client/directory/usePosts.ts
|
|
4074
|
-
import { useCallback as
|
|
4230
|
+
import { useCallback as useCallback24 } from "react";
|
|
4075
4231
|
function usePosts(opts) {
|
|
4076
4232
|
const { records: allPosts, status } = useQuery("posts");
|
|
4077
4233
|
const postMut = useMutations("posts");
|
|
4078
4234
|
const { user } = useUser();
|
|
4079
4235
|
const ready = status === "ready";
|
|
4080
4236
|
const posts = opts?.communityId ? allPosts.filter((p) => p.data.CommunityId === opts.communityId) : allPosts;
|
|
4081
|
-
const createPost =
|
|
4237
|
+
const createPost = useCallback24(
|
|
4082
4238
|
async (data) => {
|
|
4083
4239
|
const recordId = await postMut.create({
|
|
4084
4240
|
Title: data.title,
|
|
@@ -4096,7 +4252,7 @@ function usePosts(opts) {
|
|
|
4096
4252
|
},
|
|
4097
4253
|
[postMut, user?.id]
|
|
4098
4254
|
);
|
|
4099
|
-
const updatePost =
|
|
4255
|
+
const updatePost = useCallback24(
|
|
4100
4256
|
(postId, updates) => {
|
|
4101
4257
|
const existing = allPosts.find((p) => p.recordId === postId);
|
|
4102
4258
|
if (!existing) return;
|
|
@@ -4104,13 +4260,13 @@ function usePosts(opts) {
|
|
|
4104
4260
|
},
|
|
4105
4261
|
[postMut, allPosts]
|
|
4106
4262
|
);
|
|
4107
|
-
const deletePost =
|
|
4263
|
+
const deletePost = useCallback24(
|
|
4108
4264
|
(postId) => {
|
|
4109
4265
|
postMut.remove(postId);
|
|
4110
4266
|
},
|
|
4111
4267
|
[postMut]
|
|
4112
4268
|
);
|
|
4113
|
-
const setConversationId =
|
|
4269
|
+
const setConversationId = useCallback24(
|
|
4114
4270
|
(postId, conversationId) => {
|
|
4115
4271
|
updatePost(postId, { ConversationId: conversationId });
|
|
4116
4272
|
},
|
|
@@ -4127,7 +4283,7 @@ function usePosts(opts) {
|
|
|
4127
4283
|
}
|
|
4128
4284
|
|
|
4129
4285
|
// src/client/theme/DeepSpaceThemeProvider.tsx
|
|
4130
|
-
import { useEffect as
|
|
4286
|
+
import { useEffect as useEffect16 } from "react";
|
|
4131
4287
|
|
|
4132
4288
|
// src/client/theme/applyTheme.ts
|
|
4133
4289
|
function mix(color, pct, base = "transparent") {
|
|
@@ -4440,7 +4596,7 @@ function DeepSpaceThemeProvider({
|
|
|
4440
4596
|
children,
|
|
4441
4597
|
theme
|
|
4442
4598
|
}) {
|
|
4443
|
-
|
|
4599
|
+
useEffect16(() => {
|
|
4444
4600
|
const root = document.documentElement;
|
|
4445
4601
|
const config = theme ?? readThemeFromDOM(root);
|
|
4446
4602
|
applyDeepSpaceTheme(config, root);
|
|
@@ -4449,12 +4605,12 @@ function DeepSpaceThemeProvider({
|
|
|
4449
4605
|
}
|
|
4450
4606
|
|
|
4451
4607
|
// src/client/theme/useIsDarkTheme.ts
|
|
4452
|
-
import { useState as
|
|
4608
|
+
import { useState as useState14, useEffect as useEffect17 } from "react";
|
|
4453
4609
|
function useIsDarkTheme() {
|
|
4454
|
-
const [isDark, setIsDark] =
|
|
4610
|
+
const [isDark, setIsDark] = useState14(
|
|
4455
4611
|
() => typeof document === "undefined" || document.documentElement.dataset.uiTheme !== "light"
|
|
4456
4612
|
);
|
|
4457
|
-
|
|
4613
|
+
useEffect17(() => {
|
|
4458
4614
|
const update = () => {
|
|
4459
4615
|
setIsDark(document.documentElement.dataset.uiTheme !== "light");
|
|
4460
4616
|
};
|
|
@@ -4466,7 +4622,7 @@ function useIsDarkTheme() {
|
|
|
4466
4622
|
}
|
|
4467
4623
|
|
|
4468
4624
|
// src/client/platform/PlatformProvider.tsx
|
|
4469
|
-
import { createContext as createContext3, useContext as useContext5, useState as
|
|
4625
|
+
import { createContext as createContext3, useContext as useContext5, useState as useState15, useEffect as useEffect18, useRef as useRef15, useCallback as useCallback25 } from "react";
|
|
4470
4626
|
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
4471
4627
|
var PlatformContext = createContext3(null);
|
|
4472
4628
|
function usePlatform() {
|
|
@@ -4476,14 +4632,14 @@ function usePlatform() {
|
|
|
4476
4632
|
}
|
|
4477
4633
|
function useInbox() {
|
|
4478
4634
|
const { inbox, subscribeInbox } = usePlatform();
|
|
4479
|
-
|
|
4635
|
+
useEffect18(() => subscribeInbox(), [subscribeInbox]);
|
|
4480
4636
|
return inbox;
|
|
4481
4637
|
}
|
|
4482
4638
|
function PlatformProvider({ children }) {
|
|
4483
|
-
const [inbox, setInbox] =
|
|
4484
|
-
const inboxSubscribers =
|
|
4485
|
-
const [inboxActive, setInboxActive] =
|
|
4486
|
-
const subscribeInbox =
|
|
4639
|
+
const [inbox, setInbox] = useState15([]);
|
|
4640
|
+
const inboxSubscribers = useRef15(0);
|
|
4641
|
+
const [inboxActive, setInboxActive] = useState15(false);
|
|
4642
|
+
const subscribeInbox = useCallback25(() => {
|
|
4487
4643
|
inboxSubscribers.current++;
|
|
4488
4644
|
if (inboxSubscribers.current === 1) setInboxActive(true);
|
|
4489
4645
|
return () => {
|
|
@@ -4491,7 +4647,7 @@ function PlatformProvider({ children }) {
|
|
|
4491
4647
|
if (inboxSubscribers.current === 0) setInboxActive(false);
|
|
4492
4648
|
};
|
|
4493
4649
|
}, []);
|
|
4494
|
-
|
|
4650
|
+
useEffect18(() => {
|
|
4495
4651
|
if (!inboxActive) return;
|
|
4496
4652
|
let mounted = true;
|
|
4497
4653
|
let ws = null;
|
|
@@ -4549,7 +4705,7 @@ function PlatformProvider({ children }) {
|
|
|
4549
4705
|
setInbox([]);
|
|
4550
4706
|
};
|
|
4551
4707
|
}, [inboxActive]);
|
|
4552
|
-
const platformFetch =
|
|
4708
|
+
const platformFetch = useCallback25(async (path, init) => {
|
|
4553
4709
|
const token = await getAuthToken();
|
|
4554
4710
|
const headers = new Headers(init?.headers);
|
|
4555
4711
|
if (token) headers.set("Authorization", `Bearer ${token}`);
|
|
@@ -4560,28 +4716,28 @@ function PlatformProvider({ children }) {
|
|
|
4560
4716
|
}
|
|
4561
4717
|
|
|
4562
4718
|
// src/client/platform/usePlatformWS.ts
|
|
4563
|
-
import { useState as
|
|
4719
|
+
import { useState as useState16, useEffect as useEffect19, useRef as useRef16 } from "react";
|
|
4564
4720
|
var MAX_RECONNECT_DELAY = 1e4;
|
|
4565
4721
|
var BASE_RECONNECT_DELAY = 500;
|
|
4566
4722
|
function usePlatformWS(options) {
|
|
4567
4723
|
const { path, scopeId, initialState, onMessage } = options;
|
|
4568
|
-
const wsRef =
|
|
4569
|
-
const pingIntervalRef =
|
|
4570
|
-
const [state, setState] =
|
|
4571
|
-
const reconnectAttemptRef =
|
|
4572
|
-
const reconnectTimerRef =
|
|
4573
|
-
const mountedRef =
|
|
4574
|
-
const onMessageRef =
|
|
4724
|
+
const wsRef = useRef16(null);
|
|
4725
|
+
const pingIntervalRef = useRef16(null);
|
|
4726
|
+
const [state, setState] = useState16(initialState);
|
|
4727
|
+
const reconnectAttemptRef = useRef16(0);
|
|
4728
|
+
const reconnectTimerRef = useRef16(null);
|
|
4729
|
+
const mountedRef = useRef16(true);
|
|
4730
|
+
const onMessageRef = useRef16(onMessage);
|
|
4575
4731
|
onMessageRef.current = onMessage;
|
|
4576
|
-
const initialStateRef =
|
|
4732
|
+
const initialStateRef = useRef16(initialState);
|
|
4577
4733
|
initialStateRef.current = initialState;
|
|
4578
|
-
|
|
4734
|
+
useEffect19(() => {
|
|
4579
4735
|
mountedRef.current = true;
|
|
4580
4736
|
return () => {
|
|
4581
4737
|
mountedRef.current = false;
|
|
4582
4738
|
};
|
|
4583
4739
|
}, []);
|
|
4584
|
-
|
|
4740
|
+
useEffect19(() => {
|
|
4585
4741
|
if (!scopeId) return;
|
|
4586
4742
|
setState(initialStateRef.current);
|
|
4587
4743
|
reconnectAttemptRef.current = 0;
|
|
@@ -4640,7 +4796,7 @@ function usePlatformWS(options) {
|
|
|
4640
4796
|
wsRef.current = null;
|
|
4641
4797
|
};
|
|
4642
4798
|
}, [scopeId, path]);
|
|
4643
|
-
const send =
|
|
4799
|
+
const send = useRef16((msg) => {
|
|
4644
4800
|
wsRef.current?.send(JSON.stringify(msg));
|
|
4645
4801
|
}).current;
|
|
4646
4802
|
return { state, send };
|
|
@@ -4802,7 +4958,7 @@ function decodeAiStreamChunk(chunk) {
|
|
|
4802
4958
|
}
|
|
4803
4959
|
|
|
4804
4960
|
// src/client/subscriptions/useSubscription.ts
|
|
4805
|
-
import { useCallback as
|
|
4961
|
+
import { useCallback as useCallback26, useEffect as useEffect20, useState as useState17 } from "react";
|
|
4806
4962
|
|
|
4807
4963
|
// src/shared/subscription.ts
|
|
4808
4964
|
var ENTITLED_STATUSES = /* @__PURE__ */ new Set([
|
|
@@ -4833,7 +4989,7 @@ async function authedJson(path, init) {
|
|
|
4833
4989
|
return data;
|
|
4834
4990
|
}
|
|
4835
4991
|
function useSubscription() {
|
|
4836
|
-
const [state, setState] =
|
|
4992
|
+
const [state, setState] = useState17({
|
|
4837
4993
|
tier: "free",
|
|
4838
4994
|
status: "none",
|
|
4839
4995
|
interval: null,
|
|
@@ -4842,9 +4998,9 @@ function useSubscription() {
|
|
|
4842
4998
|
trialEndsAt: null,
|
|
4843
4999
|
plans: []
|
|
4844
5000
|
});
|
|
4845
|
-
const [isLoading, setLoading] =
|
|
4846
|
-
const [error, setError] =
|
|
4847
|
-
const refresh =
|
|
5001
|
+
const [isLoading, setLoading] = useState17(true);
|
|
5002
|
+
const [error, setError] = useState17(null);
|
|
5003
|
+
const refresh = useCallback26(async () => {
|
|
4848
5004
|
setLoading(true);
|
|
4849
5005
|
try {
|
|
4850
5006
|
const r = await authedJson("/_deepspace/subscriptions/me");
|
|
@@ -4864,15 +5020,15 @@ function useSubscription() {
|
|
|
4864
5020
|
setLoading(false);
|
|
4865
5021
|
}
|
|
4866
5022
|
}, []);
|
|
4867
|
-
|
|
5023
|
+
useEffect20(() => {
|
|
4868
5024
|
refresh();
|
|
4869
5025
|
}, [refresh]);
|
|
4870
5026
|
const entitled = isEntitled(state.tier, state.status);
|
|
4871
|
-
const hasTier =
|
|
5027
|
+
const hasTier = useCallback26(
|
|
4872
5028
|
(slug) => state.tier === slug && isEntitled(state.tier, state.status),
|
|
4873
5029
|
[state.tier, state.status]
|
|
4874
5030
|
);
|
|
4875
|
-
const isAtLeast =
|
|
5031
|
+
const isAtLeast = useCallback26(
|
|
4876
5032
|
(slug) => {
|
|
4877
5033
|
if (!isEntitled(state.tier, state.status)) return false;
|
|
4878
5034
|
const targetRank = state.plans.find((p) => p.slug === slug)?.rank;
|
|
@@ -4882,7 +5038,7 @@ function useSubscription() {
|
|
|
4882
5038
|
},
|
|
4883
5039
|
[state.plans, state.tier, state.status]
|
|
4884
5040
|
);
|
|
4885
|
-
const subscribe =
|
|
5041
|
+
const subscribe = useCallback26(
|
|
4886
5042
|
async (planSlug, opts) => {
|
|
4887
5043
|
const result = await authedJson("/_deepspace/subscriptions/checkout", {
|
|
4888
5044
|
method: "POST",
|
|
@@ -4902,7 +5058,7 @@ function useSubscription() {
|
|
|
4902
5058
|
},
|
|
4903
5059
|
[refresh]
|
|
4904
5060
|
);
|
|
4905
|
-
const openPortal =
|
|
5061
|
+
const openPortal = useCallback26(
|
|
4906
5062
|
async (returnUrl) => {
|
|
4907
5063
|
return authedJson("/_deepspace/subscriptions/portal", {
|
|
4908
5064
|
method: "POST",
|
|
@@ -4971,7 +5127,7 @@ function PricingTable(props) {
|
|
|
4971
5127
|
}
|
|
4972
5128
|
|
|
4973
5129
|
// src/client/charges/useCheckout.ts
|
|
4974
|
-
import { useCallback as
|
|
5130
|
+
import { useCallback as useCallback27, useEffect as useEffect21, useMemo as useMemo15, useState as useState18 } from "react";
|
|
4975
5131
|
async function authedJson2(path, init) {
|
|
4976
5132
|
const token = await getAuthToken();
|
|
4977
5133
|
const res = await fetch(path, {
|
|
@@ -4990,10 +5146,10 @@ async function authedJson2(path, init) {
|
|
|
4990
5146
|
return data;
|
|
4991
5147
|
}
|
|
4992
5148
|
function useCheckout(opts) {
|
|
4993
|
-
const [purchases, setPurchases] =
|
|
4994
|
-
const [isLoading, setLoading] =
|
|
4995
|
-
const [error, setError] =
|
|
4996
|
-
const refresh =
|
|
5149
|
+
const [purchases, setPurchases] = useState18([]);
|
|
5150
|
+
const [isLoading, setLoading] = useState18(true);
|
|
5151
|
+
const [error, setError] = useState18(null);
|
|
5152
|
+
const refresh = useCallback27(async () => {
|
|
4997
5153
|
setLoading(true);
|
|
4998
5154
|
try {
|
|
4999
5155
|
const r = await authedJson2(
|
|
@@ -5007,10 +5163,10 @@ function useCheckout(opts) {
|
|
|
5007
5163
|
setLoading(false);
|
|
5008
5164
|
}
|
|
5009
5165
|
}, []);
|
|
5010
|
-
|
|
5166
|
+
useEffect21(() => {
|
|
5011
5167
|
refresh();
|
|
5012
5168
|
}, [refresh]);
|
|
5013
|
-
const chargeOnce =
|
|
5169
|
+
const chargeOnce = useCallback27(
|
|
5014
5170
|
async (chargeOpts) => {
|
|
5015
5171
|
setError(null);
|
|
5016
5172
|
const common = {
|
|
@@ -5044,7 +5200,7 @@ function useCheckout(opts) {
|
|
|
5044
5200
|
},
|
|
5045
5201
|
[]
|
|
5046
5202
|
);
|
|
5047
|
-
const ownsProduct =
|
|
5203
|
+
const ownsProduct = useCallback27(
|
|
5048
5204
|
(productId) => purchases.some((p) => p.productId === productId),
|
|
5049
5205
|
[purchases]
|
|
5050
5206
|
);
|
|
@@ -5895,9 +6051,9 @@ AlertDescription.displayName = "AlertDescription";
|
|
|
5895
6051
|
import {
|
|
5896
6052
|
createContext as createContext4,
|
|
5897
6053
|
useContext as useContext6,
|
|
5898
|
-
useState as
|
|
5899
|
-
useCallback as
|
|
5900
|
-
useEffect as
|
|
6054
|
+
useState as useState19,
|
|
6055
|
+
useCallback as useCallback28,
|
|
6056
|
+
useEffect as useEffect22
|
|
5901
6057
|
} from "react";
|
|
5902
6058
|
import { jsx as jsx28, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
5903
6059
|
function CheckCircleIcon({ className }) {
|
|
@@ -5944,14 +6100,14 @@ function ToastProvider({
|
|
|
5944
6100
|
position = "bottom-right",
|
|
5945
6101
|
maxToasts = 5
|
|
5946
6102
|
}) {
|
|
5947
|
-
const [toasts, setToasts] =
|
|
5948
|
-
const dismiss =
|
|
6103
|
+
const [toasts, setToasts] = useState19([]);
|
|
6104
|
+
const dismiss = useCallback28((id) => {
|
|
5949
6105
|
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
5950
6106
|
}, []);
|
|
5951
|
-
const dismissAll =
|
|
6107
|
+
const dismissAll = useCallback28(() => {
|
|
5952
6108
|
setToasts([]);
|
|
5953
6109
|
}, []);
|
|
5954
|
-
const addToast =
|
|
6110
|
+
const addToast = useCallback28(
|
|
5955
6111
|
(options) => {
|
|
5956
6112
|
const id = Math.random().toString(36).slice(2);
|
|
5957
6113
|
const duration = options.duration ?? 5e3;
|
|
@@ -5965,23 +6121,23 @@ function ToastProvider({
|
|
|
5965
6121
|
},
|
|
5966
6122
|
[dismiss, maxToasts]
|
|
5967
6123
|
);
|
|
5968
|
-
const toast =
|
|
6124
|
+
const toast = useCallback28(
|
|
5969
6125
|
(options) => addToast(options),
|
|
5970
6126
|
[addToast]
|
|
5971
6127
|
);
|
|
5972
|
-
const success =
|
|
6128
|
+
const success = useCallback28(
|
|
5973
6129
|
(title, description) => addToast({ type: "success", title, description }),
|
|
5974
6130
|
[addToast]
|
|
5975
6131
|
);
|
|
5976
|
-
const error =
|
|
6132
|
+
const error = useCallback28(
|
|
5977
6133
|
(title, description) => addToast({ type: "error", title, description }),
|
|
5978
6134
|
[addToast]
|
|
5979
6135
|
);
|
|
5980
|
-
const warning =
|
|
6136
|
+
const warning = useCallback28(
|
|
5981
6137
|
(title, description) => addToast({ type: "warning", title, description }),
|
|
5982
6138
|
[addToast]
|
|
5983
6139
|
);
|
|
5984
|
-
const info =
|
|
6140
|
+
const info = useCallback28(
|
|
5985
6141
|
(title, description) => addToast({ type: "info", title, description }),
|
|
5986
6142
|
[addToast]
|
|
5987
6143
|
);
|
|
@@ -6018,8 +6174,8 @@ var TOAST_CONFIG = {
|
|
|
6018
6174
|
};
|
|
6019
6175
|
function ToastItem({ toast, onDismiss }) {
|
|
6020
6176
|
const { Icon: Icon2, accent, icon } = TOAST_CONFIG[toast.type];
|
|
6021
|
-
const [exiting, setExiting] =
|
|
6022
|
-
|
|
6177
|
+
const [exiting, setExiting] = useState19(false);
|
|
6178
|
+
useEffect22(() => {
|
|
6023
6179
|
if (exiting) {
|
|
6024
6180
|
const timer = setTimeout(onDismiss, 150);
|
|
6025
6181
|
return () => clearTimeout(timer);
|
|
@@ -6701,6 +6857,7 @@ export {
|
|
|
6701
6857
|
useGameRoom,
|
|
6702
6858
|
useInbox,
|
|
6703
6859
|
useIsDarkTheme,
|
|
6860
|
+
useJobs,
|
|
6704
6861
|
useMessages,
|
|
6705
6862
|
useMutations,
|
|
6706
6863
|
usePlatform,
|