@dxos/plugin-thread 0.6.12-main.f9d0246 → 0.6.12-staging.0b4bb48

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.
Files changed (79) hide show
  1. package/dist/lib/browser/{ThreadArticle-4VU752F4.mjs → ThreadArticle-O64ZECMF.mjs} +3 -3
  2. package/dist/lib/browser/{ThreadMain-ML3P4XSD.mjs → ThreadMain-ZDCRC6RG.mjs} +3 -3
  3. package/dist/lib/browser/{chunk-7NUYW5IW.mjs → chunk-5IBJO53M.mjs} +5 -2
  4. package/dist/lib/browser/chunk-5IBJO53M.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-GJRBBPXI.mjs → chunk-GKPZHUT3.mjs} +2 -2
  6. package/dist/lib/browser/{chunk-GJRBBPXI.mjs.map → chunk-GKPZHUT3.mjs.map} +1 -1
  7. package/dist/lib/browser/{chunk-XF5QKI75.mjs → chunk-P7ZE5N5M.mjs} +11 -13
  8. package/dist/lib/browser/chunk-P7ZE5N5M.mjs.map +7 -0
  9. package/dist/lib/browser/index.mjs +207 -237
  10. package/dist/lib/browser/index.mjs.map +4 -4
  11. package/dist/lib/browser/meta.json +1 -1
  12. package/dist/lib/browser/meta.mjs +1 -1
  13. package/dist/lib/browser/types.mjs +2 -2
  14. package/dist/lib/node/{ThreadArticle-ERUHPHVT.cjs → ThreadArticle-DO56JXBU.cjs} +7 -7
  15. package/dist/lib/node/{ThreadMain-6DN7FDNB.cjs → ThreadMain-XJX75GHG.cjs} +7 -7
  16. package/dist/lib/node/{chunk-PZVUW4W2.cjs → chunk-5PZNPPQF.cjs} +63 -65
  17. package/dist/lib/node/chunk-5PZNPPQF.cjs.map +7 -0
  18. package/dist/lib/node/{chunk-6EVXCSDS.cjs → chunk-BWBONZGU.cjs} +18 -5
  19. package/dist/lib/node/chunk-BWBONZGU.cjs.map +7 -0
  20. package/dist/lib/node/{chunk-FXD3DYMO.cjs → chunk-D5GOVXHS.cjs} +6 -6
  21. package/dist/lib/node/{chunk-FXD3DYMO.cjs.map → chunk-D5GOVXHS.cjs.map} +1 -1
  22. package/dist/lib/node/index.cjs +296 -324
  23. package/dist/lib/node/index.cjs.map +4 -4
  24. package/dist/lib/node/meta.cjs +4 -4
  25. package/dist/lib/node/meta.cjs.map +1 -1
  26. package/dist/lib/node/meta.json +1 -1
  27. package/dist/lib/node/types.cjs +3 -3
  28. package/dist/lib/node/types.cjs.map +1 -1
  29. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  30. package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
  31. package/dist/types/src/components/CommentContainer.d.ts.map +1 -1
  32. package/dist/types/src/components/CommentsContainer.d.ts.map +1 -1
  33. package/dist/types/src/components/MessageContainer.d.ts.map +1 -1
  34. package/dist/types/src/components/testing.d.ts +0 -2
  35. package/dist/types/src/components/testing.d.ts.map +1 -1
  36. package/dist/types/src/meta.d.ts +4 -1
  37. package/dist/types/src/meta.d.ts.map +1 -1
  38. package/dist/types/src/types.d.ts +1 -1
  39. package/dist/types/src/types.d.ts.map +1 -1
  40. package/dist/types/src/types.test.d.ts +2 -0
  41. package/dist/types/src/types.test.d.ts.map +1 -0
  42. package/package.json +34 -37
  43. package/src/ThreadPlugin.tsx +178 -68
  44. package/src/components/ChatContainer.tsx +8 -7
  45. package/src/components/CommentContainer.tsx +7 -10
  46. package/src/components/Comments.stories.tsx +2 -2
  47. package/src/components/CommentsContainer.tsx +18 -22
  48. package/src/components/MessageContainer.tsx +1 -2
  49. package/src/meta.tsx +5 -1
  50. package/src/types.test.ts +13 -0
  51. package/src/types.ts +1 -1
  52. package/dist/lib/browser/chunk-7NUYW5IW.mjs.map +0 -7
  53. package/dist/lib/browser/chunk-XF5QKI75.mjs.map +0 -7
  54. package/dist/lib/node/chunk-6EVXCSDS.cjs.map +0 -7
  55. package/dist/lib/node/chunk-PZVUW4W2.cjs.map +0 -7
  56. package/dist/lib/node-esm/ThreadArticle-NKI5F4W5.mjs +0 -19
  57. package/dist/lib/node-esm/ThreadArticle-NKI5F4W5.mjs.map +0 -7
  58. package/dist/lib/node-esm/ThreadMain-2A3VQLCW.mjs +0 -27
  59. package/dist/lib/node-esm/ThreadMain-2A3VQLCW.mjs.map +0 -7
  60. package/dist/lib/node-esm/chunk-A44C4MTQ.mjs +0 -413
  61. package/dist/lib/node-esm/chunk-A44C4MTQ.mjs.map +0 -7
  62. package/dist/lib/node-esm/chunk-Y475KZTX.mjs +0 -20
  63. package/dist/lib/node-esm/chunk-Y475KZTX.mjs.map +0 -7
  64. package/dist/lib/node-esm/chunk-YO46JGAE.mjs +0 -21
  65. package/dist/lib/node-esm/chunk-YO46JGAE.mjs.map +0 -7
  66. package/dist/lib/node-esm/index.mjs +0 -1133
  67. package/dist/lib/node-esm/index.mjs.map +0 -7
  68. package/dist/lib/node-esm/meta.json +0 -1
  69. package/dist/lib/node-esm/meta.mjs +0 -12
  70. package/dist/lib/node-esm/meta.mjs.map +0 -7
  71. package/dist/lib/node-esm/types.mjs +0 -9
  72. package/dist/lib/node-esm/types.mjs.map +0 -7
  73. package/dist/types/src/components/ThreadComplementary.d.ts +0 -11
  74. package/dist/types/src/components/ThreadComplementary.d.ts.map +0 -1
  75. package/src/components/ThreadComplementary.tsx +0 -120
  76. /package/dist/lib/browser/{ThreadArticle-4VU752F4.mjs.map → ThreadArticle-O64ZECMF.mjs.map} +0 -0
  77. /package/dist/lib/browser/{ThreadMain-ML3P4XSD.mjs.map → ThreadMain-ZDCRC6RG.mjs.map} +0 -0
  78. /package/dist/lib/node/{ThreadArticle-ERUHPHVT.cjs.map → ThreadArticle-DO56JXBU.cjs.map} +0 -0
  79. /package/dist/lib/node/{ThreadMain-6DN7FDNB.cjs.map → ThreadMain-XJX75GHG.cjs.map} +0 -0
@@ -1,1133 +0,0 @@
1
- import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
- import {
3
- ThreadAction
4
- } from "./chunk-YO46JGAE.mjs";
5
- import {
6
- ChatContainer,
7
- ChatHeading,
8
- MessageContainer,
9
- command,
10
- getMessageMetadata,
11
- useAnalyticsCallback,
12
- useOnEditAnalytics,
13
- useStatus
14
- } from "./chunk-A44C4MTQ.mjs";
15
- import {
16
- THREAD_ITEM,
17
- THREAD_PLUGIN,
18
- meta_default
19
- } from "./chunk-Y475KZTX.mjs";
20
-
21
- // packages/plugins/plugin-thread/src/ThreadPlugin.tsx
22
- import { computed, effect } from "@preact/signals-core";
23
- import React6 from "react";
24
- import { LayoutAction as LayoutAction2, NavigationAction, parseIntentPlugin, parseNavigationPlugin, resolvePlugin, isLayoutParts, parseMetadataResolverPlugin } from "@dxos/app-framework";
25
- import { getTypename } from "@dxos/echo-schema";
26
- import { create as create2 } from "@dxos/echo-schema";
27
- import { LocalStorageStore } from "@dxos/local-storage";
28
- import { log } from "@dxos/log";
29
- import { parseClientPlugin } from "@dxos/plugin-client";
30
- import { createExtension, isActionGroup, toSignal } from "@dxos/plugin-graph";
31
- import { ObservabilityAction } from "@dxos/plugin-observability/meta";
32
- import { SpaceAction } from "@dxos/plugin-space";
33
- import { ThreadType, MessageType as MessageType2, ChannelType } from "@dxos/plugin-space/types";
34
- import { getSpace as getSpace2, getTextInRange, createDocAccessor, fullyQualifiedId as fullyQualifiedId4, loadObjectReferences } from "@dxos/react-client/echo";
35
- import { comments, createExternalCommentSync, listener as listener2 } from "@dxos/react-ui-editor";
36
- import { translations as threadTranslations } from "@dxos/react-ui-thread";
37
- import { nonNullable as nonNullable3 } from "@dxos/util";
38
-
39
- // packages/plugins/plugin-thread/src/components/index.ts
40
- import React4 from "react";
41
-
42
- // packages/plugins/plugin-thread/src/components/ThreadSettings.tsx
43
- import React from "react";
44
- import { SettingsValue } from "@dxos/plugin-settings";
45
- import { Input, useTranslation } from "@dxos/react-ui";
46
- var ThreadSettings = ({ settings }) => {
47
- const { t } = useTranslation(THREAD_PLUGIN);
48
- return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(SettingsValue, {
49
- label: t("settings standalone label")
50
- }, /* @__PURE__ */ React.createElement(Input.Switch, {
51
- checked: settings.standalone,
52
- onCheckedChange: (checked) => settings.standalone = !!checked
53
- })));
54
- };
55
-
56
- // packages/plugins/plugin-thread/src/components/CommentContainer.tsx
57
- import { CheckCircle, X } from "@phosphor-icons/react";
58
- import React2, { useCallback, useEffect, useMemo, useRef, useState } from "react";
59
- import { create } from "@dxos/echo-schema";
60
- import { MessageType } from "@dxos/plugin-space/types";
61
- import { fullyQualifiedId, getSpace, useMembers } from "@dxos/react-client/echo";
62
- import { useIdentity } from "@dxos/react-client/halo";
63
- import { Button, Tag, Tooltip, useThemeContext, useTranslation as useTranslation2 } from "@dxos/react-ui";
64
- import { createBasicExtensions, createThemeExtensions, listener } from "@dxos/react-ui-editor";
65
- import { getSize, hoverableControlItem, hoverableControls, hoverableFocusedWithinControls, mx } from "@dxos/react-ui-theme";
66
- import { MessageTextbox, Thread, ThreadFooter, ThreadHeading } from "@dxos/react-ui-thread";
67
- import { nonNullable } from "@dxos/util";
68
- var sizeClass = getSize(4);
69
- var ToggleResolvedButton = ({ isResolved, onResolve }) => {
70
- const { t } = useTranslation2(THREAD_PLUGIN);
71
- const label = t(isResolved ? "mark as unresolved label" : "mark as resolved label");
72
- return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
73
- asChild: true
74
- }, /* @__PURE__ */ React2.createElement(Button, {
75
- variant: "ghost",
76
- "data-testid": "thread.toggle-resolved",
77
- onClick: onResolve,
78
- classNames: [
79
- "min-bs-0 p-1",
80
- !isResolved && hoverableControlItem
81
- ]
82
- }, /* @__PURE__ */ React2.createElement("span", {
83
- className: "sr-only"
84
- }, label), isResolved ? /* @__PURE__ */ React2.createElement(CheckCircle, {
85
- className: sizeClass,
86
- weight: "fill"
87
- }) : /* @__PURE__ */ React2.createElement(CheckCircle, {
88
- className: sizeClass
89
- }))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, {
90
- classNames: "z-[21]"
91
- }, label, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
92
- };
93
- var DeleteThreadButton = ({ onDelete }) => {
94
- const { t } = useTranslation2(THREAD_PLUGIN);
95
- const label = t("delete thread label");
96
- return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
97
- asChild: true
98
- }, /* @__PURE__ */ React2.createElement(Button, {
99
- variant: "ghost",
100
- "data-testid": "thread.delete",
101
- onClick: onDelete,
102
- classNames: [
103
- "min-bs-0 p-1",
104
- hoverableControlItem
105
- ]
106
- }, /* @__PURE__ */ React2.createElement("span", {
107
- className: "sr-only"
108
- }, label), /* @__PURE__ */ React2.createElement(X, {
109
- className: sizeClass
110
- }))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, {
111
- classNames: "z-[21]"
112
- }, label, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
113
- };
114
- var CommentContainer = ({ thread, detached, context, current, autoFocusTextbox, onAttend, onThreadDelete, onMessageDelete, onResolve, onComment }) => {
115
- const identity = useIdentity();
116
- const space = getSpace(thread);
117
- const members = useMembers(space?.key);
118
- const activity = useStatus(space, fullyQualifiedId(thread));
119
- const { t } = useTranslation2(THREAD_PLUGIN);
120
- const threadScrollRef = useRef(null);
121
- const [autoFocus, setAutoFocus] = useState(!!autoFocusTextbox);
122
- const { themeMode } = useThemeContext();
123
- const textboxMetadata = getMessageMetadata(fullyQualifiedId(thread), identity);
124
- const [_count, _setCount] = useState(0);
125
- const rerenderEditor = () => _setCount((count) => count + 1);
126
- const messageRef = useRef("");
127
- const extensions = useMemo(() => [
128
- createBasicExtensions({
129
- placeholder: t("message placeholder")
130
- }),
131
- createThemeExtensions({
132
- themeMode
133
- }),
134
- listener({
135
- onChange: (text) => messageRef.current = text
136
- }),
137
- command
138
- ], [
139
- _count
140
- ]);
141
- useEffect(() => {
142
- setAutoFocus(!!autoFocusTextbox);
143
- }, [
144
- autoFocusTextbox
145
- ]);
146
- const scrollToEnd = (behavior) => setTimeout(() => threadScrollRef.current?.scrollIntoView({
147
- behavior,
148
- block: "end"
149
- }), 10);
150
- const handleCreate = useCallback(() => {
151
- if (!messageRef.current) {
152
- return false;
153
- }
154
- thread.messages.push(create(MessageType, {
155
- sender: {
156
- identityKey: identity.identityKey.toHex()
157
- },
158
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
159
- text: messageRef.current,
160
- context
161
- }));
162
- onComment?.(thread);
163
- messageRef.current = "";
164
- setAutoFocus(true);
165
- scrollToEnd("instant");
166
- rerenderEditor();
167
- return true;
168
- }, [
169
- thread,
170
- identity
171
- ]);
172
- return /* @__PURE__ */ React2.createElement(Thread, {
173
- onClickCapture: onAttend,
174
- onFocusCapture: onAttend,
175
- current,
176
- id: fullyQualifiedId(thread)
177
- }, /* @__PURE__ */ React2.createElement("div", {
178
- role: "none",
179
- className: mx("col-span-2 grid grid-cols-[var(--rail-size)_1fr_min-content]", hoverableControls, hoverableFocusedWithinControls)
180
- }, detached ? /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
181
- asChild: true
182
- }, /* @__PURE__ */ React2.createElement(ThreadHeading, {
183
- detached: true
184
- }, thread.name ?? t("thread title placeholder"))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, {
185
- classNames: "z-[21]",
186
- side: "top"
187
- }, t("detached thread label"), /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null)))) : /* @__PURE__ */ React2.createElement(ThreadHeading, null, thread.name ?? t("thread title placeholder")), /* @__PURE__ */ React2.createElement("div", {
188
- className: "flex flex-row items-center pli-1"
189
- }, thread.status === "staged" && /* @__PURE__ */ React2.createElement(Tag, {
190
- palette: "neutral"
191
- }, t("draft button")), onResolve && !(thread?.status === "staged") && /* @__PURE__ */ React2.createElement(ToggleResolvedButton, {
192
- isResolved: thread?.status === "resolved",
193
- onResolve
194
- }), onThreadDelete && /* @__PURE__ */ React2.createElement(DeleteThreadButton, {
195
- onDelete: onThreadDelete
196
- }))), thread.messages.filter(nonNullable).map((message) => /* @__PURE__ */ React2.createElement(MessageContainer, {
197
- key: message.id,
198
- message,
199
- members,
200
- onDelete: (id) => onMessageDelete?.(id)
201
- })), /* @__PURE__ */ React2.createElement(MessageTextbox, {
202
- extensions,
203
- autoFocus,
204
- onSend: handleCreate,
205
- ...textboxMetadata
206
- }), /* @__PURE__ */ React2.createElement(ThreadFooter, {
207
- activity
208
- }, t("activity message")), /* @__PURE__ */ React2.createElement("div", {
209
- role: "none",
210
- className: "bs-px -mbs-px",
211
- ref: threadScrollRef
212
- }));
213
- };
214
-
215
- // packages/plugins/plugin-thread/src/components/CommentsContainer.tsx
216
- import { ChatText } from "@phosphor-icons/react";
217
- import React3, { useEffect as useEffect2 } from "react";
218
- import { fullyQualifiedId as fullyQualifiedId2 } from "@dxos/react-client/echo";
219
- import { useTranslation as useTranslation3, Icon, Trans } from "@dxos/react-ui";
220
- import { PlankHeading } from "@dxos/react-ui-deck";
221
- import { descriptionText, mx as mx2 } from "@dxos/react-ui-theme";
222
- var CommentsHeading = ({ attendableId }) => {
223
- const { t } = useTranslation3(THREAD_PLUGIN);
224
- return /* @__PURE__ */ React3.createElement("div", {
225
- role: "none",
226
- className: "flex items-center"
227
- }, /* @__PURE__ */ React3.createElement(PlankHeading.Button, {
228
- attendableId
229
- }, /* @__PURE__ */ React3.createElement(Icon, {
230
- icon: "ph--quotes--regular",
231
- size: 5
232
- })), /* @__PURE__ */ React3.createElement(PlankHeading.Label, {
233
- attendableId
234
- }, t("comments heading")));
235
- };
236
- var CommentsContainer = ({ threads, detached = [], currentId, autoFocusCurrentTextbox, showResolvedThreads, onThreadAttend, onThreadDelete, onMessageDelete, onThreadToggleResolved, ...props }) => {
237
- const { t } = useTranslation3(THREAD_PLUGIN);
238
- const filteredThreads = showResolvedThreads ? threads : threads.filter((thread) => !(thread?.status === "resolved"));
239
- useEffect2(() => {
240
- if (currentId) {
241
- document.getElementById(currentId)?.scrollIntoView({
242
- behavior: "smooth",
243
- block: "end"
244
- });
245
- }
246
- }, [
247
- currentId
248
- ]);
249
- return /* @__PURE__ */ React3.createElement(React3.Fragment, null, filteredThreads.length > 0 ? filteredThreads.map((thread) => {
250
- const threadId = fullyQualifiedId2(thread);
251
- return /* @__PURE__ */ React3.createElement(CommentContainer, {
252
- key: threadId,
253
- thread,
254
- current: currentId === threadId,
255
- detached: detached.includes(threadId),
256
- autoFocusTextbox: autoFocusCurrentTextbox && currentId === threadId,
257
- ...onThreadAttend && {
258
- onAttend: () => onThreadAttend(thread)
259
- },
260
- ...onThreadDelete && {
261
- onThreadDelete: () => onThreadDelete(thread)
262
- },
263
- ...onMessageDelete && {
264
- onMessageDelete: (messageId) => onMessageDelete(thread, messageId)
265
- },
266
- ...onThreadToggleResolved && {
267
- onResolve: () => onThreadToggleResolved(thread)
268
- },
269
- ...props
270
- });
271
- }) : /* @__PURE__ */ React3.createElement("div", {
272
- role: "alert",
273
- className: mx2(descriptionText, "place-self-center border border-dashed border-neutral-400/50 rounded-lg text-center p-4 m-4")
274
- }, /* @__PURE__ */ React3.createElement("h2", {
275
- className: "mbe-2 font-medium text-baseText"
276
- }, t("no comments title")), /* @__PURE__ */ React3.createElement("p", null, /* @__PURE__ */ React3.createElement(Trans, {
277
- t,
278
- i18nKey: "no comments message",
279
- components: {
280
- commentIcon: /* @__PURE__ */ React3.createElement(ChatText, {
281
- className: "inline-block"
282
- })
283
- }
284
- }))));
285
- };
286
-
287
- // packages/plugins/plugin-thread/src/components/index.ts
288
- var ThreadMain = React4.lazy(() => import("./ThreadMain-2A3VQLCW.mjs"));
289
- var ThreadArticle = React4.lazy(() => import("./ThreadArticle-NKI5F4W5.mjs"));
290
-
291
- // packages/plugins/plugin-thread/src/components/ThreadComplementary.tsx
292
- import React5, { useEffect as useEffect3, useMemo as useMemo2 } from "react";
293
- import { LayoutAction, useIntentDispatcher, useResolvePlugins } from "@dxos/app-framework";
294
- import { fullyQualifiedId as fullyQualifiedId3 } from "@dxos/react-client/echo";
295
- import { ScrollArea } from "@dxos/react-ui";
296
- import { createAttendableAttributes, useAttentionContext } from "@dxos/react-ui-attention";
297
- import { nonNullable as nonNullable2 } from "@dxos/util";
298
- var providesThreadsConfig = (plugin) => "thread" in plugin.provides ? plugin : void 0;
299
- var ThreadComplementary = ({ role, subject, stagedThreads, current, focus, showResolvedThreads }) => {
300
- const dispatch = useIntentDispatcher();
301
- const threadsIntegrators = useResolvePlugins(providesThreadsConfig);
302
- const threadProvides = useMemo2(() => threadsIntegrators.map((p) => p.provides.thread), [
303
- threadsIntegrators
304
- ]);
305
- const createSort = useMemo2(() => threadProvides.find((p) => p.predicate(subject))?.createSort, [
306
- threadProvides,
307
- subject
308
- ]);
309
- const sort = useMemo2(() => createSort?.(subject), [
310
- createSort,
311
- subject
312
- ]);
313
- const threads = useMemo2(() => {
314
- return subject.threads.concat(stagedThreads ?? []).filter(nonNullable2);
315
- }, [
316
- JSON.stringify(subject.threads),
317
- JSON.stringify(stagedThreads)
318
- ]);
319
- const detachedIds = useMemo2(() => {
320
- return threads.filter(({ anchor }) => !anchor).map((thread) => fullyQualifiedId3(thread));
321
- }, [
322
- threads
323
- ]);
324
- useEffect3(() => {
325
- if (!sort) {
326
- return;
327
- }
328
- threads.sort((a, b) => sort(a?.anchor, b?.anchor));
329
- }, [
330
- sort,
331
- threads
332
- ]);
333
- const { attended } = useAttentionContext("Thread Complementary");
334
- const qualifiedSubjectId = fullyQualifiedId3(subject);
335
- const attendableAttrs = createAttendableAttributes(qualifiedSubjectId);
336
- return /* @__PURE__ */ React5.createElement("div", {
337
- role: "none",
338
- className: "contents group/attention",
339
- ...attendableAttrs
340
- }, role === "complementary" && /* @__PURE__ */ React5.createElement(CommentsHeading, {
341
- attendableId: qualifiedSubjectId
342
- }), /* @__PURE__ */ React5.createElement(ScrollArea.Root, {
343
- classNames: "row-span-2"
344
- }, /* @__PURE__ */ React5.createElement(ScrollArea.Viewport, null, /* @__PURE__ */ React5.createElement(CommentsContainer, {
345
- threads,
346
- detached: detachedIds,
347
- currentId: attended.has(qualifiedSubjectId) ? current : void 0,
348
- autoFocusCurrentTextbox: focus,
349
- showResolvedThreads,
350
- onThreadAttend: (thread) => {
351
- const threadId = fullyQualifiedId3(thread);
352
- if (current !== threadId) {
353
- current = threadId;
354
- void dispatch?.([
355
- {
356
- action: LayoutAction.SCROLL_INTO_VIEW,
357
- data: {
358
- id: fullyQualifiedId3(subject),
359
- thread: threadId,
360
- cursor: thread.anchor
361
- }
362
- }
363
- ]);
364
- }
365
- },
366
- onThreadDelete: (thread) => {
367
- return dispatch({
368
- plugin: THREAD_PLUGIN,
369
- action: ThreadAction.DELETE,
370
- data: {
371
- subject,
372
- thread
373
- }
374
- });
375
- },
376
- onMessageDelete: (thread, messageId) => dispatch({
377
- plugin: THREAD_PLUGIN,
378
- action: ThreadAction.DELETE_MESSAGE,
379
- data: {
380
- subject,
381
- thread,
382
- messageId
383
- }
384
- }),
385
- onThreadToggleResolved: (thread) => dispatch({
386
- plugin: THREAD_PLUGIN,
387
- action: ThreadAction.TOGGLE_RESOLVED,
388
- data: {
389
- thread
390
- }
391
- }),
392
- onComment: (thread) => {
393
- void dispatch({
394
- action: ThreadAction.ON_MESSAGE_ADD,
395
- data: {
396
- thread,
397
- subject
398
- }
399
- });
400
- }
401
- }), /* @__PURE__ */ React5.createElement("div", {
402
- role: "none",
403
- className: "bs-10"
404
- }), /* @__PURE__ */ React5.createElement(ScrollArea.Scrollbar, null, /* @__PURE__ */ React5.createElement(ScrollArea.Thumb, null)))));
405
- };
406
-
407
- // packages/plugins/plugin-thread/src/translations.ts
408
- var translations_default = [
409
- {
410
- "en-US": {
411
- [THREAD_PLUGIN]: {
412
- "plugin name": "Threads",
413
- "channel name placeholder": "New channel",
414
- "channel title label": "Title",
415
- "delete channel label": "Delete channel",
416
- "create channel label": "Create channel",
417
- "message placeholder": "Reply\u2026",
418
- "settings standalone label": "Enable channel creation (experimental)",
419
- "activity message": "Processing\u2026",
420
- "anonymous label": "Anonymous",
421
- "delete message block label": "Delete message block",
422
- "detached thread label": "Referenced content was removed",
423
- "delete thread label": "Delete thread",
424
- "thread deleted label": "You deleted a thread.",
425
- "message deleted label": "You deleted a message.",
426
- "comments heading": "Comments",
427
- "chat heading": "Chat",
428
- "draft button": "DRAFT",
429
- "no comments title": "No comments (yet)",
430
- "no comments message": "To start a comment thread, select a range of text in a document and click the <commentIcon></commentIcon> Create comment button in the toolbar.",
431
- "toggle show resolved": "Show resolved",
432
- "unnamed object threads label": "Threads",
433
- "mark as resolved label": "Mark as resolved",
434
- "mark as unresolved label": "Mark as unresolved",
435
- "save message label": "Save",
436
- "edit message label": "Edit",
437
- "delete message label": "Delete message"
438
- }
439
- }
440
- }
441
- ];
442
-
443
- // packages/plugins/plugin-thread/src/ThreadPlugin.tsx
444
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-thread/src/ThreadPlugin.tsx";
445
- var initialViewState = {
446
- showResolvedThreads: false
447
- };
448
- var ThreadPlugin = () => {
449
- const settings = new LocalStorageStore(THREAD_PLUGIN);
450
- const state = create2({
451
- staging: {}
452
- });
453
- const viewStore = create2({});
454
- const getViewState = (subjectId) => {
455
- if (!viewStore[subjectId]) {
456
- viewStore[subjectId] = {
457
- ...initialViewState
458
- };
459
- }
460
- return viewStore[subjectId];
461
- };
462
- let navigationPlugin;
463
- let intentPlugin;
464
- const unsubscribeCallbacks = [];
465
- return {
466
- meta: meta_default,
467
- ready: async (plugins) => {
468
- settings.prop({
469
- key: "standalone",
470
- type: LocalStorageStore.bool({
471
- allowUndefined: true
472
- })
473
- });
474
- navigationPlugin = resolvePlugin(plugins, parseNavigationPlugin);
475
- intentPlugin = resolvePlugin(plugins, parseIntentPlugin);
476
- },
477
- unload: async () => {
478
- unsubscribeCallbacks.forEach((unsubscribe) => unsubscribe());
479
- },
480
- provides: {
481
- settings: settings.values,
482
- metadata: {
483
- records: {
484
- [ChannelType.typename]: {
485
- placeholder: [
486
- "channel title placeholder",
487
- {
488
- ns: THREAD_PLUGIN
489
- }
490
- ],
491
- icon: "ph--chat--regular",
492
- // TODO(wittjosiah): Move out of metadata.
493
- loadReferences: (channel) => loadObjectReferences(channel, (channel2) => channel2.threads)
494
- },
495
- [ThreadType.typename]: {
496
- // TODO(wittjosiah): Move out of metadata.
497
- loadReferences: (thread) => loadObjectReferences(thread, (thread2) => thread2.messages)
498
- },
499
- [MessageType2.typename]: {
500
- // TODO(wittjosiah): Move out of metadata.
501
- loadReferences: (message) => []
502
- },
503
- [THREAD_ITEM]: {
504
- parse: (item, type) => {
505
- switch (type) {
506
- case "node":
507
- return {
508
- id: item.id,
509
- label: item.title,
510
- data: item
511
- };
512
- case "object":
513
- return item;
514
- case "view-object":
515
- return {
516
- id: `${item.id}-view`,
517
- object: item
518
- };
519
- }
520
- }
521
- }
522
- }
523
- },
524
- translations: [
525
- ...translations_default,
526
- ...threadTranslations
527
- ],
528
- echo: {
529
- schema: [
530
- ChannelType,
531
- ThreadType,
532
- MessageType2
533
- ]
534
- },
535
- graph: {
536
- builder: (plugins) => {
537
- const client = resolvePlugin(plugins, parseClientPlugin)?.provides.client;
538
- const dispatch = resolvePlugin(plugins, parseIntentPlugin)?.provides.intent.dispatch;
539
- const metadataResolver = resolvePlugin(plugins, parseMetadataResolverPlugin)?.provides.metadata.resolver;
540
- if (!client || !dispatch || !metadataResolver) {
541
- return [];
542
- }
543
- return [
544
- createExtension({
545
- id: `${THREAD_PLUGIN}/comments-for-subject`,
546
- resolver: ({ id }) => {
547
- if (!id.endsWith("~comments")) {
548
- return;
549
- }
550
- const subjectId = id.split("~").at(0);
551
- const [spaceId, objectId] = subjectId?.split(":") ?? [];
552
- const space = client.spaces.get().find((space2) => space2.id === spaceId);
553
- const object = toSignal((onChange) => {
554
- const timeout = setTimeout(async () => {
555
- await space?.db.loadObjectById(objectId);
556
- onChange();
557
- });
558
- return () => clearTimeout(timeout);
559
- }, () => space?.db.getObjectById(objectId), subjectId);
560
- if (!object || !subjectId) {
561
- return;
562
- }
563
- const meta = metadataResolver(getTypename(object) ?? "");
564
- const label = meta.label?.(object) || object.name || meta.placeholder || [
565
- "unnamed object threads label",
566
- {
567
- ns: THREAD_PLUGIN
568
- }
569
- ];
570
- const viewState = getViewState(subjectId);
571
- return {
572
- id,
573
- type: "orphan-comments-for-subject",
574
- data: object,
575
- properties: {
576
- icon: meta.icon,
577
- label,
578
- showResolvedThreads: viewState.showResolvedThreads
579
- }
580
- };
581
- },
582
- actions: ({ node }) => {
583
- const dataId = node.id.split("~").at(0);
584
- if (!node.id.endsWith("~comments") || !dataId) {
585
- return;
586
- }
587
- const [spaceId, objectId] = dataId.split(":");
588
- const viewState = getViewState(dataId);
589
- const toggle = () => {
590
- const newToggleState = !viewState.showResolvedThreads;
591
- viewState.showResolvedThreads = newToggleState;
592
- void dispatch({
593
- action: ObservabilityAction.SEND_EVENT,
594
- data: {
595
- name: "threads.toggle-show-resolved",
596
- properties: {
597
- spaceId,
598
- threadId: objectId,
599
- showResolved: newToggleState
600
- }
601
- }
602
- });
603
- };
604
- return [
605
- {
606
- id: `${THREAD_PLUGIN}/toggle-show-resolved/${node.id}`,
607
- data: toggle,
608
- properties: {
609
- label: [
610
- "toggle show resolved",
611
- {
612
- ns: THREAD_PLUGIN
613
- }
614
- ],
615
- menuItemType: "toggle",
616
- isChecked: viewState.showResolvedThreads,
617
- testId: "threadPlugin.toggleShowResolved",
618
- icon: viewState.showResolvedThreads ? "ph--eye-slash--regular" : "ph--eye--regular"
619
- }
620
- }
621
- ];
622
- }
623
- }),
624
- createExtension({
625
- id: ThreadAction.CREATE,
626
- filter: (node) => !!settings.values.standalone && isActionGroup(node) && node.id.startsWith(SpaceAction.ADD_OBJECT),
627
- actions: ({ node }) => {
628
- const id = node.id.split("/").at(-1);
629
- const [spaceId, objectId] = id?.split(":") ?? [];
630
- const space = client.spaces.get().find((space2) => space2.id === spaceId);
631
- const object = objectId && space?.db.getObjectById(objectId);
632
- const target = objectId ? object : space;
633
- if (!target) {
634
- return;
635
- }
636
- return [
637
- {
638
- id: `${THREAD_PLUGIN}/create/${node.id}`,
639
- data: async () => {
640
- await dispatch([
641
- {
642
- plugin: THREAD_PLUGIN,
643
- action: ThreadAction.CREATE
644
- },
645
- {
646
- action: SpaceAction.ADD_OBJECT,
647
- data: {
648
- target
649
- }
650
- },
651
- {
652
- action: NavigationAction.OPEN
653
- }
654
- ]);
655
- },
656
- properties: {
657
- label: [
658
- "create channel label",
659
- {
660
- ns: THREAD_PLUGIN
661
- }
662
- ],
663
- icon: "ph--chat--regular",
664
- testId: "threadPlugin.createObject"
665
- }
666
- }
667
- ];
668
- }
669
- })
670
- ];
671
- }
672
- },
673
- surface: {
674
- component: ({ data, role }) => {
675
- switch (role) {
676
- case "main": {
677
- return data.active instanceof ChannelType && data.active.threads[0] ? /* @__PURE__ */ React6.createElement(ThreadMain, {
678
- thread: data.active.threads[0]
679
- }) : null;
680
- }
681
- case "settings": {
682
- return data.plugin === meta_default.id ? /* @__PURE__ */ React6.createElement(ThreadSettings, {
683
- settings: settings.values
684
- }) : null;
685
- }
686
- case "article":
687
- case "complementary": {
688
- const location = navigationPlugin?.provides.location;
689
- if (data.object instanceof ChannelType && data.object.threads[0]) {
690
- const channel = data.object;
691
- if (isLayoutParts(location?.active) && location.active.main) {
692
- const layoutEntries = location.active.main;
693
- const currentPosition = layoutEntries.findIndex((entry) => channel.id === entry.id);
694
- if (currentPosition > 0) {
695
- const objectToTheLeft = layoutEntries[currentPosition - 1];
696
- const context = getSpace2(data.object)?.db.getObjectById(objectToTheLeft.id);
697
- return /* @__PURE__ */ React6.createElement(ThreadArticle, {
698
- thread: data.object.threads[0],
699
- context
700
- });
701
- }
702
- }
703
- return /* @__PURE__ */ React6.createElement(ThreadArticle, {
704
- thread: data.object.threads[0]
705
- });
706
- }
707
- if (data.subject instanceof ThreadType) {
708
- return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(ChatHeading, {
709
- attendableId: data.subject.id
710
- }), /* @__PURE__ */ React6.createElement(ChatContainer, {
711
- thread: data.subject
712
- }));
713
- }
714
- if (data.subject && typeof data.subject === "object" && "threads" in data.subject && Array.isArray(data.subject.threads)) {
715
- const { showResolvedThreads } = getViewState(fullyQualifiedId4(data.subject));
716
- return /* @__PURE__ */ React6.createElement(ThreadComplementary, {
717
- role,
718
- subject: data.subject,
719
- stagedThreads: state.staging[fullyQualifiedId4(data.subject)],
720
- current: state.current,
721
- focus: true,
722
- showResolvedThreads
723
- });
724
- }
725
- }
726
- }
727
- return null;
728
- }
729
- },
730
- intent: {
731
- resolver: async (intent) => {
732
- switch (intent.action) {
733
- case ThreadAction.CREATE: {
734
- if (intent.data && intent.data.cursor !== void 0) {
735
- const { cursor, name, subject } = intent.data;
736
- if (subject?.threads === void 0) {
737
- try {
738
- subject.threads = [];
739
- } catch (e) {
740
- log.error("Subject does not support threads array", subject?.typename, {
741
- F: __dxlog_file,
742
- L: 332,
743
- S: void 0,
744
- C: (f, a) => f(...a)
745
- });
746
- return;
747
- }
748
- }
749
- const subjectId = fullyQualifiedId4(subject);
750
- const thread = create2(ThreadType, {
751
- name,
752
- anchor: cursor,
753
- messages: [],
754
- status: "staged"
755
- });
756
- const stagingArea = state.staging[subjectId];
757
- if (stagingArea) {
758
- stagingArea.push(thread);
759
- } else {
760
- state.staging[subjectId] = [
761
- thread
762
- ];
763
- }
764
- return {
765
- data: thread,
766
- intents: [
767
- [
768
- {
769
- action: ThreadAction.SELECT,
770
- data: {
771
- current: fullyQualifiedId4(thread),
772
- focus: true
773
- }
774
- },
775
- {
776
- action: LayoutAction2.SET_LAYOUT,
777
- data: {
778
- element: "complementary",
779
- subject: subjectId,
780
- state: true
781
- }
782
- }
783
- ]
784
- ]
785
- };
786
- } else {
787
- return {
788
- data: create2(ChannelType, {
789
- threads: [
790
- create2(ThreadType, {
791
- messages: []
792
- })
793
- ]
794
- })
795
- };
796
- }
797
- }
798
- case ThreadAction.SELECT: {
799
- state.focus = intent.data?.current === state.current ? state.focus : intent.data?.focus;
800
- state.current = intent.data?.current;
801
- return {
802
- data: true
803
- };
804
- }
805
- case ThreadAction.TOGGLE_RESOLVED: {
806
- const { thread } = intent.data ?? {};
807
- if (!(thread instanceof ThreadType)) {
808
- return;
809
- }
810
- if (thread.status === "active" || thread.status === void 0) {
811
- thread.status = "resolved";
812
- } else if (thread.status === "resolved") {
813
- thread.status = "active";
814
- }
815
- const space = getSpace2(thread);
816
- const spaceId = space?.id;
817
- return {
818
- intents: [
819
- [
820
- {
821
- action: ObservabilityAction.SEND_EVENT,
822
- data: {
823
- name: "threads.toggle-resolved",
824
- properties: {
825
- threadId: thread.id,
826
- spaceId
827
- }
828
- }
829
- }
830
- ]
831
- ]
832
- };
833
- }
834
- case ThreadAction.DELETE: {
835
- const { subject, thread } = intent.data ?? {};
836
- if (!(thread instanceof ThreadType) || !(subject && typeof subject === "object" && "threads" in subject)) {
837
- return;
838
- }
839
- const subjectId = fullyQualifiedId4(subject);
840
- const stagingArea = state.staging[subjectId];
841
- if (stagingArea) {
842
- const index = stagingArea.findIndex((t) => t.id === thread.id);
843
- if (index !== -1) {
844
- stagingArea.splice(index, 1);
845
- return {
846
- data: true
847
- };
848
- }
849
- }
850
- const space = getSpace2(thread);
851
- if (!space || !subject.threads) {
852
- return;
853
- }
854
- if (!intent.undo) {
855
- const index = subject.threads.findIndex((t) => t?.id === thread.id);
856
- const cursor = subject.threads[index]?.anchor;
857
- if (index !== -1) {
858
- subject.threads?.splice(index, 1);
859
- }
860
- space.db.remove(thread);
861
- return {
862
- undoable: {
863
- message: translations_default[0]["en-US"][THREAD_PLUGIN]["thread deleted label"],
864
- data: {
865
- cursor
866
- }
867
- },
868
- intents: [
869
- [
870
- {
871
- action: ObservabilityAction.SEND_EVENT,
872
- data: {
873
- name: "threads.delete",
874
- properties: {
875
- threadId: thread.id,
876
- spaceId: space.id
877
- }
878
- }
879
- }
880
- ]
881
- ]
882
- };
883
- } else if (intent.undo) {
884
- const savedThread = space.db.add(thread);
885
- subject.threads.push(savedThread);
886
- return {
887
- data: true,
888
- intents: [
889
- [
890
- {
891
- action: ObservabilityAction.SEND_EVENT,
892
- data: {
893
- name: "threads.undo-delete",
894
- properties: {
895
- threadId: thread.id,
896
- spaceId: space.id
897
- }
898
- }
899
- }
900
- ]
901
- ]
902
- };
903
- }
904
- break;
905
- }
906
- case ThreadAction.ON_MESSAGE_ADD: {
907
- const { thread, subject } = intent.data ?? {};
908
- if (!(thread instanceof ThreadType) || !(subject && typeof subject === "object" && "threads" in subject && Array.isArray(subject.threads))) {
909
- return;
910
- }
911
- const subjectId = fullyQualifiedId4(subject);
912
- const space = getSpace2(subject);
913
- const intents = [];
914
- const analyticsProperties = {
915
- threadId: thread.id,
916
- spaceId: space?.id
917
- };
918
- if (state.staging[subjectId]?.find((t) => t === thread)) {
919
- thread.status = "active";
920
- subject.threads ? subject.threads.push(thread) : subject.threads = [
921
- thread
922
- ];
923
- state.staging[subjectId] = state.staging[subjectId]?.filter((t) => t.id !== thread.id);
924
- intents.push({
925
- action: ObservabilityAction.SEND_EVENT,
926
- data: {
927
- name: "threads.thread-created",
928
- properties: analyticsProperties
929
- }
930
- });
931
- }
932
- intents.push({
933
- action: ObservabilityAction.SEND_EVENT,
934
- data: {
935
- name: "threads.message-added",
936
- properties: {
937
- ...analyticsProperties,
938
- threadLength: thread.messages.length
939
- }
940
- }
941
- });
942
- return {
943
- data: thread,
944
- intents: [
945
- intents
946
- ]
947
- };
948
- }
949
- case ThreadAction.DELETE_MESSAGE: {
950
- const { subject, thread, messageId } = intent.data ?? {};
951
- const space = getSpace2(subject);
952
- if (!(thread instanceof ThreadType) || !(subject && typeof subject === "object" && "threads" in subject)) {
953
- return;
954
- }
955
- if (!intent.undo) {
956
- const message = thread.messages.find((m) => m?.id === messageId);
957
- const messageIndex = thread.messages.findIndex((m) => m?.id === messageId);
958
- if (messageIndex === -1 || !message) {
959
- return void 0;
960
- }
961
- if (messageIndex === 0 && thread.messages.length === 1) {
962
- return {
963
- intents: [
964
- [
965
- {
966
- action: ThreadAction.DELETE,
967
- data: {
968
- subject,
969
- thread
970
- }
971
- }
972
- ]
973
- ]
974
- };
975
- } else {
976
- thread.messages.splice(messageIndex, 1);
977
- }
978
- return {
979
- undoable: {
980
- message: translations_default[0]["en-US"][THREAD_PLUGIN]["message deleted label"],
981
- data: {
982
- message,
983
- messageIndex
984
- }
985
- },
986
- intents: [
987
- [
988
- {
989
- action: ObservabilityAction.SEND_EVENT,
990
- data: {
991
- name: "threads.message.delete",
992
- properties: {
993
- threadId: thread.id,
994
- spaceId: space?.id
995
- }
996
- }
997
- }
998
- ]
999
- ]
1000
- };
1001
- } else if (intent.undo) {
1002
- const message = intent.data?.message;
1003
- const messageIndex = intent.data?.messageIndex;
1004
- if (!(message instanceof MessageType2) || !(typeof messageIndex === "number")) {
1005
- return;
1006
- }
1007
- thread.messages.splice(messageIndex, 0, message);
1008
- return {
1009
- data: true,
1010
- intents: [
1011
- [
1012
- {
1013
- action: ObservabilityAction.SEND_EVENT,
1014
- data: {
1015
- name: "threads.message.undo-delete",
1016
- properties: {
1017
- threadId: thread.id,
1018
- spaceId: space?.id
1019
- }
1020
- }
1021
- }
1022
- ]
1023
- ]
1024
- };
1025
- }
1026
- }
1027
- }
1028
- }
1029
- },
1030
- markdown: {
1031
- // TODO(burdon): Factor out extension factory into separate file (for simplicity).
1032
- extensions: ({ document: doc }) => {
1033
- const space = doc && getSpace2(doc);
1034
- if (!doc || !space) {
1035
- return [
1036
- comments()
1037
- ];
1038
- }
1039
- const threads = computed(() => [
1040
- ...doc.threads.filter(nonNullable3),
1041
- ...state.staging[fullyQualifiedId4(doc)] ?? []
1042
- ].filter((thread) => !(thread?.status === "resolved")));
1043
- return [
1044
- listener2({
1045
- onChange: () => {
1046
- doc.threads.forEach((thread) => {
1047
- if (thread?.anchor) {
1048
- const [start, end] = thread.anchor.split(":");
1049
- const name = doc.content && getTextInRange(createDocAccessor(doc.content, [
1050
- "content"
1051
- ]), start, end);
1052
- if (name && name !== thread.name) {
1053
- thread.name = name;
1054
- }
1055
- }
1056
- });
1057
- }
1058
- }),
1059
- createExternalCommentSync(doc.id, (sink) => effect(() => sink()), () => threads.value.filter((thread) => thread?.anchor).map((thread) => ({
1060
- id: fullyQualifiedId4(thread),
1061
- cursor: thread.anchor
1062
- }))),
1063
- comments({
1064
- id: doc.id,
1065
- onCreate: ({ cursor }) => {
1066
- const [start, end] = cursor.split(":");
1067
- const name = doc.content && getTextInRange(createDocAccessor(doc.content, [
1068
- "content"
1069
- ]), start, end);
1070
- void intentPlugin?.provides.intent.dispatch({
1071
- action: ThreadAction.CREATE,
1072
- data: {
1073
- cursor,
1074
- name,
1075
- subject: doc
1076
- }
1077
- });
1078
- },
1079
- onDelete: ({ id }) => {
1080
- const stagingArea = state.staging[fullyQualifiedId4(doc)];
1081
- if (stagingArea) {
1082
- const index = stagingArea.findIndex((thread2) => fullyQualifiedId4(thread2) === id);
1083
- if (index !== -1) {
1084
- stagingArea.splice(index, 1);
1085
- }
1086
- }
1087
- const thread = doc.threads.find((thread2) => thread2?.id === id);
1088
- if (thread) {
1089
- thread.anchor = void 0;
1090
- }
1091
- },
1092
- onUpdate: ({ id, cursor }) => {
1093
- const thread = state.staging[fullyQualifiedId4(doc)]?.find((thread2) => fullyQualifiedId4(thread2) === id) ?? doc.threads.find((thread2) => thread2?.id === id);
1094
- if (thread instanceof ThreadType && thread.anchor) {
1095
- const [start, end] = thread.anchor.split(":");
1096
- thread.name = doc.content && getTextInRange(createDocAccessor(doc.content, [
1097
- "content"
1098
- ]), start, end);
1099
- thread.anchor = cursor;
1100
- }
1101
- },
1102
- onSelect: ({ selection: { current, closest } }) => {
1103
- const dispatch = intentPlugin?.provides.intent.dispatch;
1104
- if (dispatch) {
1105
- void dispatch([
1106
- {
1107
- action: ThreadAction.SELECT,
1108
- data: {
1109
- current: current ?? closest
1110
- }
1111
- }
1112
- ]);
1113
- }
1114
- }
1115
- })
1116
- ];
1117
- }
1118
- }
1119
- }
1120
- };
1121
- };
1122
-
1123
- // packages/plugins/plugin-thread/src/index.ts
1124
- var src_default = ThreadPlugin;
1125
- export {
1126
- ThreadAction,
1127
- ThreadPlugin,
1128
- src_default as default,
1129
- useAnalyticsCallback,
1130
- useOnEditAnalytics,
1131
- useStatus
1132
- };
1133
- //# sourceMappingURL=index.mjs.map