@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.
@@ -0,0 +1,316 @@
1
+ import {
2
+ createRichTextTriggerRegistry
3
+ } from "./chunk-3UTSSMV7.js";
4
+
5
+ // src/service/richTextMentionIdentityKey.ts
6
+ function compareScopeKeys(left, right) {
7
+ return left < right ? -1 : left > right ? 1 : 0;
8
+ }
9
+ function canonicalizeRichTextMentionScope(scope) {
10
+ if (!scope) {
11
+ return "{}";
12
+ }
13
+ const sortedScope = Object.fromEntries(
14
+ Object.entries(scope).sort(
15
+ ([left], [right]) => compareScopeKeys(left, right)
16
+ )
17
+ );
18
+ return JSON.stringify(sortedScope);
19
+ }
20
+ function normalizeRichTextMentionIdentity(identity) {
21
+ const providerId = identity.providerId.trim();
22
+ const entityId = identity.entityId.trim();
23
+ if (!providerId) {
24
+ throw new Error("Rich text mention provider id is required.");
25
+ }
26
+ if (!entityId) {
27
+ throw new Error("Rich text mention entity id is required.");
28
+ }
29
+ const scopeEntries = Object.entries(identity.scope ?? {}).sort(
30
+ ([left], [right]) => compareScopeKeys(left, right)
31
+ );
32
+ return {
33
+ providerId,
34
+ entityId,
35
+ label: identity.label,
36
+ ...scopeEntries.length > 0 ? { scope: Object.freeze(Object.fromEntries(scopeEntries)) } : {}
37
+ };
38
+ }
39
+ function createRichTextMentionIdentityKey(identity) {
40
+ const normalized = normalizeRichTextMentionIdentity(identity);
41
+ return `${normalized.providerId}\0${normalized.entityId}\0${canonicalizeRichTextMentionScope(normalized.scope)}`;
42
+ }
43
+
44
+ // src/service/RichTextMentionService.ts
45
+ var RICH_TEXT_MENTION_READY_TTL_MS = 3e5;
46
+ var RICH_TEXT_MENTION_MISSING_TTL_MS = 3e4;
47
+ var RICH_TEXT_MENTION_ERROR_RETRY_MS = 5e3;
48
+ var RICH_TEXT_MENTION_CACHE_CAPACITY = 1e3;
49
+ var idleSnapshot = Object.freeze({ state: "idle" });
50
+ function createRichTextMentionService(input) {
51
+ const registry = createRichTextTriggerRegistry(input.providers);
52
+ const now = input.now ?? Date.now;
53
+ const entries = /* @__PURE__ */ new Map();
54
+ const subscriptions = /* @__PURE__ */ new Set();
55
+ let disposed = false;
56
+ const emit = (event) => {
57
+ try {
58
+ input.diagnostics?.(event);
59
+ } catch {
60
+ }
61
+ };
62
+ const notify = (changedKeys) => {
63
+ if (disposed) return;
64
+ for (const subscription of [...subscriptions]) {
65
+ if (!subscription.key || !changedKeys || changedKeys.has(subscription.key)) {
66
+ try {
67
+ subscription.listener();
68
+ } catch {
69
+ }
70
+ }
71
+ }
72
+ };
73
+ const evictIfNeeded = () => {
74
+ if (entries.size <= RICH_TEXT_MENTION_CACHE_CAPACITY) return;
75
+ const candidates = [...entries.values()].filter((entry) => !entry.inFlight && entry.subscriberCount === 0).sort((left, right) => left.lastAccess - right.lastAccess);
76
+ while (entries.size > RICH_TEXT_MENTION_CACHE_CAPACITY && candidates.length > 0) {
77
+ const entry = candidates.shift();
78
+ if (entry) entries.delete(entry.key);
79
+ }
80
+ };
81
+ const getOrCreateEntry = (identity) => {
82
+ const normalized = normalizeRichTextMentionIdentity(identity);
83
+ const key = createRichTextMentionIdentityKey(normalized);
84
+ const existing = entries.get(key);
85
+ if (existing) {
86
+ existing.identity = normalized;
87
+ existing.lastAccess = now();
88
+ return existing;
89
+ }
90
+ const created = {
91
+ identity: normalized,
92
+ key,
93
+ snapshot: idleSnapshot,
94
+ expiresAt: 0,
95
+ lastAccess: now(),
96
+ revision: 0,
97
+ subscriberCount: 0,
98
+ invalidatedWhileInFlight: false
99
+ };
100
+ entries.set(key, created);
101
+ evictIfNeeded();
102
+ return created;
103
+ };
104
+ const startResolve = (entry) => {
105
+ if (entry.inFlight) return entry.inFlight;
106
+ if (disposed) return Promise.resolve(entry.snapshot);
107
+ const startedAt = now();
108
+ const requestRevision = entry.revision;
109
+ const previousReady = entry.snapshot.state === "ready" ? entry.snapshot : void 0;
110
+ const promise = Promise.resolve().then(async () => {
111
+ const provider = registry.getProvider(entry.identity.providerId);
112
+ const resolved = provider?.resolveMention ? await provider.resolveMention(entry.identity) : null;
113
+ if (disposed) return entry.snapshot;
114
+ const completedAt = now();
115
+ if (resolved) {
116
+ entry.snapshot = Object.freeze({
117
+ state: "ready",
118
+ resolved,
119
+ updatedAtUnixMs: completedAt
120
+ });
121
+ entry.expiresAt = completedAt + RICH_TEXT_MENTION_READY_TTL_MS;
122
+ emit({
123
+ name: "mention_resolve_completed",
124
+ providerId: entry.identity.providerId,
125
+ outcome: "success",
126
+ cacheStatus: previousReady ? "stale" : "miss",
127
+ durationMs: Math.max(0, completedAt - startedAt)
128
+ });
129
+ } else {
130
+ entry.snapshot = Object.freeze({
131
+ state: "missing",
132
+ updatedAtUnixMs: completedAt
133
+ });
134
+ entry.expiresAt = completedAt + RICH_TEXT_MENTION_MISSING_TTL_MS;
135
+ emit({
136
+ name: "mention_resolve_completed",
137
+ providerId: entry.identity.providerId,
138
+ outcome: "missing",
139
+ cacheStatus: previousReady ? "stale" : "miss",
140
+ durationMs: Math.max(0, completedAt - startedAt)
141
+ });
142
+ }
143
+ notify(/* @__PURE__ */ new Set([entry.key]));
144
+ return entry.snapshot;
145
+ }).catch(() => {
146
+ if (disposed) return entry.snapshot;
147
+ const completedAt = now();
148
+ if (previousReady) {
149
+ entry.snapshot = previousReady;
150
+ } else {
151
+ entry.snapshot = Object.freeze({
152
+ state: "error",
153
+ updatedAtUnixMs: completedAt
154
+ });
155
+ }
156
+ entry.expiresAt = completedAt + RICH_TEXT_MENTION_ERROR_RETRY_MS;
157
+ emit({
158
+ name: "mention_resolve_completed",
159
+ providerId: entry.identity.providerId,
160
+ outcome: "error",
161
+ cacheStatus: previousReady ? "stale" : "miss",
162
+ durationMs: Math.max(0, completedAt - startedAt)
163
+ });
164
+ notify(/* @__PURE__ */ new Set([entry.key]));
165
+ return entry.snapshot;
166
+ }).finally(() => {
167
+ entry.inFlight = void 0;
168
+ const needsTrailingResolve = !disposed && (entry.invalidatedWhileInFlight || entry.revision !== requestRevision);
169
+ entry.invalidatedWhileInFlight = false;
170
+ if (needsTrailingResolve) {
171
+ void startResolve(entry);
172
+ }
173
+ evictIfNeeded();
174
+ });
175
+ entry.inFlight = promise;
176
+ if (!previousReady) {
177
+ entry.snapshot = Object.freeze({ state: "loading" });
178
+ notify(/* @__PURE__ */ new Set([entry.key]));
179
+ }
180
+ return promise;
181
+ };
182
+ const service = {
183
+ listProviders: registry.listProviders,
184
+ getProvider: registry.getProvider,
185
+ listTriggerConfigs: registry.listTriggerConfigs,
186
+ async query(queryInput) {
187
+ const startedAt = now();
188
+ try {
189
+ const matches = await registry.query(queryInput);
190
+ emit({
191
+ name: "mention_query_completed",
192
+ providerId: "*",
193
+ outcome: "success",
194
+ cacheStatus: "miss",
195
+ durationMs: Math.max(0, now() - startedAt)
196
+ });
197
+ return matches;
198
+ } catch (error) {
199
+ emit({
200
+ name: "mention_query_completed",
201
+ providerId: "*",
202
+ outcome: "error",
203
+ cacheStatus: "miss",
204
+ durationMs: Math.max(0, now() - startedAt)
205
+ });
206
+ throw error;
207
+ }
208
+ },
209
+ resolve(identity) {
210
+ const entry = getOrCreateEntry(identity);
211
+ const currentTime = now();
212
+ if (entry.snapshot.state !== "idle" && entry.snapshot.state !== "loading" && currentTime < entry.expiresAt) {
213
+ emit({
214
+ name: "mention_resolve_completed",
215
+ providerId: entry.identity.providerId,
216
+ outcome: entry.snapshot.state === "ready" ? "success" : entry.snapshot.state === "missing" ? "missing" : "error",
217
+ cacheStatus: "hit",
218
+ durationMs: 0
219
+ });
220
+ return Promise.resolve(entry.snapshot);
221
+ }
222
+ if (entry.inFlight) {
223
+ return entry.snapshot.state === "ready" ? Promise.resolve(entry.snapshot) : entry.inFlight;
224
+ }
225
+ if (entry.snapshot.state === "ready") {
226
+ void startResolve(entry);
227
+ return Promise.resolve(entry.snapshot);
228
+ }
229
+ return startResolve(entry);
230
+ },
231
+ getSnapshot(identity) {
232
+ const key = createRichTextMentionIdentityKey(identity);
233
+ const entry = entries.get(key);
234
+ if (!entry) return idleSnapshot;
235
+ entry.lastAccess = now();
236
+ return entry.snapshot;
237
+ },
238
+ invalidate(selector) {
239
+ if (disposed) return;
240
+ const normalizedProviderId = selector?.providerId?.trim();
241
+ const normalizedEntityId = selector?.entityId?.trim();
242
+ const entriesToRefresh = [];
243
+ const invalidatedKeys = /* @__PURE__ */ new Set();
244
+ let invalidated = 0;
245
+ for (const entry of entries.values()) {
246
+ if (normalizedProviderId && entry.identity.providerId !== normalizedProviderId) {
247
+ continue;
248
+ }
249
+ if (normalizedEntityId && entry.identity.entityId !== normalizedEntityId) {
250
+ continue;
251
+ }
252
+ if (selector?.workspaceId && entry.identity.scope?.workspaceId !== selector.workspaceId) {
253
+ continue;
254
+ }
255
+ entry.revision += 1;
256
+ entry.expiresAt = 0;
257
+ if (entry.inFlight) entry.invalidatedWhileInFlight = true;
258
+ if (entry.subscriberCount > 0 && !entry.inFlight) {
259
+ entriesToRefresh.push(entry);
260
+ }
261
+ invalidatedKeys.add(entry.key);
262
+ invalidated += 1;
263
+ }
264
+ emit({
265
+ name: "mention_cache_invalidated",
266
+ providerId: normalizedProviderId ?? "*",
267
+ outcome: "success",
268
+ cacheStatus: "invalidated",
269
+ durationMs: 0
270
+ });
271
+ if (invalidated > 0) notify(invalidatedKeys);
272
+ for (const entry of entriesToRefresh) void startResolve(entry);
273
+ },
274
+ subscribe(listener, identity) {
275
+ if (disposed) return () => {
276
+ };
277
+ const entry = identity ? getOrCreateEntry(identity) : void 0;
278
+ const subscription = { listener, key: entry?.key };
279
+ subscriptions.add(subscription);
280
+ if (entry) {
281
+ entry.subscriberCount += 1;
282
+ if (!entries.has(entry.key)) entries.set(entry.key, entry);
283
+ evictIfNeeded();
284
+ }
285
+ let subscribed = true;
286
+ return () => {
287
+ if (!subscribed) return;
288
+ subscribed = false;
289
+ subscriptions.delete(subscription);
290
+ if (entry) {
291
+ entry.subscriberCount = Math.max(0, entry.subscriberCount - 1);
292
+ evictIfNeeded();
293
+ }
294
+ };
295
+ },
296
+ dispose() {
297
+ if (disposed) return;
298
+ disposed = true;
299
+ subscriptions.clear();
300
+ entries.clear();
301
+ }
302
+ };
303
+ return service;
304
+ }
305
+
306
+ export {
307
+ canonicalizeRichTextMentionScope,
308
+ normalizeRichTextMentionIdentity,
309
+ createRichTextMentionIdentityKey,
310
+ RICH_TEXT_MENTION_READY_TTL_MS,
311
+ RICH_TEXT_MENTION_MISSING_TTL_MS,
312
+ RICH_TEXT_MENTION_ERROR_RETRY_MS,
313
+ RICH_TEXT_MENTION_CACHE_CAPACITY,
314
+ createRichTextMentionService
315
+ };
316
+ //# sourceMappingURL=chunk-XN4EGZGR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/service/richTextMentionIdentityKey.ts","../src/service/RichTextMentionService.ts"],"sourcesContent":["import type { RichTextMentionIdentity } from \"../types/mention.ts\";\n\nexport interface NormalizedRichTextMentionIdentity extends RichTextMentionIdentity {\n providerId: string;\n entityId: string;\n scope?: Readonly<Record<string, string>>;\n}\n\nfunction compareScopeKeys(left: string, right: string): number {\n return left < right ? -1 : left > right ? 1 : 0;\n}\n\nexport function canonicalizeRichTextMentionScope(\n scope: RichTextMentionIdentity[\"scope\"]\n): string {\n if (!scope) {\n return \"{}\";\n }\n\n const sortedScope = Object.fromEntries(\n Object.entries(scope).sort(([left], [right]) =>\n compareScopeKeys(left, right)\n )\n );\n return JSON.stringify(sortedScope);\n}\n\nexport function normalizeRichTextMentionIdentity(\n identity: RichTextMentionIdentity\n): NormalizedRichTextMentionIdentity {\n const providerId = identity.providerId.trim();\n const entityId = identity.entityId.trim();\n if (!providerId) {\n throw new Error(\"Rich text mention provider id is required.\");\n }\n if (!entityId) {\n throw new Error(\"Rich text mention entity id is required.\");\n }\n\n const scopeEntries = Object.entries(identity.scope ?? {}).sort(\n ([left], [right]) => compareScopeKeys(left, right)\n );\n return {\n providerId,\n entityId,\n label: identity.label,\n ...(scopeEntries.length > 0\n ? { scope: Object.freeze(Object.fromEntries(scopeEntries)) }\n : {})\n };\n}\n\nexport function createRichTextMentionIdentityKey(\n identity: RichTextMentionIdentity\n): string {\n const normalized = normalizeRichTextMentionIdentity(identity);\n return `${normalized.providerId}\\0${normalized.entityId}\\0${canonicalizeRichTextMentionScope(normalized.scope)}`;\n}\n","import { createRichTextTriggerRegistry } from \"../plugins/triggerRegistry.ts\";\nimport type {\n RichTextMentionIdentity,\n RichTextMentionResolved\n} from \"../types/mention.ts\";\nimport type {\n RichTextTriggerConfig,\n RichTextTriggerProvider,\n RichTextTriggerQueryInput,\n RichTextTriggerQueryMatch\n} from \"../types/trigger.ts\";\nimport {\n createRichTextMentionIdentityKey,\n normalizeRichTextMentionIdentity,\n type NormalizedRichTextMentionIdentity\n} from \"./richTextMentionIdentityKey.ts\";\n\nexport const RICH_TEXT_MENTION_READY_TTL_MS = 300_000;\nexport const RICH_TEXT_MENTION_MISSING_TTL_MS = 30_000;\nexport const RICH_TEXT_MENTION_ERROR_RETRY_MS = 5_000;\nexport const RICH_TEXT_MENTION_CACHE_CAPACITY = 1_000;\n\nexport type RichTextMentionResolutionState =\n | \"idle\"\n | \"loading\"\n | \"ready\"\n | \"missing\"\n | \"error\";\n\nexport interface RichTextMentionSnapshot {\n state: RichTextMentionResolutionState;\n resolved?: RichTextMentionResolved;\n updatedAtUnixMs?: number;\n}\n\nexport interface RichTextMentionInvalidationSelector {\n providerId?: string;\n workspaceId?: string;\n entityId?: string;\n}\n\nexport type RichTextMentionDiagnosticEventName =\n | \"mention_query_completed\"\n | \"mention_resolve_completed\"\n | \"mention_cache_invalidated\";\n\nexport interface RichTextMentionDiagnosticEvent {\n name: RichTextMentionDiagnosticEventName;\n providerId: string;\n outcome: \"success\" | \"missing\" | \"error\";\n cacheStatus: \"hit\" | \"miss\" | \"stale\" | \"invalidated\";\n durationMs: number;\n}\n\nexport interface CreateRichTextMentionServiceInput {\n providers: readonly RichTextTriggerProvider[];\n now?: () => number;\n diagnostics?: (event: RichTextMentionDiagnosticEvent) => void;\n}\n\nexport interface RichTextMentionService {\n listProviders(): readonly RichTextTriggerProvider[];\n getProvider(providerId: string): RichTextTriggerProvider | undefined;\n listTriggerConfigs(): readonly RichTextTriggerConfig[];\n query(\n input: RichTextTriggerQueryInput\n ): Promise<readonly RichTextTriggerQueryMatch[]>;\n resolve(identity: RichTextMentionIdentity): Promise<RichTextMentionSnapshot>;\n getSnapshot(identity: RichTextMentionIdentity): RichTextMentionSnapshot;\n invalidate(selector?: RichTextMentionInvalidationSelector): void;\n subscribe(\n listener: () => void,\n identity?: RichTextMentionIdentity\n ): () => void;\n dispose(): void;\n}\n\ninterface MentionCacheEntry {\n identity: NormalizedRichTextMentionIdentity;\n key: string;\n snapshot: RichTextMentionSnapshot;\n expiresAt: number;\n lastAccess: number;\n revision: number;\n subscriberCount: number;\n inFlight?: Promise<RichTextMentionSnapshot>;\n invalidatedWhileInFlight: boolean;\n}\n\nconst idleSnapshot: RichTextMentionSnapshot = Object.freeze({ state: \"idle\" });\n\nexport function createRichTextMentionService(\n input: CreateRichTextMentionServiceInput\n): RichTextMentionService {\n const registry = createRichTextTriggerRegistry(input.providers);\n const now = input.now ?? Date.now;\n const entries = new Map<string, MentionCacheEntry>();\n const subscriptions = new Set<{\n key?: string;\n listener: () => void;\n }>();\n let disposed = false;\n\n const emit = (event: RichTextMentionDiagnosticEvent): void => {\n try {\n input.diagnostics?.(event);\n } catch {\n // Diagnostics are observational and must never change mention behavior.\n }\n };\n\n const notify = (changedKeys?: ReadonlySet<string>): void => {\n if (disposed) return;\n for (const subscription of [...subscriptions]) {\n if (\n !subscription.key ||\n !changedKeys ||\n changedKeys.has(subscription.key)\n ) {\n try {\n subscription.listener();\n } catch {\n // One observer must not interrupt cache transitions or other observers.\n }\n }\n }\n };\n\n const evictIfNeeded = (): void => {\n if (entries.size <= RICH_TEXT_MENTION_CACHE_CAPACITY) return;\n const candidates = [...entries.values()]\n .filter((entry) => !entry.inFlight && entry.subscriberCount === 0)\n .sort((left, right) => left.lastAccess - right.lastAccess);\n while (\n entries.size > RICH_TEXT_MENTION_CACHE_CAPACITY &&\n candidates.length > 0\n ) {\n const entry = candidates.shift();\n if (entry) entries.delete(entry.key);\n }\n };\n\n const getOrCreateEntry = (\n identity: RichTextMentionIdentity\n ): MentionCacheEntry => {\n const normalized = normalizeRichTextMentionIdentity(identity);\n const key = createRichTextMentionIdentityKey(normalized);\n const existing = entries.get(key);\n if (existing) {\n existing.identity = normalized;\n existing.lastAccess = now();\n return existing;\n }\n const created: MentionCacheEntry = {\n identity: normalized,\n key,\n snapshot: idleSnapshot,\n expiresAt: 0,\n lastAccess: now(),\n revision: 0,\n subscriberCount: 0,\n invalidatedWhileInFlight: false\n };\n entries.set(key, created);\n evictIfNeeded();\n return created;\n };\n\n const startResolve = (\n entry: MentionCacheEntry\n ): Promise<RichTextMentionSnapshot> => {\n if (entry.inFlight) return entry.inFlight;\n if (disposed) return Promise.resolve(entry.snapshot);\n\n const startedAt = now();\n const requestRevision = entry.revision;\n const previousReady =\n entry.snapshot.state === \"ready\" ? entry.snapshot : undefined;\n const promise = Promise.resolve()\n .then(async () => {\n const provider = registry.getProvider(entry.identity.providerId);\n const resolved = provider?.resolveMention\n ? await provider.resolveMention(entry.identity)\n : null;\n if (disposed) return entry.snapshot;\n\n const completedAt = now();\n if (resolved) {\n entry.snapshot = Object.freeze({\n state: \"ready\",\n resolved,\n updatedAtUnixMs: completedAt\n });\n entry.expiresAt = completedAt + RICH_TEXT_MENTION_READY_TTL_MS;\n emit({\n name: \"mention_resolve_completed\",\n providerId: entry.identity.providerId,\n outcome: \"success\",\n cacheStatus: previousReady ? \"stale\" : \"miss\",\n durationMs: Math.max(0, completedAt - startedAt)\n });\n } else {\n entry.snapshot = Object.freeze({\n state: \"missing\",\n updatedAtUnixMs: completedAt\n });\n entry.expiresAt = completedAt + RICH_TEXT_MENTION_MISSING_TTL_MS;\n emit({\n name: \"mention_resolve_completed\",\n providerId: entry.identity.providerId,\n outcome: \"missing\",\n cacheStatus: previousReady ? \"stale\" : \"miss\",\n durationMs: Math.max(0, completedAt - startedAt)\n });\n }\n notify(new Set([entry.key]));\n return entry.snapshot;\n })\n .catch(() => {\n if (disposed) return entry.snapshot;\n const completedAt = now();\n if (previousReady) {\n entry.snapshot = previousReady;\n } else {\n entry.snapshot = Object.freeze({\n state: \"error\",\n updatedAtUnixMs: completedAt\n });\n }\n entry.expiresAt = completedAt + RICH_TEXT_MENTION_ERROR_RETRY_MS;\n emit({\n name: \"mention_resolve_completed\",\n providerId: entry.identity.providerId,\n outcome: \"error\",\n cacheStatus: previousReady ? \"stale\" : \"miss\",\n durationMs: Math.max(0, completedAt - startedAt)\n });\n notify(new Set([entry.key]));\n return entry.snapshot;\n })\n .finally(() => {\n entry.inFlight = undefined;\n const needsTrailingResolve =\n !disposed &&\n (entry.invalidatedWhileInFlight ||\n entry.revision !== requestRevision);\n entry.invalidatedWhileInFlight = false;\n if (needsTrailingResolve) {\n void startResolve(entry);\n }\n evictIfNeeded();\n });\n entry.inFlight = promise;\n if (!previousReady) {\n entry.snapshot = Object.freeze({ state: \"loading\" });\n notify(new Set([entry.key]));\n }\n return promise;\n };\n\n const service: RichTextMentionService = {\n listProviders: registry.listProviders,\n getProvider: registry.getProvider,\n listTriggerConfigs: registry.listTriggerConfigs,\n async query(queryInput) {\n const startedAt = now();\n try {\n const matches = await registry.query(queryInput);\n emit({\n name: \"mention_query_completed\",\n providerId: \"*\",\n outcome: \"success\",\n cacheStatus: \"miss\",\n durationMs: Math.max(0, now() - startedAt)\n });\n return matches;\n } catch (error) {\n emit({\n name: \"mention_query_completed\",\n providerId: \"*\",\n outcome: \"error\",\n cacheStatus: \"miss\",\n durationMs: Math.max(0, now() - startedAt)\n });\n throw error;\n }\n },\n resolve(identity) {\n const entry = getOrCreateEntry(identity);\n const currentTime = now();\n if (\n entry.snapshot.state !== \"idle\" &&\n entry.snapshot.state !== \"loading\" &&\n currentTime < entry.expiresAt\n ) {\n emit({\n name: \"mention_resolve_completed\",\n providerId: entry.identity.providerId,\n outcome:\n entry.snapshot.state === \"ready\"\n ? \"success\"\n : entry.snapshot.state === \"missing\"\n ? \"missing\"\n : \"error\",\n cacheStatus: \"hit\",\n durationMs: 0\n });\n return Promise.resolve(entry.snapshot);\n }\n if (entry.inFlight) {\n return entry.snapshot.state === \"ready\"\n ? Promise.resolve(entry.snapshot)\n : entry.inFlight;\n }\n if (entry.snapshot.state === \"ready\") {\n void startResolve(entry);\n return Promise.resolve(entry.snapshot);\n }\n return startResolve(entry);\n },\n getSnapshot(identity) {\n const key = createRichTextMentionIdentityKey(identity);\n const entry = entries.get(key);\n if (!entry) return idleSnapshot;\n entry.lastAccess = now();\n return entry.snapshot;\n },\n invalidate(selector) {\n if (disposed) return;\n const normalizedProviderId = selector?.providerId?.trim();\n const normalizedEntityId = selector?.entityId?.trim();\n const entriesToRefresh: MentionCacheEntry[] = [];\n const invalidatedKeys = new Set<string>();\n let invalidated = 0;\n for (const entry of entries.values()) {\n if (\n normalizedProviderId &&\n entry.identity.providerId !== normalizedProviderId\n ) {\n continue;\n }\n if (\n normalizedEntityId &&\n entry.identity.entityId !== normalizedEntityId\n ) {\n continue;\n }\n if (\n selector?.workspaceId &&\n entry.identity.scope?.workspaceId !== selector.workspaceId\n ) {\n continue;\n }\n entry.revision += 1;\n entry.expiresAt = 0;\n if (entry.inFlight) entry.invalidatedWhileInFlight = true;\n if (entry.subscriberCount > 0 && !entry.inFlight) {\n entriesToRefresh.push(entry);\n }\n invalidatedKeys.add(entry.key);\n invalidated += 1;\n }\n emit({\n name: \"mention_cache_invalidated\",\n providerId: normalizedProviderId ?? \"*\",\n outcome: \"success\",\n cacheStatus: \"invalidated\",\n durationMs: 0\n });\n if (invalidated > 0) notify(invalidatedKeys);\n for (const entry of entriesToRefresh) void startResolve(entry);\n },\n subscribe(listener, identity) {\n if (disposed) return () => {};\n const entry = identity ? getOrCreateEntry(identity) : undefined;\n const subscription = { listener, key: entry?.key };\n subscriptions.add(subscription);\n if (entry) {\n entry.subscriberCount += 1;\n if (!entries.has(entry.key)) entries.set(entry.key, entry);\n evictIfNeeded();\n }\n let subscribed = true;\n return () => {\n if (!subscribed) return;\n subscribed = false;\n subscriptions.delete(subscription);\n if (entry) {\n entry.subscriberCount = Math.max(0, entry.subscriberCount - 1);\n evictIfNeeded();\n }\n };\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n subscriptions.clear();\n entries.clear();\n }\n };\n\n return service;\n}\n"],"mappings":"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","names":[]}
@@ -1,8 +1,9 @@
1
1
  import { ReactNode, JSX } from 'react';
2
2
  import { RichTextTriggerProvider, RichTextTriggerQueryMatch, RichTextTrigger, RichTextTriggerConfig, RichTextTriggerBoundary, RichTextTriggerRegistry, RichTextTriggerQueryInput } from '../types/index.js';
3
3
  import { a as MentionPaletteCategoryConfig } from '../mentionPaletteModel-CT8fzBE2.js';
4
+ import { h as RichTextMentionService, i as RichTextMentionSnapshot } from '../RichTextMentionService-CsZ9CGQf.js';
4
5
  import { a as RichTextI18nRuntime } from '../richTextI18n-CUeqHuEQ.js';
5
- import { R as RichTextMentionAttrs, l as RichTextResolvedMention, m as RichTextResolvedMentionView } from '../mention-DJq2OJ4K.js';
6
+ import { R as RichTextMentionAttrs, l as RichTextResolvedMention, m as RichTextResolvedMentionView, a as RichTextMentionIdentity } from '../mention-DJq2OJ4K.js';
6
7
  import '@tutti-os/ui-i18n-runtime';
7
8
 
8
9
  interface RichTextTriggerTextOverrides {
@@ -17,7 +18,9 @@ type RichTextTriggerMenuAnchor = "cursor" | "editor";
17
18
  interface RichTextTriggerEditorProps {
18
19
  value: string;
19
20
  onChange: (value: string) => void;
21
+ /** @deprecated Prefer mentionService or RichTextMentionServiceProvider. */
20
22
  triggerProviders?: readonly RichTextTriggerProvider[];
23
+ mentionService?: RichTextMentionService;
21
24
  placeholder?: string;
22
25
  disabled?: boolean;
23
26
  className?: string;
@@ -48,12 +51,14 @@ interface RichTextTriggerEditorPaletteOptions {
48
51
  };
49
52
  maxHeightPx?: number;
50
53
  }
51
- declare function RichTextTriggerEditor({ value, onChange, triggerProviders, placeholder, disabled, className, textareaClassName, placeholderClassName, minQueryLength, maxResults, removeDecorationAriaLabel, i18n, textOverrides, overlay, focusSignal, menuAnchor, menuPlacement, menuOffset, menuZIndex, palette }: RichTextTriggerEditorProps): JSX.Element;
54
+ declare function RichTextTriggerEditor({ value, onChange, triggerProviders, mentionService, placeholder, disabled, className, textareaClassName, placeholderClassName, minQueryLength, maxResults, removeDecorationAriaLabel, i18n, textOverrides, overlay, focusSignal, menuAnchor, menuPlacement, menuOffset, menuZIndex, palette }: RichTextTriggerEditorProps): JSX.Element;
52
55
 
53
56
  interface RichTextTriggerTextareaProps {
54
57
  value: string;
55
58
  onChange: (value: string) => void;
59
+ /** @deprecated Prefer mentionService or RichTextMentionServiceProvider. */
56
60
  triggerProviders?: readonly RichTextTriggerProvider[];
61
+ mentionService?: RichTextMentionService;
57
62
  placeholder?: string;
58
63
  disabled?: boolean;
59
64
  className?: string;
@@ -66,7 +71,7 @@ interface RichTextTriggerTextareaProps {
66
71
  textOverrides?: RichTextTriggerTextOverrides;
67
72
  overlay?: ReactNode;
68
73
  }
69
- declare function RichTextTriggerTextarea({ value, onChange, triggerProviders, placeholder, disabled, className, textareaClassName, rows, minQueryLength, maxResults, removeDecorationAriaLabel, i18n, textOverrides, overlay }: RichTextTriggerTextareaProps): JSX.Element;
74
+ declare function RichTextTriggerTextarea({ value, onChange, triggerProviders, mentionService, placeholder, disabled, className, textareaClassName, rows, minQueryLength, maxResults, removeDecorationAriaLabel, i18n, textOverrides, overlay }: RichTextTriggerTextareaProps): JSX.Element;
70
75
 
71
76
  interface RichTextMentionReadonlyClickPayload<TResolved = unknown> {
72
77
  mention: RichTextMentionAttrs;
@@ -91,10 +96,25 @@ interface RichTextReadonlyContentProps {
91
96
  value: string;
92
97
  className?: string;
93
98
  paragraphClassName?: string;
99
+ /** @deprecated Prefer mentionService or RichTextMentionServiceProvider. */
100
+ triggerProviders?: readonly RichTextTriggerProvider[];
101
+ mentionService?: RichTextMentionService;
94
102
  onMentionAction?: (mention: RichTextMentionAttrs) => void | Promise<void>;
95
103
  onOpenWorkspaceReference?: (reference: RichTextReadonlyWorkspaceReference) => void | Promise<void>;
96
104
  }
97
- declare function RichTextReadonlyContent({ value, className, paragraphClassName, onMentionAction, onOpenWorkspaceReference }: RichTextReadonlyContentProps): JSX.Element | null;
105
+ declare function RichTextReadonlyContent({ value, className, paragraphClassName, triggerProviders, mentionService, onMentionAction, onOpenWorkspaceReference }: RichTextReadonlyContentProps): JSX.Element | null;
106
+
107
+ interface RichTextMentionServiceProviderProps {
108
+ service: RichTextMentionService;
109
+ children?: ReactNode;
110
+ }
111
+ declare function RichTextMentionServiceProvider({ service, children }: RichTextMentionServiceProviderProps): JSX.Element;
112
+ declare function useRichTextMentionService(explicitService?: RichTextMentionService): RichTextMentionService | null;
113
+ declare function useEffectiveRichTextMentionService(input: {
114
+ mentionService?: RichTextMentionService;
115
+ triggerProviders?: readonly RichTextTriggerProvider[];
116
+ }): RichTextMentionService;
117
+ declare function useResolvedRichTextMention(identity: RichTextMentionIdentity, explicitService?: RichTextMentionService): RichTextMentionSnapshot;
98
118
 
99
119
  interface RichTextTriggerQueryState {
100
120
  from: number;
@@ -106,4 +126,4 @@ declare function isRichTextTriggerPrefixBoundary(character: string, boundary: Ri
106
126
  declare function findRichTextTriggerQuery(value: string, caret: number, triggerConfigs: readonly RichTextTriggerConfig[]): RichTextTriggerQueryState | null;
107
127
  declare function queryRichTextTriggerMatches(registry: RichTextTriggerRegistry, input: RichTextTriggerQueryInput): Promise<readonly RichTextTriggerQueryMatch[]>;
108
128
 
109
- export { RichTextMentionReadonly, type RichTextMentionReadonlyClickPayload, type RichTextMentionReadonlyProps, RichTextReadonlyContent, type RichTextReadonlyContentProps, type RichTextReadonlyWorkspaceReference, RichTextTriggerEditor, type RichTextTriggerEditorProps, type RichTextTriggerMenuAnchor, type RichTextTriggerMenuPlacement, type RichTextTriggerQueryState, type RichTextTriggerTextOverrides, RichTextTriggerTextarea, type RichTextTriggerTextareaProps, findRichTextTriggerQuery, isRichTextTriggerPrefixBoundary, queryRichTextTriggerMatches };
129
+ export { RichTextMentionReadonly, type RichTextMentionReadonlyClickPayload, type RichTextMentionReadonlyProps, RichTextMentionServiceProvider, type RichTextMentionServiceProviderProps, RichTextReadonlyContent, type RichTextReadonlyContentProps, type RichTextReadonlyWorkspaceReference, RichTextTriggerEditor, type RichTextTriggerEditorProps, type RichTextTriggerMenuAnchor, type RichTextTriggerMenuPlacement, type RichTextTriggerQueryState, type RichTextTriggerTextOverrides, RichTextTriggerTextarea, type RichTextTriggerTextareaProps, findRichTextTriggerQuery, isRichTextTriggerPrefixBoundary, queryRichTextTriggerMatches, useEffectiveRichTextMentionService, useResolvedRichTextMention, useRichTextMentionService };