@plannotator/ui 0.31.0 → 0.32.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/README.md +45 -1
- package/components/AnnotationPanel.tsx +96 -4
- package/components/AnnotationToolbar.tsx +25 -25
- package/components/CommentPopover.tsx +26 -0
- package/components/GraphvizBlock.tsx +86 -7
- package/components/HtmlSurfaceControls.tsx +170 -0
- package/components/InlineMarkdown.tsx +22 -2
- package/components/MermaidBlock.tsx +60 -26
- package/components/Settings.tsx +40 -1
- package/components/blocks/MathBlock.tsx +26 -14
- package/components/html-viewer/HtmlViewer.tsx +115 -5
- package/components/html-viewer/bridge-script.ts +41 -7
- package/components/html-viewer/hostThreads.ts +37 -0
- package/components/html-viewer/index.ts +9 -0
- package/components/html-viewer/unanchored.ts +47 -0
- package/components/html-viewer/useHtmlAnnotation.ts +95 -5
- package/configure.ts +32 -0
- package/hooks/useHtmlRefresh.ts +149 -0
- package/hooks/useMathRenderer.ts +30 -0
- package/hooks/useSharing.ts +31 -5
- package/package.json +4 -2
- package/styles.css +1 -1
- package/types.ts +1 -0
- package/utils/generateIdentity.ts +64 -14
- package/utils/identity-tater.ts +36 -0
- package/utils/math-eager.ts +25 -0
- package/utils/math.ts +146 -0
- package/utils/mermaid-eager.ts +28 -0
- package/utils/mermaid.ts +132 -0
- package/utils/parser.ts +38 -0
- package/utils/quickLabels.ts +13 -0
- package/webmcp/activity.ts +46 -0
- package/webmcp/changes.ts +227 -0
- package/webmcp/index.ts +72 -0
- package/webmcp/modelContext.ts +103 -0
- package/webmcp/nudges.ts +174 -0
- package/webmcp/policy.ts +50 -0
- package/webmcp/preference.ts +50 -0
- package/webmcp/schema.ts +81 -0
- package/webmcp/toolset.ts +337 -0
- package/webmcp/useToolset.ts +74 -0
package/hooks/useSharing.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* - Tracking whether current session is from a shared link
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import React, { useState, useEffect, useCallback, useRef } from 'react';
|
|
11
|
+
import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react';
|
|
12
12
|
import { Annotation, type ImageAttachment } from '../types';
|
|
13
13
|
import {
|
|
14
14
|
type SharePayload,
|
|
@@ -104,6 +104,7 @@ export function useSharing(
|
|
|
104
104
|
setRawHtml?: (h: string) => void,
|
|
105
105
|
setShareHtml?: (h: string) => void,
|
|
106
106
|
setRenderAs?: (m: 'markdown' | 'html') => void,
|
|
107
|
+
contentRevision = 0,
|
|
107
108
|
): UseSharingResult {
|
|
108
109
|
const [isSharedSession, setIsSharedSession] = useState(false);
|
|
109
110
|
const [isLoadingShared, setIsLoadingShared] = useState(true);
|
|
@@ -115,6 +116,23 @@ export function useSharing(
|
|
|
115
116
|
const [pendingSharedAnnotations, setPendingSharedAnnotations] = useState<Annotation[] | null>(null);
|
|
116
117
|
const [sharedGlobalAttachments, setSharedGlobalAttachments] = useState<ImageAttachment[] | null>(null);
|
|
117
118
|
const [shareLoadError, setShareLoadError] = useState('');
|
|
119
|
+
// Identity token for in-flight share requests: a new token invalidates any
|
|
120
|
+
// response still on the wire. Content inputs only — resolveRawHtmlForShare
|
|
121
|
+
// is deliberately NOT a dependency: its identity changes when it caches the
|
|
122
|
+
// portable HTML mid-request (App memoizes it on shareHtml), and listing it
|
|
123
|
+
// would make the first short-link generation on an HTML session discard its
|
|
124
|
+
// own result. HTML refreshes invalidate through contentRevision instead.
|
|
125
|
+
const shareRequestContext = useMemo(() => ({}), [
|
|
126
|
+
markdown,
|
|
127
|
+
annotations,
|
|
128
|
+
globalAttachments,
|
|
129
|
+
shareBaseUrl,
|
|
130
|
+
pasteApiUrl,
|
|
131
|
+
rawHtml,
|
|
132
|
+
contentRevision,
|
|
133
|
+
]);
|
|
134
|
+
const latestShareRequestContextRef = useRef(shareRequestContext);
|
|
135
|
+
latestShareRequestContextRef.current = shareRequestContext;
|
|
118
136
|
|
|
119
137
|
const clearPendingSharedAnnotations = useCallback(() => {
|
|
120
138
|
setPendingSharedAnnotations(null);
|
|
@@ -257,16 +275,19 @@ export function useSharing(
|
|
|
257
275
|
|
|
258
276
|
// Generate share URL when markdown or annotations change
|
|
259
277
|
const refreshShareUrl = useCallback(async () => {
|
|
278
|
+
const requestContext = shareRequestContext;
|
|
260
279
|
try {
|
|
261
280
|
const url = await generateShareUrl(markdown, annotations, globalAttachments, shareBaseUrl, rawHtml);
|
|
281
|
+
if (latestShareRequestContextRef.current !== requestContext) return;
|
|
262
282
|
setShareUrl(url ?? '');
|
|
263
283
|
setShareUrlSize(url ? formatUrlSize(url) : '');
|
|
264
284
|
} catch (e) {
|
|
285
|
+
if (latestShareRequestContextRef.current !== requestContext) return;
|
|
265
286
|
console.error('Failed to generate share URL:', e);
|
|
266
287
|
setShareUrl('');
|
|
267
288
|
setShareUrlSize('');
|
|
268
289
|
}
|
|
269
|
-
}, [markdown, annotations, globalAttachments, shareBaseUrl, rawHtml]);
|
|
290
|
+
}, [markdown, annotations, globalAttachments, shareBaseUrl, rawHtml, shareRequestContext]);
|
|
270
291
|
|
|
271
292
|
// Auto-refresh share URL when dependencies change
|
|
272
293
|
useEffect(() => {
|
|
@@ -280,9 +301,10 @@ export function useSharing(
|
|
|
280
301
|
useEffect(() => {
|
|
281
302
|
if (isSharedSession) { isSharedRef.current = true; return; }
|
|
282
303
|
if (isSharedRef.current) { isSharedRef.current = false; return; }
|
|
304
|
+
setIsGeneratingShortUrl(false);
|
|
283
305
|
setShortShareUrl('');
|
|
284
306
|
setShortUrlError('');
|
|
285
|
-
}, [markdown, annotations, globalAttachments, rawHtml, isSharedSession]);
|
|
307
|
+
}, [markdown, annotations, globalAttachments, rawHtml, isSharedSession, contentRevision]);
|
|
286
308
|
|
|
287
309
|
/**
|
|
288
310
|
* Generate a short URL via the paste service.
|
|
@@ -295,6 +317,7 @@ export function useSharing(
|
|
|
295
317
|
|
|
296
318
|
setIsGeneratingShortUrl(true);
|
|
297
319
|
setShortUrlError('');
|
|
320
|
+
const requestContext = shareRequestContext;
|
|
298
321
|
|
|
299
322
|
try {
|
|
300
323
|
const htmlForShare = rawHtml
|
|
@@ -308,6 +331,8 @@ export function useSharing(
|
|
|
308
331
|
htmlForShare,
|
|
309
332
|
);
|
|
310
333
|
|
|
334
|
+
if (latestShareRequestContextRef.current !== requestContext) return null;
|
|
335
|
+
|
|
311
336
|
if (result) {
|
|
312
337
|
setShortShareUrl(result.shortUrl);
|
|
313
338
|
return result.shortUrl;
|
|
@@ -317,13 +342,14 @@ export function useSharing(
|
|
|
317
342
|
return null;
|
|
318
343
|
}
|
|
319
344
|
} catch (e) {
|
|
345
|
+
if (latestShareRequestContextRef.current !== requestContext) return null;
|
|
320
346
|
setShortShareUrl('');
|
|
321
347
|
setShortUrlError(e instanceof Error ? e.message : 'Failed to generate short URL');
|
|
322
348
|
return null;
|
|
323
349
|
} finally {
|
|
324
|
-
setIsGeneratingShortUrl(false);
|
|
350
|
+
if (latestShareRequestContextRef.current === requestContext) setIsGeneratingShortUrl(false);
|
|
325
351
|
}
|
|
326
|
-
}, [markdown, annotations, globalAttachments, shareBaseUrl, pasteApiUrl, rawHtml, resolveRawHtmlForShare]);
|
|
352
|
+
}, [markdown, annotations, globalAttachments, shareBaseUrl, pasteApiUrl, rawHtml, resolveRawHtmlForShare, shareRequestContext]);
|
|
327
353
|
|
|
328
354
|
// Import annotations from a teammate's share URL (supports both hash-based and short /p/<id> URLs)
|
|
329
355
|
const importFromShareUrl = useCallback(async (url: string): Promise<ImportResult> => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plannotator/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./components/*": "./components/*.tsx",
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"./lib/*": "./lib/*.ts",
|
|
18
18
|
"./hooks/*": "./hooks/*.ts",
|
|
19
19
|
"./shortcuts": "./shortcuts/index.ts",
|
|
20
|
+
"./webmcp": "./webmcp/index.ts",
|
|
20
21
|
"./config": "./config/index.ts",
|
|
21
22
|
"./configure": "./configure.ts",
|
|
22
23
|
"./theme-modes": "./components/themeModes.tsx",
|
|
@@ -32,6 +33,7 @@
|
|
|
32
33
|
"lib",
|
|
33
34
|
"shortcuts",
|
|
34
35
|
"utils",
|
|
36
|
+
"webmcp",
|
|
35
37
|
"assets",
|
|
36
38
|
"themes",
|
|
37
39
|
"sprite_package_additional",
|
|
@@ -69,7 +71,7 @@
|
|
|
69
71
|
"@lezer/highlight": "^1.2.3",
|
|
70
72
|
"@pierre/diffs": "1.3.2",
|
|
71
73
|
"@plannotator/atomic-editor": "^0.8.0",
|
|
72
|
-
"@plannotator/core": "0.
|
|
74
|
+
"@plannotator/core": "0.25.0",
|
|
73
75
|
"@plannotator/markdown-editor": "^0.4.0",
|
|
74
76
|
"@plannotator/web-highlighter": "^0.8.1",
|
|
75
77
|
"@tanstack/react-table": "^8.21.3",
|