@veltdev/lexical-velt-comments 4.5.2-beta.1 → 4.5.2-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/cjs/index.js +1 -1
  2. package/cjs/index.js.map +1 -1
  3. package/cjs/types/src/adapters/host/doc.d.ts +97 -0
  4. package/cjs/types/src/adapters/host/marks.d.ts +89 -0
  5. package/cjs/types/src/adapters/host/storage.d.ts +37 -0
  6. package/cjs/types/src/adapters/velt.d.ts +55 -0
  7. package/cjs/types/src/constants/common.d.ts +67 -0
  8. package/cjs/types/src/core/extension.d.ts +40 -0
  9. package/cjs/types/src/core/registry.d.ts +71 -0
  10. package/cjs/types/src/core/state.d.ts +86 -0
  11. package/cjs/types/src/features/addComment.d.ts +63 -0
  12. package/cjs/types/src/features/commentRenderer.d.ts +46 -0
  13. package/cjs/types/src/features/renderComments.d.ts +73 -0
  14. package/cjs/types/src/features/updateContent.d.ts +32 -0
  15. package/cjs/types/src/index.d.ts +26 -0
  16. package/cjs/types/src/types/common.d.ts +72 -0
  17. package/cjs/types/src/types/host.d.ts +65 -0
  18. package/cjs/types/src/types/state.d.ts +28 -0
  19. package/cjs/types/src/types/velt.d.ts +6 -0
  20. package/cjs/types/src/utils/common.d.ts +56 -0
  21. package/cjs/types/src/utils/console.d.ts +37 -0
  22. package/cjs/types/src/utils/host.d.ts +44 -0
  23. package/cjs/types/src/utils/serializer.d.ts +19 -0
  24. package/esm/index.js +1 -1
  25. package/esm/index.js.map +1 -1
  26. package/esm/types/src/adapters/host/doc.d.ts +97 -0
  27. package/esm/types/src/adapters/host/marks.d.ts +89 -0
  28. package/esm/types/src/adapters/host/storage.d.ts +37 -0
  29. package/esm/types/src/adapters/velt.d.ts +55 -0
  30. package/esm/types/src/constants/common.d.ts +67 -0
  31. package/esm/types/src/core/extension.d.ts +40 -0
  32. package/esm/types/src/core/registry.d.ts +71 -0
  33. package/esm/types/src/core/state.d.ts +86 -0
  34. package/esm/types/src/features/addComment.d.ts +63 -0
  35. package/esm/types/src/features/commentRenderer.d.ts +46 -0
  36. package/esm/types/src/features/renderComments.d.ts +73 -0
  37. package/esm/types/src/features/updateContent.d.ts +32 -0
  38. package/esm/types/src/index.d.ts +26 -0
  39. package/esm/types/src/types/common.d.ts +72 -0
  40. package/esm/types/src/types/host.d.ts +65 -0
  41. package/esm/types/src/types/state.d.ts +28 -0
  42. package/esm/types/src/types/velt.d.ts +6 -0
  43. package/esm/types/src/utils/common.d.ts +56 -0
  44. package/esm/types/src/utils/console.d.ts +37 -0
  45. package/esm/types/src/utils/host.d.ts +44 -0
  46. package/esm/types/src/utils/serializer.d.ts +19 -0
  47. package/index.d.ts +275 -30
  48. package/package.json +1 -1
  49. package/tsconfig.tsbuildinfo +1 -0
  50. package/cjs/types/comment-node.d.ts +0 -23
  51. package/cjs/types/constants.d.ts +0 -6
  52. package/cjs/types/editor.d.ts +0 -166
  53. package/cjs/types/index.d.ts +0 -24
  54. package/cjs/types/plugin.d.ts +0 -14
  55. package/cjs/types/serializer.d.ts +0 -9
  56. package/cjs/types/store.d.ts +0 -39
  57. package/cjs/types/types.d.ts +0 -40
  58. package/cjs/types/utility.d.ts +0 -122
  59. package/cjs/types/velt.d.ts +0 -21
  60. package/esm/types/comment-node.d.ts +0 -23
  61. package/esm/types/constants.d.ts +0 -6
  62. package/esm/types/editor.d.ts +0 -166
  63. package/esm/types/index.d.ts +0 -24
  64. package/esm/types/plugin.d.ts +0 -14
  65. package/esm/types/serializer.d.ts +0 -9
  66. package/esm/types/store.d.ts +0 -39
  67. package/esm/types/types.d.ts +0 -40
  68. package/esm/types/utility.d.ts +0 -122
  69. package/esm/types/velt.d.ts +0 -21
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Render comments feature module.
3
+ *
4
+ * Purpose: Public API entry point for rendering comment annotations.
5
+ * Orchestrates state updates, subscriptions, and delegates to commentRenderer.
6
+ *
7
+ * Key responsibilities:
8
+ * - Update state with new annotations
9
+ * - Subscribe to selected annotations from Velt
10
+ * - Delegate rendering logic to commentRenderer
11
+ *
12
+ * Dependencies:
13
+ * - adapters/velt.ts (for Velt SDK subscription)
14
+ * - adapters/host/doc.ts (for editor setup)
15
+ * - core/state.ts (for state management)
16
+ * - core/registry.ts (for editor ID extraction)
17
+ * - features/commentRenderer.ts (for rendering logic)
18
+ * - types/velt.ts (for CommentAnnotation)
19
+ *
20
+ * IMPORTANT: This module MUST NOT import editor or Velt types directly.
21
+ * All SDK access goes through adapters.
22
+ */
23
+ import type { RenderCommentsRequest } from '@/types/common';
24
+ /**
25
+ * Renders comment annotations as marks in the editor.
26
+ *
27
+ * This function renders comment annotations as visual marks in the editor.
28
+ * It filters annotations for the specific editor and applies marks accordingly.
29
+ *
30
+ * @param request - Object containing editor, editorId (optional), and commentAnnotations (optional)
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * // Simple usage
35
+ * renderComments({ editor });
36
+ *
37
+ * // With editor ID
38
+ * renderComments({ editorId: 'my-editor', editor });
39
+ *
40
+ * // With annotations
41
+ * renderComments({
42
+ * editorId: 'my-editor',
43
+ * editor,
44
+ * commentAnnotations: [
45
+ * {
46
+ * annotationId: 'ann-123',
47
+ * context: {
48
+ * textEditorConfig: {
49
+ * text: 'Hello world',
50
+ * occurrence: 1,
51
+ * editorId: 'my-editor'
52
+ * }
53
+ * }
54
+ * }
55
+ * ]
56
+ * });
57
+ * ```
58
+ *
59
+ * @remarks
60
+ * - Only annotations with matching editorId are rendered
61
+ * - Automatically subscribes to selected annotations changes
62
+ * - Filters out terminal/resolved comments unless they're selected
63
+ * - Removes marks when comments become resolved
64
+ * - Re-applies marks when resolved comments are selected
65
+ */
66
+ export declare const renderComments: ({ editor, editorId, commentAnnotations, }: RenderCommentsRequest) => void;
67
+ /**
68
+ * Cleans up subscriptions and renderer state for an editor.
69
+ * Should be called when editor is destroyed.
70
+ *
71
+ * @param editorId Unique identifier for the editor
72
+ */
73
+ export declare const cleanupRenderComments: (editorId: string) => void;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Update content feature module.
3
+ *
4
+ * Purpose: Handle document changes and annotation context updates.
5
+ * Orchestrates adapters and core to detect and process annotation changes.
6
+ *
7
+ * Key responsibilities:
8
+ * - Detect document changes during transactions
9
+ * - Compare current state with original annotations
10
+ * - Detect content, occurrence, and container changes
11
+ * - Update Velt contexts for changed annotations
12
+ * - Update marks in editor if needed
13
+ *
14
+ * Dependencies:
15
+ * - adapters/host/doc.ts (for change detection)
16
+ * - adapters/velt.ts (for context updates)
17
+ * - adapters/host/marks.ts (for mark updates)
18
+ * - core/state.ts (for state access)
19
+ * - types/host.ts (for AnnotationChange)
20
+ *
21
+ * IMPORTANT: This module MUST NOT import Lexical or Velt types directly.
22
+ * All SDK access goes through adapters.
23
+ */
24
+ /**
25
+ * Handles content updates when document changes occur.
26
+ * Detects annotation changes and updates Velt contexts accordingly.
27
+ *
28
+ * @param editorId Unique identifier for the editor
29
+ * @param editor The editor instance
30
+ * @param transaction The transaction object
31
+ */
32
+ export declare const handleContentUpdate: (editorId: string, editor: unknown, transaction: unknown) => void;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Public API for Lexical-Velt Comments extension.
3
+ *
4
+ * This module exports the public API surface for the v2 implementation.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { addComment, renderComments, CommentNode } from 'lexical-velt-comments';
9
+ *
10
+ * // Create editor with CommentNode registered
11
+ * const editor = createEditor({
12
+ * nodes: [CommentNode, ...otherNodes]
13
+ * });
14
+ *
15
+ * // Add a comment (auto-registers editor)
16
+ * await addComment({ editor, context: { customData: 'value' } });
17
+ *
18
+ * // Render existing comments (auto-registers editor)
19
+ * renderComments({ editor, commentAnnotations: annotations });
20
+ * ```
21
+ */
22
+ export { addComment } from '@/features/addComment';
23
+ export { renderComments } from '@/features/renderComments';
24
+ export type { AddCommentRequest, CommentAnnotationContext, LexicalVeltCommentConfig, RenderCommentsRequest } from '@/types/common';
25
+ export { CommentNode } from '@/adapters/host/marks';
26
+ export { exportJSONWithoutComments } from '@/utils/serializer';
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Common type definitions shared across the entire codebase.
3
+ * These types are SDK-agnostic and represent domain concepts.
4
+ */
5
+ import type { CommentAnnotation } from '@/types/velt';
6
+ /**
7
+ * Context object for comment annotations.
8
+ * Contains text editor configuration and any additional context data.
9
+ */
10
+ export interface CommentAnnotationContext {
11
+ textEditorConfig?: {
12
+ text: string;
13
+ occurrence: number;
14
+ editorId?: string;
15
+ targetTextNodeId?: string;
16
+ };
17
+ [key: string]: unknown;
18
+ }
19
+ /**
20
+ * Configuration options for Lexical Velt Comments extension.
21
+ * Matches Tiptap's TiptapVeltCommentConfig structure.
22
+ */
23
+ export interface LexicalVeltCommentConfig {
24
+ editorId?: string;
25
+ context?: CommentAnnotationContext;
26
+ }
27
+ /**
28
+ * Extension configuration options for LexicalVeltComments.
29
+ * Matches Tiptap's TiptapVeltCommentsOptions structure.
30
+ * Note: Lexical doesn't use HTMLAttributes or persistVeltMarks, but we keep the structure for consistency.
31
+ */
32
+ export interface LexicalVeltCommentsOptions {
33
+ HTMLAttributes?: Record<string, unknown>;
34
+ persistVeltMarks?: boolean;
35
+ editorId?: string;
36
+ context?: CommentAnnotationContext;
37
+ }
38
+ /**
39
+ * Extension configuration for registry.
40
+ */
41
+ export interface ExtensionConfig {
42
+ persistVeltMarks?: boolean;
43
+ editorId?: string;
44
+ HTMLAttributes?: Record<string, unknown>;
45
+ }
46
+ /**
47
+ * Request interface for addComment function.
48
+ * Matches legacy AddCommentRequest interface.
49
+ */
50
+ export interface AddCommentRequest {
51
+ editorId?: string;
52
+ editor: unknown;
53
+ context?: CommentAnnotationContext;
54
+ }
55
+ /**
56
+ * Request interface for renderComments function.
57
+ * Matches legacy RenderCommentsRequest interface.
58
+ */
59
+ export interface RenderCommentsRequest {
60
+ editor: unknown;
61
+ editorId?: string;
62
+ commentAnnotations?: CommentAnnotation[];
63
+ }
64
+ /**
65
+ * Editor context containing editor instance and related state.
66
+ * Note: Editor type is generic to avoid importing Lexical/Tiptap types here.
67
+ */
68
+ export interface EditorContext<TEditor = unknown> {
69
+ editorId: string;
70
+ editor: TEditor;
71
+ config: ExtensionConfig;
72
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Lexical editor-specific type definitions
3
+ *
4
+ * This is the ONLY place where Lexical types may be imported.
5
+ * All other modules must use adapter interfaces instead of concrete Lexical types.
6
+ */
7
+ import type { AnnotationData } from '@/types/state';
8
+ /**
9
+ * Selection context extracted from editor
10
+ * Contains all information needed about the current selection
11
+ */
12
+ export interface SelectionContext {
13
+ text: string;
14
+ from: number;
15
+ to: number;
16
+ occurrence: number;
17
+ targetTextNodeId?: string;
18
+ locationId?: string;
19
+ }
20
+ /**
21
+ * Occurrence match found in document
22
+ * Represents one occurrence of a text pattern
23
+ */
24
+ export interface OccurrenceMatch {
25
+ start: number;
26
+ end: number;
27
+ occurrence: number;
28
+ }
29
+ /**
30
+ * Document change event
31
+ * Represents a change to the document content
32
+ */
33
+ export interface DocumentChangeEvent {
34
+ type: 'insert' | 'delete' | 'replace';
35
+ from: number;
36
+ to: number;
37
+ insertedText?: string;
38
+ deletedText?: string;
39
+ }
40
+ /**
41
+ * Represents a detected change to an annotation during document editing.
42
+ * Matches Tiptap's AnnotationChange interface.
43
+ */
44
+ export interface AnnotationChange {
45
+ annotationId: string;
46
+ multiThreadAnnotationId?: string;
47
+ originalText: string;
48
+ currentText: string;
49
+ originalOccurrence: number;
50
+ currentOccurrence: number;
51
+ originalTargetTextNodeId: string;
52
+ newTargetTextNodeId: string;
53
+ annotation: AnnotationData;
54
+ contentChanged: boolean;
55
+ occurrenceChanged: boolean;
56
+ targetTextNodeIdChanged: boolean;
57
+ }
58
+ /**
59
+ * Text match interface for search results.
60
+ * Represents a range of text found in the document.
61
+ */
62
+ export interface TextMatch {
63
+ start: number;
64
+ end: number;
65
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * State management type definitions.
3
+ * These types represent the internal state structure for managing annotations.
4
+ */
5
+ import type { CommentAnnotationContext } from '@/types/common';
6
+ import type { CommentAnnotation } from '@/types/velt';
7
+ /**
8
+ * Represents a single annotation with its associated data and position.
9
+ */
10
+ export interface AnnotationData {
11
+ annotationId: string;
12
+ multiThreadAnnotationId?: string;
13
+ context: CommentAnnotationContext;
14
+ position?: {
15
+ from: number;
16
+ to: number;
17
+ };
18
+ }
19
+ /**
20
+ * Complete annotation state for a single editor instance.
21
+ * Maintains annotations map, comment annotations array (with status), and selected annotations set.
22
+ */
23
+ export interface AnnotationState {
24
+ annotations: Map<string, AnnotationData>;
25
+ commentAnnotations: CommentAnnotation[];
26
+ selectedAnnotations: Set<string>;
27
+ editorId: string;
28
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Velt SDK type definitions.
3
+ * Re-exports Velt types for convenience.
4
+ * NOTE: This is the ONLY place where @veltdev/types should be imported.
5
+ */
6
+ export type { CommentAnnotation, Location, Velt, CommentElement, } from '@veltdev/types';
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Pure utility functions with zero side effects
3
+ *
4
+ * This module contains pure, testable utility functions extracted from src/utility.ts.
5
+ * These functions have NO dependencies on Lexical, Velt, or any external SDKs.
6
+ */
7
+ /**
8
+ * KMP Search implementation for finding text patterns
9
+ *
10
+ * Pure function for efficient string pattern matching using the Knuth-Morris-Pratt algorithm.
11
+ * Migrated from src/utility.ts UtilityService.kmpSearch()
12
+ *
13
+ * @param text - The text to search in
14
+ * @param pattern - The pattern to search for
15
+ * @param startPos - Starting position offset (default: 0)
16
+ * @param maxOccurrences - Maximum number of occurrences to find (optional)
17
+ * @returns Array of positions where pattern was found
18
+ */
19
+ export declare const kmpSearch: (text: string, pattern: string, startPos?: number, maxOccurrences?: number) => number[];
20
+ /**
21
+ * Compute KMP failure function table
22
+ *
23
+ * Pure function that computes the longest proper prefix which is also a suffix (LPS) table
24
+ * for the Knuth-Morris-Pratt algorithm.
25
+ * Migrated from src/utility.ts UtilityService.computeKMPTable()
26
+ *
27
+ * @param pattern - The pattern to compute table for
28
+ * @returns Array representing the failure function (LPS table)
29
+ */
30
+ export declare const computeKMPTable: (pattern: string) => number[];
31
+ /**
32
+ * Find text occurrences in a string
33
+ *
34
+ * Convenience function that uses KMP search to find all occurrences.
35
+ *
36
+ * @param text - Text to search in
37
+ * @param searchText - Text to search for
38
+ * @returns Array of occurrence matches with start/end positions
39
+ */
40
+ export declare const findTextOccurrences: (text: string, searchText: string) => Array<{
41
+ start: number;
42
+ end: number;
43
+ }>;
44
+ /**
45
+ * Calculate occurrence index for a given position
46
+ *
47
+ * Determines which occurrence (1-indexed) a given position corresponds to.
48
+ *
49
+ * @param matches - Array of match positions with start/end
50
+ * @param position - Position to find occurrence for
51
+ * @returns 1-indexed occurrence number, or null if not found
52
+ */
53
+ export declare const calculateOccurrenceIndex: (matches: Array<{
54
+ start: number;
55
+ end: number;
56
+ }>, position: number) => number | null;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Console utility class providing controlled logging with debug mode support.
3
+ *
4
+ * Logging methods (log, warn, error, debug, info) are only active when debug mode
5
+ * is enabled via sessionStorage. The `catch` method always outputs as warnings
6
+ * for error handling visibility.
7
+ */
8
+ export declare class Console {
9
+ /** Log a message (only when debug mode is enabled via sessionStorage) */
10
+ static log: (...data: any[]) => void;
11
+ /** Log a warning (only when debug mode is enabled via sessionStorage) */
12
+ static warn: (...data: any[]) => void;
13
+ /** Log an error (only when debug mode is enabled via sessionStorage) */
14
+ static error: (...data: any[]) => void;
15
+ /** Log debug info (only when debug mode is enabled via sessionStorage) */
16
+ static debug: (...data: any[]) => void;
17
+ /** Log info (only when debug mode is enabled via sessionStorage) */
18
+ static info: (...data: any[]) => void;
19
+ /** Flag indicating if logging is enabled (used by catch method) */
20
+ static logsEnabled: boolean;
21
+ /**
22
+ * Log caught errors from try/catch blocks.
23
+ * Always outputs as console.warn with the LOG_PREFIX for visibility.
24
+ * Use this instead of console.error in catch blocks.
25
+ *
26
+ * @param message - Descriptive message about what operation failed
27
+ * @param error - Optional error object caught in the try/catch
28
+ */
29
+ static catch: (message: string, error?: unknown) => void;
30
+ /**
31
+ * Check if debug logging should be shown.
32
+ * Checks sessionStorage for debugMode or forceDebugMode flags.
33
+ *
34
+ * @returns true if debug mode is enabled, false otherwise
35
+ */
36
+ static showLogs(): boolean;
37
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Host editor-specific utility functions
3
+ *
4
+ * This module contains host editor-specific utility functions that are shared
5
+ * across multiple adapters. These functions depend on host editor types (Lexical).
6
+ *
7
+ * For pure utilities without host editor dependencies, see utils/common.ts
8
+ */
9
+ import { type LexicalEditor, type LexicalNode, type TextNode } from 'lexical';
10
+ /**
11
+ * Collect all text content including paragraph breaks.
12
+ * Migrated from src/utility.ts UtilityService.collectTextContent()
13
+ *
14
+ * @param root - Root Lexical node to traverse
15
+ * @returns Object with combined text and node map
16
+ */
17
+ export declare const collectTextContent: (root: LexicalNode) => {
18
+ combinedText: string;
19
+ nodeMap: Array<{
20
+ node: TextNode | null;
21
+ start: number;
22
+ end: number;
23
+ isParagraphBreak?: boolean;
24
+ }>;
25
+ };
26
+ /**
27
+ * Get text content for a specific container.
28
+ * Migrated from src/utility.ts UtilityService.getContainerTextContent()
29
+ *
30
+ * @param containerElement - DOM element representing the container
31
+ * @param editor - Lexical editor instance
32
+ * @param nodeMap - Node map from collectTextContent
33
+ * @param combinedText - Combined text from collectTextContent
34
+ * @returns Container text content with start offset, or null if not found
35
+ */
36
+ export declare const getContainerTextContent: (containerElement: HTMLElement, editor: LexicalEditor, nodeMap: Array<{
37
+ node: TextNode | null;
38
+ start: number;
39
+ end: number;
40
+ isParagraphBreak?: boolean;
41
+ }>, combinedText: string) => {
42
+ text: string;
43
+ startOffset: number;
44
+ } | null;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Serializer utilities for Lexical editor state
3
+ *
4
+ * This module provides utilities for serializing Lexical editor state,
5
+ * particularly for removing comment nodes from serialized JSON.
6
+ *
7
+ * Migrated from src/serializer.ts
8
+ */
9
+ import type { LexicalEditor, SerializedEditorState, SerializedLexicalNode } from 'lexical';
10
+ /**
11
+ * Export JSON without comment nodes.
12
+ *
13
+ * This function serializes the editor state and removes all comment nodes,
14
+ * unwrapping their children and normalizing adjacent text nodes.
15
+ *
16
+ * @param editor - Lexical editor instance
17
+ * @returns Serialized editor state without comment nodes
18
+ */
19
+ export declare const exportJSONWithoutComments: (editor: LexicalEditor) => SerializedEditorState<SerializedLexicalNode>;
package/esm/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{ElementNode as t,$isTextNode as e,$isElementNode as n,$getRoot as r,$createTextNode as o,$getSelection as i,$isRangeSelection as a,createEditor as c}from"lexical";const s={EDITOR_ID:"data-editor-id",LOCATION_ID:"data-velt-location-id"};class d extends t{static getType(){return"comment"}static clone(t){return new d(t.__annotationId,t.__multiThreadAnnotationId,t.__key)}constructor(t,e,n){super(n),this.__annotationId=t,this.__multiThreadAnnotationId=e}createDOM(t){const e=document.createElement("velt-comment-text");return this.__annotationId&&e.setAttribute("annotation-id",this.__annotationId),this.__multiThreadAnnotationId&&e.setAttribute("multi-thread-annotation-id",this.__multiThreadAnnotationId),e}updateDOM(t,e,n){return!1}static importJSON(t){return l(t.annotationId,t.multiThreadAnnotationId)}exportJSON(){return{...super.exportJSON(),annotationId:this.__annotationId,multiThreadAnnotationId:this.__multiThreadAnnotationId,type:"comment",version:1}}isInline(){return!0}}function l(t,e){return new d(t,e)}function g(t){return t instanceof d}var u;class h{}u=h,h.selectedCommentsMap=new Map,h.subscribers=new Map,h.isSubscribed=!1,h.getCommentElement=()=>{try{const t=window.Velt;return t?.getCommentElement?t.getCommentElement():null}catch(t){return u.catchError("Error getting comment element:",t),null}},h.addManualComment=({context:t,location:e})=>{try{const n=u.getCommentElement();return n?n.addManualComment({context:t,location:e}):Promise.resolve(null)}catch(t){return u.catchError("Error adding manual comment:",t),Promise.resolve(null)}},h.updateContext=({annotationId:t,context:e})=>{try{const n=u.getCommentElement();return n?n.updateContext(t,e):Promise.resolve(null)}catch(t){u.catchError("Error updating context:",t)}},h.subscribeToSelectedCommentsMap=(t,e)=>{try{u.subscribeToSelectedAnnotationsMapSingleton(),u.subscribers.set(t,e)}catch(t){u.catchError("Error subscribing to selected comments map:",t)}},h.unsubscribeFromSelectedCommentsMap=t=>{try{u.subscribers.delete(t)}catch(t){u.catchError("Error unsubscribing from selected comments map:",t)}},h.catchError=(t,e)=>{try{let n={};e&&"object"==typeof e&&(n={...n,...e}),t&&(n.message=t),n.sdkVersion=window.Velt?.version}catch(t){}},h.subscribeToSelectedAnnotationsMapSingleton=()=>{try{if(u.isSubscribed)return;const t=u.getCommentElement();t&&"function"==typeof t?.getSelectedComments&&(t?.getSelectedComments()?.subscribe(t=>{const e=new Map;t?.forEach(t=>{t?.annotationId&&e.set(t?.annotationId,!0)});((t,e)=>{if(t.size!==e.size)return!1;for(const[n,r]of t)if(e.get(n)!==r)return!1;return!0})(e,u.selectedCommentsMap||new Map)||u.updateSelectedCommentsMap(e)}),u.isSubscribed=!0)}catch(t){return new Map}},h.updateSelectedCommentsMap=t=>{try{u.selectedCommentsMap=t,u.subscribers.forEach(t=>{"function"==typeof t&&t(u.selectedCommentsMap)})}catch(t){u.catchError("Error updating selected comments map:",t)}};class f{static kmpSearch(t,e,n=0,r){try{const o=[];if(!e||!t||e.length>t.length)return o;const i=f.computeKMPTable(e);let a=0,c=0;for(;a<t.length;)if(e[c]===t[a]&&(a++,c++),c===e.length){if(o.push(n+a-c),c=i[c-1],r&&o.length>=r)break}else a<t.length&&e[c]!==t[a]&&(0!==c?c=i[c-1]:a++);return o}catch(t){return[]}}static computeKMPTable(t){try{const e=new Array(t.length).fill(0);let n=0,r=1;for(;r<t.length;)t[r]===t[n]?(n++,e[r]=n,r++):0!==n?n=e[n-1]:(e[r]=0,r++);return e}catch(t){return[]}}static collectTextContent(t){try{const r=[];let o="",i=0;const a=(t,c=0)=>{if(e(t)){const e=t.getTextContent(),n=i,a=i+e.length;r.push({node:t,start:n,end:a}),o+=e,i+=e.length}else if(n(t)){const e=t.getChildren(),s=t.getType();for(let t=0;t<e.length;t++)a(e[t],c+1);if("paragraph"===s&&1===c){const e=t.getParent();if(e&&n(e)){const n=e.getChildren();if(n.indexOf(t)<n.length-1){const t=i,e=i+1;r.push({node:null,start:t,end:e,isParagraphBreak:!0}),o+="\n",i+=1}}}}};return a(t),{combinedText:o,nodeMap:r}}catch(t){return h.catchError("Error collecting text content:",t),{combinedText:"",nodeMap:[]}}}static getTextNodesInRange(t,e,n,r){try{const o=[],{combinedText:i,nodeMap:a}=f.collectTextContent(t);for(const t of a){if(t.isParagraphBreak||!t.node)continue;const i=t.node.getParent();if((!g(i)||!r||i.__annotationId!==r)&&(t.end>e&&t.start<n)){const r=Math.max(0,e-t.start),i=Math.min(t.node.getTextContent().length,n-t.start),a=r>0||i<t.node.getTextContent().length;o.push({node:t.node,startOffset:r,endOffset:i,isPartial:a})}}return o}catch(t){return h.catchError("Error getting text nodes in range:",t),[]}}static isRangeAlreadyWrapped(t,r,o,i){try{let a=0,c=!1;const s=t=>{if(g(t)){if(t.__annotationId===i){const e=t.getTextContent(),n=a,i=a+e.length;if(n<=r&&i>=o)return c=!0,!0}const e=t.getTextContent();a+=e.length}else if(e(t)){const e=t.getTextContent();a+=e.length}else if(n(t)){const e=t.getChildren();for(const t of e)if(s(t))return!0;if("paragraph"===t.getType()){const e=t.getParent();if(e&&n(e)){const n=e.getChildren();n.indexOf(t)<n.length-1&&(a+=1)}}}return!1};return s(t),c}catch(t){return!0}}static findParagraphParent(t){let e=t.getParent();for(;e;){if(n(e)&&"paragraph"===e.getType())return e;e=e.getParent()}return null}static getContainerTextContent(t,e,n,r){try{let o=-1,i=-1;for(let r=0;r<n.length;r++){const a=n[r];if(!a.isParagraphBreak&&a.node)try{const n=a.node.getKey(),r=e.getElementByKey(n);r&&t.contains(r)&&(-1===o&&(o=a.start),i=a.end)}catch(t){continue}}if(-1===o||-1===i)return null;return{text:r.substring(o,i),startOffset:o}}catch(t){return null}}static findCommonParentWithId(t,e,n){try{const r=100;let o=0;const i=[];let a=t;for(;a&&a!==document.body&&o<r&&n.contains(a);)a.id&&i.push(a),a=a.parentElement,o++;let c=e;for(o=0;c&&c!==document.body&&o<r&&n.contains(c);){if(c.id&&i.includes(c))return c;c=c.parentElement,o++}return null}catch(t){return null}}static findContainerWithId(t,e){try{const n=100;let r=0,o=t;for(;o&&o!==document.body&&r<n&&e.contains(o);){if(o.id)return o;o=o.parentElement,r++}return null}catch(t){return null}}static getSelectionTextRange(t,e){const n=r(),{nodeMap:o}=f.collectTextContent(n),i=e.anchor.getNode(),a=e.focus.getNode(),c=e.anchor.offset,s=e.focus.offset;let d=0,l=0;for(const t of o){if(t.isParagraphBreak||!t.node)continue;const e=t.node.getKey();e===i.getKey()&&(d=t.start+c),e===a.getKey()&&(l=t.start+s)}return{start:Math.min(d,l),end:Math.max(d,l)}}static wrapPartialTextNode(t,e,n,r){try{const i=t.getWritable(),a=i.getTextContent(),c=a.substring(0,e),s=a.substring(e,n),d=a.substring(n),l=o(s);if(l.setFormat(i.getFormat()),l.setStyle(i.getStyle()),r.append(l),c){const t=o(c);t.setFormat(i.getFormat()),t.setStyle(i.getStyle()),i.insertBefore(t)}if(i.insertBefore(r),d){const t=o(d);t.setFormat(i.getFormat()),t.setStyle(i.getStyle()),i.insertBefore(t)}i.remove()}catch(t){}}static wrapEntireTextNode(t,e){try{const n=t.getWritable();e.append(n);const r=n.getParent();if(r){const t=r.getWritable(),o=n.getIndexWithinParent();t.splice(o,1,[e])}}catch(t){}}static wrapMultipleTextNodesWithFormatting(t,e){try{const n=new Map;for(const e of t){const t=f.findParagraphParent(e.node),r=t?t.getKey():"no-paragraph";n.has(r)||n.set(r,[]),n.get(r).push(e)}let r=!0;for(const[,t]of n.entries()){const n=r?e:l(e.__annotationId,e.__multiThreadAnnotationId);if(1===t.length){const e=t[0],{node:r,startOffset:o,endOffset:i,isPartial:a}=e;a?f.wrapPartialTextNode(r,o,i,n):f.wrapEntireTextNode(r,n)}else f.wrapMultipleNodesInSameParagraph(t,n);r=!1}}catch(t){h.catchError("Error in wrapMultipleTextNodesWithFormatting:",t)}}static wrapMultipleNodesInSameParagraph(t,e){try{const n=[...t].sort((t,e)=>t.node.getIndexWithinParent()-e.node.getIndexWithinParent()),r=n[0],i=n[n.length-1],a=r.node.getWritable(),c=a.getParent();if(!c)return;const s=c.getWritable();let d=a.getIndexWithinParent();if(r.isPartial&&r.startOffset>0){const t=r.node.getTextContent().substring(0,r.startOffset),n=r.node.getTextContent().substring(r.startOffset),i=o(t);i.setFormat(a.getFormat()),i.setStyle(a.getStyle());const c=o(n);c.setFormat(a.getFormat()),c.setStyle(a.getStyle()),e.append(c),s.splice(d,1,[i,e])}else e.append(a),s.splice(d,1,[e]);for(let t=1;t<n.length-1;t++){const r=n[t].node.getWritable();e.append(r)}if(n.length>1){const t=i.node.getWritable();if(i.isPartial&&i.endOffset<i.node.getTextContent().length){const n=i.node.getTextContent().substring(0,i.endOffset),r=i.node.getTextContent().substring(i.endOffset),a=o(n);a.setFormat(t.getFormat()),a.setStyle(t.getStyle());const c=o(r);c.setFormat(t.getFormat()),c.setStyle(t.getStyle()),e.append(a),t.replace(c)}else e.append(t)}}catch(t){h.catchError("Error in wrapMultipleNodesInSameParagraph:",t)}}}class m{constructor(t){this.plugin=t}initializeTransactionListener(t){try{this.editorUpdateListenerRemover&&this.editorUpdateListenerRemover(),this.editorUpdateListenerRemover=t.registerUpdateListener(({editorState:e,prevEditorState:n})=>{try{if(e===n||!this.hasDocumentChanged(e,n))return;this.onTransaction(t)}catch(t){}})}catch(t){h.catchError("Error initializing transaction listener:",t)}}destroyTransactionListener(){try{this.editorUpdateListenerRemover&&(this.editorUpdateListenerRemover(),this.editorUpdateListenerRemover=void 0)}catch(t){h.catchError("Error destroying transaction listener:",t)}}hasDocumentChanged(t,e){try{return t.read(()=>{const t=r().getTextContent();return e.read(()=>{const e=r().getTextContent();return t!==e})})}catch(t){return!0}}onTransaction(t){try{const e=new Map,n=this.collectDocumentAnnotations(t);for(const[r,o]of Array.from(n.entries())){const n=this.processAnnotationChanges(t,o);n&&e.set(r,n)}if(e.size>0){if(!h.getCommentElement())return;this.updateVeltComments(e,t)}}catch(t){h.catchError("Error in onTransaction:",t)}}getCommentNodeTextWithStructure(t){try{let r="";const o=(t,i=0)=>{if(e(t))r+=t.getTextContent();else if(n(t)){const e=t.getChildren(),a=t.getType();for(let t=0;t<e.length;t++)o(e[t],i+1);if("paragraph"===a&&i>=0){const e=t.getParent();if(e&&n(e)){const n=e.getChildren();n.indexOf(t)<n.length-1&&(r+="\n")}}}};return o(t),r}catch(e){return t.getTextContent()}}collectDocumentAnnotations(t){try{const o=new Map,i=this;return t.getEditorState().read(()=>{const t=r();let a=0;const c=t=>{if(g(t)){const e=t.__annotationId;if(!e)return;const n=i.plugin.storeService.annotationStore.get(e);if(!n)return;const r=i.getCommentNodeTextWithStructure(t),c=r.length,s=o.get(e),d={node:{text:r,nodeSize:c},pos:a};s?s.nodes.push(d):o.set(e,{id:e,multiThreadAnnotationId:t.__multiThreadAnnotationId,annotation:n.annotation,nodes:[d],originalText:n.annotation.context?.textEditorConfig?.text||"",originalOccurrence:n.annotation.context?.textEditorConfig?.occurrence||1,targetTextNodeId:n.annotation.context?.textEditorConfig?.targetTextNodeId||""}),a+=c}else if(e(t))a+=t.getTextContent().length;else if(n(t)){const e=t.getChildren();for(const t of e)c(t)}};c(t)}),o}catch(t){return h.catchError("Error collecting document annotations:",t),new Map}}processAnnotationChanges(t,e){try{if(!t||!e)throw new Error("Invalid input: editor and data are required");if(!e.originalText||!e.annotation)return null;if(!Array.isArray(e.nodes)||0===e.nodes.length)return null;const{currentText:n,contentChanged:r}=this.detectContentChanges(e.nodes,e.originalText),{targetTextNodeIdChanged:o,newTargetTextNodeId:i,searchResults:a}=this.detectContainerChanges(t,{annotationId:e.id,currentText:n,targetTextNodeId:e.targetTextNodeId,nodes:e.nodes}),c=this.calculateNewOccurrence(t,{searchResults:a,nodes:e.nodes,contentChanged:r,currentText:n,targetTextNodeId:o?i:e.targetTextNodeId,originalOccurrence:e.originalOccurrence}),s=c!==e.originalOccurrence;return r||s||o?this.createAnnotationChange(e,{currentText:n,contentChanged:r,currentOccurrence:c,occurrenceChanged:s,targetTextNodeIdChanged:o,newTargetTextNodeId:i}):null}catch(t){return h.catchError("Error processing annotation changes:",t),null}}detectContentChanges(t,e){const n=[...t].sort((t,e)=>t.pos-e.pos),r=n.length>1&&e.includes("\n")?n.map(t=>t.node.text||"").join("\n"):n.map(t=>t.node.text||"").join("");return{currentText:r,contentChanged:r!==e}}detectContainerChanges(t,e){const{annotationId:n,currentText:r,targetTextNodeId:o,nodes:i}=e;let a=!1,c=o,s=[];const d=this.processContainerChanges(t,{annotationId:n,currentText:r,targetTextNodeId:o,nodes:i});return d?(a=d.changed,c=d.newId,s=d.searchResults):s=o?this.findTextInDomElement(t,r,o,void 0):this.findTextInDocument(t,r,void 0),{targetTextNodeIdChanged:a,newTargetTextNodeId:c,searchResults:s}}processContainerChanges(t,o){const{annotationId:i,currentText:a,targetTextNodeId:c}=o;if(!c)return null;let s=null;if(t.getEditorState().read(()=>{const t=r();let o=0;!function t(r){if(g(r)&&r.__annotationId===i)s=o;else if(e(r))o+=r.getTextContent().length;else if(n(r)){const e=r.getChildren();for(const n of e)if(t(n),null!==s)return}}(t)}),null!==s){const e=t.getRootElement();if(!e)return null;if(e.querySelector(`#${c}`)){if(0===this.findTextInDomElement(t,a,c,void 0).length){const e=this.findNewContainer(t,a);if(e&&e.id!==c){const n=this.findTextInDomElement(t,a,e.id,void 0);return{changed:!0,newId:e.id,searchResults:n}}}}}return null}findNewContainer(t,e){const n=t.getRootElement();if(!n)return null;const r=n.querySelectorAll("[id]");for(const t of Array.from(r))if(t.textContent?.includes(e))return t;return null}calculateNewOccurrence(t,e){if(0===e.searchResults.length)return e.originalOccurrence;const n=e.nodes[0],r=e.nodes[e.nodes.length-1],o=n.pos,i=r.pos+(r.node.nodeSize||0);for(let t=0;t<e.searchResults.length;t++){const n=e.searchResults[t];if(n.start<=o&&n.end>=o||n.start<=i&&n.end>=i||o<=n.start&&i>=n.end)return t+1}return e.originalOccurrence}createAnnotationChange(t,e){const{currentText:n,contentChanged:r,currentOccurrence:o,occurrenceChanged:i,targetTextNodeIdChanged:a,newTargetTextNodeId:c}=e;return{annotationId:t.id,multiThreadAnnotationId:t.multiThreadAnnotationId,originalText:t.originalText,currentText:r?n:t.originalText,originalOccurrence:t.originalOccurrence,currentOccurrence:o,originalTargetTextNodeId:t.targetTextNodeId,newTargetTextNodeId:a?c:t.targetTextNodeId,annotation:t.annotation,contentChanged:r,occurrenceChanged:i,targetTextNodeIdChanged:a}}async updateVeltComments(t,e){try{for(const[n,r]of Array.from(t.entries()))try{if(!r.annotation.context?.textEditorConfig)continue;const t=JSON.parse(JSON.stringify(r.annotation.context.textEditorConfig));r.contentChanged&&(t.text=r.currentText),r.occurrenceChanged&&(t.occurrence=r.currentOccurrence),r.targetTextNodeIdChanged&&(t.targetTextNodeId=r.newTargetTextNodeId);const o={...r.annotation.context,textEditorConfig:t};this.plugin.storeService.annotationStore.remove(n),this.removeVeltCommentFromEditor(e,n),await new Promise(t=>setTimeout(t,100)),h.updateContext({annotationId:n,context:o})}catch(t){h.catchError("Error updating individual Velt comment:",t)}}catch(t){h.catchError("Error updating Velt comments:",t)}}getSelectedText(t){return t.getEditorState().read(()=>{const t=i();return a(t)?t.getTextContent():""})}findOccurrenceIndex(t,e,n){try{if(!e.trim())return 1;let r=[],o=0,c=0;t.getEditorState().read(()=>{const s=i();if(a(s)){const i=f.getSelectionTextRange(t,s);o=i.start,c=i.end,r=n&&n.id?this.findTextInContainer(t,e,n.id):this.findTextInEditor(t,e)}});for(let t=0;t<r.length;t++)if(r[t].start===o&&r[t].end===c)return t+1;return 1}catch(t){return h.catchError("Error finding occurrence index:",t),1}}findTextInEditor(t,e){try{const n=[];return t.getEditorState().read(()=>{const t=r(),{combinedText:o}=f.collectTextContent(t),i=f.kmpSearch(o,e);for(const t of i)n.push({start:t,end:t+e.length})}),n}catch(t){return h.catchError("Error finding text in editor:",t),[]}}findTextInContainer(t,e,n){try{const o=[],i=document.getElementById(n);return i?(t.getEditorState().read(()=>{const n=r(),{combinedText:a,nodeMap:c}=f.collectTextContent(n),s=f.getContainerTextContent(i,t,c,a);if(!s)return;const d=f.kmpSearch(s.text,e);for(const t of d)o.push({start:s.startOffset+t,end:s.startOffset+t+e.length})}),o):o}catch(t){return h.catchError("Error finding text in container:",t),[]}}findParentNodeWithId(t){try{return t.getEditorState().read(()=>{const e=i();if(!a(e))return null;const n=e.anchor.getNode(),r=e.focus.getNode(),o=t.getRootElement();if(!o)return null;let c=null,s=null;try{const e=n.getKey();if(c=t.getElementByKey(e),!c){const e=n.getParent()?.getKey();e&&(c=t.getElementByKey(e))}}catch(t){}try{const e=r.getKey();if(s=t.getElementByKey(e),!s){const e=r.getParent()?.getKey();e&&(s=t.getElementByKey(e))}}catch(t){}if(!c&&!s){const t=o.querySelector("p");return f.findContainerWithId(t,o)}const d=c||s,l=s||c;if(!d||!l)return null;if(d===l)return f.findContainerWithId(d,o);let g=f.findCommonParentWithId(d,l,o);if(g){const t=e.getTextContent();if(t.includes("\n")){if("p"===g.tagName.toLowerCase())return null;const e=g.textContent||"",n=t.replace(/\s+/g," ").trim();return e.replace(/\s+/g," ").trim().includes(n)?g:null}return(g.textContent||"").includes(t)?g:null}return null})}catch(t){return h.catchError("Error finding parent node with ID:",t),null}}highlightTextWithVeltComment(t,e,n){try{const{targetTextNodeId:o}=n,i=n?.occurrence||1;if(n.annotationId){const e=this.plugin.storeService.annotationStore.get(n.annotationId);if(e){const r=e.annotation.context?.textEditorConfig,o=n.originalAnnotation?.context?.textEditorConfig;r&&o&&(r.text!==o.text||r.occurrence!==o.occurrence||r.targetTextNodeId!==o.targetTextNodeId)&&this.removeVeltCommentFromEditor(t,n.annotationId)}}if(!e||0===e.length)return;if(o){const t=document.getElementById(o);if(t){const e=t.closest("[data-velt-location-id]")?.getAttribute("data-velt-location-id");if(e!==n.originalAnnotation?.location?.id)return}}let a=[];if(a=o?this.findTextInDomElement(t,e,o,i):this.findTextInDocument(t,e,i),0===a.length)return;const c=a[Math.min(i,a.length)-1];if(c&&n.annotationId){if(t.getEditorState().read(()=>{const t=r();return f.isRangeAlreadyWrapped(t,c.start,c.end,n.annotationId)}))return;this.plugin.storeService.annotationStore.set(n.annotationId,{annotation:n.originalAnnotation||{annotationId:n.annotationId,multiThreadAnnotationId:n.multiThreadAnnotationId,text:e},pluginReference:{node:document.createElement("velt-comment-text"),position:{from:c.start,to:c.end}}}),this.setVeltComment(t,n.annotationId,n.multiThreadAnnotationId,c.start,c.end)}}catch(t){h.catchError("Error highlighting text with Velt comment:",t)}}findTextInDomElement(t,e,n,o){try{const i=[],a=document.getElementById(n);return a?(t.getEditorState().read(()=>{const n=r(),{combinedText:c,nodeMap:s}=f.collectTextContent(n),d=f.getContainerTextContent(a,t,s,c);if(!d)return;const l=f.kmpSearch(d.text,e,0,o);for(const t of l)i.push({start:d.startOffset+t,end:d.startOffset+t+e.length})}),i):i}catch(t){return[]}}findTextInDocument(t,e,n){try{const o=[];return t.getEditorState().read(()=>{const t=r(),{combinedText:i}=f.collectTextContent(t),a=f.kmpSearch(i,e,0,n);for(const t of a)o.push({start:t,end:t+e.length})}),o}catch(t){return h.catchError("Error finding text in document:",t),[]}}setVeltComment(t,e,n,o,i){try{t.update(()=>{const t=r(),a=f.getTextNodesInRange(t,o,i,e);if(0===a.length)return;const c=l(e,n);if(1===a.length){const{node:t,startOffset:e,endOffset:n,isPartial:r}=a[0];r?f.wrapPartialTextNode(t,e,n,c):f.wrapEntireTextNode(t,c)}else f.wrapMultipleTextNodesWithFormatting(a,c)})}catch(t){h.catchError("Error setting Velt comment:",t)}}removeVeltCommentFromEditor(t,e){try{if(!t||!e)throw new Error("Invalid input: editor and annotationId are required");let i=!1;return t.update(()=>{const t=r(),a=[];!function t(r){if(g(r))r.__annotationId===e&&a.push(r);else if(n(r)){const e=r.getChildren();for(const n of e)t(n)}}(t);for(const t of a)try{const e=t.getWritable(),n=e.getChildren();if(n.length>0){const t=n[0];e.replace(t);let r=t;for(let t=1;t<n.length;t++)r.insertAfter(n[t]),r=n[t]}else{const t=e.getTextContent();if(t){const n=o(t);e.replace(n)}else e.remove()}i=!0}catch(t){h.catchError("Error removing individual comment node:",t)}}),i&&this.plugin.storeService.annotationStore.remove(e),i}catch(t){return!1}}}m.getEditorId=t=>{try{return t&&t._config?t._config.namespace:null}catch(t){return h.catchError("Error finding editor ID:",t),null}};class p{constructor(t){this.isSubscribed=!1,this.globalStore={editor:null,comments:[],filteredComments:[],selectedCommentsMap:new Map},this.globalAnnotationStore=new Map,this.annotationStore={get:t=>this.globalAnnotationStore.get(t),set:(t,e)=>{this.globalAnnotationStore.set(t,e)},getAll:()=>new Map(this.globalAnnotationStore),clear:()=>{this.globalAnnotationStore.clear()},remove:t=>{this.globalAnnotationStore.delete(t)},hasAnnotationTextChanged:(t,e)=>{try{const n=this.globalAnnotationStore.get(t);if(!n||!e)return!1;const r=n.annotation.text,o=e.context?.textEditorConfig?.text;return r!==o}catch(t){return!1}}},this.updateGlobalStore=t=>{try{const e=t?.comments||this.globalStore?.comments||[],n=t?.selectedCommentsMap||this.globalStore?.selectedCommentsMap||new Map,r=this.globalStore?.filteredComments||[],o=e.filter(t=>"terminal"!==t?.status?.type||n?.get(t?.annotationId)),i=new Set(o.map(t=>t?.annotationId));r.map(t=>t?.annotationId).filter(t=>t&&!i.has(t)).forEach(t=>{this.globalStore?.editor&&t&&this.plugin.editorService.removeVeltCommentFromEditor(this.globalStore?.editor,t)}),this.globalStore={...this.globalStore,...t,filteredComments:o},this.highlightCommentsFromGlobalStore()}catch(t){h.catchError("Error updating global store:",t)}},this.highlightCommentsFromGlobalStore=()=>{try{const{editor:t,filteredComments:e}=this.globalStore;if(!t||!e)return;for(const n of e){const e=n?.context?.textEditorConfig?.text,r=n?.context?.textEditorConfig?.occurrence;e&&this.plugin.editorService.highlightTextWithVeltComment(t,e,{annotationId:n?.annotationId,multiThreadAnnotationId:n?.multiThreadAnnotationId,occurrence:r,targetTextNodeId:n?.context?.textEditorConfig?.targetTextNodeId,originalAnnotation:n})}}catch(t){h.catchError("Error highlighting comments from global store:",t)}},this.plugin=t;try{h.subscribeToSelectedCommentsMap(this.plugin.editorId,t=>{try{this.updateGlobalStore({selectedCommentsMap:t})}catch(t){h.catchError("Error updating global store:",t)}})}catch(t){h.catchError("Error subscribing to selected comments map:",t)}}}p.storeInstanceMap=new Map;const x=new Map;class T{constructor(t,e){this.editorId=t,this.editor=e,this.editorService=new m(this),e&&this.editorService.initializeTransactionListener(e),this.storeService=new p(this)}static getInstance(t){let{editorId:e,editor:n}=t||{};return e||(e="default"),x.has(e)||x.set(e,new T(e,n)),x.get(e)}}function C(t){const e=function(t){const e=t._createEditorArgs,n={namespace:`shadow-editor-${Date.now()}`,nodes:e?.nodes||[],theme:{},onError:t=>{},editable:!1};return c(n)}(t);try{const o=t.getEditorState();e.setEditorState(o),e.update(()=>{!function(t){const e=[];function r(t){if(g(t))e.push(t);else if(n(t)){t.getChildren().forEach(r)}}r(t),e.forEach(t=>{try{const e=t.getParent();if(!e)return;const n=t.getChildren(),r=t.getIndexWithinParent();t.remove(),n.length>0&&e.splice(r,0,n)}catch(t){}}),t.markDirty()}(r())},{discrete:!0});const i=e.getEditorState().toJSON();return JSON.stringify(i)}catch(e){return function(t){return t.getEditorState().read(()=>{const e=E(y(t.getEditorState().toJSON()));return JSON.stringify(e)})}(t)}}function y(t){if(!t||"object"!=typeof t)return t;if(Array.isArray(t)){const e=[];for(const n of t)if(n&&"comment"===n.type){if(n.children&&Array.isArray(n.children))for(const t of n.children)e.push(y(t))}else e.push(y(n));return e}const e={...t};if("comment"===e.type)return e.children&&Array.isArray(e.children)?e.children.map(t=>y(t)):null;for(const[t,n]of Object.entries(e))("children"===t&&Array.isArray(n)||"object"==typeof n&&null!==n)&&(e[t]=y(n));return e}function E(t){if(!t||"object"!=typeof t)return t;if(Array.isArray(t))return t.map(t=>E(t));const e={...t};if(e.children&&Array.isArray(e.children)){const t=e.children.map(t=>E(t));e.children=function(t){if(!Array.isArray(t)||t.length<=1)return t;const e=[];let n=0;for(;n<t.length;){const r=t[n];if(r&&"text"===r.type){let o=r.text||"",i=n+1;for(;i<t.length;){const e=t[i];if(!e||"text"!==e.type||!I(r,e))break;o+=e.text||"",i++}e.push({...r,text:o}),n=i}else e.push(r),n++}return e}(t)}for(const[t,n]of Object.entries(e))"children"!==t&&"object"==typeof n&&null!==n&&(e[t]=E(n));return e}function I(t,e){return t.format===e.format&&t.style===e.style&&t.mode===e.mode&&t.detail===e.detail}const S=t=>{try{return C(t)}catch(e){return t.getEditorState().read(()=>{const t=r();return JSON.stringify({root:{children:[{children:[{detail:0,format:0,mode:"normal",style:"",text:t.getTextContent(),type:"text",version:1}],direction:"ltr",format:"",indent:0,type:"paragraph",version:1,textFormat:0,textStyle:""}],direction:"ltr",format:"",indent:0,type:"root",version:1}})})}};function b(t,e){try{const n=JSON.parse(e);t.setEditorState(t.parseEditorState(n))}catch(e){t.update(()=>{r().clear()})}}const A=async(t,e)=>{try{return N({editor:t,context:e?.context})}catch(t){h.catchError("Error triggering add comment",t)}},N=async({editorId:t,editor:e,context:n})=>{try{const r=h.getCommentElement();if(!r)return;await new Promise(t=>setTimeout(t,500)),t||(t=m.getEditorId(e)??void 0);const o=T.getInstance({editorId:t,editor:e}),i=o.editorService.getSelectedText(e);if(!i)return;const a=o.editorService.findParentNodeWithId(e);let c,d;a&&(c=a.id,d=a.closest(`[${s.LOCATION_ID}]`)?.getAttribute(s.LOCATION_ID));const l=o.editorService.findOccurrenceIndex(e,i,a);if(!l)return;let g,u={};n&&"object"==typeof n&&(u={...u,...n}),u.textEditorConfig={text:i,occurrence:l,targetTextNodeId:c},t&&(u.textEditorConfig.editorId=t),d&&(g={id:d}),r?.addManualComment({context:u,location:g})?.then(t=>{})}catch(t){h.catchError("Error adding lexical-velt-comments",t)}};function w(t,e,n){try{v({editor:t,editorId:n,commentAnnotations:e})}catch(t){h.catchError("Error highlighting lexical-velt-comments",t)}}const v=({editor:t,editorId:e,commentAnnotations:n})=>{try{if(t){if(e||(e=m.getEditorId(t)??void 0),!Array.isArray(n))return;n=JSON.parse(JSON.stringify(n));const r=n?.filter(t=>!!t.context?.textEditorConfig&&t.context?.textEditorConfig?.editorId===e)||[];T.getInstance({editorId:e,editor:t}).storeService.updateGlobalStore({editor:t,comments:r}),h.subscribeToSelectedAnnotationsMapSingleton()}}catch(t){h.catchError("Error highlighting lexical-velt-comments",t)}};export{l as $createCommentNode,g as $isCommentNode,d as CommentNode,N as addComment,b as deserializeCleanState,S as exportCleanEditorContent,w as highlightComments,v as renderComments,A as triggerAddComment};
1
+ import{$isTextNode as t,$isElementNode as e,ElementNode as n,$getRoot as o,$getSelection as r,$setSelection as a,$createTextNode as c,$isRangeSelection as i}from"lexical";const s={ATTRIBUTES:{EDITOR_ID:"data-editor-id",LOCATION_ID:"data-velt-location-id",ANNOTATION_ID:"annotation-id",MULTI_THREAD_ANNOTATION_ID:"multi-thread-annotation-id"},MARK_NAME:"lexicalVeltComments",STORAGE_KEY:"lexicalVeltComments",TAG_NAME:"velt-comment-text",DEFAULT_EXTENSION_NAME:"VeltComments",NODE_TYPE:"comment",DEFAULT_EDITOR_ID:"__default__",STATUS_TERMINAL:"terminal",LOG_PREFIX:"LexicalVeltComments: ",DEBUG_MODE_KEY:"debugMode",FORCE_DEBUG_MODE_KEY:"forceDebugMode",BLOCK_TYPES:["paragraph","heading","listitem","quote","code"]};class d{static showLogs(){try{return!!sessionStorage.getItem(s.DEBUG_MODE_KEY)||!!sessionStorage.getItem(s.FORCE_DEBUG_MODE_KEY)}catch(t){return d.catch("Error in showLogs: ",t),!1}}}d.log=d.showLogs()?console.log:()=>{},d.warn=d.showLogs()?console.warn:()=>{},d.error=d.showLogs()?console.error:()=>{},d.debug=d.showLogs()?console.debug:()=>{},d.info=d.showLogs()?console.info:()=>{},d.logsEnabled=!0,d.catch=(t,e)=>{try{d.logsEnabled&&(void 0!==e?console.warn(s.LOG_PREFIX,t,e):console.warn(s.LOG_PREFIX,t))}catch(t){}};const l=(t,e,n=0,o)=>{try{const r=[];if(!e||!t||e.length>t.length)return r;const a=u(e);let c=0,i=0;for(;c<t.length;)if(e[i]===t[c]&&(c++,i++),i===e.length){if(r.push(n+c-i),i=a[i-1],o&&r.length>=o)break}else c<t.length&&e[i]!==t[c]&&(0!==i?i=a[i-1]:c++);return r}catch(t){return[]}},u=t=>{try{const e=new Array(t.length).fill(0);let n=0,o=1;for(;o<t.length;)t[o]===t[n]?(n++,e[o]=n,o++):0!==n?n=e[n-1]:(e[o]=0,o++);return e}catch(t){return[]}},g=n=>{try{const o=[];let r="",a=0;const c=(n,i=0)=>{if(t(n)){const t=n.getTextContent(),e=a,c=a+t.length;o.push({node:n,start:e,end:c}),r+=t,a+=t.length}else if(e(n)){const t=n.getChildren(),d=n.getType();for(let e=0;e<t.length;e++)c(t[e],i+1);if(s.BLOCK_TYPES.includes(d)&&1===i){const t=n.getParent();if(t&&e(t)){const e=t.getChildren();if(e.indexOf(n)<e.length-1){const t=a,e=a+1;o.push({node:null,start:t,end:e,isParagraphBreak:!0}),r+="\n",a+=1}}}}};return c(n),{combinedText:r,nodeMap:o}}catch(t){return d.catch("Error collecting text content",t),{combinedText:"",nodeMap:[]}}},h=(t,e,n,o)=>{try{let r=-1,a=-1;for(let o=0;o<n.length;o++){const c=n[o];if(!c.isParagraphBreak&&c.node)try{const n=c.node.getKey(),o=e.getElementByKey(n);o&&t.contains(o)&&(-1===r&&(r=c.start),a=c.end)}catch(t){continue}}if(-1===r||-1===a)return null;return{text:o.substring(r,a),startOffset:r}}catch(t){return null}};class f extends n{static getType(){return s.NODE_TYPE}static clone(t){return new f(t.__annotationId,t.__multiThreadAnnotationId,t.__key)}constructor(t,e,n){super(n),this.__annotationId=t,this.__multiThreadAnnotationId=e}createDOM(t){const e=document.createElement(s.TAG_NAME);return this.__annotationId&&e.setAttribute(s.ATTRIBUTES.ANNOTATION_ID,this.__annotationId),this.__multiThreadAnnotationId&&e.setAttribute(s.ATTRIBUTES.MULTI_THREAD_ANNOTATION_ID,this.__multiThreadAnnotationId),e}updateDOM(t,e,n){return!1}static importJSON(t){return m(t.annotationId,t.multiThreadAnnotationId)}exportJSON(){return{...super.exportJSON(),annotationId:this.__annotationId,multiThreadAnnotationId:this.__multiThreadAnnotationId,type:s.NODE_TYPE,version:1}}isInline(){return!0}}const m=(t,e)=>new f(t,e),p=t=>t instanceof f,T=(n,o,r,a)=>{try{let c=0,i=!1;const s=n=>{if(p(n)){if(n.__annotationId===a){const t=n.getTextContent(),e=c,a=c+t.length;if(e<=o&&a>=r)return i=!0,!0}const t=n.getTextContent();c+=t.length}else if(t(n)){const t=n.getTextContent();c+=t.length}else if(e(n)){const t=n.getChildren();for(const e of t)if(s(e))return!0;if("paragraph"===n.getType()){const t=n.getParent();if(t&&e(t)){const e=t.getChildren();e.indexOf(n)<e.length-1&&(c+=1)}}}return!1};return s(n),i}catch(t){return!0}},I=(t,e,n,o)=>{try{const r=[],{combinedText:a,nodeMap:c}=g(t);for(const t of c){if(t.isParagraphBreak||!t.node)continue;const a=t.node.getParent();if((!p(a)||!o||a.__annotationId!==o)&&(t.end>e&&t.start<n)){const o=Math.max(0,e-t.start),a=Math.min(t.node.getTextContent().length,n-t.start),c=o>0||a<t.node.getTextContent().length;r.push({node:t.node,startOffset:o,endOffset:a,isPartial:c})}}return r}catch(t){return d.catch("Error getting text nodes in range",t),[]}},x=t=>{const n=["paragraph","heading","listitem","quote","code"];let o=t.getParent();for(;o;){if(e(o)){const t=o.getType();if(n.includes(t))return o;const e=o.getParent();if(e&&"root"===e.getType())return o}o=o.getParent()}return null},E=(t,e,n,o)=>{try{const r=t.getTextContent(),a=t.getFormat(),i=t.getStyle(),s=t.getParent(),d=t.getIndexWithinParent();if(!s)return;const l=r.substring(0,e),u=r.substring(e,n),g=r.substring(n),h=c(u);h.setFormat(a),h.setStyle(i),o.append(h);const f=[];if(l){const t=c(l);t.setFormat(a),t.setStyle(i),f.push(t)}if(f.push(o),g){const t=c(g);t.setFormat(a),t.setStyle(i),f.push(t)}s.getWritable().splice(d,1,f)}catch(t){d.catch("Error in wrapPartialTextNode",t)}},y=(t,e)=>{try{const n=t.getParent(),o=t.getIndexWithinParent();if(!n)return void d.warn("[wrapEntireTextNode] No parent found for text node");n.getWritable().splice(o,1,[e]);const r=t.getWritable();e.append(r)}catch(t){d.catch("[wrapEntireTextNode] Error",t)}},_=(t,e)=>{const n=`[wrapMultipleTextNodesWithFormatting][${e.__annotationId}]`;try{const n=new Map;for(const e of t){const t=x(e.node),o=t?t.getKey():"no-paragraph";n.has(o)||n.set(o,[]),n.get(o).push(e)}let o=!0,r=0;for(const[t,a]of n.entries()){const t=o?e:m(e.__annotationId,e.__multiThreadAnnotationId);if(1===a.length){const e=a[0],{node:n,startOffset:o,endOffset:r,isPartial:c}=e;c?E(n,o,r,t):y(n,t)}else A(a,t);o=!1,r++}}catch(t){d.catch(`${n} Error in wrapMultipleTextNodesWithFormatting`,t)}},A=(t,e)=>{const n=`[wrapMultipleNodesInSameParagraph][${e.__annotationId}]`;try{const o=[...t].sort((t,e)=>t.node.getIndexWithinParent()-e.node.getIndexWithinParent()),r=o[0],a=o[o.length-1],i=r.node.getParent(),s=r.node.getIndexWithinParent();if(!i)return;const l=i.getChildrenSize();if(s<0||s>=l)return void d.warn(`${n} Invalid index ${s} for parent with ${l} children`);const u=r.node.getWritable(),g=i.getWritable(),h=s;if(r.isPartial&&r.startOffset>0){const t=r.node.getTextContent().substring(0,r.startOffset),o=r.node.getTextContent().substring(r.startOffset),a=c(t);a.setFormat(u.getFormat()),a.setStyle(u.getStyle());const i=c(o);i.setFormat(u.getFormat()),i.setStyle(u.getStyle()),e.append(i);const s=g.getChildrenSize();if(h+1>s)return void d.warn(`${n} Cannot splice: index ${h} + 1 > size ${s}`);g.splice(h,1,[a,e])}else{const t=g.getChildrenSize();if(h+1>t)return void d.warn(`${n} Cannot splice: index ${h} + 1 > size ${t}`);g.splice(h,1,[e]),e.append(u)}for(let t=1;t<o.length-1;t++){const n=o[t].node.getWritable();e.append(n)}if(o.length>1){const t=a.node.getWritable();if(a.isPartial&&a.endOffset<a.node.getTextContent().length){const n=a.node.getTextContent().substring(0,a.endOffset),o=a.node.getTextContent().substring(a.endOffset),r=c(n);r.setFormat(t.getFormat()),r.setStyle(t.getStyle());const i=c(o);i.setFormat(t.getFormat()),i.setStyle(t.getStyle()),e.append(r),t.replace(i)}else e.append(t)}}catch(t){d.catch("Error in wrapMultipleNodesInSameParagraph",t)}},O=(t,e)=>{try{const n=[],r=e.context?.textEditorConfig?.text;return r?(t.getEditorState().read(()=>{const t=o(),{combinedText:e}=g(t),a=l(e,r);for(const t of a)n.push({start:t,end:t+r.length})}),n):n}catch(t){return d.catch("Error finding text matches",t),[]}},C=(t,e)=>{try{for(const n of e){const e=`[applyAnnotationMarks][${n.annotationId}]`,c=n.context?.textEditorConfig?.text;if(!c||0===c.length)continue;const i=n.context?.textEditorConfig?.occurrence||1,s=n.context?.textEditorConfig?.targetTextNodeId;let u=[];if(s){const e=document.getElementById(s);e&&t.getEditorState().read(()=>{const n=o(),{combinedText:r,nodeMap:a}=g(n),s=h(e,t,a,r);if(s){const t=l(s.text,c,0,i);u=t.map(t=>({start:s.startOffset+t,end:s.startOffset+t+c.length}))}})}else u=O(t,n);if(0===u.length)continue;const f=Math.min(i,u.length),p=u[f-1];if(!p)continue;if(!t.getEditorState().read(()=>{const t=o();return T(t,p.start,p.end,n.annotationId)}))try{t.update(()=>{const t=o();r()&&a(null);const e=I(t,p.start,p.end,n.annotationId);if(0===e.length)return;const c=m(n.annotationId,n.multiThreadAnnotationId);if(1===e.length){const{node:t,startOffset:n,endOffset:o,isPartial:r}=e[0];r?E(t,n,o,c):y(t,c)}else _(e,c)},{discrete:!0})}catch(t){throw d.catch(`${e} Error in editor.update`,t),t}}}catch(t){d.catch("Error applying annotation marks",t)}},N=t=>{const e="[getCurrentSelectionContext]";try{return t.getEditorState().read(()=>{const n=r();if(!i(n))return null;const a=n.getTextContent();if(!a.trim())return null;const c=((t,e)=>{const n=o(),{nodeMap:r}=g(n),a=e.anchor.getNode(),c=e.focus.getNode(),i=e.anchor.offset,s=e.focus.offset;let d=0,l=0;for(const t of r){if(t.isParagraphBreak||!t.node)continue;const e=t.node.getKey();e===a.getKey()&&(d=t.start+i),e===c.getKey()&&(l=t.start+s)}return{start:Math.min(d,l),end:Math.max(d,l)}})(0,n);n.anchor.getNode(),n.focus.getNode();let l,u;try{const e=t.getRootElement();if(e){const o=n.anchor.key,r=t.getElementByKey(o);if(r){let t=r;const n=100;let o=0;for(;t&&t!==document.body&&o<n&&e.contains(t);){if(t.id){l=t.id;break}t=t.parentElement,o++}if(l){const t=r.closest(`[${s.ATTRIBUTES.LOCATION_ID}]`);u=t?.getAttribute(s.ATTRIBUTES.LOCATION_ID)||void 0}}}}catch(t){d.catch(`${e} Error finding targetTextNodeId or locationId`,t)}let h=1;try{const e=S(t,a);for(const t of e)if(t.start===c.start&&t.end===c.end){h=t.occurrence;break}if(1===h&&e.length>0)for(const t of e)if(c.start>=t.start&&c.end<=t.end){h=t.occurrence;break}}catch(t){d.catch(`${e} Error calculating occurrence`,t)}return{text:a,from:c.start,to:c.end,occurrence:h,targetTextNodeId:l,locationId:u}})}catch(t){return d.catch(`${e} Error getting selection context`,t),null}},S=(t,e)=>{try{const n=[];return t.getEditorState().read(()=>{const t=o(),{combinedText:r}=g(t),a=l(r,e);for(let t=0;t<a.length;t++){const o=a[t];n.push({start:o,end:o+e.length,occurrence:t+1})}}),n}catch(t){return d.catch("Error finding occurrences by text",t),[]}},w=(t,e)=>{const n="[subscribeToDocumentChanges]";try{let r="";t.getEditorState().read(()=>{r=o().getTextContent()});return t.registerUpdateListener(({editorState:t,prevEditorState:a})=>{const c=`${n}[updateListener]`;try{if(t===a)return;const n=((t,e)=>{try{return t.read(()=>{const t=o().getTextContent();return e.read(()=>{const e=o().getTextContent();return t!==e})})}catch(t){return d.catch("[hasDocumentChanged] Error comparing editor states",t),!0}})(t,a);if(!n)return;t.read(()=>{const t=o().getTextContent(),n={type:"replace",from:0,to:r.length,insertedText:t,deletedText:r};e(n),r=t})}catch(t){d.catch(`${c} Error in document change listener`,t)}})}catch(t){return d.catch(`${n} Error subscribing to document changes`,t),()=>{}}},b=(t,e)=>{const{annotationId:n,currentText:r,targetTextNodeId:a}=e;let c=!1,i=a,s=[];if(a){const e=document.getElementById(a);if(e&&(t.getEditorState().read(()=>{const n=o(),{combinedText:a,nodeMap:c}=g(n),i=h(e,t,c,a);if(i){const t=l(i.text,r);for(const e of t)s.push({start:i.startOffset+e,end:i.startOffset+e+r.length})}}),0===s.length)){const e=D(t,r);e&&e.id!==a&&(c=!0,i=e.id,t.getEditorState().read(()=>{const n=o(),{combinedText:a,nodeMap:c}=g(n),i=h(e,t,c,a);if(i){const t=l(i.text,r);for(const e of t)s.push({start:i.startOffset+e,end:i.startOffset+e+r.length})}}))}}return 0===s.length&&t.getEditorState().read(()=>{const t=o(),{combinedText:e}=g(t),n=l(e,r);for(const t of n)s.push({start:t,end:t+r.length})}),{targetTextNodeIdChanged:c,newTargetTextNodeId:i,searchResults:s}},D=(t,e)=>{const n=t.getRootElement();if(!n)return null;const o=n.querySelectorAll("[id]");for(const t of Array.from(o))if(t.textContent?.includes(e))return t;return null},$=(t,e)=>{if(0===e.searchResults.length)return e.originalOccurrence;const n=e.nodes[0],o=e.nodes[e.nodes.length-1],r=n.pos,a=o.pos+(o.node.nodeSize||0);for(let t=0;t<e.searchResults.length;t++){const n=e.searchResults[t];if(n.start<=r&&n.end>=r||n.start<=a&&n.end>=a||r<=n.start&&a>=n.end)return t+1}return e.originalOccurrence};let M=!1,R=new Map;const v=new Map,P=()=>{try{const t=window.Velt;return t?.getCommentElement?t.getCommentElement():null}catch(t){return d.catch("Error getting Velt comment element",t),null}},F=(t,e)=>{try{const n=P();if(!n)return void d.warn("Velt SDK not available, cannot update annotation context");n.updateContext(t,e)}catch(t){d.catch("Error updating annotation context",t)}},L=new Map,k=t=>{const e={annotations:new Map,commentAnnotations:[],selectedAnnotations:new Set,editorId:t};return L.set(t,e),e},U=t=>{let e=L.get(t);return e||(e=k(t)),e},B=(t,e)=>{try{const n=U(t);n.commentAnnotations=e,n.annotations.clear();for(const t of e){if(!t?.annotationId)continue;const e={annotationId:t.annotationId,multiThreadAnnotationId:t.multiThreadAnnotationId,context:t.context};n.annotations.set(t.annotationId,e)}}catch(t){d.catch("[updateAnnotations] Error updating annotations",t)}},K=(t,e)=>{try{const n=L.get(t);if(!n)return null;return n.annotations.get(e)||null}catch(t){return d.catch("[getAnnotation] Error getting annotation",t),null}},W=new Map,V=(t,e,n)=>{let o=t;o||(o=(t=>{try{if(!t)return null;if(t._config?.namespace)return t._config.namespace;const e=t.getRootElement();if(e){const t=e.closest(`[${s.ATTRIBUTES.EDITOR_ID}]`)?.getAttribute(s.ATTRIBUTES.EDITOR_ID);if(t)return t}return null}catch(t){return d.catch("Error finding editor ID",t),null}})(e)||s.DEFAULT_EDITOR_ID);const r=(t=>W.get(t)||null)(o);return r||((t,e,n)=>{const o=t||s.DEFAULT_EDITOR_ID;k(o);const r={editorId:o,editor:e,config:n||{}};return W.set(o,r),r})(o,e,n)},Y=(n,r,a)=>{const c="[handleContentUpdate]";try{const a=((n,r)=>{const a="[detectDocumentChanges]",c=new Map;try{const i=new Map;let s=0;n.getEditorState().read(()=>{const n=o();let r=0;const c=n=>{if(p(n)){s++;const t=n.__annotationId;if(!t)return void d.warn(`${a}[traverse] CommentNode found but no annotationId`);const e=n.getTextContent(),o=e.length,c={node:{text:e,nodeSize:o},pos:r},l=i.get(t);l?l.nodes.push(c):i.set(t,{id:t,multiThreadAnnotationId:n.__multiThreadAnnotationId,nodes:[c]}),r+=o}else if(t(n))r+=n.getTextContent().length;else if(e(n)){const t=n.getChildren();for(const e of t)c(e)}};c(n)});for(const[t,e]of Array.from(i.entries())){const o=`${a}[${t}]`,i=r(t);if(!i){d.warn(`${o} No stored data found, skipping`);continue}const s=[...e.nodes].sort((t,e)=>t.pos-e.pos).map(t=>t.node.text||"").join(""),l=s!==i.originalText,u=b(n,{annotationId:e.id,currentText:s,targetTextNodeId:i.targetTextNodeId,nodes:e.nodes}),g=u.targetTextNodeIdChanged,h=u.newTargetTextNodeId,f=u.searchResults,m=$(n,{searchResults:f,nodes:e.nodes,contentChanged:l,currentText:s,targetTextNodeId:g?h:i.targetTextNodeId,originalOccurrence:i.originalOccurrence}),p=m!==i.originalOccurrence;if(l||p||g){const n={annotationId:e.id,multiThreadAnnotationId:e.multiThreadAnnotationId,originalText:i.originalText,currentText:l?s:i.originalText,originalOccurrence:i.originalOccurrence,currentOccurrence:m,originalTargetTextNodeId:i.targetTextNodeId,newTargetTextNodeId:g?h:i.targetTextNodeId,annotation:i.annotation,contentChanged:l,occurrenceChanged:p,targetTextNodeIdChanged:g};c.set(t,n)}}}catch(t){d.catch(`${a} Error detecting document changes`,t)}return c})(r,t=>{const e=K(n,t);if(!e)return d.warn(`${c} Annotation not found in state: ${t}`),null;const o=e.context?.textEditorConfig;return{annotation:e,originalText:o?.text||"",originalOccurrence:o?.occurrence||1,targetTextNodeId:o?.targetTextNodeId||""}});if(0===a.size)return;for(const[t,e]of Array.from(a.entries())){const o=`${c}[${t}]`,r=K(n,t);if(!r){d.warn(`${o} Annotation not found in state, skipping`);continue}if(!r.context?.textEditorConfig){d.warn(`${o} No textEditorConfig, skipping`);continue}const a=JSON.parse(JSON.stringify(r.context.textEditorConfig));e.contentChanged&&(a.text=e.currentText),e.occurrenceChanged&&(a.occurrence=e.currentOccurrence),e.targetTextNodeIdChanged&&(a.targetTextNodeId=e.newTargetTextNodeId);const i={...r.context,textEditorConfig:a};F(t,i)}}catch(t){d.catch("Error handling content update",t)}},G=new Map,z=(t,e)=>{try{const n=V(t,e).editorId;return((t,e)=>{if(G.has(t))return!0;try{const n=w(e,()=>{Y(t,e)});return G.set(t,n),!0}catch(t){return d.catch("[ensureDocumentChangeListeners] Error setting up document change listeners",t),!1}})(n,e),{editorId:n}}catch(e){return d.catch("[ensureEditorSetup] Error setting up editor",e),{editorId:t||s.DEFAULT_EDITOR_ID}}};async function J({editorId:t,editor:e,context:n}){const r="[addComment]";if(e)try{if(!P())return void d.warn(`${r} Velt SDK not available, cannot add comment`);const a=N(e);if(!a)return void d.warn(`${r} No valid selection found, exiting`);const{editorId:c}=z(t,e),i=void 0!==t||c!==s.DEFAULT_EDITOR_ID,l={...n,textEditorConfig:{text:a.text,occurrence:a.occurrence,...i&&{editorId:c},targetTextNodeId:a.targetTextNodeId}};let u;a.locationId&&(u={id:a.locationId});const h=await(t=>{const e="[addVeltComment]";try{const n=P();return n?n.addManualComment({context:t.context,location:t.location}).then(t=>t?.annotation?{annotation:t.annotation,result:t}:(d.warn(`${e} No annotation in result`),{annotation:null,result:t})).catch(t=>(d.catch(`${e} Error adding Velt comment`,t),{annotation:null,result:null})):(d.warn(`${e} Velt SDK not available, cannot add comment`),Promise.resolve({annotation:null,result:null}))}catch(t){return d.catch(`${e} Exception adding Velt comment`,t),Promise.resolve({annotation:null,result:null})}})({context:l,location:u}),f=h.annotation;if(!f)return void d.warn(`${r} Failed to create comment via Velt SDK`);(()=>{try{return!0}catch(t){return d.catch("[shouldApplyMark] Error checking persistVeltMarks, defaulting to true",t),!0}})(0,s.STORAGE_KEY)&&f.annotationId&&((t,e,n,r,a,c=1)=>{const i="[applyAnnotationMark]";try{if(!t||!e)return!1;if(r>=a)return d.warn(`${i} Invalid position range: from must be less than to`),!1;const s=t;let l="";try{s.getEditorState().read(()=>{const t=o(),{combinedText:e}=g(t);l=e.substring(r,a)})}catch(t){return d.catch(`${i} Could not extract text from positions, mark may not apply correctly`,t),!1}return l&&0!==l.trim().length?(C(s,[{annotationId:e,multiThreadAnnotationId:n,context:{textEditorConfig:{text:l,occurrence:c,editorId:""}},position:{from:r,to:a}}]),!0):(d.warn(`${i} No text found at positions ${r}-${a}`),!1)}catch(t){return d.catch(`${i} Error applying annotation mark`,t),!1}})(e,f.annotationId,f.multiThreadAnnotationId,a.from,a.to,a.occurrence),f.annotationId?B(c,[f]):d.warn(`${r} No annotationId, skipping state update`),(t=>{const e="[resetEditorSelection]";try{const n=t;n?.focus?n.focus():d.warn(`${e} Editor focus API not available`)}catch(t){d.catch(`${e} Error resetting selection`,t)}})(e)}catch(t){d.catch(`${r} Error adding comment`,t)}else d.catch(`${r} ERROR: No editor provided`)}const X=new Map,q=(t,e)=>{const n=(t=>{try{const e=L.get(t);return e?new Map(e.annotations):new Map}catch(t){return d.catch("Error getting all annotations",t),new Map}})(t),o=new Map;for(const[t,e]of n)o.set(t,e);const r=[];for(const t of e){if(!t.annotationId)continue;const e=o.get(t.annotationId);e?r.push(e):r.push({annotationId:t.annotationId,multiThreadAnnotationId:t.multiThreadAnnotationId,context:t.context})}return r},j=(t,n,i)=>{try{const l=X.get(t);l?l.editor=n:X.set(t,{editor:n,previousFilteredAnnotations:[]});const u=(t=>{try{const e=L.get(t);return e?new Set(e.selectedAnnotations):new Set}catch(t){return d.catch("Error getting selected annotations",t),new Set}})(t),g=((t,e)=>t.filter(t=>t?.status?.type!==s.STATUS_TERMINAL||e.has(t.annotationId)))(i,u),h=X.get(t)?.previousFilteredAnnotations||[],f=new Set(g.map(t=>t.annotationId).filter(Boolean)),m=new Set(h.map(t=>t.annotationId).filter(Boolean)),T=Array.from(m).filter(t=>!f.has(t));T.length>0&&((t,n)=>{try{t.update(()=>{const t=o();r()&&a(null);const i=[];!function t(o){if(p(o))o.__annotationId&&n.includes(o.__annotationId)&&i.push(o);else if(e(o)){const e=o.getChildren();for(const n of e)t(n)}}(t);for(const t of i)try{const e=t.getWritable(),n=e.getChildren();if(n.length>0){const t=n[0];e.replace(t);let o=t;for(let t=1;t<n.length;t++)o.insertAfter(n[t]),o=n[t]}else{const t=e.getTextContent();if(t){const n=c(t);e.replace(n)}else e.remove()}}catch(t){d.catch("Error removing individual comment mark",t)}},{discrete:!0})}catch(t){d.catch("Error removing annotation marks",t)}})(n,T);const I=X.get(t);I&&(I.previousFilteredAnnotations=g);const x=q(t,g);x.length>0&&C(n,x)}catch(t){d.catch("[commentRenderer:updateComments] Error updating comments",t)}},H=(t,e)=>{const n="[commentRenderer:updateSelection]";try{const e=X.get(t);if(!e||!e.editor)return void d.warn(`${n} No editor found for editorId: ${t}`);const o=(t=>{try{const e=L.get(t);return e?.commentAnnotations||[]}catch(t){return d.catch("Error getting comment annotations",t),[]}})(t);j(t,e.editor,o)}catch(t){d.catch(`${n} Error updating selection`,t)}},Q=new Map,Z=({editor:t,editorId:e,commentAnnotations:n})=>{const o="[renderComments]";try{if(!t)return void d.warn(`${o} No editor provided`);n&&Array.isArray(n)||(n=[]);const{editorId:r}=z(e,t),a=JSON.parse(JSON.stringify(n)).filter(t=>{if(!t?.context?.textEditorConfig)return!1;const e=t.context.textEditorConfig.editorId;return r===s.DEFAULT_EDITOR_ID?void 0===e||e===s.DEFAULT_EDITOR_ID:e===r});if(B(r,a),!Q.has(r)){const t=r,e=((t,e)=>{try{const n=e||`subscriber-${Date.now()}-${Math.random()}`;if(!M){const t=P();t&&"function"==typeof t.getSelectedComments&&(t.getSelectedComments().subscribe(t=>{const e=new Map;if(t?.forEach(t=>{t?.annotationId&&e.set(t.annotationId,!0)}),!((t,e)=>{if(t.size!==e.size)return!1;for(const[n,o]of Array.from(t))if(e.get(n)!==o)return!1;return!0})(e,R)){R=e;const t=new Set;for(const[e]of Array.from(R))t.add(e);v.forEach(e=>{if("function"==typeof e)try{e(t)}catch(t){d.catch("Error in selected annotations subscriber",t)}})}}),M=!0)}return v.set(n,t),()=>{v.delete(n)}}catch(t){return d.catch("Error subscribing to selected annotations",t),()=>{}}})(e=>{((t,e)=>{try{U(t).selectedAnnotations=new Set(e)}catch(t){d.catch("Error setting selected annotations",t)}})(t,e),H(t)},t);Q.set(r,e)}j(r,t,a)}catch(t){d.catch(`${o} Error rendering comments`,t)}},tt=s.NODE_TYPE,et=t=>{const e=t.getEditorState();return e.read(()=>{const t=e.toJSON(),n=nt(t.root);return{root:at(n)}})},nt=t=>{const e=ot(t.children);return{...t,children:e}},ot=t=>{const e=[];for(const n of t)if(n.type!==tt)e.push(rt(n));else if(st(n)){const t=ot(n.children);e.push(...t)}return e},rt=t=>{if(st(t)){const e=ot(t.children);return{...t,children:e}}return t},at=t=>{const e=t.children.map(ct);return{...t,children:it(e)}},ct=t=>{if(st(t)){const e=t.children.map(ct);return{...t,children:it(e)}}return t},it=t=>{if(t.length<2)return t;const e=[];let n=0;for(;n<t.length;){const o=t[n];if(dt(o)){let r=o.text??"",a=n+1;for(;a<t.length;){const e=t[a];if(!dt(e)||!lt(o,e))break;r+=e.text??"",a++}e.push({...o,text:r}),n=a}else e.push(o),n++}return e},st=t=>Object.prototype.hasOwnProperty.call(t,"children"),dt=t=>"text"===t.type,lt=(t,e)=>t.format===e.format&&t.style===e.style&&t.mode===e.mode&&t.detail===e.detail;export{f as CommentNode,J as addComment,et as exportJSONWithoutComments,Z as renderComments};
2
2
  //# sourceMappingURL=index.js.map