@dxos/plugin-thread 0.10.0 → 0.11.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/lib/{neutral/ThreadPlugin.mjs → ThreadPlugin.mjs} +26 -66
- package/dist/lib/ThreadPlugin.mjs.map +1 -0
- package/dist/lib/ThreadPlugin.node.mjs +19 -0
- package/dist/lib/ThreadPlugin.node.mjs.map +1 -0
- package/dist/lib/ThreadPlugin.workerd.mjs +19 -0
- package/dist/lib/ThreadPlugin.workerd.mjs.map +1 -0
- package/dist/lib/capabilities/node.mjs +8 -0
- package/dist/lib/capabilities/node.mjs.map +1 -0
- package/dist/lib/capabilities.mjs +11 -0
- package/dist/lib/capabilities.mjs.map +1 -0
- package/dist/lib/chunk-ChannelArticle.mjs +104 -0
- package/dist/lib/chunk-ChannelArticle.mjs.map +1 -0
- package/dist/lib/chunk-ChannelCreatePanel.mjs +41 -0
- package/dist/lib/chunk-ChannelCreatePanel.mjs.map +1 -0
- package/dist/lib/chunk-ThreadArticle.mjs +58 -0
- package/dist/lib/chunk-ThreadArticle.mjs.map +1 -0
- package/dist/lib/chunk-app-graph-builder.mjs +49 -0
- package/dist/lib/chunk-app-graph-builder.mjs.map +1 -0
- package/dist/lib/chunk-append-channel-message.mjs +30 -0
- package/dist/lib/chunk-append-channel-message.mjs.map +1 -0
- package/dist/lib/chunk-channel-backend-feed.mjs +68 -0
- package/dist/lib/chunk-channel-backend-feed.mjs.map +1 -0
- package/dist/lib/chunk-create-channel.mjs +31 -0
- package/dist/lib/chunk-create-channel.mjs.map +1 -0
- package/dist/lib/chunk-create-object.mjs +36 -0
- package/dist/lib/chunk-create-object.mjs.map +1 -0
- package/dist/lib/{neutral/chunk-A5JYVGL2.mjs → chunk-meta.mjs} +20 -25
- package/dist/lib/chunk-meta.mjs.map +1 -0
- package/dist/lib/chunk-operation-handler.mjs +11 -0
- package/dist/lib/chunk-operation-handler.mjs.map +1 -0
- package/dist/lib/chunk-paths.mjs +8 -0
- package/dist/lib/chunk-paths.mjs.map +1 -0
- package/dist/lib/chunk-react-surface.mjs +38 -0
- package/dist/lib/chunk-react-surface.mjs.map +1 -0
- package/dist/lib/chunk-types.mjs +99 -0
- package/dist/lib/chunk-types.mjs.map +1 -0
- package/dist/lib/components.mjs +105 -0
- package/dist/lib/components.mjs.map +1 -0
- package/dist/lib/containers.mjs +9 -0
- package/dist/lib/containers.mjs.map +1 -0
- package/dist/lib/hooks.mjs +45 -0
- package/dist/lib/hooks.mjs.map +1 -0
- package/dist/lib/index.mjs +5 -0
- package/dist/lib/meta.mjs +2 -0
- package/dist/lib/operations.mjs +7 -0
- package/dist/lib/operations.mjs.map +1 -0
- package/dist/lib/plugin.mjs +9 -0
- package/dist/lib/plugin.mjs.map +1 -0
- package/dist/lib/translations.mjs +84 -0
- package/dist/lib/translations.mjs.map +1 -0
- package/dist/lib/types.mjs +2 -0
- package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
- package/dist/types/src/ThreadPlugin.node.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +1 -1
- package/dist/types/src/capabilities/channel-backend-feed.d.ts +1 -1
- package/dist/types/src/capabilities/channel-backend-feed.d.ts.map +1 -1
- package/dist/types/src/capabilities/create-object.d.ts +1 -1
- package/dist/types/src/capabilities/index.d.ts +0 -1
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/node.d.ts +5 -0
- package/dist/types/src/capabilities/node.d.ts.map +1 -0
- package/dist/types/src/capabilities/operation-handler.d.ts +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/components/{Chat/Chat.d.ts → MessageThread/MessageThread.d.ts} +11 -12
- package/dist/types/src/components/MessageThread/MessageThread.d.ts.map +1 -0
- package/dist/types/src/components/MessageThread/index.d.ts +2 -0
- package/dist/types/src/components/MessageThread/index.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +1 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/containers/ChannelArticle/ChannelArticle.d.ts +4 -9
- package/dist/types/src/containers/ChannelArticle/ChannelArticle.d.ts.map +1 -1
- package/dist/types/src/containers/ChannelArticle/ChannelArticle.stories.d.ts +4 -1
- package/dist/types/src/containers/ChannelArticle/ChannelArticle.stories.d.ts.map +1 -1
- package/dist/types/src/containers/ChannelCreatePanel/ChannelCreatePanel.d.ts +4 -8
- package/dist/types/src/containers/ChannelCreatePanel/ChannelCreatePanel.d.ts.map +1 -1
- package/dist/types/src/containers/ThreadArticle/ThreadArticle.d.ts +1 -3
- package/dist/types/src/containers/ThreadArticle/ThreadArticle.d.ts.map +1 -1
- package/dist/types/src/containers/ThreadArticle/ThreadArticle.stories.d.ts.map +1 -1
- package/dist/types/src/util.d.ts +14 -3
- package/dist/types/src/util.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/dx.config.ts +2 -1
- package/package.json +54 -46
- package/src/ThreadPlugin.node.ts +1 -2
- package/src/ThreadPlugin.test.ts +5 -2
- package/src/ThreadPlugin.tsx +1 -10
- package/src/capabilities/app-graph-builder.ts +5 -3
- package/src/capabilities/index.ts +0 -1
- package/src/capabilities/node.ts +18 -0
- package/src/capabilities/{react-surface.tsx → react-surface.ts} +6 -14
- package/src/components/{Chat/Chat.tsx → MessageThread/MessageThread.tsx} +20 -17
- package/src/components/{Chat → MessageThread}/index.ts +1 -1
- package/src/components/index.ts +1 -1
- package/src/containers/ChannelArticle/ChannelArticle.stories.tsx +4 -1
- package/src/containers/ChannelArticle/ChannelArticle.tsx +6 -4
- package/src/containers/ChannelCreatePanel/ChannelCreatePanel.tsx +4 -3
- package/src/containers/ThreadArticle/ThreadArticle.stories.tsx +4 -2
- package/src/containers/ThreadArticle/ThreadArticle.tsx +30 -18
- package/src/paths.ts +3 -3
- package/src/util.ts +21 -7
- package/dist/lib/neutral/ChannelArticle-CTYSCRTR.mjs +0 -122
- package/dist/lib/neutral/ChannelArticle-CTYSCRTR.mjs.map +0 -7
- package/dist/lib/neutral/ChannelCreatePanel-NUXXKHZQ.mjs +0 -38
- package/dist/lib/neutral/ChannelCreatePanel-NUXXKHZQ.mjs.map +0 -7
- package/dist/lib/neutral/ThreadArticle-ROQXQLEZ.mjs +0 -57
- package/dist/lib/neutral/ThreadArticle-ROQXQLEZ.mjs.map +0 -7
- package/dist/lib/neutral/ThreadPlugin.mjs.map +0 -7
- package/dist/lib/neutral/ThreadPlugin.node.mjs +0 -29
- package/dist/lib/neutral/ThreadPlugin.node.mjs.map +0 -7
- package/dist/lib/neutral/ThreadPlugin.workerd.mjs +0 -27
- package/dist/lib/neutral/ThreadPlugin.workerd.mjs.map +0 -7
- package/dist/lib/neutral/app-graph-builder-NZOWDFE5.mjs +0 -65
- package/dist/lib/neutral/app-graph-builder-NZOWDFE5.mjs.map +0 -7
- package/dist/lib/neutral/append-channel-message-YIIJY6GX.mjs +0 -34
- package/dist/lib/neutral/append-channel-message-YIIJY6GX.mjs.map +0 -7
- package/dist/lib/neutral/capabilities/index.mjs +0 -19
- package/dist/lib/neutral/capabilities/index.mjs.map +0 -7
- package/dist/lib/neutral/channel-backend-feed-TOS55NID.mjs +0 -57
- package/dist/lib/neutral/channel-backend-feed-TOS55NID.mjs.map +0 -7
- package/dist/lib/neutral/chunk-5VTDNDBV.mjs +0 -109
- package/dist/lib/neutral/chunk-5VTDNDBV.mjs.map +0 -7
- package/dist/lib/neutral/chunk-A5JYVGL2.mjs.map +0 -7
- package/dist/lib/neutral/chunk-GM3SGQMJ.mjs +0 -69
- package/dist/lib/neutral/chunk-GM3SGQMJ.mjs.map +0 -7
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs +0 -10
- package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +0 -7
- package/dist/lib/neutral/chunk-J7OTCRYF.mjs +0 -12
- package/dist/lib/neutral/chunk-J7OTCRYF.mjs.map +0 -7
- package/dist/lib/neutral/chunk-XPUQE4Y7.mjs +0 -8
- package/dist/lib/neutral/chunk-XPUQE4Y7.mjs.map +0 -7
- package/dist/lib/neutral/components/index.mjs +0 -96
- package/dist/lib/neutral/components/index.mjs.map +0 -7
- package/dist/lib/neutral/containers/index.mjs +0 -13
- package/dist/lib/neutral/containers/index.mjs.map +0 -7
- package/dist/lib/neutral/create-channel-4CA7P2M5.mjs +0 -41
- package/dist/lib/neutral/create-channel-4CA7P2M5.mjs.map +0 -7
- package/dist/lib/neutral/create-object-O3TZ2MCJ.mjs +0 -45
- package/dist/lib/neutral/create-object-O3TZ2MCJ.mjs.map +0 -7
- package/dist/lib/neutral/hooks/index.mjs +0 -11
- package/dist/lib/neutral/hooks/index.mjs.map +0 -7
- package/dist/lib/neutral/index.mjs +0 -34
- package/dist/lib/neutral/index.mjs.map +0 -7
- package/dist/lib/neutral/meta.json +0 -1
- package/dist/lib/neutral/meta.mjs +0 -10
- package/dist/lib/neutral/meta.mjs.map +0 -7
- package/dist/lib/neutral/navigation-resolver-LSTZL32O.mjs +0 -18
- package/dist/lib/neutral/navigation-resolver-LSTZL32O.mjs.map +0 -7
- package/dist/lib/neutral/operation-handler-RU6K2S4L.mjs +0 -13
- package/dist/lib/neutral/operation-handler-RU6K2S4L.mjs.map +0 -7
- package/dist/lib/neutral/operations/index.mjs +0 -8
- package/dist/lib/neutral/operations/index.mjs.map +0 -7
- package/dist/lib/neutral/plugin.mjs +0 -16
- package/dist/lib/neutral/plugin.mjs.map +0 -7
- package/dist/lib/neutral/react-surface-H2EKIMSK.mjs +0 -49
- package/dist/lib/neutral/react-surface-H2EKIMSK.mjs.map +0 -7
- package/dist/lib/neutral/translations.mjs +0 -91
- package/dist/lib/neutral/translations.mjs.map +0 -7
- package/dist/lib/neutral/types/index.mjs +0 -16
- package/dist/lib/neutral/types/index.mjs.map +0 -7
- package/dist/types/src/capabilities/navigation-resolver.d.ts +0 -5
- package/dist/types/src/capabilities/navigation-resolver.d.ts.map +0 -1
- package/dist/types/src/components/Chat/Chat.d.ts.map +0 -1
- package/dist/types/src/components/Chat/index.d.ts +0 -2
- package/dist/types/src/components/Chat/index.d.ts.map +0 -1
- package/src/capabilities/navigation-resolver.ts +0 -20
|
@@ -1,69 +1,29 @@
|
|
|
1
|
-
import "./chunk-J5LGTIGS.mjs";
|
|
2
|
-
|
|
3
|
-
// src/ThreadPlugin.tsx
|
|
4
1
|
import { ActivationEvents, Plugin } from "@dxos/app-framework";
|
|
5
|
-
import { AppPlugin } from "@dxos/app-toolkit";
|
|
6
|
-
import { ClientEvents } from "@dxos/plugin-client";
|
|
7
|
-
import { translations as threadTranslations } from "@dxos/react-ui-thread/translations";
|
|
8
|
-
import { Channel, Message, Thread } from "@dxos/types";
|
|
9
|
-
import { AppGraphBuilder, ChannelBackendFeed, CreateObject, NavigationResolver, OperationHandler, ReactSurface } from "#capabilities";
|
|
10
2
|
import { meta } from "#meta";
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
3
|
+
import { Channel, Message, Thread } from "@dxos/types";
|
|
4
|
+
import { AppPlugin } from "@dxos/app-toolkit";
|
|
5
|
+
import { translations } from "@dxos/react-ui-thread/translations";
|
|
6
|
+
import { AppGraphBuilder, ChannelBackendFeed, CreateObject, OperationHandler, ReactSurface } from "#capabilities";
|
|
7
|
+
import { translations as translations$1 } from "#translations";
|
|
8
|
+
//#region PLUGIN.mdl?raw
|
|
9
|
+
var PLUGIN_default = "---\nid: org.dxos.plugin.thread\nname: ThreadPlugin\nversion: 0.1.0\n---\n\nThreadPlugin provides chat: channels backed by an ECHO feed and free-standing message threads.\nIt renders the channel article + companion surfaces and a thread surface, and contributes the\noperations that create a channel and append messages. Shared message/thread UI comes from\n`@dxos/react-ui-thread`, and the `Channel`/`Message`/`Thread` schema comes from `@dxos/types`.\nDocument comments and the comment-thread AI agent live in `@dxos/plugin-comments`.\n\n## Extensions\n\nThe following extension dialects are used in this document.\n\n| Term | URI |\n|-------------|--------------------------------|\n| `type` | `org.dxos.mdl.type@1.0` |\n| `feat` | `org.dxos.mdl.feat@1.0` |\n| `op` | `org.dxos.mdl.op@1.0` |\n\n## Types\n\n```mdl\ntype Channel\n desc: |\n A chat channel. Defined in @dxos/types. Carries an optional `feed` Ref whose\n queue holds the channel's Message objects in order.\n```\n\n## Operations\n\n```mdl\nop OnCreateSpace\n key: org.dxos.plugin.thread.operation.onCreateSpace\n desc: On space creation, create a default \"General\" channel in the root collection.\n```\n\n```mdl\nop CreateChannel\n key: org.dxos.plugin.thread.operation.createChannel\n desc: Create a new Channel in the given space.\n in:\n spaceId: SpaceId\n name?: String\n out:\n object: Channel\n```\n\n```mdl\nop AppendChannelMessage\n key: org.dxos.plugin.thread.operation.appendChannelMessage\n desc: Append a Message authored by `sender` to the channel's feed.\n in:\n channel: Channel\n sender: Actor\n text: String\n```\n\n## Features\n\n```mdl\nfeat F-1: Channel chat\n req F-1.1: A Channel article MUST render its feed messages newest-last with a\n pinned composer; sending invokes AppendChannelMessage.\n req F-1.2: Externally-synced channels (those carrying foreign-key Obj.Meta) MUST\n render read-only — the composer is suppressed.\n```\n\n```mdl\nfeat F-2: Thread chat\n req F-2.1: A Thread article MUST render the thread's messages and append new\n messages by pushing onto `thread.messages`.\n```\n";
|
|
10
|
+
//#endregion
|
|
11
|
+
//#region src/ThreadPlugin.tsx
|
|
12
|
+
var ThreadPlugin = Plugin.define(meta).pipe(AppPlugin.addAppGraphModule({ activate: AppGraphBuilder }), AppPlugin.addCreateObjectModule({ activate: CreateObject }), AppPlugin.addOperationHandlerModule({ activate: OperationHandler }), AppPlugin.addSchemaModule({ schema: [
|
|
13
|
+
Channel.Channel,
|
|
14
|
+
Message.Message,
|
|
15
|
+
Thread.Thread
|
|
16
|
+
] }), AppPlugin.addSurfaceModule({ activate: ReactSurface }), AppPlugin.addTranslationsModule({ translations: [...translations$1, ...translations] }), Plugin.addModule({
|
|
17
|
+
id: "channel-backend-feed",
|
|
18
|
+
activatesOn: ActivationEvents.Startup,
|
|
19
|
+
activate: ChannelBackendFeed
|
|
20
|
+
}), AppPlugin.addPluginAssetModule({ asset: {
|
|
21
|
+
pluginId: meta.profile.key,
|
|
22
|
+
path: "PLUGIN.mdl",
|
|
23
|
+
content: PLUGIN_default,
|
|
24
|
+
mimeType: "application/x-mdl"
|
|
25
|
+
} }), Plugin.make);
|
|
26
|
+
//#endregion
|
|
27
|
+
export { ThreadPlugin, ThreadPlugin as default };
|
|
15
28
|
|
|
16
|
-
|
|
17
|
-
var ThreadPlugin = Plugin.define(meta).pipe(
|
|
18
|
-
AppPlugin.addAppGraphModule({
|
|
19
|
-
activate: AppGraphBuilder
|
|
20
|
-
}),
|
|
21
|
-
AppPlugin.addNavigationResolverModule({
|
|
22
|
-
activatesOn: ClientEvents.ClientReady,
|
|
23
|
-
activate: NavigationResolver
|
|
24
|
-
}),
|
|
25
|
-
AppPlugin.addCreateObjectModule({
|
|
26
|
-
activate: CreateObject
|
|
27
|
-
}),
|
|
28
|
-
AppPlugin.addOperationHandlerModule({
|
|
29
|
-
activate: OperationHandler
|
|
30
|
-
}),
|
|
31
|
-
AppPlugin.addSchemaModule({
|
|
32
|
-
schema: [
|
|
33
|
-
Channel.Channel,
|
|
34
|
-
Message.Message,
|
|
35
|
-
Thread.Thread
|
|
36
|
-
]
|
|
37
|
-
}),
|
|
38
|
-
AppPlugin.addSurfaceModule({
|
|
39
|
-
activate: ReactSurface
|
|
40
|
-
}),
|
|
41
|
-
AppPlugin.addTranslationsModule({
|
|
42
|
-
translations: [
|
|
43
|
-
...translations,
|
|
44
|
-
...threadTranslations
|
|
45
|
-
]
|
|
46
|
-
}),
|
|
47
|
-
// Default local-feed channel backend. Other plugins contribute additional
|
|
48
|
-
// `ChannelBackend` providers (e.g. ATProto) earlier in plugin order.
|
|
49
|
-
Plugin.addModule({
|
|
50
|
-
id: "channel-backend-feed",
|
|
51
|
-
activatesOn: ActivationEvents.Startup,
|
|
52
|
-
activate: ChannelBackendFeed
|
|
53
|
-
}),
|
|
54
|
-
AppPlugin.addPluginAssetModule({
|
|
55
|
-
asset: {
|
|
56
|
-
pluginId: meta.profile.key,
|
|
57
|
-
path: "PLUGIN.mdl",
|
|
58
|
-
content: PLUGIN_default,
|
|
59
|
-
mimeType: "application/x-mdl"
|
|
60
|
-
}
|
|
61
|
-
}),
|
|
62
|
-
Plugin.make
|
|
63
|
-
);
|
|
64
|
-
var ThreadPlugin_default = ThreadPlugin;
|
|
65
|
-
export {
|
|
66
|
-
ThreadPlugin,
|
|
67
|
-
ThreadPlugin_default as default
|
|
68
|
-
};
|
|
69
|
-
//# sourceMappingURL=ThreadPlugin.mjs.map
|
|
29
|
+
//# sourceMappingURL=ThreadPlugin.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadPlugin.mjs","names":[],"sources":["../../src/ThreadPlugin.tsx"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport { ActivationEvents, Plugin } from '@dxos/app-framework';\nimport { AppPlugin } from '@dxos/app-toolkit';\nimport { translations as threadTranslations } from '@dxos/react-ui-thread/translations';\nimport { Channel, Message, Thread } from '@dxos/types';\n\nimport { AppGraphBuilder, ChannelBackendFeed, CreateObject, OperationHandler, ReactSurface } from '#capabilities';\nimport { meta } from '#meta';\nimport { translations } from '#translations';\n\n// eslint-disable-next-line import/no-relative-packages\nimport pluginSpec from '../PLUGIN.mdl?raw';\n\n// TODO(wittjosiah): Rename to ChatPlugin.\n\nexport const ThreadPlugin = Plugin.define(meta).pipe(\n AppPlugin.addAppGraphModule({ activate: AppGraphBuilder }),\n AppPlugin.addCreateObjectModule({ activate: CreateObject }),\n AppPlugin.addOperationHandlerModule({ activate: OperationHandler }),\n AppPlugin.addSchemaModule({\n schema: [Channel.Channel, Message.Message, Thread.Thread],\n }),\n AppPlugin.addSurfaceModule({ activate: ReactSurface }),\n AppPlugin.addTranslationsModule({ translations: [...translations, ...threadTranslations] }),\n // Default local-feed channel backend. Other plugins contribute additional\n // `ChannelBackend` providers (e.g. ATProto) earlier in plugin order.\n Plugin.addModule({\n id: 'channel-backend-feed',\n activatesOn: ActivationEvents.Startup,\n activate: ChannelBackendFeed,\n }),\n AppPlugin.addPluginAssetModule({\n asset: { pluginId: meta.profile.key, path: 'PLUGIN.mdl', content: pluginSpec, mimeType: 'application/x-mdl' },\n }),\n Plugin.make,\n);\n\nexport default ThreadPlugin;\n"],"mappings":";;;;;;;;;;;AAkBA,IAAa,eAAe,OAAO,OAAO,IAAI,CAAC,CAAC,KAC9C,UAAU,kBAAkB,EAAE,UAAU,gBAAgB,CAAC,GACzD,UAAU,sBAAsB,EAAE,UAAU,aAAa,CAAC,GAC1D,UAAU,0BAA0B,EAAE,UAAU,iBAAiB,CAAC,GAClE,UAAU,gBAAgB,EACxB,QAAQ;CAAC,QAAQ;CAAS,QAAQ;CAAS,OAAO;AAAM,EAC1D,CAAC,GACD,UAAU,iBAAiB,EAAE,UAAU,aAAa,CAAC,GACrD,UAAU,sBAAsB,EAAE,cAAc,CAAC,GAAG,gBAAc,GAAG,YAAkB,EAAE,CAAC,GAG1F,OAAO,UAAU;CACf,IAAI;CACJ,aAAa,iBAAiB;CAC9B,UAAU;AACZ,CAAC,GACD,UAAU,qBAAqB,EAC7B,OAAO;CAAE,UAAU,KAAK,QAAQ;CAAK,MAAM;CAAc,SAAS;CAAY,UAAU;AAAoB,EAC9G,CAAC,GACD,OAAO,IACT"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ActivationEvents, Plugin } from "@dxos/app-framework";
|
|
2
|
+
import { meta } from "#meta";
|
|
3
|
+
import { Channel, Message, Thread } from "@dxos/types";
|
|
4
|
+
import { AppPlugin } from "@dxos/app-toolkit";
|
|
5
|
+
import { ChannelBackendFeed, OperationHandler } from "#capabilities";
|
|
6
|
+
//#region src/ThreadPlugin.node.ts
|
|
7
|
+
var ThreadPlugin = Plugin.define(meta).pipe(AppPlugin.addOperationHandlerModule({ activate: OperationHandler }), AppPlugin.addSchemaModule({ schema: [
|
|
8
|
+
Channel.Channel,
|
|
9
|
+
Message.Message,
|
|
10
|
+
Thread.Thread
|
|
11
|
+
] }), Plugin.addModule({
|
|
12
|
+
id: "channel-backend-feed",
|
|
13
|
+
activatesOn: ActivationEvents.Startup,
|
|
14
|
+
activate: ChannelBackendFeed
|
|
15
|
+
}), Plugin.make);
|
|
16
|
+
//#endregion
|
|
17
|
+
export { ThreadPlugin, ThreadPlugin as default };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=ThreadPlugin.node.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadPlugin.node.mjs","names":[],"sources":["../../src/ThreadPlugin.node.ts"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport { ActivationEvents, Plugin } from '@dxos/app-framework';\nimport { AppPlugin } from '@dxos/app-toolkit';\nimport { Channel, Message, Thread } from '@dxos/types';\n\nimport { ChannelBackendFeed, OperationHandler } from '#capabilities';\nimport { meta } from '#meta';\n\nexport const ThreadPlugin = Plugin.define(meta).pipe(\n AppPlugin.addOperationHandlerModule({ activate: OperationHandler }),\n AppPlugin.addSchemaModule({\n schema: [Channel.Channel, Message.Message, Thread.Thread],\n }),\n Plugin.addModule({\n id: 'channel-backend-feed',\n activatesOn: ActivationEvents.Startup,\n activate: ChannelBackendFeed,\n }),\n Plugin.make,\n);\n\nexport default ThreadPlugin;\n"],"mappings":";;;;;;AAWA,IAAa,eAAe,OAAO,OAAO,IAAI,CAAC,CAAC,KAC9C,UAAU,0BAA0B,EAAE,UAAU,iBAAiB,CAAC,GAClE,UAAU,gBAAgB,EACxB,QAAQ;CAAC,QAAQ;CAAS,QAAQ;CAAS,OAAO;AAAM,EAC1D,CAAC,GACD,OAAO,UAAU;CACf,IAAI;CACJ,aAAa,iBAAiB;CAC9B,UAAU;AACZ,CAAC,GACD,OAAO,IACT"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ActivationEvents, Plugin } from "@dxos/app-framework";
|
|
2
|
+
import { meta } from "#meta";
|
|
3
|
+
import { Channel, Message, Thread } from "@dxos/types";
|
|
4
|
+
import { AppPlugin } from "@dxos/app-toolkit";
|
|
5
|
+
import { ChannelBackendFeed, OperationHandler } from "#capabilities";
|
|
6
|
+
//#region src/ThreadPlugin.workerd.ts
|
|
7
|
+
var ThreadPlugin = Plugin.define(meta).pipe(AppPlugin.addOperationHandlerModule({ activate: OperationHandler }), AppPlugin.addSchemaModule({ schema: [
|
|
8
|
+
Channel.Channel,
|
|
9
|
+
Message.Message,
|
|
10
|
+
Thread.Thread
|
|
11
|
+
] }), Plugin.addModule({
|
|
12
|
+
id: "channel-backend-feed",
|
|
13
|
+
activatesOn: ActivationEvents.Startup,
|
|
14
|
+
activate: ChannelBackendFeed
|
|
15
|
+
}), Plugin.make);
|
|
16
|
+
//#endregion
|
|
17
|
+
export { ThreadPlugin, ThreadPlugin as default };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=ThreadPlugin.workerd.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThreadPlugin.workerd.mjs","names":[],"sources":["../../src/ThreadPlugin.workerd.ts"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport { ActivationEvents, Plugin } from '@dxos/app-framework';\nimport { AppPlugin } from '@dxos/app-toolkit';\nimport { Channel, Message, Thread } from '@dxos/types';\n\nimport { ChannelBackendFeed, OperationHandler } from '#capabilities';\nimport { meta } from '#meta';\n\nexport const ThreadPlugin = Plugin.define(meta).pipe(\n AppPlugin.addOperationHandlerModule({ activate: OperationHandler }),\n AppPlugin.addSchemaModule({\n schema: [Channel.Channel, Message.Message, Thread.Thread],\n }),\n Plugin.addModule({\n id: 'channel-backend-feed',\n activatesOn: ActivationEvents.Startup,\n activate: ChannelBackendFeed,\n }),\n Plugin.make,\n);\n\nexport default ThreadPlugin;\n"],"mappings":";;;;;;AAWA,IAAa,eAAe,OAAO,OAAO,IAAI,CAAC,CAAC,KAC9C,UAAU,0BAA0B,EAAE,UAAU,iBAAiB,CAAC,GAClE,UAAU,gBAAgB,EACxB,QAAQ;CAAC,QAAQ;CAAS,QAAQ;CAAS,OAAO;AAAM,EAC1D,CAAC,GACD,OAAO,UAAU;CACf,IAAI;CACJ,aAAa,iBAAiB;CAC9B,UAAU;AACZ,CAAC,GACD,OAAO,IACT"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Capability } from "@dxos/app-framework";
|
|
2
|
+
//#region src/capabilities/node.ts
|
|
3
|
+
var ChannelBackendFeed = Capability.lazy("ChannelBackendFeed", () => import("../chunk-channel-backend-feed.mjs"));
|
|
4
|
+
var OperationHandler = Capability.lazy("OperationHandler", () => import("../chunk-operation-handler.mjs"));
|
|
5
|
+
//#endregion
|
|
6
|
+
export { ChannelBackendFeed, OperationHandler };
|
|
7
|
+
|
|
8
|
+
//# sourceMappingURL=node.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.mjs","names":[],"sources":["../../../src/capabilities/node.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport { Capability } from '@dxos/app-framework';\nimport type { OperationHandlerSet } from '@dxos/compute';\n\n// The capabilities `ThreadPlugin.node` activates, and only those. `Capability.lazy` defers the\n// import at runtime but a bundler still walks it, so listing the React surfaces here would pull\n// the plugin's components into every node and bun build. `CreateObject` is omitted: its\n// `CreateObjectEntry` carries a `customPanel` React component alongside the object factory.\n// TODO(wittjosiah): Split the panel out of the entry so node can contribute the factory.\n\nexport const ChannelBackendFeed = Capability.lazy('ChannelBackendFeed', () => import('./channel-backend-feed'));\nexport const OperationHandler = Capability.lazy<OperationHandlerSet.OperationHandlerSet>(\n 'OperationHandler',\n () => import('./operation-handler'),\n);\n"],"mappings":";;AAaA,IAAa,qBAAqB,WAAW,KAAK,4BAA4B,OAAO,oCAAyB;AAC9G,IAAa,mBAAmB,WAAW,KACzC,0BACM,OAAO,iCACf"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Capability } from "@dxos/app-framework";
|
|
2
|
+
//#region src/capabilities/index.ts
|
|
3
|
+
var AppGraphBuilder = Capability.lazy("AppGraphBuilder", () => import("./chunk-app-graph-builder.mjs"));
|
|
4
|
+
var ChannelBackendFeed = Capability.lazy("ChannelBackendFeed", () => import("./chunk-channel-backend-feed.mjs"));
|
|
5
|
+
var CreateObject = Capability.lazy("CreateObject", () => import("./chunk-create-object.mjs"));
|
|
6
|
+
var OperationHandler = Capability.lazy("OperationHandler", () => import("./chunk-operation-handler.mjs"));
|
|
7
|
+
var ReactSurface = Capability.lazy("ReactSurface", () => import("./chunk-react-surface.mjs"));
|
|
8
|
+
//#endregion
|
|
9
|
+
export { AppGraphBuilder, ChannelBackendFeed, CreateObject, OperationHandler, ReactSurface };
|
|
10
|
+
|
|
11
|
+
//# sourceMappingURL=capabilities.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.mjs","names":[],"sources":["../../src/capabilities/index.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Capability } from '@dxos/app-framework';\nimport type { OperationHandlerSet } from '@dxos/compute';\n\nexport const AppGraphBuilder = Capability.lazy('AppGraphBuilder', () => import('./app-graph-builder'));\nexport const ChannelBackendFeed = Capability.lazy('ChannelBackendFeed', () => import('./channel-backend-feed'));\nexport const CreateObject = Capability.lazy('CreateObject', () => import('./create-object'));\nexport const OperationHandler = Capability.lazy<OperationHandlerSet.OperationHandlerSet>(\n 'OperationHandler',\n () => import('./operation-handler'),\n);\nexport const ReactSurface = Capability.lazy('ReactSurface', () => import('./react-surface'));\n"],"mappings":";;AAOA,IAAa,kBAAkB,WAAW,KAAK,yBAAyB,OAAO,gCAAsB;AACrG,IAAa,qBAAqB,WAAW,KAAK,4BAA4B,OAAO,mCAAyB;AAC9G,IAAa,eAAe,WAAW,KAAK,sBAAsB,OAAO,4BAAkB;AAC3F,IAAa,mBAAmB,WAAW,KACzC,0BACM,OAAO,gCACf;AACA,IAAa,eAAe,WAAW,KAAK,sBAAsB,OAAO,4BAAkB"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { Surface, useCapabilities, useOperationInvoker } from "@dxos/app-framework/ui";
|
|
3
|
+
import { meta } from "#meta";
|
|
4
|
+
import { Obj } from "@dxos/echo";
|
|
5
|
+
import { AppSurface } from "@dxos/app-toolkit/ui";
|
|
6
|
+
import { Panel } from "@dxos/react-ui";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
import { CallsCapabilities } from "@dxos/plugin-calls/types";
|
|
9
|
+
import { Atom, useAtomValue } from "@effect-atom/atom-react";
|
|
10
|
+
import { useIdentity, useMembers } from "@dxos/halo-react";
|
|
11
|
+
import { getSpace } from "@dxos/react-client/echo";
|
|
12
|
+
import { Menu, MenuBuilder, useMenuBuilder } from "@dxos/react-ui-menu";
|
|
13
|
+
import { MessageThread } from "#components";
|
|
14
|
+
import { useMessages, useStatus } from "#hooks";
|
|
15
|
+
import { ThreadCapabilities, ThreadOperation, resolveProvider } from "#types";
|
|
16
|
+
//#region src/containers/ChannelArticle/ChannelArticle.tsx
|
|
17
|
+
var NOT_JOINED = Atom.make(false);
|
|
18
|
+
var NO_ROOM = Atom.make(void 0);
|
|
19
|
+
/**
|
|
20
|
+
* Channel article: renders the channel chat inside a document panel. Messages
|
|
21
|
+
* are read and written through the channel's backend provider (resolved by
|
|
22
|
+
* `channel.backend.kind`), so the container is agnostic to where messages are
|
|
23
|
+
* stored. Read-only state defaults to the provider's policy, or to "channel
|
|
24
|
+
* carries foreign-key `Obj.Meta`" when the provider has none. When plugin-calls is present, a
|
|
25
|
+
* "Start video call" action switches the article to the call surface and the chat moves to a companion.
|
|
26
|
+
*/
|
|
27
|
+
var ChannelArticle = ({ role, subject: channel, attendableId, chatOnly }) => {
|
|
28
|
+
const identity = useIdentity();
|
|
29
|
+
const space = channel ? getSpace(channel) : void 0;
|
|
30
|
+
const members = useMembers(space?.id);
|
|
31
|
+
const id = channel ? Obj.getURI(channel) : void 0;
|
|
32
|
+
const activity = useStatus(space, id);
|
|
33
|
+
const { invokePromise } = useOperationInvoker();
|
|
34
|
+
const providers = useCapabilities(ThreadCapabilities.ChannelBackend);
|
|
35
|
+
const provider = channel ? resolveProvider(providers, channel.backend.kind) : void 0;
|
|
36
|
+
const messages = useMessages(channel);
|
|
37
|
+
const readOnly = channel ? provider?.readOnly?.(channel) ?? Obj.getMeta(channel).keys.length > 0 : false;
|
|
38
|
+
const callProvider = useCapabilities(CallsCapabilities.CallTransportProvider)[0];
|
|
39
|
+
const callManager = useCapabilities(CallsCapabilities.Manager)[0];
|
|
40
|
+
const joined = useAtomValue(callManager?.joinedAtom ?? NOT_JOINED);
|
|
41
|
+
const currentRoomId = useAtomValue(callManager?.roomIdAtom ?? NO_ROOM);
|
|
42
|
+
const inThisCall = !!id && joined && currentRoomId === id;
|
|
43
|
+
const showCall = inThisCall && !chatOnly;
|
|
44
|
+
const canStartCall = !!callProvider && !inThisCall;
|
|
45
|
+
const handleStartCall = useCallback(async () => {
|
|
46
|
+
if (!callProvider || !id) return;
|
|
47
|
+
await callProvider.join(id);
|
|
48
|
+
}, [callProvider, id]);
|
|
49
|
+
const menuActions = useMenuBuilder(() => {
|
|
50
|
+
const builder = MenuBuilder.make().root({ label: ["channel-toolbar.title", { ns: meta.profile.key }] });
|
|
51
|
+
if (canStartCall) builder.action("start-video-call", {
|
|
52
|
+
label: ["start-video-call.menu", { ns: meta.profile.key }],
|
|
53
|
+
icon: "ph--video-camera--regular"
|
|
54
|
+
}, () => {
|
|
55
|
+
handleStartCall();
|
|
56
|
+
});
|
|
57
|
+
return builder.build();
|
|
58
|
+
}, [canStartCall, handleStartCall]);
|
|
59
|
+
const handleSend = (text) => {
|
|
60
|
+
if (!channel || !identity || readOnly) return false;
|
|
61
|
+
invokePromise(ThreadOperation.AppendChannelMessage, {
|
|
62
|
+
channel,
|
|
63
|
+
sender: { identityDid: identity.did },
|
|
64
|
+
text
|
|
65
|
+
});
|
|
66
|
+
return true;
|
|
67
|
+
};
|
|
68
|
+
if (!space || !channel || !id) return null;
|
|
69
|
+
return /* @__PURE__ */ jsxs(Panel.Root, {
|
|
70
|
+
role,
|
|
71
|
+
children: [canStartCall && /* @__PURE__ */ jsx(Menu.Root, {
|
|
72
|
+
...menuActions,
|
|
73
|
+
attendableId,
|
|
74
|
+
children: /* @__PURE__ */ jsx(Panel.Toolbar, {
|
|
75
|
+
asChild: true,
|
|
76
|
+
children: /* @__PURE__ */ jsx(Menu.Toolbar, {})
|
|
77
|
+
})
|
|
78
|
+
}), showCall ? /* @__PURE__ */ jsx(Panel.Content, { children: /* @__PURE__ */ jsx(Surface.Surface, {
|
|
79
|
+
type: AppSurface.Article,
|
|
80
|
+
data: {
|
|
81
|
+
subject: { roomId: id },
|
|
82
|
+
attendableId
|
|
83
|
+
},
|
|
84
|
+
limit: 1
|
|
85
|
+
}) }) : /* @__PURE__ */ jsx(Panel.Content, {
|
|
86
|
+
asChild: true,
|
|
87
|
+
children: /* @__PURE__ */ jsx(MessageThread, {
|
|
88
|
+
id,
|
|
89
|
+
classNames: "dx-document",
|
|
90
|
+
identity: identity ?? void 0,
|
|
91
|
+
members,
|
|
92
|
+
messages,
|
|
93
|
+
activity,
|
|
94
|
+
onSend: handleSend,
|
|
95
|
+
readOnly
|
|
96
|
+
})
|
|
97
|
+
})]
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
ChannelArticle.displayName = "ChannelArticle";
|
|
101
|
+
//#endregion
|
|
102
|
+
export { ChannelArticle as default };
|
|
103
|
+
|
|
104
|
+
//# sourceMappingURL=chunk-ChannelArticle.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk-ChannelArticle.mjs","names":[],"sources":["../../src/containers/ChannelArticle/ChannelArticle.tsx"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Atom, useAtomValue } from '@effect-atom/atom-react';\nimport React, { useCallback } from 'react';\n\nimport { Surface, useCapabilities, useOperationInvoker } from '@dxos/app-framework/ui';\nimport { AppSurface } from '@dxos/app-toolkit/ui';\nimport { Obj } from '@dxos/echo';\nimport { useIdentity, useMembers } from '@dxos/halo-react';\nimport { CallsCapabilities } from '@dxos/plugin-calls/types';\nimport { getSpace } from '@dxos/react-client/echo';\nimport { Panel } from '@dxos/react-ui';\nimport { Menu, MenuBuilder, useMenuBuilder } from '@dxos/react-ui-menu';\nimport { type Channel } from '@dxos/types';\n\nimport { MessageThread } from '#components';\nimport { useMessages, useStatus } from '#hooks';\nimport { meta } from '#meta';\nimport { ThreadCapabilities, ThreadOperation, resolveProvider } from '#types';\n\n// Stable fallbacks so `useAtomValue` always receives an atom when plugin-calls isn't present.\nconst NOT_JOINED = Atom.make(false);\nconst NO_ROOM = Atom.make<string | undefined>(undefined);\n\nexport type ChannelArticleProps = AppSurface.ObjectArticleProps<\n Channel.Channel | undefined,\n {\n roomId?: string;\n fullscreen?: boolean;\n /** Always render the chat, even while in this channel's call (used by the in-call chat companion). */\n chatOnly?: boolean;\n }\n>;\n\n/**\n * Channel article: renders the channel chat inside a document panel. Messages\n * are read and written through the channel's backend provider (resolved by\n * `channel.backend.kind`), so the container is agnostic to where messages are\n * stored. Read-only state defaults to the provider's policy, or to \"channel\n * carries foreign-key `Obj.Meta`\" when the provider has none. When plugin-calls is present, a\n * \"Start video call\" action switches the article to the call surface and the chat moves to a companion.\n */\nexport const ChannelArticle = ({ role, subject: channel, attendableId, chatOnly }: ChannelArticleProps) => {\n const identity = useIdentity();\n const space = channel ? getSpace(channel) : undefined;\n const members = useMembers(space?.id);\n const id = channel ? Obj.getURI(channel) : undefined;\n const activity = useStatus(space, id);\n const { invokePromise } = useOperationInvoker();\n\n const providers = useCapabilities(ThreadCapabilities.ChannelBackend);\n const provider = channel ? resolveProvider(providers, channel.backend.kind) : undefined;\n const messages = useMessages(channel);\n const readOnly = channel ? (provider?.readOnly?.(channel) ?? Obj.getMeta(channel).keys.length > 0) : false;\n\n const callProvider = useCapabilities(CallsCapabilities.CallTransportProvider)[0];\n const callManager = useCapabilities(CallsCapabilities.Manager)[0];\n const joined = useAtomValue(callManager?.joinedAtom ?? NOT_JOINED);\n const currentRoomId = useAtomValue(callManager?.roomIdAtom ?? NO_ROOM);\n // `chatOnly` (the in-call chat companion) keeps showing messages so the call lives only in the primary.\n const inThisCall = !!id && joined && currentRoomId === id;\n const showCall = inThisCall && !chatOnly;\n const canStartCall = !!callProvider && !inThisCall;\n\n const handleStartCall = useCallback(async () => {\n if (!callProvider || !id) {\n return;\n }\n await callProvider.join(id);\n }, [callProvider, id]);\n\n const menuActions = useMenuBuilder(() => {\n const builder = MenuBuilder.make().root({ label: ['channel-toolbar.title', { ns: meta.profile.key }] });\n if (canStartCall) {\n builder.action(\n 'start-video-call',\n { label: ['start-video-call.menu', { ns: meta.profile.key }], icon: 'ph--video-camera--regular' },\n () => {\n void handleStartCall();\n },\n );\n }\n return builder.build();\n }, [canStartCall, handleStartCall]);\n\n const handleSend = (text: string) => {\n if (!channel || !identity || readOnly) {\n return false;\n }\n\n void invokePromise(ThreadOperation.AppendChannelMessage, {\n channel,\n sender: { identityDid: identity.did },\n text,\n });\n\n return true;\n };\n\n if (!space || !channel || !id) {\n return null;\n }\n\n return (\n <Panel.Root role={role}>\n {canStartCall && (\n <Menu.Root {...menuActions} attendableId={attendableId}>\n <Panel.Toolbar asChild>\n <Menu.Toolbar />\n </Panel.Toolbar>\n </Menu.Root>\n )}\n {showCall ? (\n <Panel.Content>\n <Surface.Surface type={AppSurface.Article} data={{ subject: { roomId: id }, attendableId }} limit={1} />\n </Panel.Content>\n ) : (\n <Panel.Content asChild>\n <MessageThread\n id={id}\n classNames='dx-document'\n identity={identity ?? undefined}\n members={members}\n messages={messages}\n activity={activity}\n onSend={handleSend}\n readOnly={readOnly}\n />\n </Panel.Content>\n )}\n </Panel.Root>\n );\n};\n\nChannelArticle.displayName = 'ChannelArticle';\n"],"mappings":";;;;;;;;;;;;;;;;AAuBA,IAAM,aAAa,KAAK,KAAK,KAAK;AAClC,IAAM,UAAU,KAAK,KAAyB,KAAA,CAAS;;;;;;;;;AAoBvD,IAAa,kBAAkB,EAAE,MAAM,SAAS,SAAS,cAAc,eAAoC;CACzG,MAAM,WAAW,YAAY;CAC7B,MAAM,QAAQ,UAAU,SAAS,OAAO,IAAI,KAAA;CAC5C,MAAM,UAAU,WAAW,OAAO,EAAE;CACpC,MAAM,KAAK,UAAU,IAAI,OAAO,OAAO,IAAI,KAAA;CAC3C,MAAM,WAAW,UAAU,OAAO,EAAE;CACpC,MAAM,EAAE,kBAAkB,oBAAoB;CAE9C,MAAM,YAAY,gBAAgB,mBAAmB,cAAc;CACnE,MAAM,WAAW,UAAU,gBAAgB,WAAW,QAAQ,QAAQ,IAAI,IAAI,KAAA;CAC9E,MAAM,WAAW,YAAY,OAAO;CACpC,MAAM,WAAW,UAAW,UAAU,WAAW,OAAO,KAAK,IAAI,QAAQ,OAAO,CAAC,CAAC,KAAK,SAAS,IAAK;CAErG,MAAM,eAAe,gBAAgB,kBAAkB,qBAAqB,CAAC,CAAC;CAC9E,MAAM,cAAc,gBAAgB,kBAAkB,OAAO,CAAC,CAAC;CAC/D,MAAM,SAAS,aAAa,aAAa,cAAc,UAAU;CACjE,MAAM,gBAAgB,aAAa,aAAa,cAAc,OAAO;CAErE,MAAM,aAAa,CAAC,CAAC,MAAM,UAAU,kBAAkB;CACvD,MAAM,WAAW,cAAc,CAAC;CAChC,MAAM,eAAe,CAAC,CAAC,gBAAgB,CAAC;CAExC,MAAM,kBAAkB,YAAY,YAAY;EAC9C,IAAI,CAAC,gBAAgB,CAAC,IACpB;EAEF,MAAM,aAAa,KAAK,EAAE;CAC5B,GAAG,CAAC,cAAc,EAAE,CAAC;CAErB,MAAM,cAAc,qBAAqB;EACvC,MAAM,UAAU,YAAY,KAAK,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,yBAAyB,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC,EAAE,CAAC;EACtG,IAAI,cACF,QAAQ,OACN,oBACA;GAAE,OAAO,CAAC,yBAAyB,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC;GAAG,MAAM;EAA4B,SAC1F;GACJ,gBAAqB;EACvB,CACF;EAEF,OAAO,QAAQ,MAAM;CACvB,GAAG,CAAC,cAAc,eAAe,CAAC;CAElC,MAAM,cAAc,SAAiB;EACnC,IAAI,CAAC,WAAW,CAAC,YAAY,UAC3B,OAAO;EAGT,cAAmB,gBAAgB,sBAAsB;GACvD;GACA,QAAQ,EAAE,aAAa,SAAS,IAAI;GACpC;EACF,CAAC;EAED,OAAO;CACT;CAEA,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IACzB,OAAO;CAGT,OACE,qBAAC,MAAM,MAAP;EAAkB;YAAlB,CACG,gBACC,oBAAC,KAAK,MAAN;GAAW,GAAI;GAA2B;aACxC,oBAAC,MAAM,SAAP;IAAe,SAAA;cACb,oBAAC,KAAK,SAAN,CAAe,CAAA;GACF,CAAA;EACN,CAAA,GAEZ,WACC,oBAAC,MAAM,SAAP,EAAA,UACE,oBAAC,QAAQ,SAAT;GAAiB,MAAM,WAAW;GAAS,MAAM;IAAE,SAAS,EAAE,QAAQ,GAAG;IAAG;GAAa;GAAG,OAAO;EAAI,CAAA,EAC1F,CAAA,IAEf,oBAAC,MAAM,SAAP;GAAe,SAAA;aACb,oBAAC,eAAD;IACM;IACJ,YAAW;IACX,UAAU,YAAY,KAAA;IACb;IACC;IACA;IACV,QAAQ;IACE;GACX,CAAA;EACY,CAAA,CAEP;;AAEhB;AAEA,eAAe,cAAc"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useCallback, useMemo } from "react";
|
|
2
|
+
import { useCapabilities } from "@dxos/app-framework/ui";
|
|
3
|
+
import { Obj } from "@dxos/echo";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { ThreadCapabilities, buildChannelFormSchema } from "#types";
|
|
6
|
+
import { Form } from "@dxos/react-ui-form";
|
|
7
|
+
//#region src/containers/ChannelCreatePanel/ChannelCreatePanel.tsx
|
|
8
|
+
/**
|
|
9
|
+
* Provider-driven create panel for channels. Reads the registered
|
|
10
|
+
* `ChannelBackend` providers and renders a react-ui-form whose schema is the
|
|
11
|
+
* assembled `{ name?, backend: Union(...) }` — a backend selector plus the
|
|
12
|
+
* selected provider's create fields (just a name field when there is a single
|
|
13
|
+
* field-less provider).
|
|
14
|
+
*/
|
|
15
|
+
var ChannelCreatePanel = ({ target, onCreateObject }) => {
|
|
16
|
+
const providers = useCapabilities(ThreadCapabilities.ChannelBackend);
|
|
17
|
+
const schema = useMemo(() => buildChannelFormSchema(providers), [providers]);
|
|
18
|
+
const handleSave = useCallback((values) => {
|
|
19
|
+
const { name, backend } = values;
|
|
20
|
+
const { kind, ...options } = backend ?? {};
|
|
21
|
+
onCreateObject({
|
|
22
|
+
name,
|
|
23
|
+
kind,
|
|
24
|
+
options
|
|
25
|
+
});
|
|
26
|
+
}, [onCreateObject]);
|
|
27
|
+
return /* @__PURE__ */ jsx(Form.Root, {
|
|
28
|
+
autoFocus: true,
|
|
29
|
+
db: Obj.isObject(target) ? Obj.getDatabase(target) : target,
|
|
30
|
+
schema,
|
|
31
|
+
defaultValues: {},
|
|
32
|
+
onSave: handleSave,
|
|
33
|
+
testId: "create-channel-form",
|
|
34
|
+
children: /* @__PURE__ */ jsx(Form.Viewport, { children: /* @__PURE__ */ jsxs(Form.Content, { children: [/* @__PURE__ */ jsx(Form.FieldSet, {}), /* @__PURE__ */ jsx(Form.Submit, {})] }) })
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
ChannelCreatePanel.displayName = "ChannelCreatePanel";
|
|
38
|
+
//#endregion
|
|
39
|
+
export { ChannelCreatePanel as default };
|
|
40
|
+
|
|
41
|
+
//# sourceMappingURL=chunk-ChannelCreatePanel.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk-ChannelCreatePanel.mjs","names":[],"sources":["../../src/containers/ChannelCreatePanel/ChannelCreatePanel.tsx"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport React, { useCallback, useMemo } from 'react';\n\nimport { useCapabilities } from '@dxos/app-framework/ui';\nimport { Obj } from '@dxos/echo';\nimport { type SpaceCapabilities } from '@dxos/plugin-space';\nimport { Form } from '@dxos/react-ui-form';\n\nimport { ThreadCapabilities, buildChannelFormSchema } from '#types';\n\n/**\n * Provider-driven create panel for channels. Reads the registered\n * `ChannelBackend` providers and renders a react-ui-form whose schema is the\n * assembled `{ name?, backend: Union(...) }` — a backend selector plus the\n * selected provider's create fields (just a name field when there is a single\n * field-less provider).\n */\nexport const ChannelCreatePanel = ({ target, onCreateObject }: SpaceCapabilities.CreateObjectCustomPanelProps) => {\n const providers = useCapabilities(ThreadCapabilities.ChannelBackend);\n const schema = useMemo(() => buildChannelFormSchema(providers), [providers]);\n\n const handleSave = useCallback(\n (values: { name?: string; backend?: { kind: string } & Record<string, unknown> }) => {\n const { name, backend } = values;\n const { kind, ...options } = backend ?? {};\n void onCreateObject({ name, kind, options });\n },\n [onCreateObject],\n );\n\n return (\n <Form.Root\n autoFocus\n db={Obj.isObject(target) ? Obj.getDatabase(target) : target}\n schema={schema}\n defaultValues={{}}\n onSave={handleSave}\n testId='create-channel-form'\n >\n <Form.Viewport>\n <Form.Content>\n <Form.FieldSet />\n <Form.Submit />\n </Form.Content>\n </Form.Viewport>\n </Form.Root>\n );\n};\n\nChannelCreatePanel.displayName = 'ChannelCreatePanel';\n"],"mappings":";;;;;;;;;;;;;;AAoBA,IAAa,sBAAsB,EAAE,QAAQ,qBAAqE;CAChH,MAAM,YAAY,gBAAgB,mBAAmB,cAAc;CACnE,MAAM,SAAS,cAAc,uBAAuB,SAAS,GAAG,CAAC,SAAS,CAAC;CAE3E,MAAM,aAAa,aAChB,WAAoF;EACnF,MAAM,EAAE,MAAM,YAAY;EAC1B,MAAM,EAAE,MAAM,GAAG,YAAY,WAAW,CAAC;EACzC,eAAoB;GAAE;GAAM;GAAM;EAAQ,CAAC;CAC7C,GACA,CAAC,cAAc,CACjB;CAEA,OACE,oBAAC,KAAK,MAAN;EACE,WAAA;EACA,IAAI,IAAI,SAAS,MAAM,IAAI,IAAI,YAAY,MAAM,IAAI;EAC7C;EACR,eAAe,CAAC;EAChB,QAAQ;EACR,QAAO;YAEP,oBAAC,KAAK,UAAN,EAAA,UACE,qBAAC,KAAK,SAAN,EAAA,UAAA,CACE,oBAAC,KAAK,UAAN,CAAgB,CAAA,GAChB,oBAAC,KAAK,QAAN,CAAc,CAAA,CACF,EAAA,CAAA,EACD,CAAA;CACN,CAAA;AAEf;AAEA,mBAAmB,cAAc"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { Obj, Ref } from "@dxos/echo";
|
|
3
|
+
import { Message } from "@dxos/types";
|
|
4
|
+
import { isNonNullable } from "@dxos/util";
|
|
5
|
+
import { Panel, composable, composableProps } from "@dxos/react-ui";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { useIdentity, useMembers } from "@dxos/halo-react";
|
|
8
|
+
import { getSpace } from "@dxos/react-client/echo";
|
|
9
|
+
import { MessageThread } from "#components";
|
|
10
|
+
import { useStatus } from "#hooks";
|
|
11
|
+
//#region src/containers/ThreadArticle/ThreadArticle.tsx
|
|
12
|
+
/**
|
|
13
|
+
* Renders an AutoMerge {@link Thread} as a chat: appends new messages by pushing
|
|
14
|
+
* onto `thread.messages`. Used for comment threads and the meeting in-call chat.
|
|
15
|
+
*/
|
|
16
|
+
var ThreadArticle = composable(({ thread, context, autoFocus, current, ...props }, forwardedRef) => {
|
|
17
|
+
const space = getSpace(thread);
|
|
18
|
+
const id = Obj.getURI(thread);
|
|
19
|
+
const identity = useIdentity();
|
|
20
|
+
const members = useMembers(space?.id);
|
|
21
|
+
const activity = useStatus(space, id);
|
|
22
|
+
const messages = useMemo(() => thread.messages.map((message) => message.target).filter(isNonNullable), [thread.messages]);
|
|
23
|
+
const handleSend = (text) => {
|
|
24
|
+
Obj.update(thread, (thread) => {
|
|
25
|
+
thread.messages.push(Ref.make(Obj.make(Message.Message, {
|
|
26
|
+
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
27
|
+
sender: { identityDid: identity.did },
|
|
28
|
+
blocks: [{
|
|
29
|
+
_tag: "text",
|
|
30
|
+
text
|
|
31
|
+
}],
|
|
32
|
+
properties: context ? { context: Ref.make(context) } : void 0
|
|
33
|
+
})));
|
|
34
|
+
});
|
|
35
|
+
return true;
|
|
36
|
+
};
|
|
37
|
+
if (!space) return null;
|
|
38
|
+
return /* @__PURE__ */ jsxs(Panel.Root, { children: [/* @__PURE__ */ jsx(Panel.Toolbar, {}), /* @__PURE__ */ jsx(Panel.Content, {
|
|
39
|
+
asChild: true,
|
|
40
|
+
children: /* @__PURE__ */ jsx(MessageThread, {
|
|
41
|
+
...composableProps(props),
|
|
42
|
+
id,
|
|
43
|
+
identity,
|
|
44
|
+
members,
|
|
45
|
+
messages,
|
|
46
|
+
activity,
|
|
47
|
+
onSend: handleSend,
|
|
48
|
+
autoFocus,
|
|
49
|
+
current,
|
|
50
|
+
ref: forwardedRef
|
|
51
|
+
})
|
|
52
|
+
})] });
|
|
53
|
+
});
|
|
54
|
+
ThreadArticle.displayName = "ThreadArticle";
|
|
55
|
+
//#endregion
|
|
56
|
+
export { ThreadArticle as default };
|
|
57
|
+
|
|
58
|
+
//# sourceMappingURL=chunk-ThreadArticle.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk-ThreadArticle.mjs","names":[],"sources":["../../src/containers/ThreadArticle/ThreadArticle.tsx"],"sourcesContent":["//\n// Copyright 2023 DXOS.org\n//\n\nimport React, { useMemo } from 'react';\n\nimport { Obj, Ref } from '@dxos/echo';\nimport { useIdentity, useMembers } from '@dxos/halo-react';\nimport { getSpace } from '@dxos/react-client/echo';\nimport { Panel, type ThemedClassName } from '@dxos/react-ui';\nimport { composable, composableProps } from '@dxos/react-ui';\nimport { type ThreadContentProps } from '@dxos/react-ui-thread';\nimport { Message, type Thread } from '@dxos/types';\nimport { isNonNullable } from '@dxos/util';\n\nimport { MessageThread } from '#components';\nimport { useStatus } from '#hooks';\n\nexport type ThreadArticleProps = ThemedClassName<\n {\n thread: Thread.Thread;\n context?: Obj.Unknown;\n autoFocus?: boolean;\n } & Pick<ThreadContentProps, 'current'>\n>;\n\n/**\n * Renders an AutoMerge {@link Thread} as a chat: appends new messages by pushing\n * onto `thread.messages`. Used for comment threads and the meeting in-call chat.\n */\nexport const ThreadArticle = composable<HTMLDivElement, ThreadArticleProps>(\n ({ thread, context, autoFocus, current, ...props }, forwardedRef) => {\n // Members and presence are space-scoped; a thread outside a space has nothing to resolve against.\n const space = getSpace(thread);\n const id = Obj.getURI(thread);\n const identity = useIdentity()!;\n const members = useMembers(space?.id);\n const activity = useStatus(space, id);\n\n const messages = useMemo(\n () => thread.messages.map((message) => message.target).filter(isNonNullable),\n [thread.messages],\n );\n\n const handleSend = (text: string) => {\n Obj.update(thread, (thread) => {\n thread.messages.push(\n Ref.make(\n Obj.make(Message.Message, {\n created: new Date().toISOString(),\n sender: { identityDid: identity.did },\n blocks: [{ _tag: 'text', text }],\n properties: context ? { context: Ref.make(context) } : undefined,\n }),\n ),\n );\n });\n return true;\n };\n\n if (!space) {\n return null;\n }\n\n return (\n <Panel.Root>\n <Panel.Toolbar></Panel.Toolbar>\n <Panel.Content asChild>\n <MessageThread\n {...composableProps(props)}\n id={id}\n identity={identity}\n members={members}\n messages={messages}\n activity={activity}\n onSend={handleSend}\n autoFocus={autoFocus}\n current={current}\n ref={forwardedRef}\n />\n </Panel.Content>\n </Panel.Root>\n );\n },\n);\n\nThreadArticle.displayName = 'ThreadArticle';\n"],"mappings":";;;;;;;;;;;;;;;AA8BA,IAAa,gBAAgB,YAC1B,EAAE,QAAQ,SAAS,WAAW,SAAS,GAAG,SAAS,iBAAiB;CAEnE,MAAM,QAAQ,SAAS,MAAM;CAC7B,MAAM,KAAK,IAAI,OAAO,MAAM;CAC5B,MAAM,WAAW,YAAY;CAC7B,MAAM,UAAU,WAAW,OAAO,EAAE;CACpC,MAAM,WAAW,UAAU,OAAO,EAAE;CAEpC,MAAM,WAAW,cACT,OAAO,SAAS,KAAK,YAAY,QAAQ,MAAM,CAAC,CAAC,OAAO,aAAa,GAC3E,CAAC,OAAO,QAAQ,CAClB;CAEA,MAAM,cAAc,SAAiB;EACnC,IAAI,OAAO,SAAS,WAAW;GAC7B,OAAO,SAAS,KACd,IAAI,KACF,IAAI,KAAK,QAAQ,SAAS;IACxB,0BAAS,IAAI,KAAK,EAAA,CAAE,YAAY;IAChC,QAAQ,EAAE,aAAa,SAAS,IAAI;IACpC,QAAQ,CAAC;KAAE,MAAM;KAAQ;IAAK,CAAC;IAC/B,YAAY,UAAU,EAAE,SAAS,IAAI,KAAK,OAAO,EAAE,IAAI,KAAA;GACzD,CAAC,CACH,CACF;EACF,CAAC;EACD,OAAO;CACT;CAEA,IAAI,CAAC,OACH,OAAO;CAGT,OACE,qBAAC,MAAM,MAAP,EAAA,UAAA,CACE,oBAAC,MAAM,SAAP,CAA8B,CAAA,GAC9B,oBAAC,MAAM,SAAP;EAAe,SAAA;YACb,oBAAC,eAAD;GACE,GAAI,gBAAgB,KAAK;GACrB;GACM;GACD;GACC;GACA;GACV,QAAQ;GACG;GACF;GACT,KAAK;EACN,CAAA;CACY,CAAA,CACL,EAAA,CAAA;AAEhB,CACF;AAEA,cAAc,cAAc"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { n as getChannelsPath } from "./chunk-paths.mjs";
|
|
2
|
+
import { Capability } from "@dxos/app-framework";
|
|
3
|
+
import { meta } from "#meta";
|
|
4
|
+
import { Operation } from "@dxos/compute";
|
|
5
|
+
import { Obj, Type } from "@dxos/echo";
|
|
6
|
+
import { Channel } from "@dxos/types";
|
|
7
|
+
import { Position } from "@dxos/util";
|
|
8
|
+
import { AppCapabilities, AppNode, AppNodeMatcher, GraphPath, TypeSection } from "@dxos/app-toolkit";
|
|
9
|
+
import * as Effect from "effect/Effect";
|
|
10
|
+
import { CallsCapabilities } from "@dxos/plugin-calls/types";
|
|
11
|
+
import { GraphBuilder } from "@dxos/plugin-graph";
|
|
12
|
+
import { SpaceOperation } from "@dxos/plugin-space";
|
|
13
|
+
//#region src/capabilities/app-graph-builder.ts
|
|
14
|
+
var channelTypename = Type.getTypename(Channel.Channel);
|
|
15
|
+
var app_graph_builder_default = Capability.makeModule(Effect.fnUntraced(function* () {
|
|
16
|
+
const capabilities = yield* Capability.Service;
|
|
17
|
+
const extensions = yield* Effect.all([TypeSection.createTypeSectionExtension(Channel.Channel, {
|
|
18
|
+
urlKey: "channel",
|
|
19
|
+
match: AppNodeMatcher.whenNavTreeGroup(GraphPath.GroupTypes.communications),
|
|
20
|
+
groupSegment: GraphPath.GroupSegments.communications,
|
|
21
|
+
createObject: (space) => Operation.invoke(SpaceOperation.OpenCreateObject, {
|
|
22
|
+
target: space.db,
|
|
23
|
+
typename: channelTypename,
|
|
24
|
+
targetNodeId: getChannelsPath(space.db.spaceId)
|
|
25
|
+
})
|
|
26
|
+
}), GraphBuilder.createTypeExtension({
|
|
27
|
+
id: "channelChatCompanion",
|
|
28
|
+
type: Channel.Channel,
|
|
29
|
+
connector: (channel, get) => {
|
|
30
|
+
const [callManager] = get(capabilities.atom(CallsCapabilities.Manager));
|
|
31
|
+
if (!callManager) return Effect.succeed([]);
|
|
32
|
+
const joined = get(callManager.joinedAtom);
|
|
33
|
+
const roomId = get(callManager.roomIdAtom);
|
|
34
|
+
if (!joined || roomId !== Obj.getURI(channel)) return Effect.succeed([]);
|
|
35
|
+
return Effect.succeed([AppNode.makeCompanion({
|
|
36
|
+
variant: "chat",
|
|
37
|
+
label: ["channel-companion.label", { ns: meta.profile.key }],
|
|
38
|
+
icon: "ph--hash--regular",
|
|
39
|
+
data: "chat",
|
|
40
|
+
position: Position.first
|
|
41
|
+
})]);
|
|
42
|
+
}
|
|
43
|
+
})]);
|
|
44
|
+
return Capability.contributes(AppCapabilities.AppGraphBuilder, extensions);
|
|
45
|
+
}));
|
|
46
|
+
//#endregion
|
|
47
|
+
export { app_graph_builder_default as default };
|
|
48
|
+
|
|
49
|
+
//# sourceMappingURL=chunk-app-graph-builder.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk-app-graph-builder.mjs","names":[],"sources":["../../src/capabilities/app-graph-builder.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capability } from '@dxos/app-framework';\nimport { AppCapabilities, AppNode, AppNodeMatcher, GraphPath, TypeSection } from '@dxos/app-toolkit';\nimport { Operation } from '@dxos/compute';\nimport { Obj, Type } from '@dxos/echo';\nimport { CallsCapabilities } from '@dxos/plugin-calls/types';\nimport { GraphBuilder } from '@dxos/plugin-graph';\nimport { SpaceOperation } from '@dxos/plugin-space';\nimport { Channel } from '@dxos/types';\nimport { Position } from '@dxos/util';\n\nimport { meta } from '#meta';\n\nimport { getChannelsPath } from '../paths';\n\nconst channelTypename = Type.getTypename(Channel.Channel);\n\nexport default Capability.makeModule(\n Effect.fnUntraced(function* () {\n const capabilities = yield* Capability.Service;\n\n const extensions = yield* Effect.all([\n TypeSection.createTypeSectionExtension(Channel.Channel, {\n urlKey: 'channel',\n match: AppNodeMatcher.whenNavTreeGroup(GraphPath.GroupTypes.communications),\n groupSegment: GraphPath.GroupSegments.communications,\n createObject: (space) =>\n Operation.invoke(SpaceOperation.OpenCreateObject, {\n target: space.db,\n typename: channelTypename,\n targetNodeId: getChannelsPath(space.db.spaceId),\n }),\n }),\n\n GraphBuilder.createTypeExtension({\n id: 'channelChatCompanion',\n type: Channel.Channel,\n connector: (channel, get) => {\n const [callManager] = get(capabilities.atom(CallsCapabilities.Manager));\n if (!callManager) {\n return Effect.succeed([]);\n }\n const joined = get(callManager.joinedAtom);\n const roomId = get(callManager.roomIdAtom);\n if (!joined || roomId !== Obj.getURI(channel)) {\n return Effect.succeed([]);\n }\n\n return Effect.succeed([\n AppNode.makeCompanion({\n variant: 'chat',\n label: ['channel-companion.label', { ns: meta.profile.key }],\n icon: 'ph--hash--regular',\n data: 'chat',\n position: Position.first,\n }),\n ]);\n },\n }),\n ]);\n\n return Capability.contributes(AppCapabilities.AppGraphBuilder, extensions);\n }),\n);\n"],"mappings":";;;;;;;;;;;;;AAoBA,IAAM,kBAAkB,KAAK,YAAY,QAAQ,OAAO;AAExD,IAAA,4BAAe,WAAW,WACxB,OAAO,WAAW,aAAa;CAC7B,MAAM,eAAe,OAAO,WAAW;CAEvC,MAAM,aAAa,OAAO,OAAO,IAAI,CACnC,YAAY,2BAA2B,QAAQ,SAAS;EACtD,QAAQ;EACR,OAAO,eAAe,iBAAiB,UAAU,WAAW,cAAc;EAC1E,cAAc,UAAU,cAAc;EACtC,eAAe,UACb,UAAU,OAAO,eAAe,kBAAkB;GAChD,QAAQ,MAAM;GACd,UAAU;GACV,cAAc,gBAAgB,MAAM,GAAG,OAAO;EAChD,CAAC;CACL,CAAC,GAED,aAAa,oBAAoB;EAC/B,IAAI;EACJ,MAAM,QAAQ;EACd,YAAY,SAAS,QAAQ;GAC3B,MAAM,CAAC,eAAe,IAAI,aAAa,KAAK,kBAAkB,OAAO,CAAC;GACtE,IAAI,CAAC,aACH,OAAO,OAAO,QAAQ,CAAC,CAAC;GAE1B,MAAM,SAAS,IAAI,YAAY,UAAU;GACzC,MAAM,SAAS,IAAI,YAAY,UAAU;GACzC,IAAI,CAAC,UAAU,WAAW,IAAI,OAAO,OAAO,GAC1C,OAAO,OAAO,QAAQ,CAAC,CAAC;GAG1B,OAAO,OAAO,QAAQ,CACpB,QAAQ,cAAc;IACpB,SAAS;IACT,OAAO,CAAC,2BAA2B,EAAE,IAAI,KAAK,QAAQ,IAAI,CAAC;IAC3D,MAAM;IACN,MAAM;IACN,UAAU,SAAS;GACrB,CAAC,CACH,CAAC;EACH;CACF,CAAC,CACH,CAAC;CAED,OAAO,WAAW,YAAY,gBAAgB,iBAAiB,UAAU;AAC3E,CAAC,CACH"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { c as resolveProvider, i as ChannelBackend, t as AppendChannelMessage } from "./chunk-types.mjs";
|
|
2
|
+
import { Capability } from "@dxos/app-framework";
|
|
3
|
+
import { Operation } from "@dxos/compute";
|
|
4
|
+
import { Message } from "@dxos/types";
|
|
5
|
+
import * as Effect from "effect/Effect";
|
|
6
|
+
import { invariant } from "@dxos/invariant";
|
|
7
|
+
//#region src/operations/append-channel-message.ts
|
|
8
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-thread/src/operations/append-channel-message.ts";
|
|
9
|
+
var handler = AppendChannelMessage.pipe(Operation.withHandler(Effect.fnUntraced(function* ({ channel, sender, text }) {
|
|
10
|
+
const provider = resolveProvider(yield* Capability.getAll(ChannelBackend), channel.backend.kind);
|
|
11
|
+
invariant(provider, `No channel backend for kind: ${channel.backend.kind}`, {
|
|
12
|
+
"~LogMeta": "~LogMeta",
|
|
13
|
+
F: __dxlog_file,
|
|
14
|
+
L: 20,
|
|
15
|
+
S: this,
|
|
16
|
+
A: ["provider", "`No channel backend for kind: ${channel.backend.kind}`"]
|
|
17
|
+
});
|
|
18
|
+
const message = Message.make({
|
|
19
|
+
sender,
|
|
20
|
+
blocks: [{
|
|
21
|
+
_tag: "text",
|
|
22
|
+
text
|
|
23
|
+
}]
|
|
24
|
+
});
|
|
25
|
+
yield* provider.send(channel, message);
|
|
26
|
+
})));
|
|
27
|
+
//#endregion
|
|
28
|
+
export { handler as default };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=chunk-append-channel-message.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk-append-channel-message.mjs","names":[],"sources":["../../src/operations/append-channel-message.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capability } from '@dxos/app-framework';\nimport { Operation } from '@dxos/compute';\nimport { invariant } from '@dxos/invariant';\nimport { Message } from '@dxos/types';\n\nimport { ThreadCapabilities, ThreadOperation, resolveProvider } from '../types';\n\nconst handler: Operation.WithHandler<typeof ThreadOperation.AppendChannelMessage> =\n ThreadOperation.AppendChannelMessage.pipe(\n Operation.withHandler(\n Effect.fnUntraced(function* ({ channel, sender, text }) {\n const providers = yield* Capability.getAll(ThreadCapabilities.ChannelBackend);\n const provider = resolveProvider(providers, channel.backend.kind);\n invariant(provider, `No channel backend for kind: ${channel.backend.kind}`);\n\n const message = Message.make({\n sender,\n blocks: [{ _tag: 'text', text }],\n });\n yield* provider.send(channel, message);\n }),\n ),\n );\n\nexport default handler;\n"],"mappings":";;;;;;;;AAaA,IAAM,UAAA,qBACiC,KACnC,UAAU,YACR,OAAO,WAAW,WAAW,EAAE,SAAS,QAAQ,QAAQ;CAEtD,MAAM,WAAW,gBAAgB,OADR,WAAW,OAAO,cAAiC,GAChC,QAAQ,QAAQ,IAAI;CAChE,UAAU,UAAU,gCAAgC,QAAQ,QAAQ,QAAK;EAAA,YAAA;EAAA,GAAA;EAAA,GAAA;EAAA,GAAA;EAAA,GAAA,CAAA,YAAA,wDAAA;CAAA,CAAC;CAE1E,MAAM,UAAU,QAAQ,KAAK;EAC3B;EACA,QAAQ,CAAC;GAAE,MAAM;GAAQ;EAAK,CAAC;CACjC,CAAC;CACD,OAAO,SAAS,KAAK,SAAS,OAAO;AACvC,CAAC,CACH,CACF"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { i as ChannelBackend } from "./chunk-types.mjs";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
import { Capability } from "@dxos/app-framework";
|
|
4
|
+
import { Database, Feed, Filter, Obj, Query } from "@dxos/echo";
|
|
5
|
+
import { Channel, Message } from "@dxos/types";
|
|
6
|
+
import * as Effect from "effect/Effect";
|
|
7
|
+
import { invariant } from "@dxos/invariant";
|
|
8
|
+
import { ClientCapabilities } from "@dxos/plugin-client";
|
|
9
|
+
//#region src/capabilities/channel-backend-feed.ts
|
|
10
|
+
var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-thread/src/capabilities/channel-backend-feed.ts";
|
|
11
|
+
/**
|
|
12
|
+
* Default local ECHO-feed-backed channel provider. Stores messages in a `Feed`
|
|
13
|
+
* (`makeConfig` → `Feed.make()`), reads them via a reactive database query, and
|
|
14
|
+
* writes via `Feed.append`. This is the backend `Channel.make()` defaults to.
|
|
15
|
+
*/
|
|
16
|
+
var feedChannelBackend = {
|
|
17
|
+
kind: Channel.FeedBackendKind,
|
|
18
|
+
label: "Feed",
|
|
19
|
+
icon: "ph--rows--regular",
|
|
20
|
+
createFields: Schema.Struct({}),
|
|
21
|
+
makeConfig: () => Feed.make(),
|
|
22
|
+
subscribe: (channel, onMessages) => {
|
|
23
|
+
const feed = Channel.getFeed(channel);
|
|
24
|
+
const db = Obj.getDatabase(channel);
|
|
25
|
+
if (!feed || !db) {
|
|
26
|
+
onMessages([]);
|
|
27
|
+
return () => {};
|
|
28
|
+
}
|
|
29
|
+
const result = db.query(Query.select(Filter.type(Message.Message)).from(feed));
|
|
30
|
+
return result.subscribe(() => onMessages(result.results), { fire: true });
|
|
31
|
+
},
|
|
32
|
+
send: (channel, message) => Effect.gen(function* () {
|
|
33
|
+
const db = Obj.getDatabase(channel);
|
|
34
|
+
invariant(db, "Database not found", {
|
|
35
|
+
"~LogMeta": "~LogMeta",
|
|
36
|
+
F: __dxlog_file,
|
|
37
|
+
L: 41,
|
|
38
|
+
S: this,
|
|
39
|
+
A: ["db", "'Database not found'"]
|
|
40
|
+
});
|
|
41
|
+
const space = (yield* Capability.get(ClientCapabilities.Client)).spaces.get(db.spaceId);
|
|
42
|
+
invariant(space, "Space not found", {
|
|
43
|
+
"~LogMeta": "~LogMeta",
|
|
44
|
+
F: __dxlog_file,
|
|
45
|
+
L: 44,
|
|
46
|
+
S: this,
|
|
47
|
+
A: ["space", "'Space not found'"]
|
|
48
|
+
});
|
|
49
|
+
const feed = Channel.getFeed(channel);
|
|
50
|
+
invariant(feed, "Channel is not feed-backed", {
|
|
51
|
+
"~LogMeta": "~LogMeta",
|
|
52
|
+
F: __dxlog_file,
|
|
53
|
+
L: 46,
|
|
54
|
+
S: this,
|
|
55
|
+
A: ["feed", "'Channel is not feed-backed'"]
|
|
56
|
+
});
|
|
57
|
+
yield* Feed.append(feed, [message]).pipe(Effect.provide(Database.layer(space.db)));
|
|
58
|
+
}),
|
|
59
|
+
readOnly: (channel) => Obj.getMeta(channel).keys.length > 0
|
|
60
|
+
};
|
|
61
|
+
/** Contributes the default feed-backed channel provider. */
|
|
62
|
+
var ChannelBackendFeed = Capability.makeModule(Effect.fnUntraced(function* () {
|
|
63
|
+
return Capability.contributes(ChannelBackend, feedChannelBackend);
|
|
64
|
+
}));
|
|
65
|
+
//#endregion
|
|
66
|
+
export { ChannelBackendFeed, ChannelBackendFeed as default, feedChannelBackend };
|
|
67
|
+
|
|
68
|
+
//# sourceMappingURL=chunk-channel-backend-feed.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk-channel-backend-feed.mjs","names":[],"sources":["../../src/capabilities/channel-backend-feed.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\nimport * as Schema from 'effect/Schema';\n\nimport { Capability } from '@dxos/app-framework';\nimport { Database, Feed, Filter, Obj, Query } from '@dxos/echo';\nimport { invariant } from '@dxos/invariant';\nimport { ClientCapabilities } from '@dxos/plugin-client';\nimport { Channel, Message } from '@dxos/types';\n\nimport { ThreadCapabilities } from '../types';\n\n/**\n * Default local ECHO-feed-backed channel provider. Stores messages in a `Feed`\n * (`makeConfig` → `Feed.make()`), reads them via a reactive database query, and\n * writes via `Feed.append`. This is the backend `Channel.make()` defaults to.\n */\nexport const feedChannelBackend: ThreadCapabilities.ChannelBackendProvider = {\n kind: Channel.FeedBackendKind,\n label: 'Feed',\n icon: 'ph--rows--regular',\n createFields: Schema.Struct({}),\n makeConfig: () => Feed.make(),\n subscribe: (channel, onMessages) => {\n const feed = Channel.getFeed(channel);\n const db = Obj.getDatabase(channel);\n if (!feed || !db) {\n onMessages([]);\n return () => {};\n }\n\n const result = db.query(Query.select(Filter.type(Message.Message)).from(feed));\n return result.subscribe(() => onMessages(result.results), { fire: true });\n },\n send: (channel, message) =>\n Effect.gen(function* () {\n const db = Obj.getDatabase(channel);\n invariant(db, 'Database not found');\n const client = yield* Capability.get(ClientCapabilities.Client);\n const space = client.spaces.get(db.spaceId);\n invariant(space, 'Space not found');\n const feed = Channel.getFeed(channel);\n invariant(feed, 'Channel is not feed-backed');\n yield* Feed.append(feed, [message]).pipe(Effect.provide(Database.layer(space.db)));\n }),\n readOnly: (channel) => Obj.getMeta(channel).keys.length > 0,\n};\n\n/** Contributes the default feed-backed channel provider. */\nexport const ChannelBackendFeed = Capability.makeModule(\n Effect.fnUntraced(function* () {\n return Capability.contributes(ThreadCapabilities.ChannelBackend, feedChannelBackend);\n }),\n);\n\nexport default ChannelBackendFeed;\n"],"mappings":";;;;;;;;;;;;;;;AAoBA,IAAa,qBAAgE;CAC3E,MAAM,QAAQ;CACd,OAAO;CACP,MAAM;CACN,cAAc,OAAO,OAAO,CAAC,CAAC;CAC9B,kBAAkB,KAAK,KAAK;CAC5B,YAAY,SAAS,eAAe;EAClC,MAAM,OAAO,QAAQ,QAAQ,OAAO;EACpC,MAAM,KAAK,IAAI,YAAY,OAAO;EAClC,IAAI,CAAC,QAAQ,CAAC,IAAI;GAChB,WAAW,CAAC,CAAC;GACb,aAAa,CAAC;EAChB;EAEA,MAAM,SAAS,GAAG,MAAM,MAAM,OAAO,OAAO,KAAK,QAAQ,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;EAC7E,OAAO,OAAO,gBAAgB,WAAW,OAAO,OAAO,GAAG,EAAE,MAAM,KAAK,CAAC;CAC1E;CACA,OAAO,SAAS,YACd,OAAO,IAAI,aAAa;EACtB,MAAM,KAAK,IAAI,YAAY,OAAO;EAClC,UAAU,IAAI,sBAAmB;GAAA,YAAA;GAAA,GAAA;GAAA,GAAA;GAAA,GAAA;GAAA,GAAA,CAAA,MAAA,sBAAA;EAAA,CAAC;EAElC,MAAM,SAAQ,OADQ,WAAW,IAAI,mBAAmB,MAAM,EAAA,CACzC,OAAO,IAAI,GAAG,OAAO;EAC1C,UAAU,OAAO,mBAAgB;GAAA,YAAA;GAAA,GAAA;GAAA,GAAA;GAAA,GAAA;GAAA,GAAA,CAAA,SAAA,mBAAA;EAAA,CAAC;EAClC,MAAM,OAAO,QAAQ,QAAQ,OAAO;EACpC,UAAU,MAAM,8BAA2B;GAAA,YAAA;GAAA,GAAA;GAAA,GAAA;GAAA,GAAA;GAAA,GAAA,CAAA,QAAA,8BAAA;EAAA,CAAC;EAC5C,OAAO,KAAK,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,QAAQ,SAAS,MAAM,MAAM,EAAE,CAAC,CAAC;CACnF,CAAC;CACH,WAAW,YAAY,IAAI,QAAQ,OAAO,CAAC,CAAC,KAAK,SAAS;AAC5D;;AAGA,IAAa,qBAAqB,WAAW,WAC3C,OAAO,WAAW,aAAa;CAC7B,OAAO,WAAW,YAAY,gBAAmC,kBAAkB;AACrF,CAAC,CACH"}
|