@veltdev/plate-comments-react 1.0.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.
Files changed (49) hide show
  1. package/README.md +59 -0
  2. package/cjs/index.js +2 -0
  3. package/cjs/index.js.map +1 -0
  4. package/cjs/types/adapters/host/doc.d.ts +69 -0
  5. package/cjs/types/adapters/host/marks.d.ts +51 -0
  6. package/cjs/types/adapters/host/storage.d.ts +36 -0
  7. package/cjs/types/adapters/velt.d.ts +50 -0
  8. package/cjs/types/constants/common.d.ts +62 -0
  9. package/cjs/types/core/ExtensionComponent.d.ts +13 -0
  10. package/cjs/types/core/extension.d.ts +50 -0
  11. package/cjs/types/core/registry.d.ts +52 -0
  12. package/cjs/types/core/state.d.ts +80 -0
  13. package/cjs/types/features/addComment.d.ts +63 -0
  14. package/cjs/types/features/commentRenderer.d.ts +46 -0
  15. package/cjs/types/features/renderComments.d.ts +73 -0
  16. package/cjs/types/features/updateContent.d.ts +20 -0
  17. package/cjs/types/index.d.ts +16 -0
  18. package/cjs/types/types/common.d.ts +54 -0
  19. package/cjs/types/types/host.d.ts +74 -0
  20. package/cjs/types/types/state.d.ts +28 -0
  21. package/cjs/types/types/velt.d.ts +23 -0
  22. package/cjs/types/utils/common.d.ts +80 -0
  23. package/cjs/types/utils/console.d.ts +10 -0
  24. package/cjs/types/utils/serializer.d.ts +20 -0
  25. package/esm/index.js +2 -0
  26. package/esm/index.js.map +1 -0
  27. package/esm/types/adapters/host/doc.d.ts +69 -0
  28. package/esm/types/adapters/host/marks.d.ts +51 -0
  29. package/esm/types/adapters/host/storage.d.ts +36 -0
  30. package/esm/types/adapters/velt.d.ts +50 -0
  31. package/esm/types/constants/common.d.ts +62 -0
  32. package/esm/types/core/ExtensionComponent.d.ts +13 -0
  33. package/esm/types/core/extension.d.ts +50 -0
  34. package/esm/types/core/registry.d.ts +52 -0
  35. package/esm/types/core/state.d.ts +80 -0
  36. package/esm/types/features/addComment.d.ts +63 -0
  37. package/esm/types/features/commentRenderer.d.ts +46 -0
  38. package/esm/types/features/renderComments.d.ts +73 -0
  39. package/esm/types/features/updateContent.d.ts +20 -0
  40. package/esm/types/index.d.ts +16 -0
  41. package/esm/types/types/common.d.ts +54 -0
  42. package/esm/types/types/host.d.ts +74 -0
  43. package/esm/types/types/state.d.ts +28 -0
  44. package/esm/types/types/velt.d.ts +23 -0
  45. package/esm/types/utils/common.d.ts +80 -0
  46. package/esm/types/utils/console.d.ts +10 -0
  47. package/esm/types/utils/serializer.d.ts +20 -0
  48. package/index.d.ts +291 -0
  49. package/package.json +28 -0
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Pure utility functions with zero side effects.
3
+ * These functions contain algorithmic logic extracted from legacy code.
4
+ *
5
+ * IMPORTANT: This module MUST NOT import any external SDKs or have side effects.
6
+ * All functions must be pure: input → output, deterministic, no mutations.
7
+ */
8
+ /**
9
+ * Computes the KMP (Knuth-Morris-Pratt) failure function (LPS array).
10
+ * This is used for efficient pattern matching in text search.
11
+ *
12
+ * @param pattern The pattern string to compute the failure function for
13
+ * @returns Longest proper prefix array (LPS array)
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const lps = computeKMPTable("abcabc");
18
+ * // Returns: [0, 0, 0, 1, 2, 3]
19
+ * ```
20
+ */
21
+ export declare const computeKMPTable: (pattern: string) => number[];
22
+ /**
23
+ * Finds all occurrences of a pattern in text using the KMP algorithm.
24
+ *
25
+ * @param text The text to search in
26
+ * @param pattern The pattern to search for
27
+ * @param startPos Starting position offset (default: 0)
28
+ * @param maxOccurrences Maximum number of occurrences to find (optional)
29
+ * @returns Array of start positions (0-based indices in the text)
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * const positions = kmpSearch("abcabcabc", "abc", 0, 2);
34
+ * // Returns: [0, 3] (first 2 occurrences)
35
+ * ```
36
+ */
37
+ export declare const kmpSearch: (text: string, pattern: string, startPos?: number, maxOccurrences?: number) => number[];
38
+ /**
39
+ * Maps text positions in a combined string back to document positions.
40
+ * Used when searching across multiple text nodes that have been concatenated.
41
+ *
42
+ * @param textNodes Array of text nodes with their document positions
43
+ * @param textPositions Positions in the combined text (from kmpSearch)
44
+ * @param patternLength Length of the pattern being searched for
45
+ * @returns Array of { from, to } ranges in document coordinates
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * const textNodes = [
50
+ * { text: "Hello ", pos: 0 },
51
+ * { text: "World", pos: 6 }
52
+ * ];
53
+ * const positions = [0]; // Found at start of combined text
54
+ * const ranges = mapTextPositionsToDocument(textNodes, positions, 5);
55
+ * // Returns: [{ from: 0, to: 5 }]
56
+ * ```
57
+ */
58
+ export declare const mapTextPositionsToDocument: (textNodes: Array<{
59
+ text: string;
60
+ pos: number;
61
+ }>, textPositions: number[], patternLength: number) => Array<{
62
+ from: number;
63
+ to: number;
64
+ }>;
65
+ /**
66
+ * Compares two maps for equality.
67
+ * Checks if both maps have the same size and identical key-value pairs.
68
+ *
69
+ * @param map1 First map to compare
70
+ * @param map2 Second map to compare
71
+ * @returns True if maps are equal, false otherwise
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * const map1 = new Map([['a', true], ['b', false]]);
76
+ * const map2 = new Map([['a', true], ['b', false]]);
77
+ * areMapsEqual(map1, map2); // Returns: true
78
+ * ```
79
+ */
80
+ export declare const areMapsEqual: <K, V>(map1: Map<K, V>, map2: Map<K, V>) => boolean;
@@ -0,0 +1,10 @@
1
+ export declare class Console {
2
+ static log: (...data: any[]) => void;
3
+ static warn: (...data: any[]) => void;
4
+ static error: (...data: any[]) => void;
5
+ static debug: (...data: any[]) => void;
6
+ static info: (...data: any[]) => void;
7
+ static logsEnabled: boolean;
8
+ static catch: (message: string, error?: unknown) => void;
9
+ static showLogs(): boolean;
10
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Serializer utilities for Plate editor content
3
+ *
4
+ * This module provides utilities for serializing Plate editor content,
5
+ * particularly for removing comment nodes from serialized JSON.
6
+ *
7
+ * Use this when persisting editor content to remove Velt comment elements
8
+ * while preserving the original text content.
9
+ */
10
+ import type { Descendant } from 'slate';
11
+ /**
12
+ * Export JSON without comment nodes.
13
+ *
14
+ * This function takes Plate editor content and removes all comment nodes,
15
+ * unwrapping their children and merging adjacent text nodes with same formatting.
16
+ *
17
+ * @param content - Plate editor content (Descendant[])
18
+ * @returns Serialized content without comment nodes
19
+ */
20
+ export declare const exportJSONWithoutComments: (content: Descendant[]) => Descendant[];
package/index.d.ts ADDED
@@ -0,0 +1,291 @@
1
+ import { CommentAnnotation } from '@veltdev/types';
2
+ import { Descendant } from 'slate';
3
+ import React from 'react';
4
+ import { RenderElementProps } from 'slate-react';
5
+ import { PlateEditor } from '@platejs/core/react';
6
+
7
+ /**
8
+ * Common type definitions shared across the entire codebase.
9
+ * These types are SDK-agnostic and represent domain concepts.
10
+ */
11
+
12
+ /**
13
+ * Context object for comment annotations.
14
+ * Contains text editor configuration and any additional context data.
15
+ */
16
+ interface CommentAnnotationContext {
17
+ textEditorConfig?: {
18
+ text: string;
19
+ occurrence: number;
20
+ editorId?: string;
21
+ targetTextNodeId?: string;
22
+ };
23
+ [key: string]: unknown;
24
+ }
25
+ /**
26
+ * Request interface for addComment function.
27
+ * Matches legacy AddCommentRequest interface.
28
+ */
29
+ interface AddCommentRequest {
30
+ editorId?: string;
31
+ editor: unknown;
32
+ context?: unknown;
33
+ }
34
+ /**
35
+ * Request interface for renderComments function.
36
+ * Matches legacy RenderCommentsRequest interface.
37
+ */
38
+ interface RenderCommentsRequest {
39
+ editor: unknown;
40
+ editorId?: string;
41
+ commentAnnotations?: CommentAnnotation[];
42
+ }
43
+
44
+ /**
45
+ * Editor-specific type definitions for Plate.js.
46
+ * This is the ONLY place where editor-specific types may be defined.
47
+ */
48
+
49
+ /**
50
+ * Extended PlateEditor interface with Velt comments functionality.
51
+ */
52
+ interface VeltCommentsEditor extends PlateEditor {
53
+ }
54
+ /**
55
+ * Velt comment element type for the editor.
56
+ * This represents a comment annotation node/element in the editor's document model.
57
+ */
58
+ type VeltCommentsElement = {
59
+ type: 'veltComment';
60
+ children: Descendant[];
61
+ annotationId?: string;
62
+ multiThreadAnnotationId?: string;
63
+ };
64
+ /**
65
+ * Plugin configuration options for VeltCommentsPlugin.
66
+ */
67
+ interface VeltCommentsPluginConfig {
68
+ editorId?: string;
69
+ persistVeltMarks?: boolean;
70
+ HistoryEditor?: unknown;
71
+ }
72
+
73
+ /**
74
+ * Core extension module for Plate.js.
75
+ * This module creates the Plate plugin that wires everything together.
76
+ *
77
+ * Responsibilities:
78
+ * - Create plugin using Plate's createPlatePlugin
79
+ * - Wire features into editor lifecycle hooks
80
+ * - Register editor in registry
81
+ * - Handle cleanup on editor destruction
82
+ *
83
+ * Architectural Rules:
84
+ * - This module MAY import Plate types (it's the extension entry point)
85
+ * - It delegates to features and adapters for actual work
86
+ *
87
+ * KEY DIFFERENCE FROM SLATE:
88
+ * - Slate uses HOC pattern: withVeltComments(editor)
89
+ * - Plate uses plugin pattern: createPlatePlugin({ key, node, handlers })
90
+ */
91
+
92
+ /**
93
+ * VeltCommentsPlugin - Plate.js plugin for Velt Comments integration.
94
+ *
95
+ * This is the main entry point that enhances the editor with comment functionality.
96
+ * It creates an inline element type for comment highlighting and sets up
97
+ * change detection for updating comment positions.
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * import { usePlateEditor } from '@platejs/core/react';
102
+ * import { VeltCommentsPlugin } from '@veltdev/plate-comments-react';
103
+ *
104
+ * const editor = usePlateEditor({
105
+ * plugins: [VeltCommentsPlugin],
106
+ * });
107
+ *
108
+ * // With configuration
109
+ * const editor = usePlateEditor({
110
+ * plugins: [
111
+ * VeltCommentsPlugin.configure({
112
+ * options: { editorId: 'my-editor' }
113
+ * })
114
+ * ],
115
+ * });
116
+ * ```
117
+ */
118
+ declare const VeltCommentsPlugin: any;
119
+
120
+ /**
121
+ * Add comment feature module.
122
+ *
123
+ * Purpose: End-to-end add comment orchestration.
124
+ * Orchestrates adapters and core to implement the add comment flow.
125
+ *
126
+ * Key responsibilities:
127
+ * - Get Velt comment element
128
+ * - Extract selection context from editor
129
+ * - Create comment via Velt SDK
130
+ * - Apply mark to editor document
131
+ * - Update state with annotation data
132
+ *
133
+ * Dependencies:
134
+ * - adapters/velt.ts (for Velt SDK calls)
135
+ * - adapters/host/doc.ts (for selection extraction, editor setup, and selection reset)
136
+ * - adapters/host/marks.ts (for mark application)
137
+ * - adapters/host/storage.ts (for mark application configuration)
138
+ * - core/state.ts (for state updates)
139
+ * - types/common.ts (for CommentAnnotationContext)
140
+ *
141
+ * IMPORTANT: This module MUST NOT import editor or Velt types directly.
142
+ * All SDK access goes through adapters.
143
+ */
144
+
145
+ /**
146
+ * Adds a comment to the currently selected text in the editor.
147
+ *
148
+ * This is the main entry point for adding comments. It handles:
149
+ * - Extracting selection context from the editor
150
+ * - Creating the comment via Velt SDK
151
+ * - Applying marks to the editor if configured
152
+ * - Updating state with annotation data
153
+ *
154
+ * @param request - Object containing editorId (optional), editor, and context (optional)
155
+ * @returns Promise that resolves when the comment is added (or fails silently)
156
+ *
157
+ * @example
158
+ * ```typescript
159
+ * // Simple usage
160
+ * await addComment({ editor });
161
+ *
162
+ * // With editor ID
163
+ * await addComment({ editorId: 'my-editor', editor });
164
+ *
165
+ * // With custom context
166
+ * await addComment({
167
+ * editorId: 'my-editor',
168
+ * editor,
169
+ * context: {
170
+ * userId: 'user123',
171
+ * metadata: { source: 'web-app' }
172
+ * }
173
+ * });
174
+ * ```
175
+ *
176
+ * @remarks
177
+ * - Requires text to be selected in the editor
178
+ * - Requires Velt SDK to be available (window.Velt)
179
+ * - Marks are only applied if persistVeltMarks is FALSE in plugin config (matching legacy behavior)
180
+ * - Fails silently if Velt SDK is unavailable or selection is invalid
181
+ */
182
+ declare function addComment({ editorId, editor, context: clientContext, }: AddCommentRequest): Promise<void>;
183
+
184
+ /**
185
+ * Render comments feature module.
186
+ *
187
+ * Purpose: Public API entry point for rendering comment annotations.
188
+ * Orchestrates state updates, subscriptions, and delegates to commentRenderer.
189
+ *
190
+ * Key responsibilities:
191
+ * - Update state with new annotations
192
+ * - Subscribe to selected annotations from Velt
193
+ * - Delegate rendering logic to commentRenderer
194
+ *
195
+ * Dependencies:
196
+ * - adapters/velt.ts (for Velt SDK subscription)
197
+ * - adapters/host/doc.ts (for editor setup)
198
+ * - core/state.ts (for state management)
199
+ * - core/registry.ts (for editor ID extraction)
200
+ * - features/commentRenderer.ts (for rendering logic)
201
+ * - types/velt.ts (for CommentAnnotation)
202
+ *
203
+ * IMPORTANT: This module MUST NOT import editor or Velt types directly.
204
+ * All SDK access goes through adapters.
205
+ */
206
+
207
+ /**
208
+ * Renders comment annotations as marks in the editor.
209
+ *
210
+ * This function renders comment annotations as visual marks in the editor.
211
+ * It filters annotations for the specific editor and applies marks accordingly.
212
+ *
213
+ * @param request - Object containing editor, editorId (optional), and commentAnnotations (optional)
214
+ *
215
+ * @example
216
+ * ```typescript
217
+ * // Simple usage
218
+ * renderComments({ editor });
219
+ *
220
+ * // With editor ID
221
+ * renderComments({ editorId: 'my-editor', editor });
222
+ *
223
+ * // With annotations
224
+ * renderComments({
225
+ * editorId: 'my-editor',
226
+ * editor,
227
+ * commentAnnotations: [
228
+ * {
229
+ * annotationId: 'ann-123',
230
+ * context: {
231
+ * textEditorConfig: {
232
+ * text: 'Hello world',
233
+ * occurrence: 1,
234
+ * editorId: 'my-editor'
235
+ * }
236
+ * }
237
+ * }
238
+ * ]
239
+ * });
240
+ * ```
241
+ *
242
+ * @remarks
243
+ * - Only annotations with matching editorId are rendered
244
+ * - Automatically subscribes to selected annotations changes
245
+ * - Filters out terminal/resolved comments unless they're selected
246
+ * - Removes marks when comments become resolved
247
+ * - Re-applies marks when resolved comments are selected
248
+ */
249
+ declare const renderComments: ({ editor, editorId, commentAnnotations, }: RenderCommentsRequest) => void;
250
+ /**
251
+ * Cleans up subscriptions and renderer state for an editor.
252
+ * Should be called when editor is destroyed.
253
+ *
254
+ * @param editorId Unique identifier for the editor
255
+ */
256
+ declare const cleanupRenderComments: (editorId: string) => void;
257
+
258
+ /**
259
+ * Serializer utilities for Plate editor content
260
+ *
261
+ * This module provides utilities for serializing Plate editor content,
262
+ * particularly for removing comment nodes from serialized JSON.
263
+ *
264
+ * Use this when persisting editor content to remove Velt comment elements
265
+ * while preserving the original text content.
266
+ */
267
+
268
+ /**
269
+ * Export JSON without comment nodes.
270
+ *
271
+ * This function takes Plate editor content and removes all comment nodes,
272
+ * unwrapping their children and merging adjacent text nodes with same formatting.
273
+ *
274
+ * @param content - Plate editor content (Descendant[])
275
+ * @returns Serialized content without comment nodes
276
+ */
277
+ declare const exportJSONWithoutComments: (content: Descendant[]) => Descendant[];
278
+
279
+ /**
280
+ * React component for rendering Velt comment elements in Plate editor.
281
+ * This component renders the <velt-comment-text> custom element.
282
+ *
283
+ * Note: velt-comment-text is an inline element, so it should only contain text nodes
284
+ * or other inline elements, never block elements like <p>.
285
+ */
286
+
287
+ declare const PlateVeltComment: (props: Omit<RenderElementProps, "element"> & {
288
+ element: VeltCommentsElement;
289
+ }) => React.ReactElement;
290
+
291
+ export { AddCommentRequest, CommentAnnotationContext, PlateVeltComment, RenderCommentsRequest, VeltCommentsEditor, VeltCommentsElement, VeltCommentsPlugin, VeltCommentsPluginConfig, addComment, cleanupRenderComments, exportJSONWithoutComments, renderComments };
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@veltdev/plate-comments-react",
3
+ "version": "1.0.0",
4
+ "description": "Velt Comments integration for Plate.js editor",
5
+ "scripts": {
6
+ "test": "echo \"Error: no test specified\" && exit 1",
7
+ "version:update": "node ../update-npm-package.mjs",
8
+ "publish:extension": "npm publish --access public"
9
+ },
10
+ "main": "cjs/index.js",
11
+ "module": "esm/index.js",
12
+ "types": "index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "import": "./esm/index.js",
16
+ "require": "./cjs/index.js",
17
+ "types": "./index.d.ts"
18
+ }
19
+ },
20
+ "peerDependencies": {
21
+ "react": "^19.0.0 || ^18.0.0 || ^17.0.0 || ^16.0.0",
22
+ "react-dom": "^19.0.0 || ^18.0.0 || ^17.0.0 || ^16.0.0",
23
+ "@platejs/core": "^49.0.0",
24
+ "slate": "^0.112.0",
25
+ "slate-react": "^0.112.1"
26
+ },
27
+ "license": "Proprietary"
28
+ }