helldots 0.3.0 → 0.4.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/dist/index.d.ts CHANGED
@@ -48,9 +48,22 @@ export interface CommentContext {
48
48
  language: string;
49
49
  }
50
50
 
51
+ /**
52
+ * Identifier of a comment or a reply.
53
+ *
54
+ * New ids are 21-character nanoid strings. The `number` arm is not legacy
55
+ * cruft to be removed later: comments created before that change are still
56
+ * sitting in hosts' localStorage and in their own back ends, and they keep
57
+ * resolving. Compare ids with `String(a) === String(b)` rather than `===`
58
+ * when either side may have crossed a JSON or URL boundary.
59
+ */
60
+ export type CommentId = string | number;
61
+
51
62
  export interface SerializedComment {
52
- id: number;
63
+ id: CommentId;
53
64
  text: string;
65
+ /** ISO timestamp of the last edit; null when never edited. */
66
+ editedAt?: string | null;
54
67
  anchor: CommentAnchor | null;
55
68
  /** location.pathname where the comment was created. */
56
69
  page: string;
@@ -94,14 +107,26 @@ export interface CommentOverlayOptions {
94
107
  autoScreenshot?: boolean;
95
108
  /** Identity used as the author of new comments and replies. */
96
109
  user?: { name: string };
110
+ /**
111
+ * Query parameter carrying a comment id in "Copy link" URLs, and read back
112
+ * on startup to open that comment. Default: "helldotsComment". Override it
113
+ * when the host already routes on that name.
114
+ */
115
+ linkParam?: string;
97
116
  /** Fired after a new comment is saved. */
98
117
  onCommentCreated?: (comment: SerializedComment) => void;
99
118
  /** Fired after a reply is added to any comment. */
100
119
  onReplyAdded?: (comment: SerializedComment, reply: CommentReply) => void;
120
+ /** Fired after deleteReply removes a reply. */
121
+ onReplyDeleted?: (comment: SerializedComment, reply: CommentReply) => void;
122
+ /** Fired after editComment rewrites a comment's text. */
123
+ onCommentEdited?: (comment: SerializedComment) => void;
124
+ /** Fired after editReply rewrites a reply's text. */
125
+ onReplyEdited?: (comment: SerializedComment, reply: CommentReply) => void;
101
126
  /** Fired for each comment that could not be re-anchored by loadComments. */
102
127
  onAnchorLost?: (comment: SerializedComment) => void;
103
128
  /** Fired after deleteComment removes a comment. */
104
- onCommentDeleted?: (id: number) => void;
129
+ onCommentDeleted?: (id: CommentId) => void;
105
130
  /** Fired after setCommentStatus changes a comment's lifecycle state. */
106
131
  onCommentStatusChanged?: (comment: SerializedComment) => void;
107
132
  /** Fired after type, priority or tags change on any comment. */
@@ -109,15 +134,17 @@ export interface CommentOverlayOptions {
109
134
  }
110
135
 
111
136
  export interface CommentReply {
112
- id: number;
137
+ id: CommentId;
113
138
  text: string;
114
139
  author: string;
115
140
  timestamp: string;
116
141
  screenshots?: string[];
142
+ /** ISO timestamp of the last edit; null when never edited. */
143
+ editedAt?: string | null;
117
144
  }
118
145
 
119
146
  export interface Comment {
120
- id: number;
147
+ id: CommentId;
121
148
  text: string;
122
149
  /** Live anchor element; null while the comment is orphaned or inactive. */
123
150
  container: HTMLElement | null;
@@ -167,17 +194,24 @@ export declare class CommentOverlay {
167
194
 
168
195
  toggleCommentMode(): void;
169
196
  addReply(comment: Comment, text: string): CommentReply;
197
+ deleteReply(commentId: CommentId, replyId: CommentId): boolean;
198
+ /** Rewrites a comment's text. False when the id is unknown, the text is blank, or nothing changed. */
199
+ editComment(id: CommentId, text: string): boolean;
200
+ /** Rewrites a reply's text. Same contract as editComment. */
201
+ editReply(commentId: CommentId, replyId: CommentId, text: string): boolean;
202
+ /** The shareable URL for a comment, or null when the id is unknown. */
203
+ commentLink(id: CommentId): string | null;
170
204
  serializeComments(): SerializedComment[];
171
205
  loadComments(data: SerializedComment[]): {
172
206
  anchored: number;
173
207
  orphaned: number;
174
208
  inactive: number;
175
209
  };
176
- deleteComment(id: number): boolean;
177
- setCommentStatus(id: number, status: CommentStatus): boolean;
178
- setCommentType(id: number, type: CommentType | null): boolean;
179
- setCommentPriority(id: number, priority: CommentPriority | null): boolean;
180
- setCommentTags(id: number, tags: string[]): boolean;
210
+ deleteComment(id: CommentId): boolean;
211
+ setCommentStatus(id: CommentId, status: CommentStatus): boolean;
212
+ setCommentType(id: CommentId, type: CommentType | null): boolean;
213
+ setCommentPriority(id: CommentId, priority: CommentPriority | null): boolean;
214
+ setCommentTags(id: CommentId, tags: string[]): boolean;
181
215
  cleanup(): void;
182
216
  }
183
217
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "helldots",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Drop-in comment overlay for web apps — click anywhere to leave a comment anchored to that element, with an automatic screenshot and environment capture",
5
5
  "keywords": [
6
6
  "comments",
@@ -43,6 +43,7 @@
43
43
  "node": ">=18"
44
44
  },
45
45
  "scripts": {
46
+ "dev": "npx --yes serve -l 4173 .",
46
47
  "test": "vitest run",
47
48
  "test:coverage": "vitest run --coverage",
48
49
  "lint": "eslint .",
@@ -65,6 +66,7 @@
65
66
  "eslint-config-prettier": "^10.1.8",
66
67
  "globals": "^17.7.0",
67
68
  "jsdom": "^29.1.1",
69
+ "nanoid": "^6.0.1",
68
70
  "prettier": "^3.9.4",
69
71
  "typescript": "^6.0.3",
70
72
  "vitest": "^4.1.9"