camox 0.71.0 → 0.72.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/dist/core/createApp.d.ts +4 -103
- package/dist/core/createApp.js +3 -24
- package/dist/core/createBlock.d.ts +2 -2
- package/dist/core/createBlock.js +41 -185
- package/dist/core/createLayout.d.ts +6 -77
- package/dist/core/createLayout.js +12 -50
- package/dist/core/editing/createEditableBlock.d.ts +9 -75
- package/dist/core/editing/createEditableBlock.js +258 -640
- package/dist/core/hooks/useIsEditable.js +2 -2
- package/dist/core/lib/artifactData.js +8 -3
- package/dist/core/lib/contentType.d.ts +23 -38
- package/dist/core/lib/contentType.js +34 -62
- package/dist/core/lib/iconTypes.d.ts +0 -3
- package/dist/core/lib/icons.js +63 -51
- package/dist/core/lib/recordScope.js +1 -1
- package/dist/features/canvas/CanvasOverlays.js +94 -176
- package/dist/features/canvas/CanvasPageFrame.js +62 -68
- package/dist/features/canvas/CanvasPreviewPageSlot.js +1 -3
- package/dist/features/canvas/canvasOverlayGeometry.js +1 -7
- package/dist/features/canvas/sidebar/CuratedPageInspector.js +3 -21
- package/dist/features/canvas/sidebar/LayoutPageBlocks.js +1 -2
- package/dist/features/canvas/useCanvasCamera.js +1 -1
- package/dist/features/canvas/useCanvasFrame.js +1 -1
- package/dist/features/content/ContentCollection.js +2 -2
- package/dist/features/content/collection-form.js +6 -7
- package/dist/features/page/CuratedPageContent.js +15 -24
- package/dist/features/page/UnplacedBlockContent.js +1 -6
- package/dist/features/preview/CamoxPreview.js +30 -33
- package/dist/features/preview/EditablePageContent.js +131 -151
- package/dist/features/preview/components/BlockActionsPopover.js +43 -152
- package/dist/features/preview/components/CanvasPreview.js +2 -2
- package/dist/features/preview/components/Frame.js +3 -3
- package/dist/features/preview/components/IconFieldEditor.js +1 -1
- package/dist/features/preview/components/ItemFieldsEditor.js +1 -3
- package/dist/features/preview/components/Overlays.js +18 -84
- package/dist/features/preview/components/PageTree.js +57 -103
- package/dist/features/preview/components/PreviewPanel.js +8 -11
- package/dist/features/preview/components/RecordCombobox.js +65 -78
- package/dist/features/preview/components/ReferenceFieldEditor.js +1 -19
- package/dist/features/preview/components/ReferenceListFieldEditor.js +1 -19
- package/dist/features/preview/components/RemovedBlockPlaceholder.js +2 -2
- package/dist/features/preview/components/SelectionEditor.js +5 -4
- package/dist/features/preview/components/useRepeatableItemActions.js +18 -24
- package/dist/features/preview/components/useUpdateBlockPosition.js +1 -1
- package/dist/features/preview/overlayMessages.js +1 -4
- package/dist/features/preview/previewStore.js +3 -23
- package/dist/features/renderer/RendererApp.js +17 -141
- package/dist/features/renderer/definitionAnswers.js +1 -8
- package/dist/features/renderer/rendererHost.js +1 -31
- package/dist/features/renderer/studioConnection.js +1 -25
- package/dist/features/runtime/pageApp.js +1 -1
- package/dist/features/runtime/runtime.js +3 -3
- package/dist/features/studio/components/ThreadMessages.js +89 -22
- package/dist/features/vite/blockBoilerplate.js +1 -1
- package/dist/features/vite/definitionsSync.js +1 -8
- package/dist/lib/queries.js +0 -1
- package/dist/lib/studio-definitions.js +0 -2
- package/dist/lib/studio-reads.js +0 -5
- package/dist/lib/use-thread.js +196 -138
- package/dist/package.js +1 -1
- package/dist/studio-overlays.css +0 -29
- package/dist/studio.css +1 -1
- package/package.json +4 -4
- package/skills/camox/SKILL.md +1 -1
- package/skills/camox/references/artifacts.md +4 -4
- package/skills/camox/references/block-definitions.md +21 -25
- package/skills/camox/references/dom-integrations.md +1 -1
- package/skills/camox/references/layout-definitions.md +3 -12
- package/skills/camox/references/routed-layouts.md +2 -2
- package/skills/camox-expand/SKILL.md +5 -5
- package/skills/camoxify/SKILL.md +4 -4
- package/dist/features/canvas/canvasInsertionSeams.js +0 -44
- package/dist/features/preview/components/AddBlockSheet.js +0 -314
- package/dist/features/preview/components/BlockPeek.js +0 -66
- package/dist/features/preview/components/BlockThumbnail.js +0 -281
- package/dist/features/preview/components/blockGridNavigation.js +0 -15
- package/dist/features/preview/referencePickerFocus.js +0 -29
|
@@ -18,7 +18,8 @@ import { MessageScroller, MessageScrollerButton, MessageScrollerContent, Message
|
|
|
18
18
|
* agent does, never how: thinking, looking around, making changes, building, fixing the build,
|
|
19
19
|
* or starting a draft. Each editor's message shows its
|
|
20
20
|
* sender's avatar, without their name. A Live turn handed off to a draft ends on the draft's
|
|
21
|
-
* card, which `onOpenDraft` opens
|
|
21
|
+
* card, which `onOpenDraft` opens, and the draft's thread shows the hand-off's Brief collapsed
|
|
22
|
+
* under the editor's messages. The thread keeps its end in view, unless the editor scrolls up.
|
|
22
23
|
*/
|
|
23
24
|
function ThreadMessages(t0) {
|
|
24
25
|
const $ = c(20);
|
|
@@ -297,7 +298,7 @@ const PUSH_OUTCOMES = {
|
|
|
297
298
|
notPreviewed: "Built, but the preview can’t show it."
|
|
298
299
|
};
|
|
299
300
|
function ThreadMessageRow(t0) {
|
|
300
|
-
const $ = c(
|
|
301
|
+
const $ = c(46);
|
|
301
302
|
const { message, onOpenDraft } = t0;
|
|
302
303
|
if (message.from === "draft") {
|
|
303
304
|
let t1;
|
|
@@ -438,54 +439,63 @@ function ThreadMessageRow(t0) {
|
|
|
438
439
|
} else t5 = $[33];
|
|
439
440
|
return t5;
|
|
440
441
|
}
|
|
442
|
+
if (message.from === "brief") {
|
|
443
|
+
let t1;
|
|
444
|
+
if ($[34] !== message.text) {
|
|
445
|
+
t1 = /* @__PURE__ */ jsx(Message, { children: /* @__PURE__ */ jsx(MessageContent, { children: /* @__PURE__ */ jsx(BriefNote, { text: message.text }) }) });
|
|
446
|
+
$[34] = message.text;
|
|
447
|
+
$[35] = t1;
|
|
448
|
+
} else t1 = $[35];
|
|
449
|
+
return t1;
|
|
450
|
+
}
|
|
441
451
|
if (message.from === "camox") {
|
|
442
452
|
let t1;
|
|
443
|
-
if ($[
|
|
453
|
+
if ($[36] === Symbol.for("react.memo_cache_sentinel")) {
|
|
444
454
|
t1 = /* @__PURE__ */ jsx(MessageHeader, {
|
|
445
455
|
className: "text-muted-foreground text-xs",
|
|
446
456
|
children: "Camox"
|
|
447
457
|
});
|
|
448
|
-
$[
|
|
449
|
-
} else t1 = $[
|
|
458
|
+
$[36] = t1;
|
|
459
|
+
} else t1 = $[36];
|
|
450
460
|
let t2;
|
|
451
|
-
if ($[
|
|
461
|
+
if ($[37] !== message.text) {
|
|
452
462
|
t2 = /* @__PURE__ */ jsx(Message, { children: /* @__PURE__ */ jsxs(MessageContent, { children: [t1, /* @__PURE__ */ jsx(Bubble, {
|
|
453
463
|
variant: "muted",
|
|
454
464
|
className: "max-w-full",
|
|
455
465
|
children: /* @__PURE__ */ jsx(BubbleContent, { children: /* @__PURE__ */ jsx(CroppedText, { text: message.text }) })
|
|
456
466
|
})] }) });
|
|
457
|
-
$[
|
|
458
|
-
$[
|
|
459
|
-
} else t2 = $[
|
|
467
|
+
$[37] = message.text;
|
|
468
|
+
$[38] = t2;
|
|
469
|
+
} else t2 = $[38];
|
|
460
470
|
return t2;
|
|
461
471
|
}
|
|
462
472
|
let t1;
|
|
463
|
-
if ($[
|
|
473
|
+
if ($[39] !== message.sender) {
|
|
464
474
|
t1 = /* @__PURE__ */ jsx(MessageAvatar, { children: /* @__PURE__ */ jsx(SenderAvatar, { sender: message.sender }) });
|
|
465
|
-
$[
|
|
466
|
-
$[
|
|
467
|
-
} else t1 = $[
|
|
475
|
+
$[39] = message.sender;
|
|
476
|
+
$[40] = t1;
|
|
477
|
+
} else t1 = $[40];
|
|
468
478
|
let t2;
|
|
469
|
-
if ($[
|
|
479
|
+
if ($[41] !== message.text) {
|
|
470
480
|
t2 = /* @__PURE__ */ jsx(MessageContent, { children: /* @__PURE__ */ jsx(Bubble, {
|
|
471
481
|
align: "end",
|
|
472
482
|
variant: "muted",
|
|
473
483
|
className: "max-w-full",
|
|
474
484
|
children: /* @__PURE__ */ jsx(BubbleContent, { children: /* @__PURE__ */ jsx(CroppedText, { text: message.text }) })
|
|
475
485
|
}) });
|
|
476
|
-
$[
|
|
477
|
-
$[
|
|
478
|
-
} else t2 = $[
|
|
486
|
+
$[41] = message.text;
|
|
487
|
+
$[42] = t2;
|
|
488
|
+
} else t2 = $[42];
|
|
479
489
|
let t3;
|
|
480
|
-
if ($[
|
|
490
|
+
if ($[43] !== t1 || $[44] !== t2) {
|
|
481
491
|
t3 = /* @__PURE__ */ jsxs(Message, {
|
|
482
492
|
align: "end",
|
|
483
493
|
children: [t1, t2]
|
|
484
494
|
});
|
|
485
|
-
$[
|
|
486
|
-
$[
|
|
487
|
-
$[
|
|
488
|
-
} else t3 = $[
|
|
495
|
+
$[43] = t1;
|
|
496
|
+
$[44] = t2;
|
|
497
|
+
$[45] = t3;
|
|
498
|
+
} else t3 = $[45];
|
|
489
499
|
return t3;
|
|
490
500
|
}
|
|
491
501
|
function _temp(subject, index) {
|
|
@@ -575,6 +585,63 @@ function CroppedText(t0) {
|
|
|
575
585
|
} else t9 = $[16];
|
|
576
586
|
return t9;
|
|
577
587
|
}
|
|
588
|
+
/**
|
|
589
|
+
* The Brief the agent on Live handed the request off with, under the editor's messages: a quiet
|
|
590
|
+
* line, so the request reads on as they sent it, which shows it once clicked.
|
|
591
|
+
*/
|
|
592
|
+
function BriefNote(t0) {
|
|
593
|
+
const $ = c(10);
|
|
594
|
+
const { text } = t0;
|
|
595
|
+
const [open, setOpen] = React.useState(false);
|
|
596
|
+
let t1;
|
|
597
|
+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
598
|
+
t1 = () => setOpen(_temp2);
|
|
599
|
+
$[0] = t1;
|
|
600
|
+
} else t1 = $[0];
|
|
601
|
+
const t2 = open ? "Hide the brief" : "Camox briefed the agent";
|
|
602
|
+
let t3;
|
|
603
|
+
if ($[1] !== open || $[2] !== t2) {
|
|
604
|
+
t3 = /* @__PURE__ */ jsx("button", {
|
|
605
|
+
type: "button",
|
|
606
|
+
"aria-expanded": open,
|
|
607
|
+
onClick: t1,
|
|
608
|
+
className: "focus-visible:ring-ring self-start rounded-sm hover:underline focus-visible:ring-2 focus-visible:outline-none",
|
|
609
|
+
children: t2
|
|
610
|
+
});
|
|
611
|
+
$[1] = open;
|
|
612
|
+
$[2] = t2;
|
|
613
|
+
$[3] = t3;
|
|
614
|
+
} else t3 = $[3];
|
|
615
|
+
let t4;
|
|
616
|
+
if ($[4] !== open || $[5] !== text) {
|
|
617
|
+
t4 = open && /* @__PURE__ */ jsx(Bubble, {
|
|
618
|
+
variant: "muted",
|
|
619
|
+
className: "max-w-full",
|
|
620
|
+
children: /* @__PURE__ */ jsx(BubbleContent, { children: /* @__PURE__ */ jsx("div", {
|
|
621
|
+
className: "whitespace-pre-wrap",
|
|
622
|
+
children: text
|
|
623
|
+
}) })
|
|
624
|
+
});
|
|
625
|
+
$[4] = open;
|
|
626
|
+
$[5] = text;
|
|
627
|
+
$[6] = t4;
|
|
628
|
+
} else t4 = $[6];
|
|
629
|
+
let t5;
|
|
630
|
+
if ($[7] !== t3 || $[8] !== t4) {
|
|
631
|
+
t5 = /* @__PURE__ */ jsxs("div", {
|
|
632
|
+
"data-thread-brief": true,
|
|
633
|
+
className: "text-muted-foreground flex flex-col gap-2 text-xs",
|
|
634
|
+
children: [t3, t4]
|
|
635
|
+
});
|
|
636
|
+
$[7] = t3;
|
|
637
|
+
$[8] = t4;
|
|
638
|
+
$[9] = t5;
|
|
639
|
+
} else t5 = $[9];
|
|
640
|
+
return t5;
|
|
641
|
+
}
|
|
642
|
+
function _temp2(current) {
|
|
643
|
+
return !current;
|
|
644
|
+
}
|
|
578
645
|
const initials = (name) => name.split(" ").map((part) => part[0]).join("").toUpperCase().slice(0, 2);
|
|
579
646
|
const DRAFT_CARD_CLASSES = "bg-muted/50 flex w-full flex-col items-start gap-0.5 rounded-lg border px-3 py-2 text-left text-sm";
|
|
580
647
|
/**
|
|
@@ -24,7 +24,7 @@ const ${camelName} = createBlock({
|
|
|
24
24
|
title: "${kebabToTitle(name)}",
|
|
25
25
|
description: "Describe when the AI should use this block.",
|
|
26
26
|
content: (field) => ({
|
|
27
|
-
title: field.string(
|
|
27
|
+
title: field.string(),
|
|
28
28
|
}),
|
|
29
29
|
toReact: ${pascalName}Component,
|
|
30
30
|
toTitle: ({ content }) => content.title,
|
|
@@ -54,14 +54,7 @@ async function syncDefinitionsToApi(options) {
|
|
|
54
54
|
const unused = layoutSyncResults.deletedDefinitionTypes;
|
|
55
55
|
if (unused.length > 0) logger.info(`[camox] Removed ${counted(unused.length, "layoutOnly block definition")} (no layout uses ${unused.length === 1 ? "it" : "them"} anymore): ${quoted(unused)}`, { timestamp: true });
|
|
56
56
|
}
|
|
57
|
-
|
|
58
|
-
if (homepage && result.homepage?.created) {
|
|
59
|
-
if (homepage.hasInitialBlocks) logger.info(`[camox] Initialized content: homepage with ${counted(result.homepage.blockCount, "block")}`, { timestamp: true });
|
|
60
|
-
else {
|
|
61
|
-
logger.info("[camox] Created empty homepage (using first layout)", { timestamp: true });
|
|
62
|
-
logger.info("[camox] Tip: add blocks.initial to your layout to pre-populate pages with content", { timestamp: true });
|
|
63
|
-
}
|
|
64
|
-
}
|
|
57
|
+
if (definitionSet.homepage && result.homepage?.created) logger.info(`[camox] Created an empty homepage with the "${definitionSet.homepage.layoutId}" layout`, { timestamp: true });
|
|
65
58
|
}
|
|
66
59
|
const VIRTUAL_CAMOX_APP = "virtual:camox/app";
|
|
67
60
|
const RESOLVED_VIRTUAL_CAMOX_APP = "\0virtual:camox/app";
|
package/dist/lib/queries.js
CHANGED
|
@@ -66,7 +66,6 @@ const localeMutations = {
|
|
|
66
66
|
addBack: () => getOrpc().locales.addBack.mutationOptions()
|
|
67
67
|
};
|
|
68
68
|
const blockMutations = {
|
|
69
|
-
create: () => getOrpc().blocks.create.mutationOptions(),
|
|
70
69
|
delete: () => getOrpc().blocks.delete.mutationOptions(),
|
|
71
70
|
deleteMany: () => getOrpc().blocks.deleteMany.mutationOptions(),
|
|
72
71
|
duplicate: () => getOrpc().blocks.duplicate.mutationOptions(),
|
|
@@ -9,8 +9,6 @@ const toBlockDefinitions = (rows) => rows.map((row) => ({
|
|
|
9
9
|
description: row.description,
|
|
10
10
|
contentSchema: row.contentSchema,
|
|
11
11
|
settingsSchema: row.settingsSchema ?? void 0,
|
|
12
|
-
defaultContent: row.defaultContent ?? {},
|
|
13
|
-
defaultSettings: row.defaultSettings ?? {},
|
|
14
12
|
layoutOnly: !!row.layoutOnly,
|
|
15
13
|
synced: row.synced
|
|
16
14
|
}));
|
package/dist/lib/studio-reads.js
CHANGED
|
@@ -157,11 +157,6 @@ const reads = {
|
|
|
157
157
|
fetch: async ({ api, signal }, id) => (await api.files.getUsageCount({ id }, { signal })).count,
|
|
158
158
|
staleTime: Infinity
|
|
159
159
|
}),
|
|
160
|
-
blockUsageCounts: entry({
|
|
161
|
-
key: () => usageCountsPrefix,
|
|
162
|
-
fetch: async ({ api, signal }, { projectId }) => Object.fromEntries((await api.blocks.getUsageCounts({ projectId }, { signal })).map(({ type, count }) => [type, count])),
|
|
163
|
-
staleTime: Infinity
|
|
164
|
-
}),
|
|
165
160
|
pageMarkdown: entry({
|
|
166
161
|
key: (pageId) => queryKeys.blocks.getPageMarkdown(pageId),
|
|
167
162
|
fetch: async ({ api, signal }, pageId) => (await api.blocks.getPageMarkdown({ pageId }, { signal })).markdown,
|
package/dist/lib/use-thread.js
CHANGED
|
@@ -18,13 +18,13 @@ const OPEN = 1;
|
|
|
18
18
|
*
|
|
19
19
|
* When the agent on Live hands a request off to a draft it started, the studio that sent a
|
|
20
20
|
* message of that run hears it (`onEnterDraft`), to enter the draft. The editor's Live thread
|
|
21
|
-
* then starts afresh
|
|
21
|
+
* then starts afresh, and every studio on Live shows it empty.
|
|
22
22
|
*
|
|
23
23
|
* It reports what each writing script touched (`touched`), for runs one of its messages was part
|
|
24
24
|
* of only, so that the studio follows the agent; teammates' runs leave it where it is.
|
|
25
25
|
*/
|
|
26
26
|
function useThread(apiUrl, projectId, draftId, t0) {
|
|
27
|
-
const $ = c(
|
|
27
|
+
const $ = c(55);
|
|
28
28
|
let t1;
|
|
29
29
|
if ($[0] !== t0) {
|
|
30
30
|
t1 = t0 === void 0 ? {} : t0;
|
|
@@ -33,40 +33,80 @@ function useThread(apiUrl, projectId, draftId, t0) {
|
|
|
33
33
|
} else t1 = $[1];
|
|
34
34
|
const { onEnterDraft } = t1;
|
|
35
35
|
const [state, setState] = React.useState(EMPTY_THREAD_STATE);
|
|
36
|
+
const latest = React.useRef(state);
|
|
36
37
|
let t2;
|
|
37
|
-
if ($[2]
|
|
38
|
-
t2 =
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
|
|
39
|
+
t2 = (frame) => {
|
|
40
|
+
latest.current = reduceThreadFrame(latest.current, frame);
|
|
41
|
+
setState(latest.current);
|
|
42
|
+
};
|
|
43
|
+
$[2] = t2;
|
|
44
|
+
} else t2 = $[2];
|
|
45
|
+
const fold = t2;
|
|
43
46
|
let t3;
|
|
44
|
-
if ($[
|
|
45
|
-
t3 =
|
|
47
|
+
if ($[3] !== state) {
|
|
48
|
+
t3 = threadViewOf(state);
|
|
49
|
+
$[3] = state;
|
|
46
50
|
$[4] = t3;
|
|
47
51
|
} else t3 = $[4];
|
|
48
|
-
const
|
|
49
|
-
const [error, setError] = React.useState();
|
|
52
|
+
const view = t3;
|
|
50
53
|
let t4;
|
|
51
|
-
if ($[5]
|
|
52
|
-
t4 =
|
|
53
|
-
$[5] =
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
|
|
55
|
+
t4 = /* @__PURE__ */ new Map();
|
|
56
|
+
$[5] = t4;
|
|
57
|
+
} else t4 = $[5];
|
|
58
|
+
const [unaccepted, setUnaccepted] = React.useState(t4);
|
|
59
|
+
const [error, setError] = React.useState();
|
|
60
|
+
let t5;
|
|
61
|
+
if ($[6] !== apiUrl || $[7] !== draftId || $[8] !== projectId) {
|
|
62
|
+
t5 = () => handedOffTo(apiUrl, projectId, draftId);
|
|
63
|
+
$[6] = apiUrl;
|
|
64
|
+
$[7] = draftId;
|
|
65
|
+
$[8] = projectId;
|
|
66
|
+
$[9] = t5;
|
|
67
|
+
} else t5 = $[9];
|
|
68
|
+
const [carried] = React.useState(t5);
|
|
69
|
+
let t6;
|
|
70
|
+
let t7;
|
|
71
|
+
if ($[10] !== apiUrl || $[11] !== carried || $[12] !== draftId || $[13] !== projectId) {
|
|
72
|
+
t6 = () => {
|
|
73
|
+
if (carried?.view) handedOff.set(threadKey(apiUrl, projectId, draftId), { sent: carried.sent });
|
|
74
|
+
};
|
|
75
|
+
t7 = [
|
|
76
|
+
apiUrl,
|
|
77
|
+
projectId,
|
|
78
|
+
draftId,
|
|
79
|
+
carried
|
|
80
|
+
];
|
|
81
|
+
$[10] = apiUrl;
|
|
82
|
+
$[11] = carried;
|
|
83
|
+
$[12] = draftId;
|
|
84
|
+
$[13] = projectId;
|
|
85
|
+
$[14] = t6;
|
|
86
|
+
$[15] = t7;
|
|
87
|
+
} else {
|
|
88
|
+
t6 = $[14];
|
|
89
|
+
t7 = $[15];
|
|
90
|
+
}
|
|
91
|
+
React.useEffect(t6, t7);
|
|
92
|
+
let t8;
|
|
93
|
+
if ($[16] !== carried?.sent) {
|
|
94
|
+
t8 = () => new Set(carried?.sent);
|
|
95
|
+
$[16] = carried?.sent;
|
|
96
|
+
$[17] = t8;
|
|
97
|
+
} else t8 = $[17];
|
|
98
|
+
const [sent] = React.useState(t8);
|
|
59
99
|
const shown = React.useRef(false);
|
|
60
100
|
const [shows, setShows] = React.useState(0);
|
|
61
101
|
const [touched, setTouched] = React.useState();
|
|
62
|
-
let
|
|
63
|
-
if ($[
|
|
64
|
-
|
|
65
|
-
$[
|
|
66
|
-
$[
|
|
67
|
-
} else
|
|
102
|
+
let t9;
|
|
103
|
+
if ($[18] !== apiUrl) {
|
|
104
|
+
t9 = apiSocketOptions(apiUrl);
|
|
105
|
+
$[18] = apiUrl;
|
|
106
|
+
$[19] = t9;
|
|
107
|
+
} else t9 = $[19];
|
|
68
108
|
const socket = usePartySocket({
|
|
69
|
-
...
|
|
109
|
+
...t9,
|
|
70
110
|
basePath: draftId ? `threads/draft/${projectId}/${draftId}` : `threads/live/${projectId}`,
|
|
71
111
|
maxEnqueuedMessages: 0,
|
|
72
112
|
shouldReconnectOnClose: _temp,
|
|
@@ -75,53 +115,56 @@ function useThread(apiUrl, projectId, draftId, t0) {
|
|
|
75
115
|
},
|
|
76
116
|
onMessage(event_0) {
|
|
77
117
|
if (typeof event_0.data !== "string") return;
|
|
78
|
-
let
|
|
118
|
+
let frame_0;
|
|
79
119
|
try {
|
|
80
|
-
|
|
120
|
+
frame_0 = JSON.parse(event_0.data);
|
|
81
121
|
} catch {
|
|
82
122
|
return;
|
|
83
123
|
}
|
|
84
|
-
onFrame(
|
|
124
|
+
onFrame(frame_0);
|
|
85
125
|
}
|
|
86
126
|
});
|
|
87
|
-
let
|
|
88
|
-
if ($[
|
|
89
|
-
|
|
90
|
-
$[
|
|
91
|
-
$[
|
|
92
|
-
$[
|
|
93
|
-
} else
|
|
94
|
-
const asked =
|
|
95
|
-
let
|
|
96
|
-
if ($[
|
|
97
|
-
|
|
98
|
-
$[
|
|
99
|
-
$[
|
|
100
|
-
} else
|
|
101
|
-
const ours =
|
|
102
|
-
let
|
|
103
|
-
if ($[
|
|
104
|
-
|
|
105
|
-
switch (
|
|
127
|
+
let t10;
|
|
128
|
+
if ($[20] !== draftId || $[21] !== sent) {
|
|
129
|
+
t10 = (started) => draftId === null && started.operationIds.some((operationId) => sent.has(operationId));
|
|
130
|
+
$[20] = draftId;
|
|
131
|
+
$[21] = sent;
|
|
132
|
+
$[22] = t10;
|
|
133
|
+
} else t10 = $[22];
|
|
134
|
+
const asked = t10;
|
|
135
|
+
let t11;
|
|
136
|
+
if ($[23] !== sent) {
|
|
137
|
+
t11 = (batch) => batch.operationIds.some((operationId_0) => sent.has(operationId_0));
|
|
138
|
+
$[23] = sent;
|
|
139
|
+
$[24] = t11;
|
|
140
|
+
} else t11 = $[24];
|
|
141
|
+
const ours = t11;
|
|
142
|
+
let t12;
|
|
143
|
+
if ($[25] !== apiUrl || $[26] !== asked || $[27] !== onEnterDraft || $[28] !== ours || $[29] !== projectId || $[30] !== sent) {
|
|
144
|
+
t12 = (frame_1) => {
|
|
145
|
+
switch (frame_1.type) {
|
|
106
146
|
case "started-draft":
|
|
107
|
-
if (asked(
|
|
108
|
-
handedOff.set(threadKey(apiUrl, projectId,
|
|
109
|
-
|
|
147
|
+
if (asked(frame_1.startedDraft)) {
|
|
148
|
+
handedOff.set(threadKey(apiUrl, projectId, frame_1.startedDraft.draftId), {
|
|
149
|
+
sent,
|
|
150
|
+
view: runOf(threadViewOf(latest.current))
|
|
151
|
+
});
|
|
152
|
+
onEnterDraft?.(frame_1.startedDraft.draftId);
|
|
110
153
|
}
|
|
111
154
|
return;
|
|
112
155
|
case "events":
|
|
113
|
-
|
|
156
|
+
fold(frame_1);
|
|
114
157
|
if (!shown.current) {
|
|
115
158
|
shown.current = true;
|
|
116
159
|
setShows(_temp2);
|
|
117
160
|
}
|
|
118
161
|
return;
|
|
119
162
|
case "drafts":
|
|
120
|
-
|
|
163
|
+
fold(frame_1);
|
|
121
164
|
return;
|
|
122
165
|
case "touched":
|
|
123
|
-
if (ours(
|
|
124
|
-
const batch_0 =
|
|
166
|
+
if (ours(frame_1.touched)) {
|
|
167
|
+
const batch_0 = frame_1.touched;
|
|
125
168
|
setTouched((last) => ({
|
|
126
169
|
sequence: (last?.sequence ?? 0) + 1,
|
|
127
170
|
batch: batch_0
|
|
@@ -129,78 +172,78 @@ function useThread(apiUrl, projectId, draftId, t0) {
|
|
|
129
172
|
}
|
|
130
173
|
return;
|
|
131
174
|
case "accepted":
|
|
132
|
-
setUnaccepted((current_0) => without(current_0,
|
|
175
|
+
setUnaccepted((current_0) => without(current_0, frame_1.operationId));
|
|
133
176
|
return;
|
|
134
177
|
case "error": {
|
|
135
|
-
console.error("[useThread]",
|
|
136
|
-
setError(
|
|
137
|
-
const { operationId: operationId_1 } =
|
|
178
|
+
console.error("[useThread]", frame_1.message);
|
|
179
|
+
setError(frame_1.message);
|
|
180
|
+
const { operationId: operationId_1 } = frame_1;
|
|
138
181
|
if (operationId_1) setUnaccepted((current) => without(current, operationId_1));
|
|
139
182
|
return;
|
|
140
183
|
}
|
|
141
184
|
}
|
|
142
185
|
};
|
|
143
|
-
$[
|
|
144
|
-
$[
|
|
145
|
-
$[
|
|
146
|
-
$[
|
|
147
|
-
$[
|
|
148
|
-
$[
|
|
149
|
-
$[
|
|
150
|
-
} else
|
|
151
|
-
const onFrame = React.useEffectEvent(
|
|
152
|
-
let
|
|
153
|
-
if ($[
|
|
154
|
-
|
|
186
|
+
$[25] = apiUrl;
|
|
187
|
+
$[26] = asked;
|
|
188
|
+
$[27] = onEnterDraft;
|
|
189
|
+
$[28] = ours;
|
|
190
|
+
$[29] = projectId;
|
|
191
|
+
$[30] = sent;
|
|
192
|
+
$[31] = t12;
|
|
193
|
+
} else t12 = $[31];
|
|
194
|
+
const onFrame = React.useEffectEvent(t12);
|
|
195
|
+
let t13;
|
|
196
|
+
if ($[32] !== socket || $[33] !== unaccepted) {
|
|
197
|
+
t13 = () => {
|
|
155
198
|
for (const [operationId_2, message] of unaccepted) transmit(socket, {
|
|
156
199
|
type: "send",
|
|
157
200
|
operationId: operationId_2,
|
|
158
201
|
...message
|
|
159
202
|
});
|
|
160
203
|
};
|
|
161
|
-
$[
|
|
162
|
-
$[
|
|
163
|
-
$[
|
|
164
|
-
} else
|
|
165
|
-
const resendUnaccepted = React.useEffectEvent(
|
|
166
|
-
let
|
|
167
|
-
if ($[
|
|
168
|
-
|
|
204
|
+
$[32] = socket;
|
|
205
|
+
$[33] = unaccepted;
|
|
206
|
+
$[34] = t13;
|
|
207
|
+
} else t13 = $[34];
|
|
208
|
+
const resendUnaccepted = React.useEffectEvent(t13);
|
|
209
|
+
let t14;
|
|
210
|
+
if ($[35] !== resendUnaccepted || $[36] !== shows) {
|
|
211
|
+
t14 = () => {
|
|
169
212
|
if (shows > 0) resendUnaccepted();
|
|
170
213
|
};
|
|
171
|
-
$[
|
|
172
|
-
$[
|
|
173
|
-
$[
|
|
174
|
-
} else
|
|
175
|
-
let
|
|
176
|
-
if ($[
|
|
177
|
-
|
|
178
|
-
$[
|
|
179
|
-
$[
|
|
180
|
-
} else
|
|
181
|
-
React.useEffect(
|
|
182
|
-
let
|
|
183
|
-
let
|
|
184
|
-
if ($[
|
|
185
|
-
|
|
214
|
+
$[35] = resendUnaccepted;
|
|
215
|
+
$[36] = shows;
|
|
216
|
+
$[37] = t14;
|
|
217
|
+
} else t14 = $[37];
|
|
218
|
+
let t15;
|
|
219
|
+
if ($[38] !== shows) {
|
|
220
|
+
t15 = [shows];
|
|
221
|
+
$[38] = shows;
|
|
222
|
+
$[39] = t15;
|
|
223
|
+
} else t15 = $[39];
|
|
224
|
+
React.useEffect(t14, t15);
|
|
225
|
+
let t16;
|
|
226
|
+
let t17;
|
|
227
|
+
if ($[40] !== socket) {
|
|
228
|
+
t16 = () => {
|
|
186
229
|
const resync = () => {
|
|
187
230
|
if (document.visibilityState === "visible") transmit(socket, { type: "resync" });
|
|
188
231
|
};
|
|
189
232
|
document.addEventListener("visibilitychange", resync);
|
|
190
233
|
return () => document.removeEventListener("visibilitychange", resync);
|
|
191
234
|
};
|
|
192
|
-
|
|
193
|
-
$[
|
|
194
|
-
$[
|
|
195
|
-
$[
|
|
235
|
+
t17 = [socket];
|
|
236
|
+
$[40] = socket;
|
|
237
|
+
$[41] = t16;
|
|
238
|
+
$[42] = t17;
|
|
196
239
|
} else {
|
|
197
|
-
|
|
198
|
-
|
|
240
|
+
t16 = $[41];
|
|
241
|
+
t17 = $[42];
|
|
199
242
|
}
|
|
200
|
-
React.useEffect(
|
|
201
|
-
let
|
|
202
|
-
if ($[
|
|
203
|
-
|
|
243
|
+
React.useEffect(t16, t17);
|
|
244
|
+
let t18;
|
|
245
|
+
if ($[43] !== sent || $[44] !== socket) {
|
|
246
|
+
t18 = (text, where) => {
|
|
204
247
|
const operationId_3 = crypto.randomUUID();
|
|
205
248
|
const message_0 = where ? {
|
|
206
249
|
text,
|
|
@@ -208,45 +251,46 @@ function useThread(apiUrl, projectId, draftId, t0) {
|
|
|
208
251
|
} : { text };
|
|
209
252
|
sent.add(operationId_3);
|
|
210
253
|
setError(void 0);
|
|
211
|
-
setUnaccepted((
|
|
254
|
+
setUnaccepted((current_1) => new Map(current_1).set(operationId_3, message_0));
|
|
212
255
|
transmit(socket, {
|
|
213
256
|
type: "send",
|
|
214
257
|
operationId: operationId_3,
|
|
215
258
|
...message_0
|
|
216
259
|
});
|
|
217
260
|
};
|
|
218
|
-
$[
|
|
219
|
-
$[
|
|
220
|
-
$[
|
|
221
|
-
} else
|
|
222
|
-
const send =
|
|
223
|
-
let
|
|
224
|
-
if ($[
|
|
225
|
-
|
|
226
|
-
$[
|
|
227
|
-
$[
|
|
228
|
-
} else
|
|
229
|
-
const stop =
|
|
230
|
-
const
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
261
|
+
$[43] = sent;
|
|
262
|
+
$[44] = socket;
|
|
263
|
+
$[45] = t18;
|
|
264
|
+
} else t18 = $[45];
|
|
265
|
+
const send = t18;
|
|
266
|
+
let t19;
|
|
267
|
+
if ($[46] !== socket) {
|
|
268
|
+
t19 = () => transmit(socket, { type: "stop" });
|
|
269
|
+
$[46] = socket;
|
|
270
|
+
$[47] = t19;
|
|
271
|
+
} else t19 = $[47];
|
|
272
|
+
const stop = t19;
|
|
273
|
+
const t20 = shows === 0 && carried?.view || view;
|
|
274
|
+
const t21 = unaccepted.size > 0;
|
|
275
|
+
let t22;
|
|
276
|
+
if ($[48] !== error || $[49] !== send || $[50] !== stop || $[51] !== t20 || $[52] !== t21 || $[53] !== touched) {
|
|
277
|
+
t22 = {
|
|
278
|
+
view: t20,
|
|
279
|
+
sending: t21,
|
|
236
280
|
send,
|
|
237
281
|
stop,
|
|
238
282
|
error,
|
|
239
283
|
touched
|
|
240
284
|
};
|
|
241
|
-
$[
|
|
242
|
-
$[
|
|
243
|
-
$[
|
|
244
|
-
$[
|
|
245
|
-
$[
|
|
246
|
-
$[
|
|
247
|
-
$[
|
|
248
|
-
} else
|
|
249
|
-
return
|
|
285
|
+
$[48] = error;
|
|
286
|
+
$[49] = send;
|
|
287
|
+
$[50] = stop;
|
|
288
|
+
$[51] = t20;
|
|
289
|
+
$[52] = t21;
|
|
290
|
+
$[53] = touched;
|
|
291
|
+
$[54] = t22;
|
|
292
|
+
} else t22 = $[54];
|
|
293
|
+
return t22;
|
|
250
294
|
}
|
|
251
295
|
function _temp2(count) {
|
|
252
296
|
return count + 1;
|
|
@@ -255,14 +299,28 @@ function _temp(event) {
|
|
|
255
299
|
return event.code !== THREAD_ENDED_CLOSE_CODE;
|
|
256
300
|
}
|
|
257
301
|
/**
|
|
258
|
-
*
|
|
259
|
-
*
|
|
260
|
-
* thread, it follows what they touch
|
|
302
|
+
* What a studio carries from Live into the draft the agent on Live handed its request off to, by
|
|
303
|
+
* that draft: the operation ids of the messages it sent on Live, which the draft's agent runs on,
|
|
304
|
+
* so once the studio follows that draft's thread, it follows what they touch; and the request as
|
|
305
|
+
* Live showed it, which the draft's thread opens with.
|
|
261
306
|
*/
|
|
262
307
|
const handedOff = /* @__PURE__ */ new Map();
|
|
308
|
+
/**
|
|
309
|
+
* The request a Live view ends on, as the draft it's handed off to goes on with it: the messages
|
|
310
|
+
* after the agent's last, the draft's agent already at work.
|
|
311
|
+
*/
|
|
312
|
+
function runOf(view) {
|
|
313
|
+
let opening = view.messages.length;
|
|
314
|
+
while (opening > 0 && ["editor", "connectedAgent"].includes(view.messages[opening - 1].from)) opening -= 1;
|
|
315
|
+
return {
|
|
316
|
+
messages: view.messages.slice(opening),
|
|
317
|
+
running: true,
|
|
318
|
+
activity: "startingDraft"
|
|
319
|
+
};
|
|
320
|
+
}
|
|
263
321
|
const threadKey = (apiUrl, projectId, draftId) => `${apiUrl}|${projectId}|${draftId}`;
|
|
264
|
-
/**
|
|
265
|
-
const handedOffTo = (apiUrl, projectId, draftId) => draftId
|
|
322
|
+
/** What a studio carries into the draft `draftId`: nothing for Live. */
|
|
323
|
+
const handedOffTo = (apiUrl, projectId, draftId) => draftId === null ? void 0 : handedOff.get(threadKey(apiUrl, projectId, draftId));
|
|
266
324
|
function transmit(socket, message) {
|
|
267
325
|
if (socket.readyState === OPEN) socket.send(JSON.stringify(message));
|
|
268
326
|
}
|