@neta-art/cohub 9.0.1 → 11.0.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/README.md +108 -102
- package/dist/board/editor/align.d.ts +11 -0
- package/dist/board/editor/align.js +72 -0
- package/dist/board/editor/animation.d.ts +17 -0
- package/dist/board/editor/animation.js +187 -0
- package/dist/board/editor/camera.d.ts +32 -0
- package/dist/board/editor/camera.js +137 -0
- package/dist/board/editor/clipboard.d.ts +41 -0
- package/dist/board/editor/clipboard.js +129 -0
- package/dist/board/editor/connection-ports.d.ts +19 -0
- package/dist/board/editor/connection-ports.js +85 -0
- package/dist/board/editor/context.d.ts +111 -0
- package/dist/board/editor/context.js +30 -0
- package/dist/board/editor/copy.d.ts +17 -0
- package/dist/board/editor/copy.js +121 -0
- package/dist/board/editor/creation.d.ts +51 -0
- package/dist/board/editor/creation.js +225 -0
- package/dist/board/editor/deletion.d.ts +9 -0
- package/dist/board/editor/deletion.js +90 -0
- package/dist/board/editor/document-edits.d.ts +22 -0
- package/dist/board/editor/document-edits.js +193 -0
- package/dist/board/editor/document.d.ts +41 -0
- package/dist/board/editor/document.js +302 -0
- package/dist/board/editor/editor.d.ts +225 -0
- package/dist/board/editor/editor.js +439 -0
- package/dist/board/editor/index.d.ts +18 -0
- package/dist/board/editor/index.js +12 -0
- package/dist/board/editor/interaction.d.ts +115 -0
- package/dist/board/editor/interaction.js +584 -0
- package/dist/board/editor/query.d.ts +27 -0
- package/dist/board/editor/query.js +203 -0
- package/dist/board/editor/remote.d.ts +11 -0
- package/dist/board/editor/remote.js +55 -0
- package/dist/board/editor/selection-transform.d.ts +24 -0
- package/dist/board/editor/selection-transform.js +81 -0
- package/dist/board/editor/selection.d.ts +33 -0
- package/dist/board/editor/selection.js +197 -0
- package/dist/board/editor/snapping.d.ts +33 -0
- package/dist/board/editor/snapping.js +75 -0
- package/dist/board/editor/snapshots.d.ts +27 -0
- package/dist/board/editor/snapshots.js +132 -0
- package/dist/board/editor/spatial.d.ts +41 -0
- package/dist/board/editor/spatial.js +191 -0
- package/dist/board/editor/state.d.ts +12 -0
- package/dist/board/editor/state.js +49 -0
- package/dist/board/editor/tool.d.ts +10 -0
- package/dist/board/editor/tool.js +19 -0
- package/dist/board/editor/wheel.d.ts +5 -0
- package/dist/board/editor/wheel.js +17 -0
- package/dist/board/export/index.d.ts +28 -6
- package/dist/board/export/index.js +47 -13
- package/dist/board/export/node/index.d.ts +56 -0
- package/dist/board/{headless → export/node}/index.js +26 -21
- package/dist/board/export/node/scripts.d.ts +16 -0
- package/dist/board/export/node/scripts.js +258 -0
- package/dist/board/export/scene.d.ts +8 -5
- package/dist/board/export/scene.js +24 -9
- package/dist/board/{animation.d.ts → model/animation.d.ts} +8 -5
- package/dist/board/{animation.js → model/animation.js} +37 -10
- package/dist/board/{core → model}/arrow-geometry.d.ts +2 -2
- package/dist/board/{core → model}/arrow-geometry.js +2 -2
- package/dist/board/model/authoring.d.ts +20 -0
- package/dist/board/model/authoring.js +185 -0
- package/dist/board/{core → model}/draw-geometry.d.ts +2 -2
- package/dist/board/{core → model}/draw-geometry.js +1 -1
- package/dist/board/model/draw-input.d.ts +14 -0
- package/dist/board/model/draw-input.js +28 -0
- package/dist/board/{core → model}/export-assets.d.ts +1 -1
- package/dist/board/{core → model}/export-assets.js +1 -1
- package/dist/board/{core → model}/export-plan.d.ts +2 -2
- package/dist/board/{core → model}/export-plan.js +3 -2
- package/dist/board/{core → model}/file-preview.d.ts +1 -1
- package/dist/board/{core → model}/file-preview.js +2 -2
- package/dist/board/{core → model}/file-snapshot.d.ts +1 -1
- package/dist/board/{core → model}/file-snapshot.js +4 -3
- package/dist/board/{geometry.d.ts → model/geometry.d.ts} +3 -3
- package/dist/board/{geometry.js → model/geometry.js} +1 -1
- package/dist/board/{image-key.d.ts → model/image-key.d.ts} +2 -2
- package/dist/board/{image-key.js → model/image-key.js} +7 -3
- package/dist/board/model/index.d.ts +42 -0
- package/dist/board/model/index.js +39 -0
- package/dist/board/model/items/builtin.d.ts +5 -0
- package/dist/board/model/items/builtin.js +119 -0
- package/dist/board/model/items/create.d.ts +61 -0
- package/dist/board/model/items/create.js +272 -0
- package/dist/board/model/items/definition.d.ts +35 -0
- package/dist/board/model/items/definition.js +18 -0
- package/dist/board/model/items/id.d.ts +5 -0
- package/dist/board/model/items/id.js +11 -0
- package/dist/board/model/items/index.d.ts +6 -0
- package/dist/board/model/items/index.js +6 -0
- package/dist/board/model/items/registry.d.ts +35 -0
- package/dist/board/model/items/registry.js +84 -0
- package/dist/board/{media-playback.d.ts → model/media-playback.d.ts} +4 -3
- package/dist/board/{media-playback.js → model/media-playback.js} +15 -5
- package/dist/board/{media.d.ts → model/media.d.ts} +1 -1
- package/dist/board/{media.js → model/media.js} +8 -2
- package/dist/board/{core → model}/palette.d.ts +1 -1
- package/dist/board/{core → model}/palette.js +1 -1
- package/dist/board/{presets.d.ts → model/presets.d.ts} +3 -3
- package/dist/board/{presets.js → model/presets.js} +1 -1
- package/dist/board/{replay.d.ts → model/replay.d.ts} +5 -5
- package/dist/board/{replay.js → model/replay.js} +2 -2
- package/dist/board/model/sampling.d.ts +19 -0
- package/dist/board/model/sampling.js +96 -0
- package/dist/board/{core → model}/scene.d.ts +1 -1
- package/dist/board/{core → model}/scene.js +1 -1
- package/dist/board/model/script-example.d.ts +4 -0
- package/dist/board/model/script-example.js +21 -0
- package/dist/board/model/script-hit.d.ts +10 -0
- package/dist/board/model/script-hit.js +52 -0
- package/dist/board/model/script-index.d.ts +7 -0
- package/dist/board/model/script-index.js +15 -0
- package/dist/board/model/script-scene.d.ts +24 -0
- package/dist/board/model/script-scene.js +267 -0
- package/dist/board/model/script.d.ts +105 -0
- package/dist/board/model/script.js +1 -0
- package/dist/board/model/shape-types.d.ts +8 -0
- package/dist/board/model/shape-types.js +8 -0
- package/dist/board/{task.d.ts → model/task.d.ts} +4 -4
- package/dist/board/{task.js → model/task.js} +3 -3
- package/dist/board/{core → model}/text-metrics.d.ts +1 -1
- package/dist/board/{core → model}/text-metrics.js +1 -1
- package/dist/board/{core → model}/tool-styles.d.ts +1 -1
- package/dist/board/{core → model}/tool-styles.js +1 -1
- package/dist/board/{runtime/board-player.d.ts → player/index.d.ts} +2 -2
- package/dist/board/{runtime/board-player.js → player/index.js} +5 -4
- package/dist/board/render/board-background.d.ts +1 -1
- package/dist/board/render/clip.d.ts +1 -1
- package/dist/board/render/css-color.d.ts +6 -1
- package/dist/board/render/css-color.js +34 -20
- package/dist/board/render/diagnostics.d.ts +20 -0
- package/dist/board/render/diagnostics.js +117 -0
- package/dist/board/render/index.d.ts +9 -6
- package/dist/board/render/index.js +10 -7
- package/dist/board/render/media-interaction.d.ts +2 -2
- package/dist/board/render/media-interaction.js +1 -1
- package/dist/board/render/palette.d.ts +3 -2
- package/dist/board/render/palette.js +7 -3
- package/dist/board/render/renderers/arrow-card-renderer.js +4 -3
- package/dist/board/render/renderers/audio-card-renderer.js +2 -1
- package/dist/board/render/renderers/board-renderer-registry.d.ts +20 -10
- package/dist/board/render/renderers/board-renderer-registry.js +17 -17
- package/dist/board/render/renderers/custom-card-renderer.d.ts +5 -0
- package/dist/board/render/renderers/{sketch-card-renderer.js → custom-card-renderer.js} +16 -15
- package/dist/board/render/renderers/draw-card-renderer.js +4 -3
- package/dist/board/render/renderers/effect-card-renderer.js +22 -5
- package/dist/board/render/renderers/far-plate.js +1 -1
- package/dist/board/render/renderers/file-card-renderer.d.ts +1 -1
- package/dist/board/render/renderers/file-card-renderer.js +2 -2
- package/dist/board/render/renderers/frame-card-renderer.js +30 -14
- package/dist/board/render/renderers/image-card-renderer.d.ts +1 -1
- package/dist/board/render/renderers/image-card-renderer.js +43 -4
- package/dist/board/render/renderers/shape-card-renderer.js +11 -28
- package/dist/board/render/renderers/task-card-renderer.js +1 -1
- package/dist/board/render/renderers/text-card-renderer.js +6 -4
- package/dist/board/render/renderers/unknown-card-renderer.js +1 -0
- package/dist/board/render/renderers/video-card-renderer.d.ts +1 -1
- package/dist/board/render/renderers/video-card-renderer.js +2 -1
- package/dist/board/render/sampling.d.ts +22 -0
- package/dist/board/render/sampling.js +21 -0
- package/dist/board/render/script-export.d.ts +11 -0
- package/dist/board/render/script-export.js +86 -0
- package/dist/board/render/script-host.d.ts +31 -0
- package/dist/board/render/script-host.js +421 -0
- package/dist/board/render/script-modules.d.ts +2 -0
- package/dist/board/render/script-modules.js +2 -0
- package/dist/board/render/script-runtime.d.ts +29 -0
- package/dist/board/render/script-runtime.js +213 -0
- package/dist/board/render/script-sandbox.d.ts +4 -0
- package/dist/board/render/script-sandbox.js +173 -0
- package/dist/board/render/stroke.d.ts +3 -2
- package/dist/board/render/stroke.js +23 -2
- package/dist/board/render/text-measurement.js +2 -2
- package/dist/board/replica/index.d.ts +70 -0
- package/dist/board/replica/index.js +276 -0
- package/dist/board/stage/assets.d.ts +41 -0
- package/dist/board/stage/assets.js +355 -0
- package/dist/board/stage/index.d.ts +8 -0
- package/dist/board/stage/index.js +8 -0
- package/dist/board/stage/lru.d.ts +32 -0
- package/dist/board/stage/lru.js +29 -0
- package/dist/board/stage/maintenance.d.ts +5 -0
- package/dist/board/stage/maintenance.js +11 -0
- package/dist/board/stage/pointer.d.ts +8 -0
- package/dist/board/stage/pointer.js +33 -0
- package/dist/board/stage/scene.d.ts +85 -0
- package/dist/board/stage/scene.js +515 -0
- package/dist/board/stage/script-pointer.d.ts +19 -0
- package/dist/board/stage/script-pointer.js +35 -0
- package/dist/board/stage/stage.d.ts +76 -0
- package/dist/board/stage/stage.js +774 -0
- package/dist/board/stage/texture-pool.d.ts +24 -0
- package/dist/board/stage/texture-pool.js +153 -0
- package/dist/board/stage/views.d.ts +38 -0
- package/dist/board/stage/views.js +93 -0
- package/dist/chunks/environment.d.ts +289 -23
- package/dist/chunks/host-bridge.d.ts +2 -2
- package/dist/chunks/http.d.ts +185 -71
- package/dist/chunks/http.js +368 -269
- package/dist/chunks/transport.js +3 -1
- package/dist/chunks/websocket.d.ts +9 -1
- package/dist/chunks/websocket.js +16 -2
- package/dist/host-bridge.js +2 -1
- package/dist/http.d.ts +2 -2
- package/dist/index.d.ts +182 -4
- package/dist/index.js +1393 -129
- package/dist/media.d.ts +1 -10
- package/dist/media.js +16 -27
- package/dist/protocol/dist/board-assets.d.ts +1 -0
- package/dist/protocol/dist/board-constants.js +2 -2
- package/dist/protocol/dist/board-model.d.ts +201 -11
- package/dist/protocol/dist/board-model.js +33 -14
- package/dist/protocol/dist/board-patch.js +3 -2
- package/dist/protocol/dist/board-schema.d.ts +4 -2
- package/dist/protocol/dist/board-schema.js +18 -4
- package/dist/protocol/dist/board-script-modules.d.ts +25 -0
- package/dist/protocol/dist/board-script-modules.js +127 -0
- package/dist/protocol/dist/board.d.ts +28 -2
- package/dist/protocol/dist/board.js +3 -1
- package/dist/protocol/dist/core/media.d.ts +5 -0
- package/dist/protocol/dist/core/media.js +39 -0
- package/dist/protocol/dist/display/index.d.ts +1 -0
- package/dist/protocol/dist/index.d.ts +7 -5
- package/dist/protocol/dist/realtime/types.d.ts +1 -0
- package/dist/protocol/dist/rtc/index.d.ts +1 -0
- package/dist/types.d.ts +1 -1
- package/package.json +21 -8
- package/dist/board/core/shape-definition.d.ts +0 -23
- package/dist/board/core/shape-definition.js +0 -45
- package/dist/board/core/shape-types.d.ts +0 -38
- package/dist/board/core/shape-types.js +0 -22
- package/dist/board/headless/index.d.ts +0 -55
- package/dist/board/headless/sketch.d.ts +0 -19
- package/dist/board/headless/sketch.js +0 -146
- package/dist/board/index.d.ts +0 -30
- package/dist/board/index.js +0 -29
- package/dist/board/render/renderers/sketch-card-renderer.d.ts +0 -5
- package/dist/board/render/sketch-host.d.ts +0 -14
- package/dist/board/render/sketch-host.js +0 -216
package/dist/chunks/http.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { M as isUuid, h as getRealtimeSpaceRoom, m as getRealtimeBoardRoom, n as HttpTransport, t as HttpError } from "./transport.js";
|
|
2
2
|
import { l as resolveExecutionToken, o as resolveApiBaseUrl } from "./environment.js";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
//#region ../protocol/dist/model/metrics.js
|
|
@@ -360,11 +360,6 @@ z.object({
|
|
|
360
360
|
quality: z.number().int().min(1).max(100).optional(),
|
|
361
361
|
maxSize: z.number().int().min(1).max(DISPLAY_DIMENSION_MAX).optional()
|
|
362
362
|
});
|
|
363
|
-
z.object({
|
|
364
|
-
urls: z.union([z.string().min(1).max(512), z.array(z.string().min(1).max(512)).min(1).max(16)]),
|
|
365
|
-
username: z.string().max(512).optional(),
|
|
366
|
-
credential: z.string().max(512).optional()
|
|
367
|
-
});
|
|
368
363
|
z.object({
|
|
369
364
|
offer: z.string().min(1).max(65536),
|
|
370
365
|
control: z.boolean().optional()
|
|
@@ -1051,17 +1046,285 @@ function ensureRealtimeConnected(websocketClient) {
|
|
|
1051
1046
|
});
|
|
1052
1047
|
}
|
|
1053
1048
|
//#endregion
|
|
1049
|
+
//#region src/board/model/items/id.ts
|
|
1050
|
+
function createBoardEntityId() {
|
|
1051
|
+
const cryptoRef = globalThis.crypto;
|
|
1052
|
+
if (cryptoRef && typeof cryptoRef.randomUUID === "function") return cryptoRef.randomUUID();
|
|
1053
|
+
return `c-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
1054
|
+
}
|
|
1055
|
+
//#endregion
|
|
1056
|
+
//#region src/board/client/index.ts
|
|
1057
|
+
var BoardRealtimeClient = class {
|
|
1058
|
+
websocketClient;
|
|
1059
|
+
spaceId;
|
|
1060
|
+
boardId;
|
|
1061
|
+
constructor(websocketClient, spaceId, boardId) {
|
|
1062
|
+
this.websocketClient = websocketClient;
|
|
1063
|
+
this.spaceId = spaceId;
|
|
1064
|
+
this.boardId = boardId;
|
|
1065
|
+
}
|
|
1066
|
+
subscribe(handlers) {
|
|
1067
|
+
if (!this.websocketClient) throw new Error("realtime transport is not configured for this client");
|
|
1068
|
+
ensureRealtimeConnected(this.websocketClient);
|
|
1069
|
+
const releaseRoom = this.websocketClient.retainRooms([getRealtimeSpaceRoom(this.spaceId), getRealtimeBoardRoom(this.boardId)]);
|
|
1070
|
+
const unsubscribe = this.websocketClient.on("event", (event) => {
|
|
1071
|
+
if (event.spaceId !== this.spaceId) return;
|
|
1072
|
+
if (event.type === "board.changed" && event.payload.boardId === this.boardId) {
|
|
1073
|
+
const changedEvent = event;
|
|
1074
|
+
handlers.event?.(changedEvent);
|
|
1075
|
+
handlers.changed?.(changedEvent);
|
|
1076
|
+
}
|
|
1077
|
+
if (event.type === "board.awareness.updated" && event.payload.boardId === this.boardId) {
|
|
1078
|
+
const awarenessEvent = event;
|
|
1079
|
+
if (awarenessEvent.payload.connectionId !== this.websocketClient?.connectionId) {
|
|
1080
|
+
handlers.event?.(awarenessEvent);
|
|
1081
|
+
handlers.awareness?.(awarenessEvent);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
if (event.type === "board.playback.changed" && event.payload.boardId === this.boardId) {
|
|
1085
|
+
const playbackEvent = event;
|
|
1086
|
+
handlers.event?.(playbackEvent);
|
|
1087
|
+
handlers.playback?.(playbackEvent);
|
|
1088
|
+
}
|
|
1089
|
+
});
|
|
1090
|
+
return () => {
|
|
1091
|
+
unsubscribe();
|
|
1092
|
+
releaseRoom();
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
on(type, handler) {
|
|
1096
|
+
if (type === "changed") return this.subscribe({ changed: handler });
|
|
1097
|
+
if (type === "awareness") return this.subscribe({ awareness: handler });
|
|
1098
|
+
return this.subscribe({ playback: handler });
|
|
1099
|
+
}
|
|
1100
|
+
};
|
|
1101
|
+
var BoardClient = class {
|
|
1102
|
+
spaceId;
|
|
1103
|
+
id;
|
|
1104
|
+
realtime;
|
|
1105
|
+
http;
|
|
1106
|
+
websocket;
|
|
1107
|
+
constructor(options) {
|
|
1108
|
+
this.spaceId = options.spaceId;
|
|
1109
|
+
this.id = options.boardId;
|
|
1110
|
+
this.http = options.http;
|
|
1111
|
+
this.websocket = options.websocket;
|
|
1112
|
+
this.realtime = new BoardRealtimeClient(options.websocket, options.spaceId, options.boardId);
|
|
1113
|
+
}
|
|
1114
|
+
get path() {
|
|
1115
|
+
return `/api/spaces/${this.spaceId}/boards/${this.id}`;
|
|
1116
|
+
}
|
|
1117
|
+
/** Read the Board, or part of it. Every value is complete, defaults included. */
|
|
1118
|
+
get(input = {}, customFetch) {
|
|
1119
|
+
const params = new URLSearchParams();
|
|
1120
|
+
if (input.only?.length) params.set("only", input.only.join(","));
|
|
1121
|
+
if (input.rect) params.set("rect", [
|
|
1122
|
+
input.rect.x,
|
|
1123
|
+
input.rect.y,
|
|
1124
|
+
input.rect.width,
|
|
1125
|
+
input.rect.height
|
|
1126
|
+
].join(","));
|
|
1127
|
+
if (input.within) params.set("within", input.within);
|
|
1128
|
+
if (input.items?.length) params.set("items", input.items.join(","));
|
|
1129
|
+
if (input.animations?.length) params.set("animations", input.animations.join(","));
|
|
1130
|
+
if (input.limit !== void 0) params.set("limit", String(input.limit));
|
|
1131
|
+
if (input.cursor) params.set("cursor", input.cursor);
|
|
1132
|
+
const query = params.toString();
|
|
1133
|
+
return this.http.request(`${this.path}${query ? `?${query}` : ""}`, { fetch: customFetch });
|
|
1134
|
+
}
|
|
1135
|
+
/** Merge a patch into the Board: fields merge, `null` deletes. */
|
|
1136
|
+
apply(patch, options = {}) {
|
|
1137
|
+
return this.http.request(`${this.path}/apply`, {
|
|
1138
|
+
method: "POST",
|
|
1139
|
+
headers: { "Content-Type": "application/json" },
|
|
1140
|
+
body: JSON.stringify({
|
|
1141
|
+
...options,
|
|
1142
|
+
patch,
|
|
1143
|
+
mutationId: options.mutationId ?? createBoardEntityId()
|
|
1144
|
+
})
|
|
1145
|
+
});
|
|
1146
|
+
}
|
|
1147
|
+
/** Transactions newest first, each with the before/after state of what it changed. */
|
|
1148
|
+
history(input = {}, customFetch) {
|
|
1149
|
+
const params = new URLSearchParams();
|
|
1150
|
+
if (input.before !== void 0) params.set("before", String(input.before));
|
|
1151
|
+
if (input.limit !== void 0) params.set("limit", String(input.limit));
|
|
1152
|
+
const query = params.toString();
|
|
1153
|
+
return this.http.request(`${this.path}/history${query ? `?${query}` : ""}`, { fetch: customFetch });
|
|
1154
|
+
}
|
|
1155
|
+
/** Return the Board to an earlier version as a new write. */
|
|
1156
|
+
restore(version) {
|
|
1157
|
+
return this.http.request(`${this.path}/restore`, {
|
|
1158
|
+
method: "POST",
|
|
1159
|
+
headers: { "Content-Type": "application/json" },
|
|
1160
|
+
body: JSON.stringify({ version })
|
|
1161
|
+
});
|
|
1162
|
+
}
|
|
1163
|
+
playback(command) {
|
|
1164
|
+
return this.http.request(`${this.path}/playback`, {
|
|
1165
|
+
method: "POST",
|
|
1166
|
+
headers: { "Content-Type": "application/json" },
|
|
1167
|
+
body: JSON.stringify(command)
|
|
1168
|
+
}).then((response) => response.playback);
|
|
1169
|
+
}
|
|
1170
|
+
/** Shared playback: every viewer follows the same clock. */
|
|
1171
|
+
play(animationId, options = {}) {
|
|
1172
|
+
return this.playback({
|
|
1173
|
+
commandId: createBoardEntityId(),
|
|
1174
|
+
type: "play",
|
|
1175
|
+
animationId,
|
|
1176
|
+
...options
|
|
1177
|
+
});
|
|
1178
|
+
}
|
|
1179
|
+
pause() {
|
|
1180
|
+
return this.playback({
|
|
1181
|
+
commandId: createBoardEntityId(),
|
|
1182
|
+
type: "pause"
|
|
1183
|
+
});
|
|
1184
|
+
}
|
|
1185
|
+
resume() {
|
|
1186
|
+
return this.playback({
|
|
1187
|
+
commandId: createBoardEntityId(),
|
|
1188
|
+
type: "resume"
|
|
1189
|
+
});
|
|
1190
|
+
}
|
|
1191
|
+
seek(position) {
|
|
1192
|
+
return this.playback({
|
|
1193
|
+
commandId: createBoardEntityId(),
|
|
1194
|
+
type: "seek",
|
|
1195
|
+
position
|
|
1196
|
+
});
|
|
1197
|
+
}
|
|
1198
|
+
/** Continue past the marker a presentation is holding at. */
|
|
1199
|
+
next() {
|
|
1200
|
+
return this.playback({
|
|
1201
|
+
commandId: createBoardEntityId(),
|
|
1202
|
+
type: "next"
|
|
1203
|
+
});
|
|
1204
|
+
}
|
|
1205
|
+
stop() {
|
|
1206
|
+
return this.playback({
|
|
1207
|
+
commandId: createBoardEntityId(),
|
|
1208
|
+
type: "stop"
|
|
1209
|
+
});
|
|
1210
|
+
}
|
|
1211
|
+
updateAwareness(seq, update) {
|
|
1212
|
+
if (!this.websocket) return Promise.resolve();
|
|
1213
|
+
return this.websocket.updateBoardAwareness({
|
|
1214
|
+
spaceId: this.spaceId,
|
|
1215
|
+
boardId: this.id,
|
|
1216
|
+
seq,
|
|
1217
|
+
update
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1220
|
+
subscribe(handlers) {
|
|
1221
|
+
return this.realtime.subscribe(handlers);
|
|
1222
|
+
}
|
|
1223
|
+
on(type, handler) {
|
|
1224
|
+
if (type === "changed") return this.realtime.on("changed", handler);
|
|
1225
|
+
if (type === "awareness") return this.realtime.on("awareness", handler);
|
|
1226
|
+
return this.realtime.on("playback", handler);
|
|
1227
|
+
}
|
|
1228
|
+
};
|
|
1229
|
+
var SpaceBoardsApi = class {
|
|
1230
|
+
http;
|
|
1231
|
+
spaceId;
|
|
1232
|
+
websocket;
|
|
1233
|
+
constructor(http, spaceId, websocket) {
|
|
1234
|
+
this.http = http;
|
|
1235
|
+
this.spaceId = spaceId;
|
|
1236
|
+
this.websocket = websocket;
|
|
1237
|
+
}
|
|
1238
|
+
byId(boardId) {
|
|
1239
|
+
return new BoardClient({
|
|
1240
|
+
http: this.http,
|
|
1241
|
+
websocket: this.websocket,
|
|
1242
|
+
spaceId: this.spaceId,
|
|
1243
|
+
boardId
|
|
1244
|
+
});
|
|
1245
|
+
}
|
|
1246
|
+
/** Create a `.board` file and its Board, optionally with an initial document. */
|
|
1247
|
+
create(input) {
|
|
1248
|
+
return this.http.request(`/api/spaces/${this.spaceId}/boards`, {
|
|
1249
|
+
method: "POST",
|
|
1250
|
+
headers: { "Content-Type": "application/json" },
|
|
1251
|
+
body: JSON.stringify(input)
|
|
1252
|
+
});
|
|
1253
|
+
}
|
|
1254
|
+
};
|
|
1255
|
+
//#endregion
|
|
1256
|
+
//#region src/rtc/index.ts
|
|
1257
|
+
const ICE_REFRESH_MARGIN_MS = 3e5;
|
|
1258
|
+
var IceServerCache = class {
|
|
1259
|
+
load;
|
|
1260
|
+
cached = null;
|
|
1261
|
+
constructor(load) {
|
|
1262
|
+
this.load = load;
|
|
1263
|
+
}
|
|
1264
|
+
async get(signal) {
|
|
1265
|
+
if (this.cached && this.cached.refreshAt > Date.now()) return this.cached.value;
|
|
1266
|
+
const value = await this.load(signal);
|
|
1267
|
+
this.cached = {
|
|
1268
|
+
value,
|
|
1269
|
+
refreshAt: Date.parse(value.expiresAt) - ICE_REFRESH_MARGIN_MS
|
|
1270
|
+
};
|
|
1271
|
+
return value;
|
|
1272
|
+
}
|
|
1273
|
+
};
|
|
1274
|
+
function waitForIceGathering(pc, timeoutMs, signal) {
|
|
1275
|
+
if (pc.iceGatheringState === "complete") return Promise.resolve();
|
|
1276
|
+
if (signal?.aborted) return Promise.reject(signal.reason ?? new DOMException("Aborted", "AbortError"));
|
|
1277
|
+
return new Promise((resolve, reject) => {
|
|
1278
|
+
const cleanup = () => {
|
|
1279
|
+
clearTimeout(timer);
|
|
1280
|
+
pc.removeEventListener("icegatheringstatechange", check);
|
|
1281
|
+
signal?.removeEventListener("abort", abort);
|
|
1282
|
+
};
|
|
1283
|
+
const done = () => {
|
|
1284
|
+
cleanup();
|
|
1285
|
+
resolve();
|
|
1286
|
+
};
|
|
1287
|
+
const check = () => {
|
|
1288
|
+
if (pc.iceGatheringState === "complete") done();
|
|
1289
|
+
};
|
|
1290
|
+
const abort = () => {
|
|
1291
|
+
cleanup();
|
|
1292
|
+
reject(signal?.reason ?? new DOMException("Aborted", "AbortError"));
|
|
1293
|
+
};
|
|
1294
|
+
const timer = setTimeout(done, timeoutMs);
|
|
1295
|
+
pc.addEventListener("icegatheringstatechange", check);
|
|
1296
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
const statNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
1300
|
+
function readRtcTransportStats(report) {
|
|
1301
|
+
const stats = {
|
|
1302
|
+
path: null,
|
|
1303
|
+
relayProtocol: null,
|
|
1304
|
+
rttMs: null
|
|
1305
|
+
};
|
|
1306
|
+
report.forEach((entry) => {
|
|
1307
|
+
if (entry.type !== "candidate-pair" || !entry.nominated || entry.state !== "succeeded") return;
|
|
1308
|
+
const local = report.get(String(entry.localCandidateId));
|
|
1309
|
+
const remote = report.get(String(entry.remoteCandidateId));
|
|
1310
|
+
stats.path = local?.candidateType === "relay" || remote?.candidateType === "relay" ? "relay" : "direct";
|
|
1311
|
+
if (local?.candidateType === "relay" && typeof local.relayProtocol === "string") stats.relayProtocol = local.relayProtocol;
|
|
1312
|
+
const rtt = statNumber(entry.currentRoundTripTime);
|
|
1313
|
+
if (rtt !== null) stats.rttMs = Math.round(rtt * 1e3);
|
|
1314
|
+
});
|
|
1315
|
+
return stats;
|
|
1316
|
+
}
|
|
1317
|
+
//#endregion
|
|
1054
1318
|
//#region src/display-stats.ts
|
|
1055
|
-
const num = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
1056
1319
|
function perFrame(seconds, previousSeconds, frames, previousFrames) {
|
|
1057
1320
|
const count = frames - previousFrames;
|
|
1058
1321
|
return count > 0 ? Math.round((seconds - previousSeconds) * 1e3 / count) : null;
|
|
1059
1322
|
}
|
|
1060
1323
|
function readDisplayStats(report, previous, fallbackRttMs = null) {
|
|
1324
|
+
const transport = readRtcTransportStats(report);
|
|
1061
1325
|
const stats = {
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
rttMs: fallbackRttMs,
|
|
1326
|
+
...transport,
|
|
1327
|
+
rttMs: transport.rttMs ?? fallbackRttMs,
|
|
1065
1328
|
fps: null,
|
|
1066
1329
|
bitrate: null,
|
|
1067
1330
|
width: null,
|
|
@@ -1073,27 +1336,19 @@ function readDisplayStats(report, previous, fallbackRttMs = null) {
|
|
|
1073
1336
|
};
|
|
1074
1337
|
let counters = null;
|
|
1075
1338
|
report.forEach((entry) => {
|
|
1076
|
-
if (entry.type === "candidate-pair" && entry.nominated && entry.state === "succeeded") {
|
|
1077
|
-
const local = report.get(String(entry.localCandidateId));
|
|
1078
|
-
const remote = report.get(String(entry.remoteCandidateId));
|
|
1079
|
-
stats.path = local?.candidateType === "relay" || remote?.candidateType === "relay" ? "relay" : "direct";
|
|
1080
|
-
if (local?.candidateType === "relay" && typeof local.relayProtocol === "string") stats.relayProtocol = local.relayProtocol;
|
|
1081
|
-
const rtt = num(entry.currentRoundTripTime);
|
|
1082
|
-
if (rtt !== null) stats.rttMs = Math.round(rtt * 1e3);
|
|
1083
|
-
}
|
|
1084
1339
|
if (entry.type === "inbound-rtp" && entry.kind === "video") {
|
|
1085
|
-
stats.fps =
|
|
1086
|
-
stats.width =
|
|
1087
|
-
stats.height =
|
|
1088
|
-
stats.packetsLost =
|
|
1089
|
-
stats.freezes =
|
|
1340
|
+
stats.fps = statNumber(entry.framesPerSecond);
|
|
1341
|
+
stats.width = statNumber(entry.frameWidth);
|
|
1342
|
+
stats.height = statNumber(entry.frameHeight);
|
|
1343
|
+
stats.packetsLost = statNumber(entry.packetsLost);
|
|
1344
|
+
stats.freezes = statNumber(entry.freezeCount);
|
|
1090
1345
|
counters = {
|
|
1091
|
-
at:
|
|
1092
|
-
bytes:
|
|
1093
|
-
jitterBufferDelay:
|
|
1094
|
-
jitterBufferEmitted:
|
|
1095
|
-
decodeTime:
|
|
1096
|
-
decoded:
|
|
1346
|
+
at: statNumber(entry.timestamp) ?? 0,
|
|
1347
|
+
bytes: statNumber(entry.bytesReceived) ?? 0,
|
|
1348
|
+
jitterBufferDelay: statNumber(entry.jitterBufferDelay) ?? 0,
|
|
1349
|
+
jitterBufferEmitted: statNumber(entry.jitterBufferEmittedCount) ?? 0,
|
|
1350
|
+
decodeTime: statNumber(entry.totalDecodeTime) ?? 0,
|
|
1351
|
+
decoded: statNumber(entry.framesDecoded) ?? 0
|
|
1097
1352
|
};
|
|
1098
1353
|
if (previous && counters.at > previous.at) {
|
|
1099
1354
|
stats.bitrate = Math.round((counters.bytes - previous.bytes) * 8 * 1e3 / (counters.at - previous.at));
|
|
@@ -1165,7 +1420,7 @@ var DisplayConnection = class DisplayConnection {
|
|
|
1165
1420
|
const connection = new DisplayConnection(api, displayId, options.control ?? true, pc);
|
|
1166
1421
|
try {
|
|
1167
1422
|
await pc.setLocalDescription(await pc.createOffer());
|
|
1168
|
-
await
|
|
1423
|
+
await waitForIceGathering(pc, options.gatherTimeoutMs ?? DEFAULT_GATHER_TIMEOUT_MS, options.signal);
|
|
1169
1424
|
const offer = pc.localDescription?.sdp;
|
|
1170
1425
|
if (!offer) throw new Error("The browser produced no offer");
|
|
1171
1426
|
const session = await api.openSession(displayId, {
|
|
@@ -1299,38 +1554,15 @@ var DisplayConnection = class DisplayConnection {
|
|
|
1299
1554
|
}
|
|
1300
1555
|
}
|
|
1301
1556
|
};
|
|
1302
|
-
function gathered(pc, timeoutMs, signal) {
|
|
1303
|
-
if (pc.iceGatheringState === "complete") return Promise.resolve();
|
|
1304
|
-
return new Promise((resolve, reject) => {
|
|
1305
|
-
const done = () => {
|
|
1306
|
-
clearTimeout(timer);
|
|
1307
|
-
pc.removeEventListener("icegatheringstatechange", check);
|
|
1308
|
-
signal?.removeEventListener("abort", abort);
|
|
1309
|
-
resolve();
|
|
1310
|
-
};
|
|
1311
|
-
const check = () => {
|
|
1312
|
-
if (pc.iceGatheringState === "complete") done();
|
|
1313
|
-
};
|
|
1314
|
-
const abort = () => {
|
|
1315
|
-
clearTimeout(timer);
|
|
1316
|
-
pc.removeEventListener("icegatheringstatechange", check);
|
|
1317
|
-
reject(signal?.reason ?? new DOMException("Aborted", "AbortError"));
|
|
1318
|
-
};
|
|
1319
|
-
const timer = setTimeout(done, timeoutMs);
|
|
1320
|
-
pc.addEventListener("icegatheringstatechange", check);
|
|
1321
|
-
signal?.addEventListener("abort", abort, { once: true });
|
|
1322
|
-
});
|
|
1323
|
-
}
|
|
1324
1557
|
function connectDisplay(api, displayId, options) {
|
|
1325
1558
|
return DisplayConnection.open(api, displayId, options);
|
|
1326
1559
|
}
|
|
1327
1560
|
//#endregion
|
|
1328
1561
|
//#region src/apis/displays.ts
|
|
1329
|
-
const ICE_REFRESH_MARGIN_MS = 3e5;
|
|
1330
1562
|
var SpaceDisplaysApi = class {
|
|
1331
1563
|
transport;
|
|
1332
1564
|
spaceId;
|
|
1333
|
-
ice =
|
|
1565
|
+
ice = new IceServerCache((signal) => this.transport.request(`/api/spaces/${this.spaceId}/rtc/ice-servers`, { signal }));
|
|
1334
1566
|
constructor(transport, spaceId) {
|
|
1335
1567
|
this.transport = transport;
|
|
1336
1568
|
this.spaceId = spaceId;
|
|
@@ -1374,14 +1606,8 @@ var SpaceDisplaysApi = class {
|
|
|
1374
1606
|
signal: options.signal
|
|
1375
1607
|
});
|
|
1376
1608
|
}
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
const value = await this.transport.request(`/api/spaces/${this.spaceId}/rtc/ice-servers`, { signal: options.signal });
|
|
1380
|
-
this.ice = {
|
|
1381
|
-
value,
|
|
1382
|
-
refreshAt: Date.parse(value.expiresAt) - ICE_REFRESH_MARGIN_MS
|
|
1383
|
-
};
|
|
1384
|
-
return value;
|
|
1609
|
+
iceServers(options = {}) {
|
|
1610
|
+
return this.ice.get(options.signal);
|
|
1385
1611
|
}
|
|
1386
1612
|
connect(displayId, options) {
|
|
1387
1613
|
return connectDisplay(this, displayId, options);
|
|
@@ -2475,18 +2701,6 @@ const getFilenameFromContentDisposition = (value) => {
|
|
|
2475
2701
|
}
|
|
2476
2702
|
return value.match(/filename="?([^";]+)"?/i)?.[1] ?? null;
|
|
2477
2703
|
};
|
|
2478
|
-
/**
|
|
2479
|
-
* Identifier for a client-authored Board entity (connection id, transaction id).
|
|
2480
|
-
*
|
|
2481
|
-
* `crypto.randomUUID` is used where available and falls back to a random string
|
|
2482
|
-
* otherwise, so the SDK works in a plain browser, a worker and Node without
|
|
2483
|
-
* pulling in a polyfill.
|
|
2484
|
-
*/
|
|
2485
|
-
function randomBoardId() {
|
|
2486
|
-
const cryptoRef = globalThis.crypto;
|
|
2487
|
-
if (cryptoRef && typeof cryptoRef.randomUUID === "function") return cryptoRef.randomUUID();
|
|
2488
|
-
return `c-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
2489
|
-
}
|
|
2490
2704
|
const toSessionEventName = (type) => {
|
|
2491
2705
|
switch (type) {
|
|
2492
2706
|
case "session.created": return "created";
|
|
@@ -3607,199 +3821,6 @@ var SpaceCommerceApi = class {
|
|
|
3607
3821
|
return this.transport.request(`/api/spaces/${this.spaceId}/commerce/orders${params.toString() ? `?${params.toString()}` : ""}`);
|
|
3608
3822
|
}
|
|
3609
3823
|
};
|
|
3610
|
-
var BoardRealtimeClient = class {
|
|
3611
|
-
websocketClient;
|
|
3612
|
-
spaceId;
|
|
3613
|
-
boardId;
|
|
3614
|
-
constructor(websocketClient, spaceId, boardId) {
|
|
3615
|
-
this.websocketClient = websocketClient;
|
|
3616
|
-
this.spaceId = spaceId;
|
|
3617
|
-
this.boardId = boardId;
|
|
3618
|
-
}
|
|
3619
|
-
subscribe(handlers) {
|
|
3620
|
-
if (!this.websocketClient) throw new Error("realtime transport is not configured for this client");
|
|
3621
|
-
ensureRealtimeConnected(this.websocketClient);
|
|
3622
|
-
const releaseRoom = this.websocketClient.retainRooms([getRealtimeSpaceRoom(this.spaceId), getRealtimeBoardRoom(this.boardId)]);
|
|
3623
|
-
const unsubscribe = this.websocketClient.on("event", (event) => {
|
|
3624
|
-
if (event.spaceId !== this.spaceId) return;
|
|
3625
|
-
if (event.type === "board.changed" && event.payload.boardId === this.boardId) {
|
|
3626
|
-
const changedEvent = event;
|
|
3627
|
-
handlers.event?.(changedEvent);
|
|
3628
|
-
handlers.changed?.(changedEvent);
|
|
3629
|
-
}
|
|
3630
|
-
if (event.type === "board.awareness.updated" && event.payload.boardId === this.boardId) {
|
|
3631
|
-
const awarenessEvent = event;
|
|
3632
|
-
if (awarenessEvent.payload.connectionId !== this.websocketClient?.connectionId) {
|
|
3633
|
-
handlers.event?.(awarenessEvent);
|
|
3634
|
-
handlers.awareness?.(awarenessEvent);
|
|
3635
|
-
}
|
|
3636
|
-
}
|
|
3637
|
-
if (event.type === "board.playback.changed" && event.payload.boardId === this.boardId) {
|
|
3638
|
-
const playbackEvent = event;
|
|
3639
|
-
handlers.event?.(playbackEvent);
|
|
3640
|
-
handlers.playback?.(playbackEvent);
|
|
3641
|
-
}
|
|
3642
|
-
});
|
|
3643
|
-
return () => {
|
|
3644
|
-
unsubscribe();
|
|
3645
|
-
releaseRoom();
|
|
3646
|
-
};
|
|
3647
|
-
}
|
|
3648
|
-
on(type, handler) {
|
|
3649
|
-
if (type === "changed") return this.subscribe({ changed: handler });
|
|
3650
|
-
if (type === "awareness") return this.subscribe({ awareness: handler });
|
|
3651
|
-
return this.subscribe({ playback: handler });
|
|
3652
|
-
}
|
|
3653
|
-
};
|
|
3654
|
-
var BoardClient = class {
|
|
3655
|
-
spaceId;
|
|
3656
|
-
id;
|
|
3657
|
-
transport;
|
|
3658
|
-
websocketClient;
|
|
3659
|
-
realtime;
|
|
3660
|
-
constructor(spaceId, id, transport, websocketClient) {
|
|
3661
|
-
this.spaceId = spaceId;
|
|
3662
|
-
this.id = id;
|
|
3663
|
-
this.transport = transport;
|
|
3664
|
-
this.websocketClient = websocketClient;
|
|
3665
|
-
this.realtime = new BoardRealtimeClient(websocketClient, spaceId, id);
|
|
3666
|
-
}
|
|
3667
|
-
get path() {
|
|
3668
|
-
return `/api/spaces/${this.spaceId}/boards/${this.id}`;
|
|
3669
|
-
}
|
|
3670
|
-
/** Read the Board, or part of it. Every value is complete, defaults included. */
|
|
3671
|
-
get(input = {}, customFetch) {
|
|
3672
|
-
const params = new URLSearchParams();
|
|
3673
|
-
if (input.only?.length) params.set("only", input.only.join(","));
|
|
3674
|
-
if (input.rect) params.set("rect", [
|
|
3675
|
-
input.rect.x,
|
|
3676
|
-
input.rect.y,
|
|
3677
|
-
input.rect.width,
|
|
3678
|
-
input.rect.height
|
|
3679
|
-
].join(","));
|
|
3680
|
-
if (input.within) params.set("within", input.within);
|
|
3681
|
-
if (input.items?.length) params.set("items", input.items.join(","));
|
|
3682
|
-
if (input.animations?.length) params.set("animations", input.animations.join(","));
|
|
3683
|
-
if (input.limit !== void 0) params.set("limit", String(input.limit));
|
|
3684
|
-
if (input.cursor) params.set("cursor", input.cursor);
|
|
3685
|
-
const query = params.toString();
|
|
3686
|
-
return this.transport.request(`${this.path}${query ? `?${query}` : ""}`, { fetch: customFetch });
|
|
3687
|
-
}
|
|
3688
|
-
/** Merge a patch into the Board: fields merge, `null` deletes. */
|
|
3689
|
-
apply(patch, options = {}) {
|
|
3690
|
-
return this.transport.request(`${this.path}/apply`, {
|
|
3691
|
-
method: "POST",
|
|
3692
|
-
headers: { "Content-Type": "application/json" },
|
|
3693
|
-
body: JSON.stringify({
|
|
3694
|
-
...options,
|
|
3695
|
-
patch,
|
|
3696
|
-
mutationId: options.mutationId ?? randomBoardId()
|
|
3697
|
-
})
|
|
3698
|
-
});
|
|
3699
|
-
}
|
|
3700
|
-
/** Transactions newest first, each with the before/after state of what it changed. */
|
|
3701
|
-
history(input = {}, customFetch) {
|
|
3702
|
-
const params = new URLSearchParams();
|
|
3703
|
-
if (input.before !== void 0) params.set("before", String(input.before));
|
|
3704
|
-
if (input.limit !== void 0) params.set("limit", String(input.limit));
|
|
3705
|
-
const query = params.toString();
|
|
3706
|
-
return this.transport.request(`${this.path}/history${query ? `?${query}` : ""}`, { fetch: customFetch });
|
|
3707
|
-
}
|
|
3708
|
-
/** Return the Board to an earlier version as a new write. */
|
|
3709
|
-
restore(version) {
|
|
3710
|
-
return this.transport.request(`${this.path}/restore`, {
|
|
3711
|
-
method: "POST",
|
|
3712
|
-
headers: { "Content-Type": "application/json" },
|
|
3713
|
-
body: JSON.stringify({ version })
|
|
3714
|
-
});
|
|
3715
|
-
}
|
|
3716
|
-
playback(command) {
|
|
3717
|
-
return this.transport.request(`${this.path}/playback`, {
|
|
3718
|
-
method: "POST",
|
|
3719
|
-
headers: { "Content-Type": "application/json" },
|
|
3720
|
-
body: JSON.stringify(command)
|
|
3721
|
-
}).then((response) => response.playback);
|
|
3722
|
-
}
|
|
3723
|
-
/** Shared playback: every viewer follows the same clock. */
|
|
3724
|
-
play(animationId, options = {}) {
|
|
3725
|
-
return this.playback({
|
|
3726
|
-
commandId: randomBoardId(),
|
|
3727
|
-
type: "play",
|
|
3728
|
-
animationId,
|
|
3729
|
-
...options
|
|
3730
|
-
});
|
|
3731
|
-
}
|
|
3732
|
-
pause() {
|
|
3733
|
-
return this.playback({
|
|
3734
|
-
commandId: randomBoardId(),
|
|
3735
|
-
type: "pause"
|
|
3736
|
-
});
|
|
3737
|
-
}
|
|
3738
|
-
resume() {
|
|
3739
|
-
return this.playback({
|
|
3740
|
-
commandId: randomBoardId(),
|
|
3741
|
-
type: "resume"
|
|
3742
|
-
});
|
|
3743
|
-
}
|
|
3744
|
-
seek(position) {
|
|
3745
|
-
return this.playback({
|
|
3746
|
-
commandId: randomBoardId(),
|
|
3747
|
-
type: "seek",
|
|
3748
|
-
position
|
|
3749
|
-
});
|
|
3750
|
-
}
|
|
3751
|
-
/** Continue past the marker a presentation is holding at. */
|
|
3752
|
-
next() {
|
|
3753
|
-
return this.playback({
|
|
3754
|
-
commandId: randomBoardId(),
|
|
3755
|
-
type: "next"
|
|
3756
|
-
});
|
|
3757
|
-
}
|
|
3758
|
-
stop() {
|
|
3759
|
-
return this.playback({
|
|
3760
|
-
commandId: randomBoardId(),
|
|
3761
|
-
type: "stop"
|
|
3762
|
-
});
|
|
3763
|
-
}
|
|
3764
|
-
updateAwareness(seq, update) {
|
|
3765
|
-
if (!this.websocketClient) return Promise.resolve();
|
|
3766
|
-
return this.websocketClient.updateBoardAwareness({
|
|
3767
|
-
spaceId: this.spaceId,
|
|
3768
|
-
boardId: this.id,
|
|
3769
|
-
seq,
|
|
3770
|
-
update
|
|
3771
|
-
});
|
|
3772
|
-
}
|
|
3773
|
-
subscribe(handlers) {
|
|
3774
|
-
return this.realtime.subscribe(handlers);
|
|
3775
|
-
}
|
|
3776
|
-
on(type, handler) {
|
|
3777
|
-
if (type === "changed") return this.realtime.on("changed", handler);
|
|
3778
|
-
if (type === "awareness") return this.realtime.on("awareness", handler);
|
|
3779
|
-
return this.realtime.on("playback", handler);
|
|
3780
|
-
}
|
|
3781
|
-
};
|
|
3782
|
-
var SpaceBoardsApi = class {
|
|
3783
|
-
transport;
|
|
3784
|
-
spaceId;
|
|
3785
|
-
websocketClient;
|
|
3786
|
-
constructor(transport, spaceId, websocketClient) {
|
|
3787
|
-
this.transport = transport;
|
|
3788
|
-
this.spaceId = spaceId;
|
|
3789
|
-
this.websocketClient = websocketClient;
|
|
3790
|
-
}
|
|
3791
|
-
byId(boardId) {
|
|
3792
|
-
return new BoardClient(this.spaceId, boardId, this.transport, this.websocketClient);
|
|
3793
|
-
}
|
|
3794
|
-
/** Create a `.board` file and its Board, optionally with an initial document. */
|
|
3795
|
-
create(input) {
|
|
3796
|
-
return this.transport.request(`/api/spaces/${this.spaceId}/boards`, {
|
|
3797
|
-
method: "POST",
|
|
3798
|
-
headers: { "Content-Type": "application/json" },
|
|
3799
|
-
body: JSON.stringify(input)
|
|
3800
|
-
});
|
|
3801
|
-
}
|
|
3802
|
-
};
|
|
3803
3824
|
var SpaceCheckpointFilesApi = class {
|
|
3804
3825
|
transport;
|
|
3805
3826
|
spaceId;
|
|
@@ -4173,7 +4194,12 @@ var SpaceClient = class {
|
|
|
4173
4194
|
return new SessionClient(this.id, sessionId, this.transport, this.websocketClient);
|
|
4174
4195
|
}
|
|
4175
4196
|
board(boardId) {
|
|
4176
|
-
return new BoardClient(
|
|
4197
|
+
return new BoardClient({
|
|
4198
|
+
http: this.transport,
|
|
4199
|
+
websocket: this.websocketClient,
|
|
4200
|
+
spaceId: this.id,
|
|
4201
|
+
boardId
|
|
4202
|
+
});
|
|
4177
4203
|
}
|
|
4178
4204
|
updatePresence(meta) {
|
|
4179
4205
|
if (!this.websocketClient) return Promise.resolve();
|
|
@@ -4739,6 +4765,77 @@ var AppCommerceApi = class {
|
|
|
4739
4765
|
/** @deprecated Use `AppCommerceApi`. */
|
|
4740
4766
|
var WorkCommerceApi = class extends AppCommerceApi {};
|
|
4741
4767
|
//#endregion
|
|
4768
|
+
//#region src/apis/rooms.ts
|
|
4769
|
+
const MAX_WAIT_PER_READ_MS = 25e3;
|
|
4770
|
+
var RoomsApi = class {
|
|
4771
|
+
transport;
|
|
4772
|
+
constructor(transport) {
|
|
4773
|
+
this.transport = transport;
|
|
4774
|
+
}
|
|
4775
|
+
create(input) {
|
|
4776
|
+
return this.post("", input);
|
|
4777
|
+
}
|
|
4778
|
+
join(input) {
|
|
4779
|
+
return this.post("/join", input);
|
|
4780
|
+
}
|
|
4781
|
+
get(roomId) {
|
|
4782
|
+
return this.transport.request(this.path(roomId));
|
|
4783
|
+
}
|
|
4784
|
+
async events(roomId, query = {}) {
|
|
4785
|
+
const deadline = Date.now() + Math.max(0, query.waitMs ?? 0);
|
|
4786
|
+
const result = {
|
|
4787
|
+
events: [],
|
|
4788
|
+
cursor: query.after ?? 0,
|
|
4789
|
+
truncated: false
|
|
4790
|
+
};
|
|
4791
|
+
if (query.limit !== void 0 && query.limit <= 0) return result;
|
|
4792
|
+
let after = query.after;
|
|
4793
|
+
for (;;) {
|
|
4794
|
+
const waitMs = Math.min(Math.max(0, deadline - Date.now()), MAX_WAIT_PER_READ_MS);
|
|
4795
|
+
const params = new URLSearchParams();
|
|
4796
|
+
if (after !== void 0) params.set("after", String(after));
|
|
4797
|
+
if (query.types?.length) params.set("types", query.types.join(","));
|
|
4798
|
+
if (query.limit !== void 0) params.set("limit", String(query.limit - result.events.length));
|
|
4799
|
+
if (waitMs > 0) params.set("wait", String(waitMs));
|
|
4800
|
+
const page = await this.transport.request(`${this.path(roomId)}/events?${params}`, { signal: query.signal });
|
|
4801
|
+
result.events.push(...page.events);
|
|
4802
|
+
result.cursor = page.cursor;
|
|
4803
|
+
result.truncated ||= page.truncated;
|
|
4804
|
+
if (result.events.some((event) => !event.self) || result.events.length >= (query.limit ?? Number.POSITIVE_INFINITY) || waitMs === 0 || Date.now() >= deadline || query.signal?.aborted) return result;
|
|
4805
|
+
after = page.cursor;
|
|
4806
|
+
}
|
|
4807
|
+
}
|
|
4808
|
+
publish(roomId, type, data) {
|
|
4809
|
+
return this.post(`/${encodeURIComponent(roomId)}/events`, {
|
|
4810
|
+
type,
|
|
4811
|
+
data: data ?? null
|
|
4812
|
+
});
|
|
4813
|
+
}
|
|
4814
|
+
setPresence(roomId, presence) {
|
|
4815
|
+
return this.transport.request(`${this.path(roomId)}/presence`, {
|
|
4816
|
+
method: "PUT",
|
|
4817
|
+
headers: { "Content-Type": "application/json" },
|
|
4818
|
+
body: JSON.stringify({ presence })
|
|
4819
|
+
});
|
|
4820
|
+
}
|
|
4821
|
+
invite(roomId, input = {}) {
|
|
4822
|
+
return this.post(`/${encodeURIComponent(roomId)}/invites`, input);
|
|
4823
|
+
}
|
|
4824
|
+
leave(roomId) {
|
|
4825
|
+
return this.transport.request(`${this.path(roomId)}/seat`, { method: "DELETE" });
|
|
4826
|
+
}
|
|
4827
|
+
path(roomId) {
|
|
4828
|
+
return `/api/rooms/${encodeURIComponent(roomId)}`;
|
|
4829
|
+
}
|
|
4830
|
+
post(path, body) {
|
|
4831
|
+
return this.transport.request(`/api/rooms${path}`, {
|
|
4832
|
+
method: "POST",
|
|
4833
|
+
headers: { "Content-Type": "application/json" },
|
|
4834
|
+
body: JSON.stringify(body)
|
|
4835
|
+
});
|
|
4836
|
+
}
|
|
4837
|
+
};
|
|
4838
|
+
//#endregion
|
|
4742
4839
|
//#region src/http.ts
|
|
4743
4840
|
var CohubHttpClient = class {
|
|
4744
4841
|
spaces;
|
|
@@ -4759,6 +4856,7 @@ var CohubHttpClient = class {
|
|
|
4759
4856
|
referrals;
|
|
4760
4857
|
apps;
|
|
4761
4858
|
appCommerce;
|
|
4859
|
+
rooms;
|
|
4762
4860
|
/** @deprecated Use `apps`. */
|
|
4763
4861
|
get works() {
|
|
4764
4862
|
return this.apps;
|
|
@@ -4799,6 +4897,7 @@ var CohubHttpClient = class {
|
|
|
4799
4897
|
this.referrals = new ReferralsApi(this.transport);
|
|
4800
4898
|
this.apps = new AppsApi(this.transport);
|
|
4801
4899
|
this.appCommerce = new AppCommerceApi(this.transport);
|
|
4900
|
+
this.rooms = new RoomsApi(this.transport);
|
|
4802
4901
|
this.desktop = new DesktopCommandsApi(this.transport);
|
|
4803
4902
|
}
|
|
4804
4903
|
space(spaceId) {
|
|
@@ -4807,4 +4906,4 @@ var CohubHttpClient = class {
|
|
|
4807
4906
|
};
|
|
4808
4907
|
const createHttpClient = (options) => new CohubHttpClient(options);
|
|
4809
4908
|
//#endregion
|
|
4810
|
-
export {
|
|
4909
|
+
export { isTerminalDesktopCommandStatus as $, BoardClient as A, CronJobsApi as B, SessionPatchReducer as C, connectDisplay as D, DisplayConnection as E, PublicAssetsApi as F, DESKTOP_COMMAND_OPEN_TIMEOUT_MS as G, DESKTOP_COMMAND_ACCEPT_TIMEOUT_MS as H, SkillsApi as I, DESKTOP_COMMAND_SETTLEMENT_GRACE_SECONDS as J, DESKTOP_COMMAND_PAYLOAD_MAX_BYTES as K, PromptsApi as L, SessionAccessApi as M, ReferencesApi as N, readRtcTransportStats as O, SearchApi as P, isDesktopCallMethod as Q, ModelsApi as R, parseAssistantMessageCommit as S, SpaceDisplaysApi as T, DESKTOP_COMMAND_DEFAULT_TIMEOUT_MS as U, ChannelsApi as V, DESKTOP_COMMAND_MAX_TIMEOUT_MS as W, DESKTOP_COMMAND_VERSION as X, DESKTOP_COMMAND_TERMINAL_TTL_SECONDS as Y, defaultDesktopCommandTimeoutMs as Z, PublicInviteApi as _, WorkCommerceApi as a, DISPLAY_INPUT_MAX_SCHEDULE_MS as at, SessionGenerationStreamClient as b, AppsApi as c, normalizeDisplayPoint as ct, UserApi as d, parseDesktopCommand as et, TasksApi as f, SpacesApi as g, SpaceWebhooksApi as h, AppCommerceApi as i, DISPLAY_ELEMENT_REF_PATTERN as it, ensureRealtimeConnected as j, waitForIceGathering as k, ReferralsApi as l, splitDisplayText as lt, SpacePublicFilesApi as m, createHttpClient as n, resolveOpenSurface as nt, DesktopCommandsApi as o, DISPLAY_INPUT_MAX_TEXT as ot, SpaceClient as p, DESKTOP_COMMAND_PENDING_TTL_SECONDS as q, RoomsApi as r, NAVIGATION_ERROR_MESSAGE_MAX_LENGTH as rt, UiCommandsApi as s, DISPLAY_SYSTEM_ACTIONS as st, CohubHttpClient as t, parseDesktopCommandId as tt, UsersApi as u, buildSpaceInvitePath as v, createSessionPatchReducer as w, createSessionGenerationStreamClient as x, buildSpacePath as y, GenerationsApi as z };
|