@tutti-os/ui-rich-text 0.0.124 → 0.0.126
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -3
- package/dist/RichTextMentionService-CsZ9CGQf.d.ts +45 -0
- package/dist/chunk-3UTSSMV7.js +113 -0
- package/dist/chunk-3UTSSMV7.js.map +1 -0
- package/dist/{chunk-RUX5KKX3.js → chunk-CLNWVUDR.js} +1 -111
- package/dist/chunk-CLNWVUDR.js.map +1 -0
- package/dist/chunk-XN4EGZGR.js +316 -0
- package/dist/chunk-XN4EGZGR.js.map +1 -0
- package/dist/editor/index.d.ts +25 -5
- package/dist/editor/index.js +247 -149
- package/dist/editor/index.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +19 -0
- package/dist/plugins/index.js +4 -2
- package/dist/service/index.d.ts +14 -0
- package/dist/service/index.js +22 -0
- package/dist/service/index.js.map +1 -0
- package/package.json +11 -3
- package/dist/chunk-RUX5KKX3.js.map +0 -1
package/README.md
CHANGED
|
@@ -129,6 +129,10 @@ Interpretation:
|
|
|
129
129
|
insertion
|
|
130
130
|
- `resolveMention` restores editor-only label or presentation data from the
|
|
131
131
|
stored mention identity
|
|
132
|
+
- readonly conversation surfaces pass the same providers to
|
|
133
|
+
`RichTextReadonlyContent.triggerProviders`; it calls `resolveMention` to
|
|
134
|
+
restore presentation such as app icons while keeping serialized Markdown
|
|
135
|
+
limited to durable identity and scope
|
|
132
136
|
- group ids, labels, totals, and cursors are candidate-panel metadata only;
|
|
133
137
|
they must not be copied into mention identity, href, or persisted scope
|
|
134
138
|
|
|
@@ -152,6 +156,53 @@ Markdown serialization includes only `providerId`, `entityId`, `label`, and
|
|
|
152
156
|
short `scope` fields. It does not serialize `presentation`, `href`, `kind`,
|
|
153
157
|
`version`, or arbitrary metadata.
|
|
154
158
|
|
|
159
|
+
## Mention Service
|
|
160
|
+
|
|
161
|
+
`RichTextMentionService` is the host-agnostic owner of provider lookup, query,
|
|
162
|
+
reverse resolution, presentation caching, invalidation, and subscriptions.
|
|
163
|
+
Create one service at the host or app root and reuse it across composer,
|
|
164
|
+
readonly conversation, preview, and AgentGUI surfaces:
|
|
165
|
+
|
|
166
|
+
```tsx
|
|
167
|
+
import {
|
|
168
|
+
RichTextMentionServiceProvider,
|
|
169
|
+
RichTextReadonlyContent,
|
|
170
|
+
RichTextTriggerEditor
|
|
171
|
+
} from "@tutti-os/ui-rich-text/editor";
|
|
172
|
+
import { createRichTextMentionService } from "@tutti-os/ui-rich-text/service";
|
|
173
|
+
|
|
174
|
+
const mentionService = createRichTextMentionService({ providers });
|
|
175
|
+
|
|
176
|
+
<RichTextMentionServiceProvider service={mentionService}>
|
|
177
|
+
<RichTextTriggerEditor value={draft} onChange={setDraft} />
|
|
178
|
+
<RichTextReadonlyContent value={savedMarkdown} />
|
|
179
|
+
</RichTextMentionServiceProvider>;
|
|
180
|
+
|
|
181
|
+
// Dispose when the owning host/workspace root is destroyed.
|
|
182
|
+
mentionService.dispose();
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Non-React consumers use the same instance directly through `query`, `resolve`,
|
|
186
|
+
`getSnapshot`, `invalidate`, and `subscribe`. The React Provider never creates
|
|
187
|
+
a network client or a global singleton; it only injects an existing service.
|
|
188
|
+
|
|
189
|
+
Resolution precedence is fixed: an explicit `mentionService` prop wins, then
|
|
190
|
+
the nearest `RichTextMentionServiceProvider`, then the deprecated
|
|
191
|
+
`triggerProviders` compatibility path. If no resolver exists, persisted label
|
|
192
|
+
text and the semantic `MentionPill` icon remain available.
|
|
193
|
+
|
|
194
|
+
The service uses a normalized `providerId + entityId + canonical scope` key.
|
|
195
|
+
Labels and presentation URLs are deliberately excluded. Ready entries are
|
|
196
|
+
cached for 5 minutes, missing entries for 30 seconds, and errors retry after 5
|
|
197
|
+
seconds. The cache is capped at 1000 identities, concurrent resolution is
|
|
198
|
+
single-flight, and stale ready presentation remains visible during refresh.
|
|
199
|
+
Explicit invalidation may target all entries, a provider, a workspace, or an
|
|
200
|
+
entity.
|
|
201
|
+
|
|
202
|
+
Never persist a resolved snapshot or copy `presentation` into Markdown. Icon
|
|
203
|
+
URLs and runtime cache state stay in memory; durable mention content remains
|
|
204
|
+
limited to provider identity, entity identity, fallback label, and short scope.
|
|
205
|
+
|
|
155
206
|
Helpers now exported:
|
|
156
207
|
|
|
157
208
|
- `createRichTextMentionPlugin`
|
|
@@ -195,14 +246,18 @@ Tutti workspace apps that already receive mention candidates from
|
|
|
195
246
|
`@tutti-os/workspace-external-core/rich-text`:
|
|
196
247
|
|
|
197
248
|
```ts
|
|
198
|
-
import {
|
|
249
|
+
import { createTuttiExternalRichTextMentionService } from "@tutti-os/workspace-external-core/rich-text";
|
|
199
250
|
|
|
200
|
-
const
|
|
201
|
-
|
|
251
|
+
const mentionService = createTuttiExternalRichTextMentionService({
|
|
252
|
+
getBridge: () => window.tuttiExternal,
|
|
202
253
|
providerIds: ["workspace-app", "agent-session"]
|
|
203
254
|
});
|
|
204
255
|
```
|
|
205
256
|
|
|
257
|
+
The older trigger-provider factory remains available for compatibility, but a
|
|
258
|
+
root-owned service is the preferred integration because editor and readonly
|
|
259
|
+
surfaces share resolution, caching, and invalidation automatically.
|
|
260
|
+
|
|
206
261
|
Use a custom `RichTextTriggerProvider` only for app-local mention sources or for
|
|
207
262
|
apps that do not use the Tutti external bridge.
|
|
208
263
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { a as RichTextMentionIdentity, k as RichTextMentionResolved } from './mention-DJq2OJ4K.js';
|
|
2
|
+
import { RichTextTriggerProvider, RichTextTriggerConfig, RichTextTriggerQueryInput, RichTextTriggerQueryMatch } from './types/index.js';
|
|
3
|
+
|
|
4
|
+
declare const RICH_TEXT_MENTION_READY_TTL_MS = 300000;
|
|
5
|
+
declare const RICH_TEXT_MENTION_MISSING_TTL_MS = 30000;
|
|
6
|
+
declare const RICH_TEXT_MENTION_ERROR_RETRY_MS = 5000;
|
|
7
|
+
declare const RICH_TEXT_MENTION_CACHE_CAPACITY = 1000;
|
|
8
|
+
type RichTextMentionResolutionState = "idle" | "loading" | "ready" | "missing" | "error";
|
|
9
|
+
interface RichTextMentionSnapshot {
|
|
10
|
+
state: RichTextMentionResolutionState;
|
|
11
|
+
resolved?: RichTextMentionResolved;
|
|
12
|
+
updatedAtUnixMs?: number;
|
|
13
|
+
}
|
|
14
|
+
interface RichTextMentionInvalidationSelector {
|
|
15
|
+
providerId?: string;
|
|
16
|
+
workspaceId?: string;
|
|
17
|
+
entityId?: string;
|
|
18
|
+
}
|
|
19
|
+
type RichTextMentionDiagnosticEventName = "mention_query_completed" | "mention_resolve_completed" | "mention_cache_invalidated";
|
|
20
|
+
interface RichTextMentionDiagnosticEvent {
|
|
21
|
+
name: RichTextMentionDiagnosticEventName;
|
|
22
|
+
providerId: string;
|
|
23
|
+
outcome: "success" | "missing" | "error";
|
|
24
|
+
cacheStatus: "hit" | "miss" | "stale" | "invalidated";
|
|
25
|
+
durationMs: number;
|
|
26
|
+
}
|
|
27
|
+
interface CreateRichTextMentionServiceInput {
|
|
28
|
+
providers: readonly RichTextTriggerProvider[];
|
|
29
|
+
now?: () => number;
|
|
30
|
+
diagnostics?: (event: RichTextMentionDiagnosticEvent) => void;
|
|
31
|
+
}
|
|
32
|
+
interface RichTextMentionService {
|
|
33
|
+
listProviders(): readonly RichTextTriggerProvider[];
|
|
34
|
+
getProvider(providerId: string): RichTextTriggerProvider | undefined;
|
|
35
|
+
listTriggerConfigs(): readonly RichTextTriggerConfig[];
|
|
36
|
+
query(input: RichTextTriggerQueryInput): Promise<readonly RichTextTriggerQueryMatch[]>;
|
|
37
|
+
resolve(identity: RichTextMentionIdentity): Promise<RichTextMentionSnapshot>;
|
|
38
|
+
getSnapshot(identity: RichTextMentionIdentity): RichTextMentionSnapshot;
|
|
39
|
+
invalidate(selector?: RichTextMentionInvalidationSelector): void;
|
|
40
|
+
subscribe(listener: () => void, identity?: RichTextMentionIdentity): () => void;
|
|
41
|
+
dispose(): void;
|
|
42
|
+
}
|
|
43
|
+
declare function createRichTextMentionService(input: CreateRichTextMentionServiceInput): RichTextMentionService;
|
|
44
|
+
|
|
45
|
+
export { type CreateRichTextMentionServiceInput as C, RICH_TEXT_MENTION_CACHE_CAPACITY as R, RICH_TEXT_MENTION_ERROR_RETRY_MS as a, RICH_TEXT_MENTION_MISSING_TTL_MS as b, RICH_TEXT_MENTION_READY_TTL_MS as c, type RichTextMentionDiagnosticEvent as d, type RichTextMentionDiagnosticEventName as e, type RichTextMentionInvalidationSelector as f, type RichTextMentionResolutionState as g, type RichTextMentionService as h, type RichTextMentionSnapshot as i, createRichTextMentionService as j };
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// src/plugins/triggerRegistry.ts
|
|
2
|
+
function normalizeProviderId(providerId) {
|
|
3
|
+
return providerId.trim();
|
|
4
|
+
}
|
|
5
|
+
function normalizeProviderTrigger(provider) {
|
|
6
|
+
return provider.trigger;
|
|
7
|
+
}
|
|
8
|
+
function normalizeProviderBoundary(provider) {
|
|
9
|
+
return provider.boundary ?? "punctuation";
|
|
10
|
+
}
|
|
11
|
+
function normalizeProviderTriggerConfig(provider) {
|
|
12
|
+
return {
|
|
13
|
+
trigger: normalizeProviderTrigger(provider),
|
|
14
|
+
boundary: normalizeProviderBoundary(provider)
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function normalizeOptionalIconUrl(value) {
|
|
18
|
+
const trimmed = value?.trim();
|
|
19
|
+
return trimmed ? trimmed : void 0;
|
|
20
|
+
}
|
|
21
|
+
function resolveInsertResultIconUrl(insertResult) {
|
|
22
|
+
if (insertResult.kind !== "mention") {
|
|
23
|
+
return void 0;
|
|
24
|
+
}
|
|
25
|
+
return normalizeOptionalIconUrl(insertResult.mention.presentation?.iconUrl);
|
|
26
|
+
}
|
|
27
|
+
async function resolveItemIconUrl(provider, item, insertResult) {
|
|
28
|
+
if (provider.getItemIconUrl) {
|
|
29
|
+
try {
|
|
30
|
+
const iconUrl = normalizeOptionalIconUrl(
|
|
31
|
+
await Promise.resolve(provider.getItemIconUrl(item))
|
|
32
|
+
);
|
|
33
|
+
if (iconUrl) {
|
|
34
|
+
return iconUrl;
|
|
35
|
+
}
|
|
36
|
+
} catch {
|
|
37
|
+
return resolveInsertResultIconUrl(insertResult);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return resolveInsertResultIconUrl(insertResult);
|
|
41
|
+
}
|
|
42
|
+
function createRichTextTriggerRegistry(providers) {
|
|
43
|
+
const providerMap = /* @__PURE__ */ new Map();
|
|
44
|
+
const triggerConfigKeys = /* @__PURE__ */ new Set();
|
|
45
|
+
const triggerConfigs = [];
|
|
46
|
+
for (const provider of providers) {
|
|
47
|
+
const providerId = normalizeProviderId(provider.id);
|
|
48
|
+
if (!providerId) {
|
|
49
|
+
throw new Error("Rich text trigger provider id is required.");
|
|
50
|
+
}
|
|
51
|
+
if (providerMap.has(providerId)) {
|
|
52
|
+
throw new Error(`Duplicate rich text trigger provider id: ${providerId}`);
|
|
53
|
+
}
|
|
54
|
+
providerMap.set(providerId, provider);
|
|
55
|
+
const triggerConfig = normalizeProviderTriggerConfig(provider);
|
|
56
|
+
const triggerConfigKey = `${triggerConfig.trigger}:${triggerConfig.boundary}`;
|
|
57
|
+
if (!triggerConfigKeys.has(triggerConfigKey)) {
|
|
58
|
+
triggerConfigKeys.add(triggerConfigKey);
|
|
59
|
+
triggerConfigs.push(triggerConfig);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async function query(input) {
|
|
63
|
+
if (input.abortSignal?.aborted) {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
const matches = await Promise.all(
|
|
67
|
+
[...providerMap.values()].filter(
|
|
68
|
+
(provider) => normalizeProviderTrigger(provider) === input.trigger
|
|
69
|
+
).map(async (provider) => {
|
|
70
|
+
if (input.abortSignal?.aborted) {
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
const items = await provider.query(input);
|
|
74
|
+
if (input.abortSignal?.aborted) {
|
|
75
|
+
return [];
|
|
76
|
+
}
|
|
77
|
+
return Promise.all(
|
|
78
|
+
items.map(async (item) => {
|
|
79
|
+
const insertResult = provider.toInsertResult(item);
|
|
80
|
+
return {
|
|
81
|
+
providerId: provider.id,
|
|
82
|
+
trigger: input.trigger,
|
|
83
|
+
key: provider.getItemKey(item),
|
|
84
|
+
label: provider.getItemLabel(item),
|
|
85
|
+
subtitle: provider.getItemSubtitle?.(item) || void 0,
|
|
86
|
+
iconUrl: await resolveItemIconUrl(provider, item, insertResult),
|
|
87
|
+
keywords: provider.getItemKeywords?.(item),
|
|
88
|
+
item,
|
|
89
|
+
insertResult
|
|
90
|
+
};
|
|
91
|
+
})
|
|
92
|
+
);
|
|
93
|
+
})
|
|
94
|
+
);
|
|
95
|
+
const flatMatches = matches.flat();
|
|
96
|
+
const limit = input.maxResults;
|
|
97
|
+
if (typeof limit === "number" && limit >= 0) {
|
|
98
|
+
return flatMatches.slice(0, limit);
|
|
99
|
+
}
|
|
100
|
+
return flatMatches;
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
listProviders: () => [...providerMap.values()],
|
|
104
|
+
getProvider: (providerId) => providerMap.get(normalizeProviderId(providerId)),
|
|
105
|
+
listTriggerConfigs: () => [...triggerConfigs],
|
|
106
|
+
query
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export {
|
|
111
|
+
createRichTextTriggerRegistry
|
|
112
|
+
};
|
|
113
|
+
//# sourceMappingURL=chunk-3UTSSMV7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/plugins/triggerRegistry.ts"],"sourcesContent":["import type {\n RichTextTrigger,\n RichTextTriggerBoundary,\n RichTextTriggerConfig,\n RichTextTriggerInsertResult,\n RichTextTriggerProvider,\n RichTextTriggerQueryInput,\n RichTextTriggerQueryMatch,\n RichTextTriggerRegistry\n} from \"../types/trigger.ts\";\n\nfunction normalizeProviderId(providerId: string): string {\n return providerId.trim();\n}\n\nfunction normalizeProviderTrigger(\n provider: RichTextTriggerProvider\n): RichTextTrigger {\n return provider.trigger;\n}\n\nfunction normalizeProviderBoundary(\n provider: RichTextTriggerProvider\n): RichTextTriggerBoundary {\n return provider.boundary ?? \"punctuation\";\n}\n\nfunction normalizeProviderTriggerConfig(\n provider: RichTextTriggerProvider\n): RichTextTriggerConfig {\n return {\n trigger: normalizeProviderTrigger(provider),\n boundary: normalizeProviderBoundary(provider)\n };\n}\n\nfunction normalizeOptionalIconUrl(\n value: string | null | undefined\n): string | undefined {\n const trimmed = value?.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction resolveInsertResultIconUrl(\n insertResult: RichTextTriggerInsertResult\n): string | undefined {\n if (insertResult.kind !== \"mention\") {\n return undefined;\n }\n return normalizeOptionalIconUrl(insertResult.mention.presentation?.iconUrl);\n}\n\nasync function resolveItemIconUrl<TItem>(\n provider: RichTextTriggerProvider<TItem>,\n item: TItem,\n insertResult: RichTextTriggerInsertResult\n): Promise<string | undefined> {\n if (provider.getItemIconUrl) {\n try {\n const iconUrl = normalizeOptionalIconUrl(\n await Promise.resolve(provider.getItemIconUrl(item))\n );\n if (iconUrl) {\n return iconUrl;\n }\n } catch {\n return resolveInsertResultIconUrl(insertResult);\n }\n }\n return resolveInsertResultIconUrl(insertResult);\n}\n\nexport function createRichTextTriggerRegistry(\n providers: readonly RichTextTriggerProvider[]\n): RichTextTriggerRegistry {\n const providerMap = new Map<string, RichTextTriggerProvider>();\n const triggerConfigKeys = new Set<string>();\n const triggerConfigs: RichTextTriggerConfig[] = [];\n\n for (const provider of providers) {\n const providerId = normalizeProviderId(provider.id);\n if (!providerId) {\n throw new Error(\"Rich text trigger provider id is required.\");\n }\n if (providerMap.has(providerId)) {\n throw new Error(`Duplicate rich text trigger provider id: ${providerId}`);\n }\n providerMap.set(providerId, provider);\n const triggerConfig = normalizeProviderTriggerConfig(provider);\n const triggerConfigKey = `${triggerConfig.trigger}:${triggerConfig.boundary}`;\n if (!triggerConfigKeys.has(triggerConfigKey)) {\n triggerConfigKeys.add(triggerConfigKey);\n triggerConfigs.push(triggerConfig);\n }\n }\n\n async function query(\n input: RichTextTriggerQueryInput\n ): Promise<readonly RichTextTriggerQueryMatch[]> {\n if (input.abortSignal?.aborted) {\n return [];\n }\n\n const matches = await Promise.all(\n [...providerMap.values()]\n .filter(\n (provider) => normalizeProviderTrigger(provider) === input.trigger\n )\n .map(async (provider) => {\n if (input.abortSignal?.aborted) {\n return [];\n }\n const items = await provider.query(input);\n if (input.abortSignal?.aborted) {\n return [];\n }\n return Promise.all(\n items.map(async (item) => {\n const insertResult = provider.toInsertResult(item);\n return {\n providerId: provider.id,\n trigger: input.trigger,\n key: provider.getItemKey(item),\n label: provider.getItemLabel(item),\n subtitle: provider.getItemSubtitle?.(item) || undefined,\n iconUrl: await resolveItemIconUrl(provider, item, insertResult),\n keywords: provider.getItemKeywords?.(item),\n item,\n insertResult\n };\n })\n );\n })\n );\n\n const flatMatches = matches.flat();\n const limit = input.maxResults;\n if (typeof limit === \"number\" && limit >= 0) {\n return flatMatches.slice(0, limit);\n }\n return flatMatches;\n }\n\n return {\n listProviders: () => [...providerMap.values()],\n getProvider: (providerId: string) =>\n providerMap.get(normalizeProviderId(providerId)),\n listTriggerConfigs: () => [...triggerConfigs],\n query\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -169,115 +169,6 @@ function createRichTextTriggerProvider(provider) {
|
|
|
169
169
|
};
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
-
// src/plugins/triggerRegistry.ts
|
|
173
|
-
function normalizeProviderId(providerId) {
|
|
174
|
-
return providerId.trim();
|
|
175
|
-
}
|
|
176
|
-
function normalizeProviderTrigger(provider) {
|
|
177
|
-
return provider.trigger;
|
|
178
|
-
}
|
|
179
|
-
function normalizeProviderBoundary(provider) {
|
|
180
|
-
return provider.boundary ?? "punctuation";
|
|
181
|
-
}
|
|
182
|
-
function normalizeProviderTriggerConfig(provider) {
|
|
183
|
-
return {
|
|
184
|
-
trigger: normalizeProviderTrigger(provider),
|
|
185
|
-
boundary: normalizeProviderBoundary(provider)
|
|
186
|
-
};
|
|
187
|
-
}
|
|
188
|
-
function normalizeOptionalIconUrl(value) {
|
|
189
|
-
const trimmed = value?.trim();
|
|
190
|
-
return trimmed ? trimmed : void 0;
|
|
191
|
-
}
|
|
192
|
-
function resolveInsertResultIconUrl(insertResult) {
|
|
193
|
-
if (insertResult.kind !== "mention") {
|
|
194
|
-
return void 0;
|
|
195
|
-
}
|
|
196
|
-
return normalizeOptionalIconUrl(insertResult.mention.presentation?.iconUrl);
|
|
197
|
-
}
|
|
198
|
-
async function resolveItemIconUrl(provider, item, insertResult) {
|
|
199
|
-
if (provider.getItemIconUrl) {
|
|
200
|
-
try {
|
|
201
|
-
const iconUrl = normalizeOptionalIconUrl(
|
|
202
|
-
await Promise.resolve(provider.getItemIconUrl(item))
|
|
203
|
-
);
|
|
204
|
-
if (iconUrl) {
|
|
205
|
-
return iconUrl;
|
|
206
|
-
}
|
|
207
|
-
} catch {
|
|
208
|
-
return resolveInsertResultIconUrl(insertResult);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
return resolveInsertResultIconUrl(insertResult);
|
|
212
|
-
}
|
|
213
|
-
function createRichTextTriggerRegistry(providers) {
|
|
214
|
-
const providerMap = /* @__PURE__ */ new Map();
|
|
215
|
-
const triggerConfigKeys = /* @__PURE__ */ new Set();
|
|
216
|
-
const triggerConfigs = [];
|
|
217
|
-
for (const provider of providers) {
|
|
218
|
-
const providerId = normalizeProviderId(provider.id);
|
|
219
|
-
if (!providerId) {
|
|
220
|
-
throw new Error("Rich text trigger provider id is required.");
|
|
221
|
-
}
|
|
222
|
-
if (providerMap.has(providerId)) {
|
|
223
|
-
throw new Error(`Duplicate rich text trigger provider id: ${providerId}`);
|
|
224
|
-
}
|
|
225
|
-
providerMap.set(providerId, provider);
|
|
226
|
-
const triggerConfig = normalizeProviderTriggerConfig(provider);
|
|
227
|
-
const triggerConfigKey = `${triggerConfig.trigger}:${triggerConfig.boundary}`;
|
|
228
|
-
if (!triggerConfigKeys.has(triggerConfigKey)) {
|
|
229
|
-
triggerConfigKeys.add(triggerConfigKey);
|
|
230
|
-
triggerConfigs.push(triggerConfig);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
async function query(input) {
|
|
234
|
-
if (input.abortSignal?.aborted) {
|
|
235
|
-
return [];
|
|
236
|
-
}
|
|
237
|
-
const matches = await Promise.all(
|
|
238
|
-
[...providerMap.values()].filter(
|
|
239
|
-
(provider) => normalizeProviderTrigger(provider) === input.trigger
|
|
240
|
-
).map(async (provider) => {
|
|
241
|
-
if (input.abortSignal?.aborted) {
|
|
242
|
-
return [];
|
|
243
|
-
}
|
|
244
|
-
const items = await provider.query(input);
|
|
245
|
-
if (input.abortSignal?.aborted) {
|
|
246
|
-
return [];
|
|
247
|
-
}
|
|
248
|
-
return Promise.all(
|
|
249
|
-
items.map(async (item) => {
|
|
250
|
-
const insertResult = provider.toInsertResult(item);
|
|
251
|
-
return {
|
|
252
|
-
providerId: provider.id,
|
|
253
|
-
trigger: input.trigger,
|
|
254
|
-
key: provider.getItemKey(item),
|
|
255
|
-
label: provider.getItemLabel(item),
|
|
256
|
-
subtitle: provider.getItemSubtitle?.(item) || void 0,
|
|
257
|
-
iconUrl: await resolveItemIconUrl(provider, item, insertResult),
|
|
258
|
-
keywords: provider.getItemKeywords?.(item),
|
|
259
|
-
item,
|
|
260
|
-
insertResult
|
|
261
|
-
};
|
|
262
|
-
})
|
|
263
|
-
);
|
|
264
|
-
})
|
|
265
|
-
);
|
|
266
|
-
const flatMatches = matches.flat();
|
|
267
|
-
const limit = input.maxResults;
|
|
268
|
-
if (typeof limit === "number" && limit >= 0) {
|
|
269
|
-
return flatMatches.slice(0, limit);
|
|
270
|
-
}
|
|
271
|
-
return flatMatches;
|
|
272
|
-
}
|
|
273
|
-
return {
|
|
274
|
-
listProviders: () => [...providerMap.values()],
|
|
275
|
-
getProvider: (providerId) => providerMap.get(normalizeProviderId(providerId)),
|
|
276
|
-
listTriggerConfigs: () => [...triggerConfigs],
|
|
277
|
-
query
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
|
|
281
172
|
// src/plugins/mentionRegistry.ts
|
|
282
173
|
function normalizePluginId(pluginId) {
|
|
283
174
|
return pluginId.trim();
|
|
@@ -352,7 +243,6 @@ export {
|
|
|
352
243
|
createRichTextMentionInsertResult,
|
|
353
244
|
renderRichTextTriggerInsertResult,
|
|
354
245
|
createRichTextTriggerProvider,
|
|
355
|
-
createRichTextTriggerRegistry,
|
|
356
246
|
createRichTextMentionRegistry
|
|
357
247
|
};
|
|
358
|
-
//# sourceMappingURL=chunk-
|
|
248
|
+
//# sourceMappingURL=chunk-CLNWVUDR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/plugins/mention.ts","../src/plugins/trigger.ts","../src/plugins/mentionRegistry.ts"],"sourcesContent":["import type {\n RichTextMentionAttrs,\n RichTextMentionInsert,\n RichTextMentionPresentation,\n RichTextMentionPlugin,\n RichTextResolvedMention,\n RichTextResolvedMentionView\n} from \"../types/mention.ts\";\n\nconst richTextMentionTrigger = \"@\";\n\nfunction normalizeOptionalString(value?: string | null): string | undefined {\n const trimmed = value?.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction normalizeMentionLabel(value: string): string {\n return value.trim().replace(/^@+/, \"\").trim();\n}\n\nfunction normalizeStringRecord(\n values?: Readonly<Record<string, string>> | null\n): Readonly<Record<string, string>> | undefined {\n if (!values) {\n return undefined;\n }\n\n const nextEntries = Object.entries(values)\n .map(([key, value]) => [key.trim(), value.trim()] as const)\n .filter(([key, value]) => key.length > 0 && value.length > 0);\n\n if (nextEntries.length === 0) {\n return undefined;\n }\n\n return Object.freeze(Object.fromEntries(nextEntries));\n}\n\nfunction normalizeMentionPresentation(\n presentation?: RichTextMentionPresentation | null\n): RichTextMentionPresentation | undefined {\n if (!presentation) {\n return undefined;\n }\n\n const normalized: RichTextMentionPresentation = {};\n for (const key of richTextMentionPresentationKeys) {\n const value = normalizeOptionalString(presentation[key]);\n if (value) {\n normalized[key] = value;\n }\n }\n\n return Object.keys(normalized).length > 0\n ? Object.freeze(normalized)\n : undefined;\n}\n\nconst richTextMentionPresentationKeys = [\n \"agentProviderId\",\n \"agentIconUrl\",\n \"iconUrl\",\n \"thumbnailUrl\",\n \"subtitle\",\n \"description\",\n \"participant\",\n \"status\",\n \"statusDataStatus\",\n \"statusLabel\",\n \"statusPulse\",\n \"userAvatarPlaceholderUrl\"\n] as const satisfies readonly (keyof RichTextMentionPresentation)[];\n\nexport function createRichTextMentionAttrs(\n providerId: string,\n mention: RichTextMentionInsert\n): RichTextMentionAttrs {\n const normalizedProviderId = providerId.trim();\n const entityId = mention.entityId.trim();\n const label = normalizeMentionLabel(mention.label);\n\n if (!normalizedProviderId) {\n throw new Error(\"Rich text mention provider id is required.\");\n }\n if (!entityId) {\n throw new Error(\"Rich text mention entityId is required.\");\n }\n if (!label) {\n throw new Error(\"Rich text mention label is required.\");\n }\n\n const attrs: RichTextMentionAttrs = {\n trigger: richTextMentionTrigger,\n providerId: normalizedProviderId,\n entityId,\n label\n };\n const scope = normalizeStringRecord(mention.scope);\n const presentation = normalizeMentionPresentation(mention.presentation);\n if (scope) {\n attrs.scope = scope;\n }\n if (presentation) {\n attrs.presentation = presentation;\n }\n return attrs;\n}\n\nexport function isRichTextMentionAttrs(\n value: unknown\n): value is RichTextMentionAttrs {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n\n const candidate = value as Partial<RichTextMentionAttrs>;\n return (\n candidate.trigger === richTextMentionTrigger &&\n typeof candidate.providerId === \"string\" &&\n candidate.providerId.trim().length > 0 &&\n typeof candidate.entityId === \"string\" &&\n candidate.entityId.trim().length > 0 &&\n typeof candidate.label === \"string\" &&\n candidate.label.trim().length > 0\n );\n}\n\nexport function getRichTextMentionDisplayText(\n attrs: RichTextMentionAttrs\n): string {\n const label = normalizeMentionLabel(attrs.label);\n return label ? `@${label}` : \"\";\n}\n\nexport function resolveRichTextMentionView(\n mention: RichTextMentionAttrs,\n resolved?: RichTextResolvedMention | null\n): RichTextResolvedMentionView {\n const state = resolved?.state ?? \"active\";\n const label = normalizeMentionLabel(resolved?.label ?? mention.label);\n const tooltip = normalizeOptionalString(resolved?.tooltip);\n\n return {\n state,\n label,\n tooltip,\n presentation: normalizeMentionPresentation(\n resolved?.presentation ?? mention.presentation\n ),\n entity: resolved?.entity,\n interactive: state === \"active\"\n };\n}\n\nexport function createRichTextMentionPlugin<TItem, TResolved = unknown>(\n plugin: RichTextMentionPlugin<TItem, TResolved>\n): RichTextMentionPlugin<TItem, TResolved> {\n const id = plugin.id.trim();\n if (!id) {\n throw new Error(\"Rich text mention plugin id is required.\");\n }\n\n return {\n ...plugin,\n id,\n trigger: richTextMentionTrigger\n };\n}\n","import { createRichTextMentionAttrs } from \"./mention.ts\";\nimport {\n createRichTextMentionMarkdown,\n createRichTextLinkMarkdown\n} from \"../core/richTextDocument.ts\";\nimport type {\n RichTextTriggerProvider,\n RichTextMarkdownLinkInsertResult,\n RichTextMentionTriggerInsertResult,\n RichTextTriggerInsertResult,\n RichTextTextInsertResult\n} from \"../types/trigger.ts\";\n\nfunction normalizeRequiredString(value: string, fieldName: string): string {\n const trimmed = value.trim();\n if (!trimmed) {\n throw new Error(`Rich text ${fieldName} is required.`);\n }\n return trimmed;\n}\n\nexport function createRichTextTextInsertResult(\n text: string\n): RichTextTextInsertResult {\n return {\n kind: \"text\",\n text\n };\n}\n\nexport function createRichTextMarkdownLinkInsertResult(\n label: string,\n href: string\n): RichTextMarkdownLinkInsertResult {\n return {\n kind: \"markdown-link\",\n label: normalizeRequiredString(label, \"insert label\"),\n href: normalizeRequiredString(href, \"insert href\")\n };\n}\n\nexport function createRichTextMentionInsertResult(\n mention: RichTextMentionTriggerInsertResult[\"mention\"]\n): RichTextMentionTriggerInsertResult {\n return {\n kind: \"mention\",\n mention\n };\n}\n\nexport function renderRichTextTriggerInsertResult(\n providerId: string,\n result: RichTextTriggerInsertResult\n): string {\n switch (result.kind) {\n case \"mention\":\n return createRichTextMentionMarkdown(\n createRichTextMentionAttrs(providerId, result.mention)\n );\n case \"markdown-link\":\n return createRichTextLinkMarkdown({\n name: result.label,\n path: result.href,\n kind: result.href.endsWith(\"/\") ? \"folder\" : \"file\"\n });\n case \"text\":\n return result.text;\n default:\n return \"\";\n }\n}\n\nexport function createRichTextTriggerProvider<TItem>(\n provider: RichTextTriggerProvider<TItem>\n): RichTextTriggerProvider<TItem> {\n const id = normalizeRequiredString(provider.id, \"provider id\");\n\n return {\n ...provider,\n id\n };\n}\n","import {\n createRichTextMentionAttrs,\n resolveRichTextMentionView\n} from \"./mention.ts\";\nimport type {\n RichTextMentionPlugin,\n RichTextMentionQueryInput,\n RichTextMentionQueryMatch,\n RichTextMentionRegistry,\n RichTextMentionResolveInput,\n RichTextResolvedMentionView\n} from \"../types/mention.ts\";\n\nfunction normalizePluginId(pluginId: string): string {\n return pluginId.trim();\n}\n\nexport function createRichTextMentionRegistry(\n plugins: readonly RichTextMentionPlugin[]\n): RichTextMentionRegistry {\n const pluginMap = new Map<string, RichTextMentionPlugin>();\n\n for (const plugin of plugins) {\n const pluginId = normalizePluginId(plugin.id);\n if (!pluginId) {\n throw new Error(\"Rich text mention plugin id is required.\");\n }\n if (pluginMap.has(pluginId)) {\n throw new Error(`Duplicate rich text mention plugin id: ${pluginId}`);\n }\n pluginMap.set(pluginId, plugin);\n }\n\n async function query(\n input: RichTextMentionQueryInput\n ): Promise<readonly RichTextMentionQueryMatch[]> {\n const matches = await Promise.all(\n [...pluginMap.values()].map(async (plugin) => {\n const items = await plugin.query(input);\n return items.map<RichTextMentionQueryMatch>((item) => ({\n pluginId: plugin.id,\n key: plugin.getItemKey(item),\n label: plugin.getItemLabel(item),\n subtitle: plugin.getItemSubtitle?.(item) || undefined,\n keywords: plugin.getItemKeywords?.(item),\n item,\n mention: createRichTextMentionAttrs(plugin.id, plugin.toMention(item))\n }));\n })\n );\n\n const flatMatches = matches.flat();\n const limit = input.maxResults;\n if (typeof limit === \"number\" && limit >= 0) {\n return flatMatches.slice(0, limit);\n }\n return flatMatches;\n }\n\n async function resolve(\n input: RichTextMentionResolveInput\n ): Promise<RichTextResolvedMentionView> {\n const plugin = pluginMap.get(input.mention.providerId);\n if (!plugin) {\n return resolveRichTextMentionView(input.mention, {\n state: \"missing\"\n });\n }\n\n if (!plugin.resolveMention) {\n return resolveRichTextMentionView(input.mention, {\n state: \"active\"\n });\n }\n\n return resolveRichTextMentionView(\n input.mention,\n await plugin.resolveMention(input)\n );\n }\n\n return {\n listPlugins: () => [...pluginMap.values()],\n getPlugin: (pluginId: string) => pluginMap.get(normalizePluginId(pluginId)),\n query,\n resolve\n };\n}\n"],"mappings":"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","names":[]}
|