@anvia/react-ui 1.1.8 → 1.2.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 +4 -0
- package/dist/chat/index.js +2 -2
- package/dist/chunk-5FZKTDZR.js +201 -0
- package/dist/chunk-5FZKTDZR.js.map +1 -0
- package/dist/{chunk-FUCSDBQK.js → chunk-W2AHKMRS.js} +2 -2
- package/dist/chunk-W2AHKMRS.js.map +1 -0
- package/dist/{chunk-EKC7W5XJ.js → chunk-Y2KAMPVJ.js} +2 -2
- package/dist/index.js +2 -2
- package/dist/message/index.js +1 -1
- package/dist/sandbox-desktop/index.d.ts +122 -0
- package/dist/sandbox-desktop/index.js +356 -0
- package/dist/sandbox-desktop/index.js.map +1 -0
- package/dist/sandbox-terminal/index.d.ts +68 -0
- package/dist/sandbox-terminal/index.js +216 -0
- package/dist/sandbox-terminal/index.js.map +1 -0
- package/dist/ticket-pexI1zIa.d.ts +33 -0
- package/package.json +30 -7
- package/dist/chunk-FUCSDBQK.js.map +0 -1
- /package/dist/{chunk-EKC7W5XJ.js.map → chunk-Y2KAMPVJ.js.map} +0 -0
package/README.md
CHANGED
|
@@ -67,6 +67,10 @@ semantic attributes and behavior; it has no package stylesheet.
|
|
|
67
67
|
- Images, selection toolbars, and optional streaming presentation smoothing.
|
|
68
68
|
- Graph exploration primitives through `@anvia/react-ui/graph-explorer`; install `@anvia/graph`
|
|
69
69
|
when using that integration.
|
|
70
|
+
- A remote sandbox terminal through `@anvia/react-ui/sandbox-terminal`; install `@xterm/xterm` and
|
|
71
|
+
`@xterm/addon-fit` when using it.
|
|
72
|
+
- A remote sandbox desktop viewer with take-over control through
|
|
73
|
+
`@anvia/react-ui/sandbox-desktop`; install `@novnc/novnc` when using it.
|
|
70
74
|
|
|
71
75
|
## Learn more
|
|
72
76
|
|
package/dist/chat/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ComposerPrimitive,
|
|
3
3
|
ThreadPrimitive
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-Y2KAMPVJ.js";
|
|
5
|
+
import "../chunk-W2AHKMRS.js";
|
|
6
6
|
import "../chunk-6XOJFLX4.js";
|
|
7
7
|
import "../chunk-F6AKBUO3.js";
|
|
8
8
|
import "../chunk-22EZJUPM.js";
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
// src/relay/connection.ts
|
|
2
|
+
var ticketSubprotocolPrefix = "anvia.ticket.";
|
|
3
|
+
var defaultInitialDelayMs = 500;
|
|
4
|
+
var defaultMaxDelayMs = 15e3;
|
|
5
|
+
var defaultMaxAttempts = 10;
|
|
6
|
+
var subprotocolToken = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
7
|
+
var RelayConnection = class {
|
|
8
|
+
constructor(options) {
|
|
9
|
+
this.options = options;
|
|
10
|
+
}
|
|
11
|
+
options;
|
|
12
|
+
socketInUse;
|
|
13
|
+
timer;
|
|
14
|
+
attempt = 0;
|
|
15
|
+
everReady = false;
|
|
16
|
+
disposed = false;
|
|
17
|
+
finished = false;
|
|
18
|
+
fatalMessage;
|
|
19
|
+
start() {
|
|
20
|
+
void this.connect();
|
|
21
|
+
}
|
|
22
|
+
/** Try again now, for a link that gave up. */
|
|
23
|
+
retry() {
|
|
24
|
+
if (this.disposed || !this.finished) return;
|
|
25
|
+
clearTimeout(this.timer);
|
|
26
|
+
this.finished = false;
|
|
27
|
+
this.attempt = 0;
|
|
28
|
+
void this.connect();
|
|
29
|
+
}
|
|
30
|
+
/** Send a JSON message, if the socket is open. */
|
|
31
|
+
sendJson(value) {
|
|
32
|
+
if (this.socketInUse?.readyState === WebSocket.OPEN) {
|
|
33
|
+
this.socketInUse.send(JSON.stringify(value));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** Send bytes, if the socket is open. */
|
|
37
|
+
sendBinary(data) {
|
|
38
|
+
if (this.socketInUse?.readyState === WebSocket.OPEN) this.socketInUse.send(data);
|
|
39
|
+
}
|
|
40
|
+
dispose() {
|
|
41
|
+
this.disposed = true;
|
|
42
|
+
clearTimeout(this.timer);
|
|
43
|
+
const socket = this.socketInUse;
|
|
44
|
+
this.socketInUse = void 0;
|
|
45
|
+
socket?.close(1e3);
|
|
46
|
+
}
|
|
47
|
+
async connect() {
|
|
48
|
+
if (this.disposed) return;
|
|
49
|
+
const { label } = this.options.protocol;
|
|
50
|
+
this.options.onStatus({ state: "connecting" });
|
|
51
|
+
this.fatalMessage = void 0;
|
|
52
|
+
let ticket;
|
|
53
|
+
try {
|
|
54
|
+
ticket = await this.options.getTicket?.();
|
|
55
|
+
} catch (error) {
|
|
56
|
+
if (this.disposed) return;
|
|
57
|
+
const detail = error instanceof Error ? `: ${error.message}` : "";
|
|
58
|
+
this.scheduleReconnect(`Could not get a ${label} ticket${detail}`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (this.disposed) return;
|
|
62
|
+
let socket;
|
|
63
|
+
try {
|
|
64
|
+
socket = new WebSocket(this.resolveUrl(), this.resolveProtocols(ticket));
|
|
65
|
+
} catch (error) {
|
|
66
|
+
this.fail(error instanceof Error ? error.message : `Could not open the ${label}.`);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (this.disposed) {
|
|
70
|
+
socket.close(1e3);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
this.socketInUse = socket;
|
|
74
|
+
socket.binaryType = "arraybuffer";
|
|
75
|
+
const session = {
|
|
76
|
+
ready: () => {
|
|
77
|
+
const reconnected = this.everReady;
|
|
78
|
+
this.everReady = true;
|
|
79
|
+
this.attempt = 0;
|
|
80
|
+
this.options.onStatus({ state: "open" });
|
|
81
|
+
return reconnected;
|
|
82
|
+
},
|
|
83
|
+
ended: (info) => {
|
|
84
|
+
this.finished = true;
|
|
85
|
+
const status = { state: "ended", message: info.message ?? "ended" };
|
|
86
|
+
if (info.exitCode !== void 0) status.exitCode = info.exitCode;
|
|
87
|
+
this.options.onStatus(status);
|
|
88
|
+
},
|
|
89
|
+
fatal: (message) => {
|
|
90
|
+
this.fatalMessage = message;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
const { protocol } = this.options;
|
|
94
|
+
socket.addEventListener("open", () => protocol.open(socket, session));
|
|
95
|
+
socket.addEventListener("message", (event) => protocol.message(event, session));
|
|
96
|
+
socket.addEventListener("close", (event) => {
|
|
97
|
+
if (this.socketInUse === socket) this.socketInUse = void 0;
|
|
98
|
+
protocol.close?.(event, session);
|
|
99
|
+
if (this.disposed || this.finished) return;
|
|
100
|
+
if (this.fatalMessage !== void 0) this.fail(this.fatalMessage);
|
|
101
|
+
else this.scheduleReconnect();
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
scheduleReconnect(reason) {
|
|
105
|
+
const { initialDelayMs, maxDelayMs, maxAttempts } = {
|
|
106
|
+
initialDelayMs: defaultInitialDelayMs,
|
|
107
|
+
maxDelayMs: defaultMaxDelayMs,
|
|
108
|
+
maxAttempts: defaultMaxAttempts,
|
|
109
|
+
...this.options.reconnect
|
|
110
|
+
};
|
|
111
|
+
if (this.attempt >= maxAttempts) {
|
|
112
|
+
this.fail(reason ?? `The connection to the ${this.options.protocol.label} was lost.`);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const delay = Math.min(maxDelayMs, initialDelayMs * 2 ** this.attempt) * (0.8 + Math.random() * 0.4);
|
|
116
|
+
this.attempt += 1;
|
|
117
|
+
this.options.onStatus({
|
|
118
|
+
state: "reconnecting",
|
|
119
|
+
attempt: this.attempt,
|
|
120
|
+
retryInMs: Math.round(delay)
|
|
121
|
+
});
|
|
122
|
+
this.timer = setTimeout(() => void this.connect(), delay);
|
|
123
|
+
}
|
|
124
|
+
fail(message) {
|
|
125
|
+
this.finished = true;
|
|
126
|
+
this.options.onStatus({ state: "failed", message });
|
|
127
|
+
}
|
|
128
|
+
resolveUrl() {
|
|
129
|
+
const url = new URL(this.options.url, globalThis.location?.href);
|
|
130
|
+
if (url.protocol === "http:") url.protocol = "ws:";
|
|
131
|
+
else if (url.protocol === "https:") url.protocol = "wss:";
|
|
132
|
+
if (this.options.sessionName !== void 0) {
|
|
133
|
+
url.searchParams.set("session", this.options.sessionName);
|
|
134
|
+
}
|
|
135
|
+
return url.toString();
|
|
136
|
+
}
|
|
137
|
+
/** The subprotocols to offer: the relay's, plus the ticket when there is one. */
|
|
138
|
+
resolveProtocols(ticket) {
|
|
139
|
+
const { subprotocol, label } = this.options.protocol;
|
|
140
|
+
if (ticket === void 0) return [subprotocol];
|
|
141
|
+
if (!subprotocolToken.test(ticket)) {
|
|
142
|
+
throw new Error(`The ${label} ticket must use only URL-safe characters (A-Z a-z 0-9 - _ .).`);
|
|
143
|
+
}
|
|
144
|
+
return [subprotocol, `${ticketSubprotocolPrefix}${ticket}`];
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// src/relay/status.tsx
|
|
149
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
150
|
+
var statusStyle = {
|
|
151
|
+
position: "absolute",
|
|
152
|
+
top: 8,
|
|
153
|
+
right: 8,
|
|
154
|
+
padding: "2px 8px",
|
|
155
|
+
borderRadius: 4,
|
|
156
|
+
fontSize: 12,
|
|
157
|
+
background: "rgba(0, 0, 0, 0.7)",
|
|
158
|
+
color: "#fff"
|
|
159
|
+
};
|
|
160
|
+
function DefaultStatus({ status, retry }) {
|
|
161
|
+
if (status.state === "open") return null;
|
|
162
|
+
return /* @__PURE__ */ jsxs("div", { role: "status", "data-relay-status": status.state, style: statusStyle, children: [
|
|
163
|
+
describe(status),
|
|
164
|
+
status.state === "failed" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
165
|
+
" ",
|
|
166
|
+
/* @__PURE__ */ jsx("button", { type: "button", onClick: retry, children: "Retry" })
|
|
167
|
+
] }) : null
|
|
168
|
+
] });
|
|
169
|
+
}
|
|
170
|
+
function describe(status) {
|
|
171
|
+
switch (status.state) {
|
|
172
|
+
case "loading":
|
|
173
|
+
case "connecting":
|
|
174
|
+
return "Connecting\u2026";
|
|
175
|
+
case "reconnecting":
|
|
176
|
+
return `Reconnecting in ${Math.max(1, Math.round((status.retryInMs ?? 0) / 1e3))}s\u2026`;
|
|
177
|
+
case "ended":
|
|
178
|
+
return status.exitCode === void 0 ? "Session ended" : `Session ended (exit ${status.exitCode})`;
|
|
179
|
+
case "failed":
|
|
180
|
+
return status.message ?? "Disconnected";
|
|
181
|
+
case "open":
|
|
182
|
+
return "";
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// src/relay/ticket.ts
|
|
187
|
+
function resolveTicket(read) {
|
|
188
|
+
if (read() === void 0) return void 0;
|
|
189
|
+
return () => {
|
|
190
|
+
const ticket = read();
|
|
191
|
+
return typeof ticket === "function" ? ticket() : ticket;
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export {
|
|
196
|
+
DefaultStatus,
|
|
197
|
+
resolveTicket,
|
|
198
|
+
ticketSubprotocolPrefix,
|
|
199
|
+
RelayConnection
|
|
200
|
+
};
|
|
201
|
+
//# sourceMappingURL=chunk-5FZKTDZR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/relay/connection.ts","../src/relay/status.tsx","../src/relay/ticket.ts"],"sourcesContent":["/** The prefix a ticket travels under in `Sec-WebSocket-Protocol`. */\nexport const ticketSubprotocolPrefix = \"anvia.ticket.\";\n\nexport type RelayState =\n /** The viewer library is still loading. */\n | \"loading\"\n | \"connecting\"\n | \"open\"\n /** The link dropped and another attempt is scheduled. */\n | \"reconnecting\"\n /** The session itself ended; reconnecting would not help. */\n | \"ended\"\n /** Gave up: a fatal error, or reconnect attempts ran out. */\n | \"failed\";\n\nexport interface RelayStatus {\n state: RelayState;\n /** Reconnect attempt number while `reconnecting`. */\n attempt?: number;\n /** Delay before the next attempt while `reconnecting`. */\n retryInMs?: number;\n /** Exit code when the session ended with one. */\n exitCode?: number;\n /** Human-readable cause for `ended` and `failed`. */\n message?: string;\n}\n\nexport interface RelayReconnectOptions {\n initialDelayMs?: number;\n maxDelayMs?: number;\n /** Consecutive failed attempts before giving up. Default 10. */\n maxAttempts?: number;\n}\n\n/** What a relay protocol can tell the connection about the socket it is driving. */\nexport interface RelaySession {\n /**\n * The relay accepted this attachment. Returns whether an earlier attachment had also been\n * accepted, so a viewer knows to start clean after a reconnect.\n */\n ready(): boolean;\n /** The session itself is over, so the socket closing is not a reason to reconnect. */\n ended(info: { message?: string | undefined; exitCode?: number | undefined }): void;\n /** Something retrying cannot fix. It takes effect when the socket closes. */\n fatal(message: string): void;\n}\n\n/** The part of a relay connection that differs between a terminal and a desktop. */\nexport interface RelayProtocol {\n /** The subprotocol the hub's upgrade handler selects. */\n subprotocol: string;\n /** Names the thing in error messages: \"terminal\", \"desktop\". */\n label: string;\n /** The socket opened. */\n open(socket: WebSocket, session: RelaySession): void;\n message(event: MessageEvent, session: RelaySession): void;\n /** The socket closed. A protocol that learns why from the close frame can call `fatal` here. */\n close?(event: CloseEvent, session: RelaySession): void;\n}\n\nexport interface RelayConnectionOptions {\n /** `ws:`, `wss:`, `http:`, `https:`, or a path relative to the page. */\n url: string;\n /** Appended as `?session=` so the server can pick the session. The server stays in charge. */\n sessionName?: string | undefined;\n /** Called for every attempt, because tickets are single use. */\n getTicket?: (() => string | Promise<string>) | undefined;\n onStatus: (status: RelayStatus) => void;\n reconnect?: RelayReconnectOptions | undefined;\n protocol: RelayProtocol;\n}\n\nconst defaultInitialDelayMs = 500;\nconst defaultMaxDelayMs = 15_000;\nconst defaultMaxAttempts = 10;\n/** Characters a ticket may use, since it travels as a WebSocket subprotocol (an HTTP token). */\nconst subprotocolToken = /^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$/;\n\n/**\n * One browser link to a hub relay: opens the socket with a fresh ticket, reconnects with backoff,\n * and reports its state. What the socket carries is the protocol's business, so this knows nothing\n * about terminals or desktops and is shared by both.\n */\nexport class RelayConnection {\n private socketInUse: WebSocket | undefined;\n private timer: ReturnType<typeof setTimeout> | undefined;\n private attempt = 0;\n private everReady = false;\n private disposed = false;\n private finished = false;\n private fatalMessage: string | undefined;\n\n constructor(private readonly options: RelayConnectionOptions) {}\n\n start(): void {\n void this.connect();\n }\n\n /** Try again now, for a link that gave up. */\n retry(): void {\n // Only a link that gave up needs this; otherwise an attempt is already under way.\n if (this.disposed || !this.finished) return;\n clearTimeout(this.timer);\n this.finished = false;\n this.attempt = 0;\n void this.connect();\n }\n\n /** Send a JSON message, if the socket is open. */\n sendJson(value: Record<string, unknown>): void {\n if (this.socketInUse?.readyState === WebSocket.OPEN) {\n this.socketInUse.send(JSON.stringify(value));\n }\n }\n\n /** Send bytes, if the socket is open. */\n sendBinary(data: ArrayBufferLike | ArrayBufferView): void {\n if (this.socketInUse?.readyState === WebSocket.OPEN) this.socketInUse.send(data);\n }\n\n dispose(): void {\n this.disposed = true;\n clearTimeout(this.timer);\n const socket = this.socketInUse;\n this.socketInUse = undefined;\n socket?.close(1000);\n }\n\n private async connect(): Promise<void> {\n if (this.disposed) return;\n const { label } = this.options.protocol;\n this.options.onStatus({ state: \"connecting\" });\n // A fatal error belongs to the attempt that hit it. Without this, one that was retried away\n // would fail every later drop.\n this.fatalMessage = undefined;\n\n let ticket: string | undefined;\n try {\n ticket = await this.options.getTicket?.();\n } catch (error) {\n // Fetching a ticket usually fails because the control plane is restarting, which is exactly\n // when reconnecting is wanted, so it backs off like a dropped socket.\n if (this.disposed) return;\n const detail = error instanceof Error ? `: ${error.message}` : \"\";\n this.scheduleReconnect(`Could not get a ${label} ticket${detail}`);\n return;\n }\n if (this.disposed) return;\n\n let socket: WebSocket;\n try {\n socket = new WebSocket(this.resolveUrl(), this.resolveProtocols(ticket));\n } catch (error) {\n // A bad URL or a malformed ticket: trying again cannot fix either.\n this.fail(error instanceof Error ? error.message : `Could not open the ${label}.`);\n return;\n }\n if (this.disposed) {\n socket.close(1000);\n return;\n }\n this.socketInUse = socket;\n socket.binaryType = \"arraybuffer\";\n\n const session: RelaySession = {\n ready: () => {\n const reconnected = this.everReady;\n this.everReady = true;\n this.attempt = 0;\n this.options.onStatus({ state: \"open\" });\n return reconnected;\n },\n ended: (info) => {\n this.finished = true;\n const status: RelayStatus = { state: \"ended\", message: info.message ?? \"ended\" };\n if (info.exitCode !== undefined) status.exitCode = info.exitCode;\n this.options.onStatus(status);\n },\n fatal: (message) => {\n this.fatalMessage = message;\n },\n };\n const { protocol } = this.options;\n socket.addEventListener(\"open\", () => protocol.open(socket, session));\n socket.addEventListener(\"message\", (event: MessageEvent) => protocol.message(event, session));\n socket.addEventListener(\"close\", (event: CloseEvent) => {\n if (this.socketInUse === socket) this.socketInUse = undefined;\n protocol.close?.(event, session);\n if (this.disposed || this.finished) return;\n if (this.fatalMessage !== undefined) this.fail(this.fatalMessage);\n else this.scheduleReconnect();\n });\n }\n\n private scheduleReconnect(reason?: string): void {\n const { initialDelayMs, maxDelayMs, maxAttempts } = {\n initialDelayMs: defaultInitialDelayMs,\n maxDelayMs: defaultMaxDelayMs,\n maxAttempts: defaultMaxAttempts,\n ...this.options.reconnect,\n };\n if (this.attempt >= maxAttempts) {\n this.fail(reason ?? `The connection to the ${this.options.protocol.label} was lost.`);\n return;\n }\n const delay =\n Math.min(maxDelayMs, initialDelayMs * 2 ** this.attempt) * (0.8 + Math.random() * 0.4);\n this.attempt += 1;\n this.options.onStatus({\n state: \"reconnecting\",\n attempt: this.attempt,\n retryInMs: Math.round(delay),\n });\n this.timer = setTimeout(() => void this.connect(), delay);\n }\n\n private fail(message: string): void {\n this.finished = true;\n this.options.onStatus({ state: \"failed\", message });\n }\n\n private resolveUrl(): string {\n const url = new URL(this.options.url, globalThis.location?.href);\n if (url.protocol === \"http:\") url.protocol = \"ws:\";\n else if (url.protocol === \"https:\") url.protocol = \"wss:\";\n if (this.options.sessionName !== undefined) {\n url.searchParams.set(\"session\", this.options.sessionName);\n }\n return url.toString();\n }\n\n /** The subprotocols to offer: the relay's, plus the ticket when there is one. */\n private resolveProtocols(ticket: string | undefined): string[] {\n const { subprotocol, label } = this.options.protocol;\n if (ticket === undefined) return [subprotocol];\n if (!subprotocolToken.test(ticket)) {\n throw new Error(`The ${label} ticket must use only URL-safe characters (A-Z a-z 0-9 - _ .).`);\n }\n return [subprotocol, `${ticketSubprotocolPrefix}${ticket}`];\n }\n}\n","import type { CSSProperties } from \"react\";\n\nimport type { RelayStatus } from \"./connection\";\n\nconst statusStyle: CSSProperties = {\n position: \"absolute\",\n top: 8,\n right: 8,\n padding: \"2px 8px\",\n borderRadius: 4,\n fontSize: 12,\n background: \"rgba(0, 0, 0, 0.7)\",\n color: \"#fff\",\n};\n\nexport function DefaultStatus({ status, retry }: { status: RelayStatus; retry: () => void }) {\n if (status.state === \"open\") return null;\n return (\n <div role=\"status\" data-relay-status={status.state} style={statusStyle}>\n {describe(status)}\n {status.state === \"failed\" ? (\n <>\n {\" \"}\n <button type=\"button\" onClick={retry}>\n Retry\n </button>\n </>\n ) : null}\n </div>\n );\n}\n\nfunction describe(status: RelayStatus): string {\n switch (status.state) {\n case \"loading\":\n case \"connecting\":\n return \"Connecting…\";\n case \"reconnecting\":\n return `Reconnecting in ${Math.max(1, Math.round((status.retryInMs ?? 0) / 1_000))}s…`;\n case \"ended\":\n return status.exitCode === undefined\n ? \"Session ended\"\n : `Session ended (exit ${status.exitCode})`;\n case \"failed\":\n return status.message ?? \"Disconnected\";\n case \"open\":\n return \"\";\n }\n}\n","/** What a viewer's `ticket` prop can be: a ticket, or a function returning one per connection. */\nexport type TicketSource = string | (() => string | Promise<string>);\n\n/**\n * Turn the latest `ticket` prop into the per-attempt function a connection wants. The prop is read\n * on every attempt, so a function is called afresh each time: tickets are single use.\n */\nexport function resolveTicket(\n read: () => TicketSource | undefined,\n): (() => string | Promise<string>) | undefined {\n if (read() === undefined) return undefined;\n return () => {\n const ticket = read();\n return typeof ticket === \"function\" ? ticket() : (ticket as string);\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -32,7 +32,7 @@ var MessageActions = forwardRef(
|
|
|
32
32
|
const chat = useChatContext();
|
|
33
33
|
const { message } = useMessage();
|
|
34
34
|
const index = chat.messages.findIndex((item) => item.id === message.id);
|
|
35
|
-
if (message.role !== "assistant" || index < 0 || messageText(message).trim().length === 0) {
|
|
35
|
+
if (message.role !== "assistant" || index < 0 || (props.children == null || typeof props.children === "boolean") && messageText(message).trim().length === 0) {
|
|
36
36
|
return null;
|
|
37
37
|
}
|
|
38
38
|
const following = chat.messages.slice(index + 1);
|
|
@@ -1089,4 +1089,4 @@ export {
|
|
|
1089
1089
|
shiftComposerEntityRanges,
|
|
1090
1090
|
MessagePrimitive
|
|
1091
1091
|
};
|
|
1092
|
-
//# sourceMappingURL=chunk-
|
|
1092
|
+
//# sourceMappingURL=chunk-W2AHKMRS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/message/actions.tsx","../src/message/entity.tsx","../src/message/parts.tsx","../src/strict-json.ts","../src/entities.ts","../src/message/markdown-entities.ts","../src/message/root.tsx","../src/message/index.ts"],"sourcesContent":["import { forwardRef, type MouseEvent, useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { useChatContext, useMessage } from \"../contexts\";\nimport { messageText } from \"../format\";\nimport { type PrimitiveProps, renderPrimitive } from \"../primitives\";\n\nconst MessageActions = forwardRef<HTMLDivElement, PrimitiveProps<\"div\">>(\n function MessageActions(props, ref) {\n const chat = useChatContext();\n const { message } = useMessage();\n const index = chat.messages.findIndex((item) => item.id === message.id);\n if (\n message.role !== \"assistant\" ||\n index < 0 ||\n ((props.children == null || typeof props.children === \"boolean\") &&\n messageText(message).trim().length === 0)\n ) {\n return null;\n }\n const following = chat.messages.slice(index + 1);\n const nextUserIndex = following.findIndex((item) => item.role === \"user\");\n const exchangeRemainder = nextUserIndex < 0 ? following : following.slice(0, nextUserIndex);\n if (\n exchangeRemainder.some((item) => item.role === \"assistant\") ||\n (nextUserIndex < 0 && (chat.status === \"submitted\" || chat.status === \"streaming\"))\n ) {\n return null;\n }\n return renderPrimitive(\n \"div\",\n {\n ...props,\n children: props.children ?? (\n <>\n <MessageCopy />\n <MessageRegenerate />\n </>\n ),\n } as PrimitiveProps<\"div\">,\n ref,\n );\n },\n);\n\ntype MessageCopyState = \"idle\" | \"copied\" | \"error\";\n\nconst MessageCopy = forwardRef<HTMLButtonElement, PrimitiveProps<\"button\">>(function MessageCopy(\n { onClick, ...props },\n ref,\n) {\n const { message } = useMessage();\n const [copyState, setCopyState] = useState<MessageCopyState>(\"idle\");\n const text = messageText(message);\n const previousTextRef = useRef(text);\n const disabled = props.disabled ?? text.length === 0;\n\n useEffect(() => {\n if (previousTextRef.current !== text) {\n previousTextRef.current = text;\n setCopyState(\"idle\");\n }\n }, [text]);\n\n const handleClick = useCallback(\n async (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (event.defaultPrevented || disabled) {\n return;\n }\n const writeText = navigator.clipboard?.writeText;\n if (writeText === undefined) {\n setCopyState(\"error\");\n return;\n }\n try {\n await writeText.call(navigator.clipboard, text);\n setCopyState(\"copied\");\n } catch {\n setCopyState(\"error\");\n }\n },\n [disabled, onClick, text],\n );\n\n return renderPrimitive(\n \"button\",\n {\n ...props,\n children: props.children ?? \"Copy\",\n disabled,\n onClick: handleClick,\n type: props.type ?? \"button\",\n \"data-state\": copyState,\n } as PrimitiveProps<\"button\">,\n ref,\n );\n});\n\nconst MessageRegenerate = forwardRef<HTMLButtonElement, PrimitiveProps<\"button\">>(\n function MessageRegenerate({ onClick, ...props }, ref) {\n const chat = useChatContext();\n const { message } = useMessage();\n const latestAssistantMessage = [...chat.messages]\n .reverse()\n .find((item) => item.role === \"assistant\");\n const disabled =\n props.disabled ??\n (chat.status === \"submitted\" ||\n chat.status === \"streaming\" ||\n message.role !== \"assistant\" ||\n latestAssistantMessage?.id !== message.id);\n\n const handleClick = useCallback(\n (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n if (event.defaultPrevented || disabled) {\n return;\n }\n void chat.regenerate();\n },\n [chat, disabled, onClick],\n );\n\n return renderPrimitive(\n \"button\",\n {\n ...props,\n children: props.children ?? \"Regenerate\",\n disabled,\n onClick: handleClick,\n type: props.type ?? \"button\",\n \"data-state\": disabled ? \"disabled\" : \"idle\",\n } as PrimitiveProps<\"button\">,\n ref,\n );\n },\n);\n\nexport { MessageActions, MessageCopy, MessageRegenerate };\n","import { forwardRef, type HTMLAttributes } from \"react\";\nimport type { ComposerEntity } from \"../contexts\";\n\nexport type MessageEntityProps = HTMLAttributes<HTMLSpanElement> & {\n entity: ComposerEntity;\n};\n\nconst MessageEntity = forwardRef<HTMLSpanElement, MessageEntityProps>(function MessageEntity(\n { children, entity, ...props },\n ref,\n) {\n return (\n <span {...props} data-role=\"entity\" ref={ref}>\n {children ?? entity.text}\n </span>\n );\n});\n\nexport { MessageEntity };\n","import type { UIAttachment, UIMessagePart } from \"@anvia/client\";\nimport {\n type SmoothStreamItemAdapter,\n type StreamSmoothingLifecycle,\n useSmoothStreamItems,\n useSmoothStreamText,\n} from \"@anvia/react\";\nimport {\n type ComponentPropsWithoutRef,\n createElement,\n forwardRef,\n type ReactNode,\n useMemo,\n} from \"react\";\nimport type { Components, Options as ReactMarkdownOptions } from \"react-markdown\";\nimport remarkGfm from \"remark-gfm\";\n\nimport { AttachmentPrimitive } from \"../attachment/index\";\nimport type { ComposerEntity } from \"../contexts\";\nimport {\n InternalAttachmentProvider,\n InternalMessagePartProvider,\n useMessage,\n useMessagePart,\n useOptionalMessagePart,\n} from \"../contexts\";\nimport { entitiesForTextSegment, messageTextLayout, validComposerEntities } from \"../entities\";\nimport { stringifyValue } from \"../format\";\nimport { type PrimitiveProps, renderPrimitive } from \"../primitives\";\nimport { StreamMarkdown } from \"../stream\";\nimport { MessageEntity } from \"./entity\";\nimport { createMessageEntityRemarkPlugin, messageEntityRehypeOptions } from \"./markdown-entities\";\n\ntype MessagePartChildren = ReactNode | ((part: UIMessagePart) => ReactNode);\nexport type MessagePartsFilter = (part: UIMessagePart) => boolean;\nexport type MessageToolPart = Extract<UIMessagePart, { type: \"tool\" }>;\ntype MessageToolChildren = ReactNode | ((part: MessageToolPart) => ReactNode);\nexport type MessageToolRenderWhen = \"always\" | \"pending\" | \"settled\";\nexport type MessageAttachmentPart = Extract<UIMessagePart, { type: \"attachment\" }>;\ntype MessageAttachmentChildren = ReactNode | ((attachment: UIAttachment) => ReactNode);\n\nexport type MessageStreamOptions = StreamSmoothingLifecycle;\n\ntype MessageStreamProps = {\n stream?: MessageStreamOptions;\n};\n\nconst messagePartStreamAdapter: SmoothStreamItemAdapter<UIMessagePart> = {\n getKey: (part) => part.id,\n getText: (part) => (part.type === \"text\" || part.type === \"reasoning\" ? part.text : undefined),\n withText: (part, text) => {\n if (part.type === \"text\" || part.type === \"reasoning\") {\n return part.text === text ? part : { ...part, text };\n }\n return part;\n },\n};\n\ntype MessagePartsProps = Omit<PrimitiveProps<\"div\">, \"children\"> & {\n children?: MessagePartChildren;\n filter?: MessagePartsFilter;\n} & MessageStreamProps;\n\nconst MessageParts = forwardRef<HTMLDivElement, MessagePartsProps>(function MessageParts(\n { children, filter, stream, ...props },\n ref,\n) {\n const { message } = useMessage();\n const parts = filter === undefined ? message.parts : message.parts.filter(filter);\n if (stream !== undefined) {\n return (\n <SmoothedMessageParts {...props} parts={parts} ref={ref} stream={stream}>\n {children}\n </SmoothedMessageParts>\n );\n }\n\n return renderPrimitive(\n \"div\",\n {\n ...props,\n children: renderMessagePartNodes(parts, children),\n \"data-role\": \"parts\",\n } as PrimitiveProps<\"div\">,\n ref,\n );\n});\n\ntype SmoothedMessagePartsProps = Omit<PrimitiveProps<\"div\">, \"children\"> & {\n children?: MessagePartChildren;\n parts: readonly UIMessagePart[];\n stream: MessageStreamOptions;\n};\n\nconst SmoothedMessageParts = forwardRef<HTMLDivElement, SmoothedMessagePartsProps>(\n function SmoothedMessageParts({ children, parts, stream, ...props }, ref) {\n const streamOptions = {\n adapter: messagePartStreamAdapter,\n isStreaming: stream.isStreaming,\n resetKey: stream.resetKey,\n };\n if (stream.flushImmediately !== undefined) {\n Object.assign(streamOptions, { flushImmediately: stream.flushImmediately });\n }\n const smooth = useSmoothStreamItems(parts, streamOptions);\n\n return renderPrimitive(\n \"div\",\n {\n ...props,\n children: renderMessagePartNodes(smooth.items, children, smooth.liveItemKey),\n \"data-role\": \"parts\",\n \"data-state\": smooth.isDraining ? \"draining\" : stream.isStreaming ? \"streaming\" : \"idle\",\n } as PrimitiveProps<\"div\">,\n ref,\n );\n },\n);\n\nfunction renderMessagePartNodes(\n parts: readonly UIMessagePart[],\n children: MessagePartChildren | undefined,\n liveItemKey?: string | null,\n): ReactNode[] {\n return parts.map((part) => (\n <InternalMessagePartProvider\n isLive={liveItemKey === part.id}\n key={part.id}\n part={part}\n streamControlled={liveItemKey !== undefined}\n >\n {typeof children === \"function\" ? children(part) : (children ?? <MessagePart />)}\n </InternalMessagePartProvider>\n ));\n}\n\ntype MessagePartProps = Omit<PrimitiveProps<\"div\">, \"children\"> & {\n children?: MessagePartChildren;\n};\n\nconst MessagePart = forwardRef<HTMLDivElement, MessagePartProps>(function MessagePart(\n { children, ...props },\n ref,\n) {\n const { part } = useMessagePart();\n const renderedChildren =\n typeof children === \"function\" ? children(part) : (children ?? defaultPart(part));\n\n return renderPrimitive(\n \"div\",\n {\n ...props,\n children: renderedChildren,\n \"data-role\": part.type,\n } as PrimitiveProps<\"div\">,\n ref,\n );\n});\n\ntype MessageTextProps = PrimitiveProps<\"span\"> & MessageStreamProps;\n\nconst MessageText = forwardRef<HTMLSpanElement, MessageTextProps>(function MessageText(props, ref) {\n const { part, streamControlled } = useMessagePart();\n if (part.type !== \"text\") {\n return null;\n }\n\n return (\n <MessageTextContent\n {...props}\n content={part.text}\n partId={part.id}\n ref={ref}\n streamControlled={streamControlled}\n />\n );\n});\n\ntype MessageTextContentProps = MessageTextProps & {\n content: string;\n partId: string;\n streamControlled: boolean;\n};\n\nconst MessageTextContent = forwardRef<HTMLSpanElement, MessageTextContentProps>(\n function MessageTextContent({ content, partId, stream, streamControlled, ...props }, ref) {\n const ownsStream = stream !== undefined && !streamControlled && props.children === undefined;\n const streamOptions = {\n isStreaming: ownsStream ? stream.isStreaming : false,\n resetKey: ownsStream ? stream.resetKey : partId,\n };\n if (ownsStream && stream.flushImmediately !== undefined) {\n Object.assign(streamOptions, { flushImmediately: stream.flushImmediately });\n }\n const smooth = useSmoothStreamText(content, streamOptions);\n\n return renderPrimitive(\n \"span\",\n {\n ...props,\n children: props.children ?? (ownsStream ? smooth.text : content),\n \"data-role\": \"text\",\n \"data-state\": ownsStream\n ? smooth.isDraining\n ? \"draining\"\n : stream.isStreaming\n ? \"streaming\"\n : \"idle\"\n : undefined,\n } as PrimitiveProps<\"span\">,\n ref,\n );\n },\n);\n\ntype MessageMarkdownProps = Omit<PrimitiveProps<\"div\">, \"children\"> &\n MessageStreamProps & {\n children?: string;\n components?: Components;\n renderEntity?: ((entity: ComposerEntity) => ReactNode) | undefined;\n remarkPlugins?: ReactMarkdownOptions[\"remarkPlugins\"];\n };\n\nconst MessageMarkdown = forwardRef<HTMLDivElement, MessageMarkdownProps>(function MessageMarkdown(\n { children, ...props },\n ref,\n) {\n const { message } = useMessage();\n const partContext = useOptionalMessagePart();\n const part = partContext?.part;\n if (part !== undefined && part.type !== \"text\") {\n return null;\n }\n\n const layout = messageTextLayout(message.parts);\n const markdown = children ?? (part?.type === \"text\" ? part.text : layout.text);\n const expectedMarkdown = part?.type === \"text\" ? part.text : layout.text;\n const validEntities =\n children === undefined || children === expectedMarkdown\n ? validComposerEntities(layout.text, message.metadata)\n : [];\n const segment =\n part?.type === \"text\"\n ? layout.segments.find((candidate) => candidate.part.id === part.id)\n : undefined;\n const entities =\n segment === undefined ? validEntities : entitiesForTextSegment(validEntities, segment);\n const lastPart = message.parts.at(-1);\n const liveEligible = part?.type === \"text\" ? lastPart?.id === part.id : lastPart?.type === \"text\";\n\n return (\n <MessageMarkdownContent\n {...props}\n entities={entities}\n liveEligible={liveEligible}\n markdown={markdown}\n ref={ref}\n resetKey={message.id}\n streamControlled={partContext?.streamControlled ?? false}\n streamLive={partContext?.isLive ?? false}\n />\n );\n});\n\ntype MessageMarkdownContentProps = Omit<MessageMarkdownProps, \"children\"> & {\n entities: ComposerEntity[];\n liveEligible: boolean;\n markdown: string;\n resetKey: string;\n streamControlled: boolean;\n streamLive: boolean;\n};\n\nconst MessageMarkdownContent = forwardRef<HTMLDivElement, MessageMarkdownContentProps>(\n function MessageMarkdownContent(\n {\n components,\n renderEntity,\n remarkPlugins,\n entities,\n liveEligible,\n markdown,\n resetKey,\n stream,\n streamControlled,\n streamLive,\n ...props\n },\n ref,\n ) {\n const ownsStream = stream !== undefined && !streamControlled;\n const streamOptions = {\n isStreaming: ownsStream ? stream.isStreaming : false,\n resetKey: ownsStream ? stream.resetKey : resetKey,\n };\n if (ownsStream && stream.flushImmediately !== undefined) {\n Object.assign(streamOptions, { flushImmediately: stream.flushImmediately });\n }\n const smooth = useSmoothStreamText(markdown, streamOptions);\n const renderedMarkdown = ownsStream ? smooth.text : markdown;\n const renderedEntities = useMemo(\n () =>\n entities.length === 0\n ? entities\n : validComposerEntities(renderedMarkdown, {\n composer: { entities },\n }),\n [entities, renderedMarkdown],\n );\n const renderedComponents = useMemo(\n () => markdownComponents(components, renderedEntities, renderEntity),\n [components, renderEntity, renderedEntities],\n );\n const renderedRemarkPlugins = useMemo(\n () =>\n renderedEntities.length === 0\n ? remarkPlugins\n : [\n createMessageEntityRemarkPlugin(renderedMarkdown, renderedEntities),\n ...(remarkPlugins ?? [remarkGfm]),\n ],\n [remarkPlugins, renderedEntities, renderedMarkdown],\n );\n const live = streamControlled\n ? streamLive\n : ownsStream && liveEligible && (stream.isStreaming || smooth.isDraining);\n\n return (\n <StreamMarkdown\n {...props}\n components={renderedComponents}\n content={renderedMarkdown}\n data-state={\n ownsStream && smooth.isDraining\n ? \"draining\"\n : ownsStream && stream.isStreaming\n ? \"streaming\"\n : \"idle\"\n }\n live={live}\n ref={ref}\n remarkPlugins={renderedRemarkPlugins}\n remarkRehypeOptions={\n renderedEntities.length === 0 ? undefined : messageEntityRehypeOptions()\n }\n />\n );\n },\n);\n\nfunction markdownComponents(\n components: Components | undefined,\n entities: ComposerEntity[],\n renderEntity: ((entity: ComposerEntity) => ReactNode) | undefined,\n): Components {\n const consumerSpan = components?.span;\n return {\n code: defaultCodeComponent,\n pre: defaultPreComponent,\n ...components,\n span(spanProps) {\n const internalProps = spanProps as typeof spanProps & {\n \"data-entity-index\"?: string | undefined;\n };\n const entityIndexValue = internalProps[\"data-entity-index\"];\n const entityIndex =\n typeof entityIndexValue === \"string\" && /^\\d+$/.test(entityIndexValue)\n ? Number(entityIndexValue)\n : undefined;\n const entity = entityIndex === undefined ? undefined : entities[entityIndex];\n const consumerProps = { ...internalProps };\n delete consumerProps[\"data-entity-index\"];\n\n if (entity !== undefined) {\n if (renderEntity !== undefined) {\n return renderEntity(entity);\n }\n const entityProps = {\n ...consumerProps,\n \"data-role\": \"entity\",\n };\n if (consumerSpan !== undefined) {\n return createElement(consumerSpan, entityProps);\n }\n const { node: _node, ...elementProps } = entityProps;\n return <MessageEntity {...elementProps} entity={entity} />;\n }\n\n if (consumerSpan !== undefined) {\n return createElement(consumerSpan, consumerProps);\n }\n const { node: _node, ...elementProps } = consumerProps;\n return <span {...elementProps} />;\n },\n };\n}\n\ntype MessageCodeBlockProps = Omit<PrimitiveProps<\"pre\">, \"children\"> & {\n children?: ReactNode;\n code?: string;\n language?: string;\n};\n\nconst MessageCodeBlock = forwardRef<HTMLPreElement, MessageCodeBlockProps>(\n function MessageCodeBlock({ children, code, language, ...props }, ref) {\n return renderPrimitive(\n \"pre\",\n {\n ...props,\n \"data-role\": \"code-block\",\n children: children ?? (\n <code className={language === undefined ? undefined : `language-${language}`}>\n {code ?? \"\"}\n </code>\n ),\n } as PrimitiveProps<\"pre\">,\n ref,\n );\n },\n);\n\nconst MessageReasoning = forwardRef<HTMLDetailsElement, PrimitiveProps<\"details\">>(\n function MessageReasoning(props, ref) {\n const { part } = useMessagePart();\n if (part.type !== \"reasoning\") {\n return null;\n }\n\n return renderPrimitive(\n \"details\",\n {\n ...props,\n children: props.children ?? (\n <>\n <summary>Reasoning</summary>\n <pre>{part.text}</pre>\n </>\n ),\n } as PrimitiveProps<\"details\">,\n ref,\n );\n },\n);\n\ntype MessageToolProps = Omit<PrimitiveProps<\"div\">, \"children\"> & {\n children?: MessageToolChildren;\n renderWhen?: MessageToolRenderWhen;\n};\n\nconst MessageTool = forwardRef<HTMLDivElement, MessageToolProps>(function MessageTool(\n { children, renderWhen = \"always\", ...props },\n ref,\n) {\n const { part } = useMessagePart();\n if (part.type !== \"tool\" || !shouldRenderTool(part, renderWhen)) {\n return null;\n }\n const renderedChildren =\n typeof children === \"function\" ? children(part) : (children ?? defaultToolContent());\n\n return renderPrimitive(\n \"div\",\n {\n ...props,\n children: renderedChildren,\n \"data-role\": \"tool\",\n \"data-state\": part.state,\n } as PrimitiveProps<\"div\">,\n ref,\n );\n});\n\nconst MessageToolName = forwardRef<HTMLSpanElement, PrimitiveProps<\"span\">>(\n function MessageToolName(props, ref) {\n const { part } = useMessagePart();\n if (part.type !== \"tool\") {\n return null;\n }\n\n return renderPrimitive(\n \"span\",\n {\n ...props,\n children: props.children ?? part.toolName,\n } as PrimitiveProps<\"span\">,\n ref,\n );\n },\n);\n\nconst MessageToolStatus = forwardRef<HTMLSpanElement, PrimitiveProps<\"span\">>(\n function MessageToolStatus(props, ref) {\n const { part } = useMessagePart();\n if (part.type !== \"tool\") {\n return null;\n }\n\n return renderPrimitive(\n \"span\",\n {\n ...props,\n children: props.children ?? toolStateLabel(part.state),\n \"data-state\": part.state,\n } as PrimitiveProps<\"span\">,\n ref,\n );\n },\n);\n\nconst MessageToolInput = forwardRef<HTMLPreElement, PrimitiveProps<\"pre\">>(\n function MessageToolInput(props, ref) {\n const { part } = useMessagePart();\n if (part.type !== \"tool\") {\n return null;\n }\n\n return renderPrimitive(\n \"pre\",\n {\n ...props,\n children: props.children ?? stringifyValue(part.input),\n } as PrimitiveProps<\"pre\">,\n ref,\n );\n },\n);\n\nconst MessageToolOutput = forwardRef<HTMLPreElement, PrimitiveProps<\"pre\">>(\n function MessageToolOutput(props, ref) {\n const { part } = useMessagePart();\n if (part.type !== \"tool\" || part.state !== \"output-available\") {\n return null;\n }\n\n return renderPrimitive(\n \"pre\",\n {\n ...props,\n children: props.children ?? stringifyValue(part.output),\n } as PrimitiveProps<\"pre\">,\n ref,\n );\n },\n);\n\nconst MessageToolError = forwardRef<HTMLDivElement, PrimitiveProps<\"div\">>(\n function MessageToolError(props, ref) {\n const { part } = useMessagePart();\n if (part.type !== \"tool\" || part.state !== \"error\") {\n return null;\n }\n\n return renderPrimitive(\n \"div\",\n {\n ...props,\n children: props.children ?? part.error.message,\n role: props.role ?? \"alert\",\n } as PrimitiveProps<\"div\">,\n ref,\n );\n },\n);\n\ntype MessageAttachmentProps = Omit<PrimitiveProps<\"div\">, \"children\"> & {\n children?: MessageAttachmentChildren;\n};\n\nconst MessageAttachment = forwardRef<HTMLDivElement, MessageAttachmentProps>(\n function MessageAttachment({ children, ...props }, ref) {\n const { part } = useMessagePart();\n if (part.type !== \"attachment\") {\n return null;\n }\n const renderedChildren =\n typeof children === \"function\"\n ? children(part.attachment)\n : (children ?? <AttachmentPrimitive.Root />);\n\n return (\n <InternalAttachmentProvider value={{ attachment: part.attachment }}>\n {renderPrimitive(\n \"div\",\n {\n ...props,\n children: renderedChildren,\n } as PrimitiveProps<\"div\">,\n ref,\n )}\n </InternalAttachmentProvider>\n );\n },\n);\n\nconst MessageData = forwardRef<HTMLPreElement, PrimitiveProps<\"pre\">>(\n function MessageData(props, ref) {\n const { part } = useMessagePart();\n if (part.type !== \"data\") {\n return null;\n }\n\n return renderPrimitive(\n \"pre\",\n {\n ...props,\n children: props.children ?? stringifyValue(part.data),\n } as PrimitiveProps<\"pre\">,\n ref,\n );\n },\n);\n\nconst MessageError = forwardRef<HTMLDivElement, PrimitiveProps<\"div\">>(\n function MessageError(props, ref) {\n const { part } = useMessagePart();\n if (part.type !== \"error\") {\n return null;\n }\n\n return renderPrimitive(\n \"div\",\n {\n ...props,\n children: props.children ?? part.error.message,\n role: props.role ?? \"alert\",\n } as PrimitiveProps<\"div\">,\n ref,\n );\n },\n);\n\nfunction defaultPart(part: UIMessagePart): ReactNode {\n if (part.type === \"text\") {\n return <MessageText />;\n }\n if (part.type === \"reasoning\") {\n return <MessageReasoning />;\n }\n if (part.type === \"tool\") {\n return <MessageTool />;\n }\n if (part.type === \"attachment\") {\n return <MessageAttachment />;\n }\n if (part.type === \"data\") {\n return <MessageData />;\n }\n return <MessageError />;\n}\n\nfunction defaultToolContent(): ReactNode {\n return (\n <>\n <MessageToolName />\n <MessageToolStatus />\n <MessageToolInput />\n <MessageToolOutput />\n <MessageToolError />\n </>\n );\n}\n\nfunction defaultCodeComponent({\n children,\n className,\n node: _node,\n ...props\n}: ComponentPropsWithoutRef<\"code\"> & { node?: unknown }): ReactNode {\n return (\n <code className={className} {...props}>\n {children}\n </code>\n );\n}\n\nfunction defaultPreComponent({\n children,\n node: _node,\n ...props\n}: ComponentPropsWithoutRef<\"pre\"> & { node?: unknown }): ReactNode {\n return <MessageCodeBlock {...props}>{children}</MessageCodeBlock>;\n}\n\nfunction shouldRenderTool(part: MessageToolPart, renderWhen: MessageToolRenderWhen): boolean {\n if (renderWhen === \"always\") {\n return true;\n }\n if (renderWhen === \"pending\") {\n return part.state === \"input-streaming\" || part.state === \"input-available\";\n }\n return part.state === \"output-available\" || part.state === \"error\";\n}\n\nfunction toolStateLabel(state: MessageToolPart[\"state\"]): string {\n if (state === \"output-available\") {\n return \"Done\";\n }\n if (state === \"error\") {\n return \"Error\";\n }\n return \"Running\";\n}\n\nexport {\n MessageAttachment,\n MessageCodeBlock,\n MessageData,\n MessageError,\n MessageMarkdown,\n MessagePart,\n MessageParts,\n MessageReasoning,\n MessageText,\n MessageTool,\n MessageToolError,\n MessageToolInput,\n MessageToolName,\n MessageToolOutput,\n MessageToolStatus,\n};\n","import type { ComposerEntityData } from \"./contexts/composer\";\n\nexport function isComposerEntityData(value: unknown): value is ComposerEntityData {\n return isComposerEntityDataWithAncestors(value, new WeakSet<object>());\n}\n\nfunction isComposerEntityDataWithAncestors(\n value: unknown,\n ancestors: WeakSet<object>,\n): value is ComposerEntityData {\n if (value === null || typeof value === \"string\" || typeof value === \"boolean\") return true;\n if (typeof value === \"number\") return Number.isFinite(value);\n if (typeof value !== \"object\" || ancestors.has(value)) return false;\n\n ancestors.add(value);\n try {\n if (Array.isArray(value)) {\n if (Object.getPrototypeOf(value) !== Array.prototype || !hasOnlyDenseArrayProperties(value)) {\n return false;\n }\n for (let index = 0; index < value.length; index += 1) {\n if (!isComposerEntityDataWithAncestors(value[index], ancestors)) return false;\n }\n return true;\n }\n\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) return false;\n for (const key of Reflect.ownKeys(value)) {\n if (typeof key !== \"string\") return false;\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n if (\n descriptor === undefined ||\n !descriptor.enumerable ||\n !(\"value\" in descriptor) ||\n !isComposerEntityDataWithAncestors(descriptor.value, ancestors)\n ) {\n return false;\n }\n }\n return true;\n } catch {\n return false;\n } finally {\n ancestors.delete(value);\n }\n}\n\nfunction hasOnlyDenseArrayProperties(value: unknown[]): boolean {\n const keys = Reflect.ownKeys(value);\n if (keys.length !== value.length + 1 || keys.at(-1) !== \"length\") return false;\n for (let index = 0; index < value.length; index += 1) {\n const key = String(index);\n if (keys[index] !== key) return false;\n const descriptor = Object.getOwnPropertyDescriptor(value, key);\n if (descriptor === undefined || !descriptor.enumerable || !(\"value\" in descriptor)) {\n return false;\n }\n }\n return true;\n}\n","import type { UIMessagePart } from \"@anvia/client\";\nimport type { ComposerEntity } from \"./contexts/composer\";\nimport { isComposerEntityData } from \"./strict-json\";\n\nexport type MessageTextSegment = {\n part: Extract<UIMessagePart, { type: \"text\" }>;\n from: number;\n to: number;\n};\n\nexport type MessageTextLayout = {\n text: string;\n segments: MessageTextSegment[];\n};\n\nexport function messageTextLayout(parts: readonly UIMessagePart[]): MessageTextLayout {\n const textParts = parts.filter(\n (part): part is Extract<UIMessagePart, { type: \"text\" }> => part.type === \"text\",\n );\n const segments: MessageTextSegment[] = [];\n let offset = 0;\n\n for (const [index, part] of textParts.entries()) {\n const from = offset;\n const to = from + part.text.length;\n segments.push({ part, from, to });\n offset = to + (index === textParts.length - 1 ? 0 : 2);\n }\n\n return {\n text: textParts.map((part) => part.text).join(\"\\n\\n\"),\n segments,\n };\n}\n\nexport function validComposerEntities(text: string, metadata: unknown): ComposerEntity[] {\n const candidates = composerEntityCandidates(metadata);\n const individuallyValid = candidates.flatMap((candidate, index) => {\n const entity = parseComposerEntity(candidate, text);\n return entity === undefined ? [] : [{ entity, index }];\n });\n individuallyValid.sort(\n (left, right) =>\n left.entity.range.from - right.entity.range.from ||\n left.entity.range.to - right.entity.range.to ||\n left.index - right.index,\n );\n\n const overlapping = new Set<number>();\n let groupStart = 0;\n let groupEnd = individuallyValid[0]?.entity.range.to ?? 0;\n let groupHasOverlap = false;\n for (let index = 1; index <= individuallyValid.length; index += 1) {\n const current = individuallyValid[index];\n if (current !== undefined && current.entity.range.from < groupEnd) {\n groupHasOverlap = true;\n groupEnd = Math.max(groupEnd, current.entity.range.to);\n continue;\n }\n if (groupHasOverlap) {\n for (let groupIndex = groupStart; groupIndex < index; groupIndex += 1) {\n const candidate = individuallyValid[groupIndex];\n if (candidate !== undefined) {\n overlapping.add(candidate.index);\n }\n }\n }\n groupStart = index;\n groupEnd = current?.entity.range.to ?? 0;\n groupHasOverlap = false;\n }\n\n return individuallyValid\n .filter((candidate) => !overlapping.has(candidate.index))\n .map((candidate) => candidate.entity);\n}\n\nexport function entitiesForTextSegment(\n entities: ComposerEntity[],\n segment: MessageTextSegment,\n): ComposerEntity[] {\n return entities.flatMap((entity) => {\n if (entity.range.from < segment.from || entity.range.to > segment.to) {\n return [];\n }\n return [\n {\n ...entity,\n range: {\n from: entity.range.from - segment.from,\n to: entity.range.to - segment.from,\n },\n },\n ];\n });\n}\n\nexport function shiftComposerEntityRanges(\n entities: ComposerEntity[],\n offset: number,\n): ComposerEntity[] {\n if (offset === 0) {\n return entities;\n }\n return entities.map((entity) => ({\n ...entity,\n range: {\n from: entity.range.from + offset,\n to: entity.range.to + offset,\n },\n }));\n}\n\nfunction composerEntityCandidates(metadata: unknown): unknown[] {\n if (!isRecord(metadata) || !isRecord(metadata.composer)) {\n return [];\n }\n return Array.isArray(metadata.composer.entities) ? metadata.composer.entities : [];\n}\n\nfunction parseComposerEntity(value: unknown, text: string): ComposerEntity | undefined {\n if (!isRecord(value) || !isRecord(value.range)) {\n return undefined;\n }\n if (\n !isNonEmptyString(value.id) ||\n !isNonEmptyString(value.triggerId) ||\n !isNonEmptyString(value.trigger) ||\n !isNonEmptyString(value.label) ||\n !isNonEmptyString(value.text)\n ) {\n return undefined;\n }\n const { from, to } = value.range;\n if (\n typeof from !== \"number\" ||\n typeof to !== \"number\" ||\n !Number.isInteger(from) ||\n !Number.isInteger(to) ||\n from < 0 ||\n to <= from ||\n to > text.length ||\n text.slice(from, to) !== value.text\n ) {\n return undefined;\n }\n if (value.data !== undefined && !isComposerEntityData(value.data)) return undefined;\n const entity: ComposerEntity = {\n id: value.id,\n triggerId: value.triggerId,\n trigger: value.trigger,\n label: value.label,\n text: value.text,\n range: { from, to },\n };\n if (value.data !== undefined) entity.data = value.data;\n return entity;\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.length > 0;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import type { Options as ReactMarkdownOptions } from \"react-markdown\";\nimport type { ComposerEntity } from \"../contexts\";\n\ntype MarkdownPoint = {\n offset?: number | undefined;\n};\n\ntype MarkdownPosition = {\n start: MarkdownPoint;\n end: MarkdownPoint;\n};\n\ntype MarkdownNode = {\n type: string;\n value?: string | undefined;\n children?: MarkdownNode[] | undefined;\n position?: MarkdownPosition | undefined;\n entityIndex?: number | undefined;\n};\n\nconst phrasingParentTypes = new Set([\n \"paragraph\",\n \"heading\",\n \"emphasis\",\n \"strong\",\n \"delete\",\n \"link\",\n \"linkReference\",\n \"tableCell\",\n]);\nconst literalNodeTypes = new Set([\"code\", \"inlineCode\", \"html\", \"yaml\"]);\n\nexport function createMessageEntityRemarkPlugin(markdown: string, entities: ComposerEntity[]) {\n return function messageEntityRemarkPlugin() {\n return (tree: MarkdownNode): void => {\n const rendered = new Set<number>();\n transformNode(tree, markdown, entities, rendered);\n };\n };\n}\n\nexport function messageEntityRehypeOptions(): ReactMarkdownOptions[\"remarkRehypeOptions\"] {\n return {\n handlers: {\n messageEntity(_state: unknown, node: MarkdownNode) {\n const entityIndex = node.entityIndex;\n return {\n type: \"element\",\n tagName: \"span\",\n properties: {\n dataEntityIndex: entityIndex === undefined ? \"\" : String(entityIndex),\n },\n children: [{ type: \"text\", value: node.value ?? \"\" }],\n };\n },\n } as never,\n };\n}\n\nfunction transformNode(\n node: MarkdownNode,\n markdown: string,\n entities: ComposerEntity[],\n rendered: Set<number>,\n): void {\n if (literalNodeTypes.has(node.type) || node.children === undefined) {\n return;\n }\n\n for (const child of node.children) {\n transformNode(child, markdown, entities, rendered);\n }\n if (!phrasingParentTypes.has(node.type)) {\n return;\n }\n\n for (let entityIndex = entities.length - 1; entityIndex >= 0; entityIndex -= 1) {\n if (rendered.has(entityIndex)) {\n continue;\n }\n const entity = entities[entityIndex];\n if (entity !== undefined && replaceEntity(node, markdown, entity, entityIndex)) {\n rendered.add(entityIndex);\n }\n }\n}\n\nfunction replaceEntity(\n parent: MarkdownNode,\n markdown: string,\n entity: ComposerEntity,\n entityIndex: number,\n): boolean {\n const children = parent.children;\n if (children === undefined) {\n return false;\n }\n const firstIndex = children.findIndex((child) => containsStart(child, entity.range.from));\n const lastIndex = findLastIndex(children, (child) => containsEnd(child, entity.range.to));\n if (firstIndex < 0 || lastIndex < firstIndex) {\n return false;\n }\n\n const first = children[firstIndex];\n const last = children[lastIndex];\n const firstPosition = offsets(first);\n const lastPosition = offsets(last);\n if (\n first === undefined ||\n last === undefined ||\n firstPosition === undefined ||\n lastPosition === undefined ||\n entity.range.from < firstPosition.from ||\n entity.range.to > lastPosition.to\n ) {\n return false;\n }\n\n if (firstIndex === lastIndex && literalNodeTypes.has(first.type)) {\n return false;\n }\n const before = contentBefore(first, markdown, entity);\n const after = contentAfter(last, markdown, entity);\n if (before === undefined || after === undefined) {\n return false;\n }\n\n const replacement: MarkdownNode[] = [];\n replacement.push(...before);\n replacement.push({\n type: \"messageEntity\",\n value: entity.text,\n entityIndex,\n position: {\n start: { offset: entity.range.from },\n end: { offset: entity.range.to },\n },\n });\n replacement.push(...after);\n children.splice(firstIndex, lastIndex - firstIndex + 1, ...replacement);\n return true;\n}\n\nfunction contentBefore(\n node: MarkdownNode,\n markdown: string,\n entity: ComposerEntity,\n): MarkdownNode[] | undefined {\n const position = offsets(node);\n if (position === undefined) {\n return undefined;\n }\n if (entity.range.from === position.from) {\n return [];\n }\n if (node.type !== \"text\" || node.value === undefined) {\n if (node.children === undefined || literalNodeTypes.has(node.type)) {\n return undefined;\n }\n const childIndex = node.children.findIndex((child) => containsStart(child, entity.range.from));\n const child = node.children[childIndex];\n if (child === undefined) {\n return undefined;\n }\n const childContent = contentBefore(child, markdown, entity);\n return childContent === undefined\n ? undefined\n : [...node.children.slice(0, childIndex), ...childContent];\n }\n const split = textValueRange(node, markdown, entity);\n if (split === undefined) {\n return undefined;\n }\n return [\n {\n ...node,\n value: node.value.slice(0, split.from),\n position: {\n start: node.position?.start ?? {},\n end: { offset: entity.range.from },\n },\n },\n ];\n}\n\nfunction contentAfter(\n node: MarkdownNode,\n markdown: string,\n entity: ComposerEntity,\n): MarkdownNode[] | undefined {\n const position = offsets(node);\n if (position === undefined) {\n return undefined;\n }\n if (entity.range.to === position.to) {\n return [];\n }\n if (node.type !== \"text\" || node.value === undefined) {\n if (node.children === undefined || literalNodeTypes.has(node.type)) {\n return undefined;\n }\n const childIndex = findLastIndex(node.children, (child) => containsEnd(child, entity.range.to));\n const child = node.children[childIndex];\n if (child === undefined) {\n return undefined;\n }\n const childContent = contentAfter(child, markdown, entity);\n return childContent === undefined\n ? undefined\n : [...childContent, ...node.children.slice(childIndex + 1)];\n }\n const split = textValueRange(node, markdown, entity);\n if (split === undefined) {\n return undefined;\n }\n return [\n {\n ...node,\n value: node.value.slice(split.to),\n position: {\n start: { offset: entity.range.to },\n end: node.position?.end ?? {},\n },\n },\n ];\n}\n\nfunction textValueRange(\n node: MarkdownNode,\n markdown: string,\n entity: ComposerEntity,\n): { from: number; to: number } | undefined {\n const position = offsets(node);\n const value = node.value;\n if (position === undefined || value === undefined) {\n return undefined;\n }\n const raw = markdown.slice(position.from, position.to);\n const relativeFrom = entity.range.from - position.from;\n const relativeTo = entity.range.to - position.from;\n if (raw === value) {\n return { from: relativeFrom, to: relativeTo };\n }\n\n const occurrence = countOccurrences(raw.slice(0, relativeFrom), entity.text);\n const valueFrom = occurrenceIndex(value, entity.text, occurrence);\n return valueFrom === undefined\n ? undefined\n : { from: valueFrom, to: valueFrom + entity.text.length };\n}\n\nfunction countOccurrences(value: string, search: string): number {\n let count = 0;\n let offset = 0;\n while (offset <= value.length - search.length) {\n const index = value.indexOf(search, offset);\n if (index < 0) {\n break;\n }\n count += 1;\n offset = index + search.length;\n }\n return count;\n}\n\nfunction occurrenceIndex(value: string, search: string, occurrence: number): number | undefined {\n let offset = 0;\n for (let index = 0; index <= occurrence; index += 1) {\n const found = value.indexOf(search, offset);\n if (found < 0) {\n return undefined;\n }\n if (index === occurrence) {\n return found;\n }\n offset = found + search.length;\n }\n return undefined;\n}\n\nfunction containsStart(node: MarkdownNode, offset: number): boolean {\n const position = offsets(node);\n return position !== undefined && offset >= position.from && offset < position.to;\n}\n\nfunction containsEnd(node: MarkdownNode, offset: number): boolean {\n const position = offsets(node);\n return position !== undefined && offset > position.from && offset <= position.to;\n}\n\nfunction offsets(node: MarkdownNode | undefined): { from: number; to: number } | undefined {\n const from = node?.position?.start.offset;\n const to = node?.position?.end.offset;\n return typeof from === \"number\" && typeof to === \"number\" ? { from, to } : undefined;\n}\n\nfunction findLastIndex<T>(items: T[], predicate: (item: T) => boolean): number {\n for (let index = items.length - 1; index >= 0; index -= 1) {\n const item = items[index];\n if (item !== undefined && predicate(item)) {\n return index;\n }\n }\n return -1;\n}\n","import type { UIMessage } from \"@anvia/client\";\nimport { forwardRef, type ReactNode, useCallback, useMemo } from \"react\";\n\nimport { useMessage } from \"../contexts\";\nimport { composeRefs, type PrimitiveProps, renderPrimitive } from \"../primitives\";\nimport { registerMessageElement } from \"./elements\";\n\ntype MessageChildren = ReactNode | ((message: UIMessage) => ReactNode);\n\ntype MessageRootProps = Omit<PrimitiveProps<\"article\">, \"children\"> & {\n children?: MessageChildren;\n};\n\nconst MessageRoot = forwardRef<HTMLElement, MessageRootProps>(function MessageRoot(\n { children, ...props },\n ref,\n) {\n const { message } = useMessage();\n const renderedChildren = typeof children === \"function\" ? children(message) : children;\n const registerElement = useCallback(\n (element: HTMLElement | null) => {\n if (element !== null) registerMessageElement(element, message.id);\n },\n [message.id],\n );\n const composedRef = useMemo(() => composeRefs(ref, registerElement), [ref, registerElement]);\n\n return renderPrimitive(\n \"article\",\n {\n ...props,\n children: renderedChildren,\n \"data-role\": message.role,\n } as PrimitiveProps<\"article\">,\n composedRef,\n );\n});\n\nconst MessageContent = forwardRef<HTMLDivElement, PrimitiveProps<\"div\">>(\n function MessageContent(props, ref) {\n return renderPrimitive(\n \"div\",\n {\n ...props,\n } as PrimitiveProps<\"div\">,\n ref,\n );\n },\n);\n\nexport { MessageContent, MessageRoot };\n","import { MessageActions, MessageCopy, MessageRegenerate } from \"./actions\";\nimport { MessageEntity } from \"./entity\";\nimport {\n MessageAttachment,\n MessageCodeBlock,\n MessageData,\n MessageError,\n MessageMarkdown,\n MessagePart,\n MessageParts,\n MessageReasoning,\n MessageText,\n MessageTool,\n MessageToolError,\n MessageToolInput,\n MessageToolName,\n MessageToolOutput,\n MessageToolStatus,\n} from \"./parts\";\nimport { MessageContent, MessageRoot } from \"./root\";\n\nexport const MessagePrimitive = {\n Root: MessageRoot,\n Content: MessageContent,\n Parts: MessageParts,\n Part: MessagePart,\n Text: MessageText,\n Markdown: MessageMarkdown,\n Entity: MessageEntity,\n CodeBlock: MessageCodeBlock,\n Reasoning: MessageReasoning,\n Tool: MessageTool,\n ToolName: MessageToolName,\n ToolInput: MessageToolInput,\n ToolOutput: MessageToolOutput,\n ToolError: MessageToolError,\n ToolStatus: MessageToolStatus,\n Attachment: MessageAttachment,\n Data: MessageData,\n Error: MessageError,\n Actions: MessageActions,\n Copy: MessageCopy,\n Regenerate: MessageRegenerate,\n} as const;\n\nexport type { MessageContextValue, MessagePartContextValue } from \"../contexts\";\nexport { useChatContext, useMessage, useMessagePart } from \"../contexts\";\nexport type { MessageEntityProps } from \"./entity\";\nexport type {\n MessageAttachmentPart,\n MessagePartsFilter,\n MessageStreamOptions,\n MessageToolPart,\n MessageToolRenderWhen,\n} from \"./parts\";\n"],"mappings":"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","names":["MessageActions","MessageCopy","MessageRegenerate","forwardRef","jsx","MessageEntity","forwardRef","child","Fragment","jsx","jsxs","forwardRef","MessageParts","SmoothedMessageParts","MessagePart","MessageText","MessageTextContent","MessageMarkdown","MessageMarkdownContent","_node","elementProps","MessageCodeBlock","MessageReasoning","MessageTool","MessageToolName","MessageToolStatus","MessageToolInput","MessageToolOutput","MessageToolError","MessageAttachment","MessageData","MessageError","forwardRef","useCallback","useMemo","forwardRef","MessageRoot","useCallback","useMemo","MessageContent"]}
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
MessagePrimitive,
|
|
3
3
|
isComposerEntityData,
|
|
4
4
|
shiftComposerEntityRanges
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-W2AHKMRS.js";
|
|
6
6
|
import {
|
|
7
7
|
AttachmentPrimitive
|
|
8
8
|
} from "./chunk-22EZJUPM.js";
|
|
@@ -1579,4 +1579,4 @@ export {
|
|
|
1579
1579
|
ComposerPrimitive,
|
|
1580
1580
|
ThreadPrimitive
|
|
1581
1581
|
};
|
|
1582
|
-
//# sourceMappingURL=chunk-
|
|
1582
|
+
//# sourceMappingURL=chunk-Y2KAMPVJ.js.map
|
package/dist/index.js
CHANGED
|
@@ -8,10 +8,10 @@ import {
|
|
|
8
8
|
import {
|
|
9
9
|
ComposerPrimitive,
|
|
10
10
|
ThreadPrimitive
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-Y2KAMPVJ.js";
|
|
12
12
|
import {
|
|
13
13
|
MessagePrimitive
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-W2AHKMRS.js";
|
|
15
15
|
import "./chunk-6XOJFLX4.js";
|
|
16
16
|
import {
|
|
17
17
|
StreamMarkdown
|
package/dist/message/index.js
CHANGED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { P as PrimitiveProps } from '../render-CRKWam2v.js';
|
|
4
|
+
import { T as TicketSource, R as RelayReconnectOptions, a as RelayStatus } from '../ticket-pexI1zIa.js';
|
|
5
|
+
export { b as SandboxDesktopState, t as ticketSubprotocolPrefix } from '../ticket-pexI1zIa.js';
|
|
6
|
+
|
|
7
|
+
/** Subprotocol the hub's `handleDesktopUpgrade` selects. */
|
|
8
|
+
declare const desktopSubprotocol = "anvia.desktop.v1";
|
|
9
|
+
/** Who is driving the desktop, as the relay reports it to this viewer. */
|
|
10
|
+
interface SandboxDesktopControl {
|
|
11
|
+
/** Someone has taken control, which pauses the agent. */
|
|
12
|
+
held: boolean;
|
|
13
|
+
/** Who. Present when `held`. */
|
|
14
|
+
holder?: string;
|
|
15
|
+
/** When the hold lapses unless renewed. */
|
|
16
|
+
expiresAt?: string;
|
|
17
|
+
/** This viewer is the holder. */
|
|
18
|
+
you: boolean;
|
|
19
|
+
/** This viewer may only watch. */
|
|
20
|
+
readOnly: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface SandboxDesktopHandle {
|
|
24
|
+
focus(): void;
|
|
25
|
+
/** Reconnect now, after the viewer gave up. */
|
|
26
|
+
reconnect(): void;
|
|
27
|
+
/** Take control, which pauses the agent. */
|
|
28
|
+
takeOver(): void;
|
|
29
|
+
/** Hand control back. */
|
|
30
|
+
release(): void;
|
|
31
|
+
}
|
|
32
|
+
interface SandboxDesktopNotice {
|
|
33
|
+
code: string;
|
|
34
|
+
message: string;
|
|
35
|
+
}
|
|
36
|
+
/** What `renderControls` is given to draw its own take-over bar. */
|
|
37
|
+
interface SandboxDesktopControlsState {
|
|
38
|
+
status: RelayStatus;
|
|
39
|
+
/** Undefined until the relay has said who has control. */
|
|
40
|
+
control: SandboxDesktopControl | undefined;
|
|
41
|
+
/** This viewer cannot send input, because of the prop or because the ticket says so. */
|
|
42
|
+
readOnly: boolean;
|
|
43
|
+
/** The latest failed request, such as taking over while someone else holds control. */
|
|
44
|
+
notice: SandboxDesktopNotice | undefined;
|
|
45
|
+
takeOver(): void;
|
|
46
|
+
release(): void;
|
|
47
|
+
}
|
|
48
|
+
type SandboxDesktopProps = Omit<PrimitiveProps<"div">, "children" | "onError"> & {
|
|
49
|
+
/**
|
|
50
|
+
* The hub's desktop endpoint (`hub.handleDesktopUpgrade`): `ws:`/`wss:`, `http:`/`https:`, or a
|
|
51
|
+
* path relative to this page.
|
|
52
|
+
*/
|
|
53
|
+
url: string;
|
|
54
|
+
/**
|
|
55
|
+
* A one-time ticket, or a function returning one. Pass a function: tickets are single use, so
|
|
56
|
+
* each reconnect needs a fresh one. It travels as a WebSocket subprotocol, not in the URL.
|
|
57
|
+
*/
|
|
58
|
+
ticket?: TicketSource;
|
|
59
|
+
/** Watch only. The server enforces it too; this also stops the viewer sending input. */
|
|
60
|
+
readOnly?: boolean;
|
|
61
|
+
/** Scale the desktop to fit the element. Default true. */
|
|
62
|
+
scaleToFit?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* JPEG quality asked of the server, 0 (smallest, blockiest) to 9 (best, most data). Default 6.
|
|
65
|
+
* Lower it for a slow link; it applies to the live connection.
|
|
66
|
+
*/
|
|
67
|
+
qualityLevel?: number;
|
|
68
|
+
/**
|
|
69
|
+
* How hard the server compresses, 0 (fastest, most data) to 9 (slowest, least data). Default 2,
|
|
70
|
+
* which keeps the server's CPU low. Raise it for a slow link; it applies to the live connection.
|
|
71
|
+
*/
|
|
72
|
+
compressionLevel?: number;
|
|
73
|
+
reconnect?: RelayReconnectOptions;
|
|
74
|
+
onStatusChange?: (status: RelayStatus) => void;
|
|
75
|
+
/** Called whenever the relay reports who has control. */
|
|
76
|
+
onControlChange?: (control: SandboxDesktopControl) => void;
|
|
77
|
+
/** Replace the default status line. Return null to show nothing. */
|
|
78
|
+
renderStatus?: (status: RelayStatus, retry: () => void) => ReactNode;
|
|
79
|
+
/** Replace the default take-over bar. Return null to show nothing. */
|
|
80
|
+
renderControls?: (state: SandboxDesktopControlsState) => ReactNode;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* A viewer for a remote sandbox's desktop, drawn with noVNC. noVNC is loaded on demand, so it costs
|
|
84
|
+
* nothing until a desktop mounts. It connects to the hub's desktop relay, reconnects with a fresh
|
|
85
|
+
* ticket when the link drops, and lets a person take over control from the agent.
|
|
86
|
+
*/
|
|
87
|
+
declare const SandboxDesktop: react.ForwardRefExoticComponent<Omit<PrimitiveProps<"div">, "children" | "onError"> & {
|
|
88
|
+
/**
|
|
89
|
+
* The hub's desktop endpoint (`hub.handleDesktopUpgrade`): `ws:`/`wss:`, `http:`/`https:`, or a
|
|
90
|
+
* path relative to this page.
|
|
91
|
+
*/
|
|
92
|
+
url: string;
|
|
93
|
+
/**
|
|
94
|
+
* A one-time ticket, or a function returning one. Pass a function: tickets are single use, so
|
|
95
|
+
* each reconnect needs a fresh one. It travels as a WebSocket subprotocol, not in the URL.
|
|
96
|
+
*/
|
|
97
|
+
ticket?: TicketSource;
|
|
98
|
+
/** Watch only. The server enforces it too; this also stops the viewer sending input. */
|
|
99
|
+
readOnly?: boolean;
|
|
100
|
+
/** Scale the desktop to fit the element. Default true. */
|
|
101
|
+
scaleToFit?: boolean;
|
|
102
|
+
/**
|
|
103
|
+
* JPEG quality asked of the server, 0 (smallest, blockiest) to 9 (best, most data). Default 6.
|
|
104
|
+
* Lower it for a slow link; it applies to the live connection.
|
|
105
|
+
*/
|
|
106
|
+
qualityLevel?: number;
|
|
107
|
+
/**
|
|
108
|
+
* How hard the server compresses, 0 (fastest, most data) to 9 (slowest, least data). Default 2,
|
|
109
|
+
* which keeps the server's CPU low. Raise it for a slow link; it applies to the live connection.
|
|
110
|
+
*/
|
|
111
|
+
compressionLevel?: number;
|
|
112
|
+
reconnect?: RelayReconnectOptions;
|
|
113
|
+
onStatusChange?: (status: RelayStatus) => void;
|
|
114
|
+
/** Called whenever the relay reports who has control. */
|
|
115
|
+
onControlChange?: (control: SandboxDesktopControl) => void;
|
|
116
|
+
/** Replace the default status line. Return null to show nothing. */
|
|
117
|
+
renderStatus?: (status: RelayStatus, retry: () => void) => ReactNode;
|
|
118
|
+
/** Replace the default take-over bar. Return null to show nothing. */
|
|
119
|
+
renderControls?: (state: SandboxDesktopControlsState) => ReactNode;
|
|
120
|
+
} & react.RefAttributes<SandboxDesktopHandle>>;
|
|
121
|
+
|
|
122
|
+
export { SandboxDesktop, type SandboxDesktopControl, type SandboxDesktopControlsState, type SandboxDesktopHandle, type SandboxDesktopNotice, type SandboxDesktopProps, RelayReconnectOptions as SandboxDesktopReconnectOptions, RelayStatus as SandboxDesktopStatus, desktopSubprotocol };
|