@devaccel-labs/app-comments-toolbar 1.1.0 → 1.3.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 +148 -30
- package/dist/react.js +417 -64
- package/dist/server.js +342 -14
- package/dist/types/capture/api.d.ts +30 -0
- package/dist/types/capture/editor.d.ts +10 -0
- package/dist/types/capture/ignore.d.ts +19 -0
- package/dist/types/capture/index.d.ts +1 -0
- package/dist/types/capture/picker.d.ts +9 -0
- package/dist/types/capture/picture.d.ts +29 -0
- package/dist/types/capture/surface.d.ts +39 -0
- package/dist/types/core/index.d.ts +2 -2
- package/dist/types/core/resolve.d.ts +2 -1
- package/dist/types/core/types.d.ts +11 -0
- package/dist/types/debug-context.d.ts +7 -0
- package/dist/types/dictation.d.ts +9 -0
- package/dist/types/embed/controller.d.ts +61 -0
- package/dist/types/embed/index.d.ts +1 -0
- package/dist/types/embed/options.d.ts +35 -0
- package/dist/types/help/index.d.ts +1 -0
- package/dist/types/help/panel-index.d.ts +1 -0
- package/dist/types/help/panel-styles.d.ts +1 -0
- package/dist/types/help/panel.d.ts +4 -0
- package/dist/types/help/pill-styles.d.ts +11 -0
- package/dist/types/help/pill.d.ts +44 -0
- package/dist/types/help/react.d.ts +12 -0
- package/dist/types/help/requests.d.ts +2 -0
- package/dist/types/help/types.d.ts +119 -0
- package/dist/types/help/wire.d.ts +61 -0
- package/dist/types/native-wire.d.ts +63 -0
- package/dist/types/native.d.ts +43 -0
- package/dist/types/react.d.ts +7 -0
- package/dist/types/replay.d.ts +6 -0
- package/dist/types/runtime/api.d.ts +250 -0
- package/dist/types/runtime/attachment-model.d.ts +16 -0
- package/dist/types/runtime/attachments.d.ts +43 -7
- package/dist/types/runtime/boot.d.ts +39 -0
- package/dist/types/runtime/browser-label.d.ts +5 -0
- package/dist/types/runtime/build-id.d.ts +1 -0
- package/dist/types/runtime/capture-ui.d.ts +45 -21
- package/dist/types/runtime/clarity-model.d.ts +260 -0
- package/dist/types/runtime/clarity-ui.d.ts +62 -0
- package/dist/types/runtime/client.d.ts +6 -197
- package/dist/types/runtime/composer-size.d.ts +30 -0
- package/dist/types/runtime/dashboard.d.ts +17 -2
- package/dist/types/runtime/debug-context-core.d.ts +88 -0
- package/dist/types/runtime/debug-context-host.d.ts +39 -0
- package/dist/types/runtime/debug-context-model.d.ts +352 -0
- package/dist/types/runtime/debug-context-redact.d.ts +48 -0
- package/dist/types/runtime/debug-context.d.ts +36 -0
- package/dist/types/runtime/details-model.d.ts +7 -0
- package/dist/types/runtime/details.d.ts +7 -5
- package/dist/types/runtime/dictation-engine.d.ts +98 -0
- package/dist/types/runtime/dictation-model.d.ts +28 -0
- package/dist/types/runtime/dictation-ui.d.ts +56 -0
- package/dist/types/runtime/dictation.d.ts +66 -0
- package/dist/types/runtime/draft-dock.d.ts +32 -0
- package/dist/types/runtime/draft-model.d.ts +104 -0
- package/dist/types/runtime/draft-store.d.ts +15 -0
- package/dist/types/runtime/edits.d.ts +1 -1
- package/dist/types/runtime/font.d.ts +16 -0
- package/dist/types/runtime/format.d.ts +30 -1
- package/dist/types/runtime/host-watch.d.ts +20 -0
- package/dist/types/runtime/icons.d.ts +16 -2
- package/dist/types/runtime/index.d.ts +2 -0
- package/dist/types/runtime/ink.d.ts +8 -0
- package/dist/types/runtime/kind-model.d.ts +14 -0
- package/dist/types/runtime/live-model.d.ts +25 -0
- package/dist/types/runtime/loader.d.ts +5 -3
- package/dist/types/runtime/markup-editor.d.ts +54 -0
- package/dist/types/runtime/markup-model.d.ts +126 -0
- package/dist/types/runtime/markup.d.ts +69 -0
- package/dist/types/runtime/mention-parse.d.ts +18 -0
- package/dist/types/runtime/mentions.d.ts +4 -4
- package/dist/types/runtime/page-background.d.ts +9 -0
- package/dist/types/runtime/page-image.d.ts +64 -11
- package/dist/types/runtime/placement.d.ts +6 -3
- package/dist/types/runtime/record.d.ts +18 -2
- package/dist/types/runtime/related.d.ts +1 -1
- package/dist/types/runtime/replay-model.d.ts +80 -0
- package/dist/types/runtime/replay.d.ts +5 -38
- package/dist/types/runtime/screen.d.ts +47 -0
- package/dist/types/runtime/screenshot.d.ts +60 -8
- package/dist/types/runtime/session-source.d.ts +45 -0
- package/dist/types/runtime/session.d.ts +20 -18
- package/dist/types/runtime/shield.d.ts +9 -0
- package/dist/types/runtime/shot.d.ts +45 -0
- package/dist/types/runtime/sketch.d.ts +26 -0
- package/dist/types/runtime/styles.d.ts +1 -1
- package/dist/types/runtime/sync.d.ts +1 -0
- package/dist/types/runtime/thread-model.d.ts +18 -0
- package/dist/types/runtime/ticket-form-model.d.ts +57 -0
- package/dist/types/runtime/ticket-form.d.ts +9 -0
- package/dist/types/runtime/toolbar.d.ts +37 -1
- package/dist/types/runtime/ui-scale.d.ts +17 -0
- package/dist/types/runtime/update.d.ts +32 -8
- package/dist/types/runtime/use-debug-context.d.ts +27 -0
- package/dist/types/server/index.d.ts +22 -0
- package/dist/types/server/support.d.ts +20 -0
- package/dist/types/server.d.ts +2 -0
- package/dist/types/vite/plugin.d.ts +15 -0
- package/dist/vite.js +121 -41
- package/package.json +24 -11
- package/src/capture/api.ts +128 -0
- package/src/capture/editor.tsx +178 -0
- package/src/capture/ignore.ts +38 -0
- package/src/capture/index.ts +27 -0
- package/src/capture/picker.tsx +171 -0
- package/src/capture/picture.ts +90 -0
- package/src/capture/surface.tsx +185 -0
- package/src/compiler/annotate.ts +202 -0
- package/src/compiler/babel.d.ts +11 -0
- package/src/compiler/enabled.ts +55 -0
- package/src/compiler/index.ts +2 -0
- package/src/core/index.ts +8 -0
- package/src/core/resolve.ts +307 -0
- package/src/core/types.ts +58 -0
- package/src/debug-context.ts +47 -0
- package/src/dictation.ts +17 -0
- package/src/embed/controller.ts +215 -0
- package/src/embed/index.ts +68 -0
- package/src/embed/options.ts +100 -0
- package/src/help/index.ts +38 -0
- package/src/help/panel-index.ts +17 -0
- package/src/help/panel-styles.ts +123 -0
- package/src/help/panel.ts +840 -0
- package/src/help/pill-styles.ts +75 -0
- package/src/help/pill.ts +338 -0
- package/src/help/react.tsx +143 -0
- package/src/help/requests.ts +111 -0
- package/src/help/types.ts +124 -0
- package/src/help/wire.ts +55 -0
- package/src/native-wire.ts +124 -0
- package/src/native.ts +282 -0
- package/src/react.ts +27 -0
- package/src/replay.ts +13 -0
- package/src/runtime/api.ts +531 -0
- package/src/runtime/attachment-model.ts +42 -0
- package/src/runtime/attachments.tsx +1260 -0
- package/src/runtime/boot.ts +95 -0
- package/src/runtime/browser-label.ts +31 -0
- package/src/runtime/build-id.ts +10 -0
- package/src/runtime/capture-ui.tsx +306 -0
- package/src/runtime/capture.ts +508 -0
- package/src/runtime/clarity-model.ts +634 -0
- package/src/runtime/clarity-ui.tsx +454 -0
- package/src/runtime/client.ts +151 -0
- package/src/runtime/composer-size.tsx +146 -0
- package/src/runtime/dashboard.tsx +1130 -0
- package/src/runtime/debug-context-core.ts +681 -0
- package/src/runtime/debug-context-host.ts +56 -0
- package/src/runtime/debug-context-model.ts +1319 -0
- package/src/runtime/debug-context-redact.ts +259 -0
- package/src/runtime/debug-context.ts +613 -0
- package/src/runtime/details-model.ts +30 -0
- package/src/runtime/details.tsx +395 -0
- package/src/runtime/dictation-engine.ts +616 -0
- package/src/runtime/dictation-model.ts +79 -0
- package/src/runtime/dictation-ui.tsx +363 -0
- package/src/runtime/dictation.ts +271 -0
- package/src/runtime/dock.ts +108 -0
- package/src/runtime/draft-dock.tsx +124 -0
- package/src/runtime/draft-model.ts +251 -0
- package/src/runtime/draft-store.ts +149 -0
- package/src/runtime/edits.tsx +165 -0
- package/src/runtime/font.ts +42 -0
- package/src/runtime/format.ts +129 -0
- package/src/runtime/freshness.ts +23 -0
- package/src/runtime/handoff.ts +76 -0
- package/src/runtime/host-watch.ts +64 -0
- package/src/runtime/icons.tsx +295 -0
- package/src/runtime/idle.ts +20 -0
- package/src/runtime/index.ts +11 -0
- package/src/runtime/ink.ts +6 -0
- package/src/runtime/kind-model.ts +20 -0
- package/src/runtime/live-model.ts +32 -0
- package/src/runtime/loader.tsx +87 -0
- package/src/runtime/markup-editor.tsx +1333 -0
- package/src/runtime/markup-model.ts +485 -0
- package/src/runtime/markup.ts +382 -0
- package/src/runtime/members.ts +58 -0
- package/src/runtime/mention-parse.ts +56 -0
- package/src/runtime/mentions.tsx +205 -0
- package/src/runtime/page-background.ts +51 -0
- package/src/runtime/page-image.ts +1592 -0
- package/src/runtime/placement.ts +336 -0
- package/src/runtime/record.ts +402 -0
- package/src/runtime/redact.ts +30 -0
- package/src/runtime/related.ts +34 -0
- package/src/runtime/render-page.ts +2 -0
- package/src/runtime/replay-model.ts +232 -0
- package/src/runtime/replay.ts +173 -0
- package/src/runtime/runtime-version.ts +7 -0
- package/src/runtime/runtime.tsx +51 -0
- package/src/runtime/screen.ts +182 -0
- package/src/runtime/screenshot.ts +260 -0
- package/src/runtime/session-source.ts +112 -0
- package/src/runtime/session.ts +108 -0
- package/src/runtime/shield.ts +34 -0
- package/src/runtime/shot.tsx +422 -0
- package/src/runtime/sketch.ts +139 -0
- package/src/runtime/styles.ts +1541 -0
- package/src/runtime/sync.ts +300 -0
- package/src/runtime/thread-model.ts +71 -0
- package/src/runtime/ticket-form-model.ts +128 -0
- package/src/runtime/ticket-form.tsx +342 -0
- package/src/runtime/toolbar.tsx +4427 -0
- package/src/runtime/ui-scale.ts +75 -0
- package/src/runtime/update.ts +98 -0
- package/src/runtime/use-debug-context.ts +81 -0
- package/src/server/index.ts +133 -0
- package/src/server/support.ts +499 -0
- package/src/server.ts +4 -0
- package/src/vite/plugin.ts +102 -0
- package/src/vite.ts +1 -0
package/dist/react.js
CHANGED
|
@@ -1,6 +1,69 @@
|
|
|
1
1
|
// src/runtime/loader.tsx
|
|
2
2
|
import { useEffect, useRef } from "react";
|
|
3
3
|
|
|
4
|
+
// src/runtime/idle.ts
|
|
5
|
+
var FALLBACK_SLICE_MS = 8;
|
|
6
|
+
function whenIdle(task, timeout) {
|
|
7
|
+
if (typeof requestIdleCallback === "function") {
|
|
8
|
+
const id2 = requestIdleCallback(task, { timeout });
|
|
9
|
+
return () => cancelIdleCallback(id2);
|
|
10
|
+
}
|
|
11
|
+
const id = setTimeout(
|
|
12
|
+
() => {
|
|
13
|
+
const end = performance.now() + FALLBACK_SLICE_MS;
|
|
14
|
+
task({ didTimeout: false, timeRemaining: () => Math.max(0, end - performance.now()) });
|
|
15
|
+
},
|
|
16
|
+
Math.min(timeout, 200)
|
|
17
|
+
);
|
|
18
|
+
return () => clearTimeout(id);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/runtime/runtime-version.ts
|
|
22
|
+
var runtimeVersion = 1;
|
|
23
|
+
|
|
24
|
+
// src/runtime/boot.ts
|
|
25
|
+
var IDLE_TIMEOUT_MS = 3e3;
|
|
26
|
+
var untilIdle = (task) => whenIdle(task, IDLE_TIMEOUT_MS);
|
|
27
|
+
var importModule = (url) => import(
|
|
28
|
+
/* @vite-ignore */
|
|
29
|
+
/* webpackIgnore: true */
|
|
30
|
+
url
|
|
31
|
+
);
|
|
32
|
+
async function loadRuntime(apiUrl, load = importModule) {
|
|
33
|
+
const url = `${apiUrl.replace(/\/+$/, "")}/v1/toolbar/${runtimeVersion}.js`;
|
|
34
|
+
const remote = await load(url);
|
|
35
|
+
if (typeof remote.mount === "function") return remote;
|
|
36
|
+
throw new Error(`${url} has no mount export`);
|
|
37
|
+
}
|
|
38
|
+
function bootToolbar(boot) {
|
|
39
|
+
let cancelled = false;
|
|
40
|
+
let mounted = null;
|
|
41
|
+
let container = null;
|
|
42
|
+
const start = async () => {
|
|
43
|
+
const session = await boot.getSession().catch(() => null);
|
|
44
|
+
if (!session || cancelled) return;
|
|
45
|
+
const runtime = await (boot.load ?? loadRuntime)(session.apiUrl);
|
|
46
|
+
if (cancelled) return;
|
|
47
|
+
container = document.createElement("div");
|
|
48
|
+
container.setAttribute("data-cs-runtime", "latest");
|
|
49
|
+
container.style.display = "contents";
|
|
50
|
+
document.body.appendChild(container);
|
|
51
|
+
mounted = runtime.mount(container, boot.props());
|
|
52
|
+
boot.onMount?.(mounted, container);
|
|
53
|
+
};
|
|
54
|
+
const cancelWait = (boot.wait ?? untilIdle)(() => {
|
|
55
|
+
start().catch((error) => console.warn("[comment-service] The toolbar could not start.", error)).finally(() => boot.onSettled?.());
|
|
56
|
+
});
|
|
57
|
+
return () => {
|
|
58
|
+
cancelled = true;
|
|
59
|
+
cancelWait();
|
|
60
|
+
queueMicrotask(() => {
|
|
61
|
+
mounted?.unmount();
|
|
62
|
+
container?.remove();
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
4
67
|
// src/runtime/handoff.ts
|
|
5
68
|
var key = "devaccel.comment.handoff";
|
|
6
69
|
var ttl = 30 * 60 * 1e3;
|
|
@@ -41,27 +104,52 @@ function captureHandoff() {
|
|
|
41
104
|
});
|
|
42
105
|
}
|
|
43
106
|
|
|
44
|
-
// src/runtime/
|
|
45
|
-
var
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
107
|
+
// src/runtime/host-watch.ts
|
|
108
|
+
var HOST_CHECK_GAP_MS = 1e4;
|
|
109
|
+
var NAVIGATED = "cs-nav";
|
|
110
|
+
var HISTORY_FLAG = "__devaccelCommentHistory";
|
|
111
|
+
function announceNavigation() {
|
|
112
|
+
if (Reflect.get(window, HISTORY_FLAG)) return;
|
|
113
|
+
Reflect.set(window, HISTORY_FLAG, true);
|
|
114
|
+
for (const name of ["pushState", "replaceState"]) {
|
|
115
|
+
const original = history[name].bind(history);
|
|
116
|
+
history[name] = (...args) => {
|
|
117
|
+
original(...args);
|
|
118
|
+
window.dispatchEvent(new Event(NAVIGATED));
|
|
119
|
+
};
|
|
50
120
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
)
|
|
58
|
-
|
|
121
|
+
}
|
|
122
|
+
function watchHost(check, gap = HOST_CHECK_GAP_MS) {
|
|
123
|
+
announceNavigation();
|
|
124
|
+
const listening = new AbortController();
|
|
125
|
+
let last = Date.now();
|
|
126
|
+
let timer = 0;
|
|
127
|
+
const run = () => {
|
|
128
|
+
window.clearTimeout(timer);
|
|
129
|
+
timer = 0;
|
|
130
|
+
last = Date.now();
|
|
131
|
+
check();
|
|
132
|
+
};
|
|
133
|
+
const soon = (event) => {
|
|
134
|
+
if (timer || document.visibilityState === "hidden") return;
|
|
135
|
+
if (event.type === "pageshow" && !event.persisted) return;
|
|
136
|
+
const wait = last + gap - Date.now();
|
|
137
|
+
if (wait <= 0) run();
|
|
138
|
+
else timer = window.setTimeout(run, wait);
|
|
139
|
+
};
|
|
140
|
+
for (const type of ["focus", "popstate", "hashchange", "pageshow", NAVIGATED])
|
|
141
|
+
window.addEventListener(type, soon, { signal: listening.signal });
|
|
142
|
+
document.addEventListener("visibilitychange", soon, { signal: listening.signal });
|
|
143
|
+
return {
|
|
144
|
+
now: run,
|
|
145
|
+
stop() {
|
|
146
|
+
window.clearTimeout(timer);
|
|
147
|
+
listening.abort();
|
|
148
|
+
}
|
|
149
|
+
};
|
|
59
150
|
}
|
|
60
151
|
|
|
61
|
-
// src/runtime/
|
|
62
|
-
var runtimeVersion = 1;
|
|
63
|
-
|
|
64
|
-
// src/runtime/session.ts
|
|
152
|
+
// src/runtime/session-source.ts
|
|
65
153
|
var EXPIRY_MARGIN_MS = 6e4;
|
|
66
154
|
var UNKNOWN_EXPIRY_MS = 5 * 6e4;
|
|
67
155
|
function readJwt(token) {
|
|
@@ -82,26 +170,28 @@ function sessionFrom(payload) {
|
|
|
82
170
|
apiUrl: value.apiUrl,
|
|
83
171
|
project: value.project,
|
|
84
172
|
environment: value.environment,
|
|
85
|
-
hostToken: value.hostToken
|
|
173
|
+
hostToken: value.hostToken,
|
|
174
|
+
...typeof value.loaderOrigin === "string" ? { loaderOrigin: value.loaderOrigin } : {}
|
|
86
175
|
};
|
|
87
176
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
cache: "no-store"
|
|
92
|
-
});
|
|
93
|
-
return response.json();
|
|
94
|
-
}
|
|
95
|
-
function sessionSource(path, load = fetchSession, now = Date.now) {
|
|
177
|
+
var SessionOff = class extends Error {
|
|
178
|
+
};
|
|
179
|
+
function sessionSource(path, load, now2 = Date.now) {
|
|
96
180
|
let kept = null;
|
|
97
181
|
let pending = null;
|
|
98
182
|
return ({ refresh = false } = {}) => {
|
|
99
|
-
if (!refresh && kept &&
|
|
183
|
+
if (!refresh && kept && now2() < kept.until) return Promise.resolve(kept.session);
|
|
100
184
|
if (pending) return pending;
|
|
101
185
|
pending = load(path).then((payload) => {
|
|
186
|
+
const failed = payload;
|
|
187
|
+
if (failed && failed.enabled === false && failed.error) {
|
|
188
|
+
throw new SessionOff(
|
|
189
|
+
typeof failed.error === "string" ? failed.error : "Comment service is unreachable."
|
|
190
|
+
);
|
|
191
|
+
}
|
|
102
192
|
const session = sessionFrom(payload);
|
|
103
193
|
const expires = session ? readJwt(session.hostToken)?.exp : void 0;
|
|
104
|
-
const until = !session ? Infinity : expires ? expires * 1e3 - EXPIRY_MARGIN_MS :
|
|
194
|
+
const until = !session ? Infinity : expires ? expires * 1e3 - EXPIRY_MARGIN_MS : now2() + UNKNOWN_EXPIRY_MS;
|
|
105
195
|
kept = { session, until };
|
|
106
196
|
return session;
|
|
107
197
|
}).finally(() => {
|
|
@@ -110,35 +200,79 @@ function sessionSource(path, load = fetchSession, now = Date.now) {
|
|
|
110
200
|
return pending;
|
|
111
201
|
};
|
|
112
202
|
}
|
|
203
|
+
|
|
204
|
+
// src/runtime/session.ts
|
|
205
|
+
var SIGN_IN_PREFIX = "devaccel.comment.http";
|
|
206
|
+
function forgetSignIns(storage = localStorage) {
|
|
207
|
+
try {
|
|
208
|
+
for (let index = storage.length - 1; index >= 0; index--) {
|
|
209
|
+
const key2 = storage.key(index);
|
|
210
|
+
if (key2?.startsWith(SIGN_IN_PREFIX)) storage.removeItem(key2);
|
|
211
|
+
}
|
|
212
|
+
} catch {
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
var reported = /* @__PURE__ */ new Set();
|
|
216
|
+
function report(path, status, error, failed) {
|
|
217
|
+
const said = typeof error === "string" ? `: ${error}` : failed ? "." : " with comments off.";
|
|
218
|
+
const line = `[comment-service] ${path} answered ${status}${said}`;
|
|
219
|
+
if (reported.has(line)) return;
|
|
220
|
+
reported.add(line);
|
|
221
|
+
if (failed) console.warn(line);
|
|
222
|
+
else console.info(line);
|
|
223
|
+
}
|
|
224
|
+
async function fetchSession(path) {
|
|
225
|
+
const response = await fetch(path, {
|
|
226
|
+
headers: { accept: "application/json", "x-comment-service-origin": window.location.origin },
|
|
227
|
+
cache: "no-store"
|
|
228
|
+
});
|
|
229
|
+
const payload = await response.json().catch(() => null);
|
|
230
|
+
const off = response.status === 401 || response.status === 403;
|
|
231
|
+
if (!response.ok && !off) {
|
|
232
|
+
report(path, response.status, payload?.error, true);
|
|
233
|
+
throw new Error(`The session route answered ${response.status}.`);
|
|
234
|
+
}
|
|
235
|
+
if (off || payload?.enabled !== true) {
|
|
236
|
+
report(path, response.status, payload?.error, false);
|
|
237
|
+
forgetSignIns();
|
|
238
|
+
return { enabled: false };
|
|
239
|
+
}
|
|
240
|
+
return payload;
|
|
241
|
+
}
|
|
242
|
+
function sessionSource2(path, load = fetchSession, now2 = Date.now) {
|
|
243
|
+
return sessionSource(path, load, now2);
|
|
244
|
+
}
|
|
113
245
|
var sources = /* @__PURE__ */ new Map();
|
|
114
246
|
function sessionFor(path) {
|
|
115
247
|
let source = sources.get(path);
|
|
116
248
|
if (!source) {
|
|
117
|
-
source =
|
|
249
|
+
source = sessionSource2(path);
|
|
118
250
|
sources.set(path, source);
|
|
119
251
|
}
|
|
120
252
|
return source;
|
|
121
253
|
}
|
|
122
254
|
|
|
123
255
|
// src/runtime/loader.tsx
|
|
124
|
-
var
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
const
|
|
128
|
-
|
|
129
|
-
/* @vite-ignore */
|
|
130
|
-
/* webpackIgnore: true */
|
|
131
|
-
url
|
|
132
|
-
);
|
|
133
|
-
if (typeof remote.mount === "function") return remote;
|
|
134
|
-
throw new Error(`${url} has no mount export`);
|
|
256
|
+
var stampedBuild = typeof __COMMENT_TOOL_HOST_BUILD__ === "object" ? __COMMENT_TOOL_HOST_BUILD__ : void 0;
|
|
257
|
+
function withStampedBuild(config) {
|
|
258
|
+
if (!config || !stampedBuild) return config;
|
|
259
|
+
const options = config === true ? {} : config;
|
|
260
|
+
return options.build ? config : { ...options, build: stampedBuild };
|
|
135
261
|
}
|
|
262
|
+
captureHandoff();
|
|
263
|
+
var now = (task) => {
|
|
264
|
+
task();
|
|
265
|
+
return () => {
|
|
266
|
+
};
|
|
267
|
+
};
|
|
136
268
|
function CommentToolbar({
|
|
137
269
|
sessionPath = "/api/comment-service/session",
|
|
138
270
|
pollMs,
|
|
139
271
|
position,
|
|
140
272
|
theme,
|
|
141
|
-
navigate
|
|
273
|
+
navigate,
|
|
274
|
+
screen,
|
|
275
|
+
debugContext
|
|
142
276
|
}) {
|
|
143
277
|
const handle = useRef(null);
|
|
144
278
|
const navigateRef = useRef(navigate);
|
|
@@ -151,43 +285,262 @@ function CommentToolbar({
|
|
|
151
285
|
position,
|
|
152
286
|
theme,
|
|
153
287
|
navigate: navigate ? (href) => navigateRef.current?.(href) : void 0,
|
|
288
|
+
screen,
|
|
289
|
+
debugContext: withStampedBuild(debugContext),
|
|
154
290
|
getSession: sessionFor(sessionPath)
|
|
155
291
|
};
|
|
156
292
|
handle.current?.update(propsRef.current);
|
|
157
|
-
}, [navigate, pollMs, position, sessionPath, theme]);
|
|
293
|
+
}, [debugContext, navigate, pollMs, position, screen, sessionPath, theme]);
|
|
158
294
|
useEffect(() => {
|
|
295
|
+
const boot = (refresh, wait) => bootToolbar({
|
|
296
|
+
getSession: () => sessionFor(sessionPath)({ refresh }),
|
|
297
|
+
props: () => propsRef.current,
|
|
298
|
+
onMount: (mounted) => {
|
|
299
|
+
handle.current = mounted;
|
|
300
|
+
},
|
|
301
|
+
...wait ? { wait } : {}
|
|
302
|
+
});
|
|
303
|
+
let stop = boot(false);
|
|
304
|
+
const watch = watchHost(() => {
|
|
305
|
+
if (handle.current) return;
|
|
306
|
+
stop();
|
|
307
|
+
stop = boot(true, now);
|
|
308
|
+
});
|
|
309
|
+
return () => {
|
|
310
|
+
watch.stop();
|
|
311
|
+
handle.current = null;
|
|
312
|
+
stop();
|
|
313
|
+
};
|
|
314
|
+
}, [sessionPath]);
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// src/runtime/debug-context-host.ts
|
|
319
|
+
var DEBUG_ERROR_EVENT = "comment-tool:error";
|
|
320
|
+
function reportToolbarError(error, componentStack) {
|
|
321
|
+
if (typeof window === "undefined" || typeof CustomEvent !== "function") return;
|
|
322
|
+
window.dispatchEvent(
|
|
323
|
+
new CustomEvent(DEBUG_ERROR_EVENT, {
|
|
324
|
+
detail: { error, componentStack: componentStack ?? null }
|
|
325
|
+
})
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
function queryCacheSummary(client, max = 50) {
|
|
329
|
+
return client.getQueryCache().getAll().slice(-max).map((query) => ({
|
|
330
|
+
key: query.queryKey,
|
|
331
|
+
status: query.state.status,
|
|
332
|
+
fetchStatus: query.state.fetchStatus,
|
|
333
|
+
error: query.state.error ?? void 0,
|
|
334
|
+
updatedAt: query.state.dataUpdatedAt,
|
|
335
|
+
observers: query.getObserversCount?.()
|
|
336
|
+
}));
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// src/help/react.tsx
|
|
340
|
+
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
341
|
+
var loading = /* @__PURE__ */ new Map();
|
|
342
|
+
function loadHelp(serviceUrl) {
|
|
343
|
+
const page = window;
|
|
344
|
+
const there = () => typeof page.CommentToolHelp?.mount === "function" ? page.CommentToolHelp : null;
|
|
345
|
+
const ready = there();
|
|
346
|
+
if (ready) return Promise.resolve(ready);
|
|
347
|
+
const url = `${serviceUrl.replace(/\/+$/, "")}/v1/toolbar/help.js`;
|
|
348
|
+
let kept = loading.get(url);
|
|
349
|
+
if (!kept) {
|
|
350
|
+
kept = new Promise((resolve, reject) => {
|
|
351
|
+
const tag = document.createElement("script");
|
|
352
|
+
tag.src = url;
|
|
353
|
+
tag.async = true;
|
|
354
|
+
tag.onload = () => {
|
|
355
|
+
const api = there();
|
|
356
|
+
if (api) resolve(api);
|
|
357
|
+
else reject(new Error(`${url} defined no CommentToolHelp.`));
|
|
358
|
+
};
|
|
359
|
+
tag.onerror = () => {
|
|
360
|
+
tag.remove();
|
|
361
|
+
reject(new Error(`${url} did not load.`));
|
|
362
|
+
};
|
|
363
|
+
document.head.appendChild(tag);
|
|
364
|
+
});
|
|
365
|
+
kept.catch(() => loading.delete(url));
|
|
366
|
+
loading.set(url, kept);
|
|
367
|
+
}
|
|
368
|
+
return kept;
|
|
369
|
+
}
|
|
370
|
+
function HelpPill(props) {
|
|
371
|
+
const {
|
|
372
|
+
serviceUrl,
|
|
373
|
+
sessionPath = "/api/comment-service/session",
|
|
374
|
+
label,
|
|
375
|
+
position,
|
|
376
|
+
theme
|
|
377
|
+
} = props;
|
|
378
|
+
const hasList = typeof props.list === "function";
|
|
379
|
+
const hasMore = typeof props.moreOptions === "function";
|
|
380
|
+
const latest = useRef2(props);
|
|
381
|
+
const mounted = useRef2(null);
|
|
382
|
+
const options = useRef2(() => {
|
|
383
|
+
const now2 = latest.current;
|
|
384
|
+
return {
|
|
385
|
+
submit: (request) => latest.current.submit(request),
|
|
386
|
+
...typeof now2.list === "function" ? {
|
|
387
|
+
list: () => {
|
|
388
|
+
const list = latest.current.list;
|
|
389
|
+
return list ? list() : Promise.resolve([]);
|
|
390
|
+
}
|
|
391
|
+
} : {},
|
|
392
|
+
label: now2.label,
|
|
393
|
+
position: now2.position,
|
|
394
|
+
theme: now2.theme,
|
|
395
|
+
captures: () => {
|
|
396
|
+
const captures = latest.current.captures;
|
|
397
|
+
return typeof captures === "function" ? captures() : captures !== false;
|
|
398
|
+
},
|
|
399
|
+
...typeof now2.moreOptions === "function" ? { moreOptions: (draft) => latest.current.moreOptions?.(draft) } : {}
|
|
400
|
+
};
|
|
401
|
+
});
|
|
402
|
+
useEffect2(() => {
|
|
403
|
+
latest.current = props;
|
|
404
|
+
});
|
|
405
|
+
useEffect2(() => {
|
|
159
406
|
let cancelled = false;
|
|
160
|
-
let mounted = null;
|
|
161
|
-
let container = null;
|
|
162
407
|
const start = async () => {
|
|
163
|
-
const
|
|
164
|
-
if (!session || cancelled) return;
|
|
165
|
-
const runtime = await loadRuntime(session.apiUrl);
|
|
408
|
+
const address = serviceUrl ?? (await sessionFor(sessionPath)().catch(() => null))?.apiUrl ?? null;
|
|
166
409
|
if (cancelled) return;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
410
|
+
if (!address) {
|
|
411
|
+
console.info(
|
|
412
|
+
`[comment-service] <HelpPill> is not shown: ${sessionPath} names no service for this person. Pass serviceUrl to show it to everyone.`
|
|
413
|
+
);
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
const api = await loadHelp(address);
|
|
417
|
+
if (cancelled) return;
|
|
418
|
+
mounted.current = { api, handle: api.mount(options.current()) };
|
|
173
419
|
};
|
|
174
|
-
const
|
|
420
|
+
const cancelWait = whenIdle(() => {
|
|
175
421
|
start().catch(
|
|
176
|
-
(error) => console.warn("[comment-service] The
|
|
422
|
+
(error) => console.warn("[comment-service] The help pill could not start.", error)
|
|
177
423
|
);
|
|
178
424
|
}, IDLE_TIMEOUT_MS);
|
|
179
425
|
return () => {
|
|
180
426
|
cancelled = true;
|
|
181
|
-
|
|
182
|
-
handle.
|
|
183
|
-
|
|
184
|
-
mounted?.unmount();
|
|
185
|
-
container?.remove();
|
|
186
|
-
});
|
|
427
|
+
cancelWait();
|
|
428
|
+
mounted.current?.handle.unmount();
|
|
429
|
+
mounted.current = null;
|
|
187
430
|
};
|
|
188
|
-
}, [sessionPath]);
|
|
431
|
+
}, [serviceUrl, sessionPath]);
|
|
432
|
+
useEffect2(() => {
|
|
433
|
+
const now2 = mounted.current;
|
|
434
|
+
if (now2) now2.handle = now2.api.mount(options.current());
|
|
435
|
+
}, [label, position, theme, hasList, hasMore]);
|
|
189
436
|
return null;
|
|
190
437
|
}
|
|
438
|
+
|
|
439
|
+
// src/help/wire.ts
|
|
440
|
+
var HELP_LIMITS = {
|
|
441
|
+
/** A request's own id: letters, digits, `.`, `_`, `:` and `-`. */
|
|
442
|
+
id: 100,
|
|
443
|
+
message: 4e3,
|
|
444
|
+
images: 3,
|
|
445
|
+
/** One picture, before base64. */
|
|
446
|
+
imageBytes: 5 * 1024 * 1024,
|
|
447
|
+
name: 200,
|
|
448
|
+
label: 200,
|
|
449
|
+
url: 1e3,
|
|
450
|
+
/** "Your requests" shows at most this many. */
|
|
451
|
+
listed: 50
|
|
452
|
+
};
|
|
453
|
+
var HELP_BODY_BYTES = Math.ceil(HELP_LIMITS.images * HELP_LIMITS.imageBytes * 4 / 3) + 256 * 1024;
|
|
454
|
+
|
|
455
|
+
// src/help/types.ts
|
|
456
|
+
var HelpError = class extends Error {
|
|
457
|
+
name = "HelpError";
|
|
458
|
+
};
|
|
459
|
+
|
|
460
|
+
// src/help/requests.ts
|
|
461
|
+
var NOT_SENT = "That did not send. Check your connection and try again.";
|
|
462
|
+
var NOT_READ = "Your requests could not be loaded.";
|
|
463
|
+
async function base64Of(blob) {
|
|
464
|
+
const bytes = new Uint8Array(await blob.arrayBuffer());
|
|
465
|
+
let binary = "";
|
|
466
|
+
const chunk = 32768;
|
|
467
|
+
for (let index = 0; index < bytes.length; index += chunk) {
|
|
468
|
+
binary += String.fromCharCode(...bytes.subarray(index, index + chunk));
|
|
469
|
+
}
|
|
470
|
+
return btoa(binary);
|
|
471
|
+
}
|
|
472
|
+
async function imageWire(image) {
|
|
473
|
+
if (image.blob.size > HELP_LIMITS.imageBytes) {
|
|
474
|
+
throw new HelpError("A picture is too large to send. Remove it and try again.");
|
|
475
|
+
}
|
|
476
|
+
return {
|
|
477
|
+
name: image.name,
|
|
478
|
+
contentType: image.blob.type,
|
|
479
|
+
width: image.width,
|
|
480
|
+
height: image.height,
|
|
481
|
+
markedUp: image.markedUp,
|
|
482
|
+
data: await base64Of(image.blob)
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
async function sentenceOf(response) {
|
|
486
|
+
const payload = await response.json().catch(() => null);
|
|
487
|
+
return typeof payload?.error === "string" && payload.error.trim() ? payload.error : null;
|
|
488
|
+
}
|
|
489
|
+
function supportRequestsAt(url) {
|
|
490
|
+
return {
|
|
491
|
+
async submit(request) {
|
|
492
|
+
const body = {
|
|
493
|
+
id: request.id,
|
|
494
|
+
message: request.message,
|
|
495
|
+
pageUrl: request.pageUrl,
|
|
496
|
+
route: request.route,
|
|
497
|
+
pointed: request.pointed,
|
|
498
|
+
images: await Promise.all(request.images.map(imageWire)),
|
|
499
|
+
client: request.client
|
|
500
|
+
};
|
|
501
|
+
let response;
|
|
502
|
+
try {
|
|
503
|
+
response = await fetch(url, {
|
|
504
|
+
method: "POST",
|
|
505
|
+
headers: { accept: "application/json", "content-type": "application/json" },
|
|
506
|
+
credentials: "same-origin",
|
|
507
|
+
cache: "no-store",
|
|
508
|
+
body: JSON.stringify(body)
|
|
509
|
+
});
|
|
510
|
+
} catch {
|
|
511
|
+
throw new HelpError(NOT_SENT);
|
|
512
|
+
}
|
|
513
|
+
if (!response.ok) throw new HelpError(await sentenceOf(response) ?? NOT_SENT);
|
|
514
|
+
const receipt = await response.json().catch(() => null);
|
|
515
|
+
return {
|
|
516
|
+
...typeof receipt?.reference === "string" ? { reference: receipt.reference } : {},
|
|
517
|
+
...typeof receipt?.url === "string" ? { url: receipt.url } : {},
|
|
518
|
+
...typeof receipt?.note === "string" ? { note: receipt.note } : {}
|
|
519
|
+
};
|
|
520
|
+
},
|
|
521
|
+
async list() {
|
|
522
|
+
let response;
|
|
523
|
+
try {
|
|
524
|
+
response = await fetch(url, {
|
|
525
|
+
headers: { accept: "application/json" },
|
|
526
|
+
credentials: "same-origin",
|
|
527
|
+
cache: "no-store"
|
|
528
|
+
});
|
|
529
|
+
} catch {
|
|
530
|
+
throw new HelpError(NOT_READ);
|
|
531
|
+
}
|
|
532
|
+
if (!response.ok) throw new HelpError(await sentenceOf(response) ?? NOT_READ);
|
|
533
|
+
const payload = await response.json().catch(() => null);
|
|
534
|
+
if (!Array.isArray(payload?.requests)) throw new HelpError(NOT_READ);
|
|
535
|
+
return payload.requests;
|
|
536
|
+
}
|
|
537
|
+
};
|
|
538
|
+
}
|
|
191
539
|
export {
|
|
192
|
-
CommentToolbar
|
|
540
|
+
CommentToolbar,
|
|
541
|
+
HelpError,
|
|
542
|
+
HelpPill,
|
|
543
|
+
queryCacheSummary,
|
|
544
|
+
reportToolbarError,
|
|
545
|
+
supportRequestsAt
|
|
193
546
|
};
|