@hachej/boring-ui-kit 0.4.49 → 0.4.51
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/THIRD_PARTY_NOTICES.md +208 -0
- package/dist/chat-react-controller.d.ts +4 -1
- package/dist/chat-react-controller.js +4 -0
- package/dist/chat-react-remote.d.ts +16 -1
- package/dist/chat-react-remote.js +69 -10
- package/dist/chat-react-session.d.ts +2 -3
- package/dist/chat-react-session.js +38 -4
- package/dist/drawio-viewer.d.ts +4 -0
- package/dist/drawio-viewer.js +6 -0
- package/dist/native-chat.d.ts +8 -1
- package/dist/native-chat.js +45 -8
- package/dist/remote-chat.js +51 -5
- package/dist/vendor/drawio-viewer-static.d.ts +3 -0
- package/dist/vendor/drawio-viewer-static.js +5 -0
- package/package.json +6 -2
- package/r/agent-target.json +4 -4
- package/r/app-shell.json +9 -9
- package/r/board-viewer.json +6 -6
- package/r/button.json +1 -1
- package/r/dock.json +1 -1
- package/r/documents.json +12 -12
- package/r/drawing-viewer.json +57 -0
- package/r/feedback.json +6 -6
- package/r/file-tree.json +4 -4
- package/r/highlights.json +3 -3
- package/r/html-viewer.json +3 -3
- package/r/looks-viewer.json +2 -2
- package/r/maquette-viewer.json +1 -1
- package/r/markdown-editor.json +3 -3
- package/r/mockup-viewer.json +1 -1
- package/r/pi-ambient.json +8 -8
- package/r/pi-app-kinds.json +10 -10
- package/r/pi-app.json +11 -11
- package/r/pi-artifacts.json +2 -2
- package/r/pi-chat-approval.json +2 -2
- package/r/pi-chat-attachments.json +1 -1
- package/r/pi-chat-markdown.json +2 -2
- package/r/pi-chat-mentions.json +1 -1
- package/r/pi-chat-pickers.json +1 -1
- package/r/pi-chat-plugins.json +11 -11
- package/r/pi-chat-question.json +1 -1
- package/r/pi-chat-slash.json +2 -2
- package/r/pi-chat-subagent.json +1 -1
- package/r/pi-chat-voice.json +3 -3
- package/r/pi-chat.json +8 -8
- package/r/pi-workspace.json +3 -3
- package/r/placed-agent.json +4 -4
- package/r/provider-setup.json +1 -1
- package/r/registry.json +210 -161
- package/r/shared-chat.json +6 -6
- package/r/spaces.json +1 -1
- package/r/task-list-viewer.json +2 -2
- package/r/version-history.json +2 -2
- package/r/viewer-code.json +2 -2
- package/r/viewer-frame.json +4 -4
- package/r/viewer-html.json +4 -4
- package/r/viewer-image.json +2 -2
- package/r/viewer-markdown.json +5 -5
- package/r/viewer-pdf.json +3 -3
- package/r/viewers.json +6 -6
- package/r/windows.json +1 -1
package/dist/remote-chat.js
CHANGED
|
@@ -14,6 +14,50 @@ export class SubmissionRefused extends Error {
|
|
|
14
14
|
code = 'submission-refused';
|
|
15
15
|
constructor(message) { super(message); this.name = 'SubmissionRefused'; }
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* A photo the host sends as a link (an image part with a `url`, `data: ''`, so the first view stays small) is handed out with its
|
|
19
|
+
* `url` resolved against the chat endpoint: a relative link names the endpoint's own route (`?op=image&…`), whatever page the chat is
|
|
20
|
+
* on. The wire replica stays as sent, so later native operations (a field set, a string append) replay on the host's own values; the
|
|
21
|
+
* linked copy is derived after each replay. Values are immutable, so a node maps to one linked node for good: unchanged entries keep
|
|
22
|
+
* their identity and only changed paths are walked again.
|
|
23
|
+
*/
|
|
24
|
+
function imageLinker(base) {
|
|
25
|
+
const linked = new WeakMap();
|
|
26
|
+
const link = (node) => {
|
|
27
|
+
if (!node || typeof node !== 'object')
|
|
28
|
+
return node;
|
|
29
|
+
if (linked.has(node))
|
|
30
|
+
return linked.get(node);
|
|
31
|
+
let out = node;
|
|
32
|
+
if (Array.isArray(node)) {
|
|
33
|
+
const items = node.map(link);
|
|
34
|
+
if (items.some((item, index) => item !== node[index]))
|
|
35
|
+
out = items;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const record = node;
|
|
39
|
+
let copy;
|
|
40
|
+
for (const key of Object.keys(record)) {
|
|
41
|
+
const value = record[key];
|
|
42
|
+
const next = key === 'url' && record.type === 'image' && typeof value === 'string' ? resolved(value) : link(value);
|
|
43
|
+
if (next !== value)
|
|
44
|
+
(copy ??= { ...record })[key] = next;
|
|
45
|
+
}
|
|
46
|
+
if (copy)
|
|
47
|
+
out = copy;
|
|
48
|
+
}
|
|
49
|
+
linked.set(node, out);
|
|
50
|
+
return out;
|
|
51
|
+
};
|
|
52
|
+
// A link that is not a URL is left as sent: the chat draws a placeholder.
|
|
53
|
+
const resolved = (url) => { try {
|
|
54
|
+
return new URL(url, base).href;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return url;
|
|
58
|
+
} };
|
|
59
|
+
return (value) => link(value);
|
|
60
|
+
}
|
|
17
61
|
async function reason(response) {
|
|
18
62
|
try {
|
|
19
63
|
const value = await response.json();
|
|
@@ -30,6 +74,7 @@ async function reason(response) {
|
|
|
30
74
|
*/
|
|
31
75
|
export async function createRemoteChat(options) {
|
|
32
76
|
const base = new URL(options.endpoint, globalThis.location?.href);
|
|
77
|
+
const linkImages = imageLinker(base);
|
|
33
78
|
const send = options.fetch, pollMs = options.pollMs ?? 500;
|
|
34
79
|
const backoff = { base: options.reconnect?.baseDelayMs ?? 1000, max: options.reconnect?.maxDelayMs ?? 30_000 };
|
|
35
80
|
const url = (op, extra = {}) => {
|
|
@@ -265,7 +310,7 @@ export async function createRemoteChat(options) {
|
|
|
265
310
|
settle(end);
|
|
266
311
|
} };
|
|
267
312
|
const handle = {
|
|
268
|
-
get value() { return value; },
|
|
313
|
+
get value() { return linkImages(value); },
|
|
269
314
|
closed,
|
|
270
315
|
lost: () => lost,
|
|
271
316
|
stop: async () => { finish({ reason: 'stopped' }); return closed; },
|
|
@@ -288,7 +333,7 @@ export async function createRemoteChat(options) {
|
|
|
288
333
|
// Native operation batches are replayed with the upstream delta implementation; a view frame resets the replica.
|
|
289
334
|
value = frame.kind === 'view' ? frame.view : applyImmutable(value, frame.ops);
|
|
290
335
|
try {
|
|
291
|
-
await listener(value, [], context);
|
|
336
|
+
await listener(linkImages(value), [], context);
|
|
292
337
|
}
|
|
293
338
|
catch (error) {
|
|
294
339
|
return finish({ reason: 'listener_error', error: error instanceof Error ? error : new Error(String(error)) });
|
|
@@ -345,7 +390,8 @@ export async function createRemoteChat(options) {
|
|
|
345
390
|
cancelRetry();
|
|
346
391
|
setReconnecting(false);
|
|
347
392
|
settle(end);
|
|
348
|
-
|
|
393
|
+
// Stopped before it started (the owner left while the first view was on its way, D-1434): the first watch is still open, close it.
|
|
394
|
+
const live = current ?? (listener ? undefined : first);
|
|
349
395
|
current = undefined;
|
|
350
396
|
void live?.stop();
|
|
351
397
|
};
|
|
@@ -478,11 +524,11 @@ export async function createRemoteChat(options) {
|
|
|
478
524
|
// The controller only reconciles a submission by request ID; no other transaction work crosses the wire.
|
|
479
525
|
commit: async (change, _context) => change({ submissionByRequest: (_conversationId, requestId) => lookup(requestId) }),
|
|
480
526
|
abort: async () => { await post('abort', {}); },
|
|
481
|
-
entries: async (query, limit, cursor) => (await call('entries', {}, { limit: String(limit),
|
|
527
|
+
entries: async (query, limit, cursor) => linkImages((await call('entries', {}, { limit: String(limit),
|
|
482
528
|
...(query.maxEntryId === undefined ? {} : { maxEntryId: String(query.maxEntryId) }),
|
|
483
529
|
...(query.minEntryId === undefined ? {} : { minEntryId: String(query.minEntryId) }),
|
|
484
530
|
...(query.order === undefined ? {} : { order: query.order }),
|
|
485
|
-
...(cursor === undefined ? {} : { cursor: JSON.stringify(cursor) }) })).page,
|
|
531
|
+
...(cursor === undefined ? {} : { cursor: JSON.stringify(cursor) }) })).page),
|
|
486
532
|
};
|
|
487
533
|
const context = BACKGROUND_CONTEXT;
|
|
488
534
|
const close = async () => { const first = unclaimed; unclaimed = undefined; await first?.stop(); };
|