helldots 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +296 -22
- package/dist/helldots.esm.js +6 -1451
- package/dist/helldots.esm.js.map +4 -4
- package/dist/helldots.umd.js +14 -1459
- package/dist/index.d.ts +312 -12
- package/package.json +4 -2
package/dist/index.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export interface CommentAnchor {
|
|
|
24
24
|
export type AnchorState = "anchored" | "orphaned" | "inactive";
|
|
25
25
|
|
|
26
26
|
/** RF09 — comment lifecycle state. */
|
|
27
|
-
export type CommentStatus = "open" | "in_progress" | "resolved";
|
|
27
|
+
export type CommentStatus = "open" | "in_progress" | "in_review" | "resolved";
|
|
28
28
|
|
|
29
29
|
/** RF3 — comment category. `null` means deliberately unclassified. */
|
|
30
30
|
export type CommentType = "bug" | "suggestion" | "question" | "improvement";
|
|
@@ -32,6 +32,72 @@ export type CommentType = "bug" | "suggestion" | "question" | "improvement";
|
|
|
32
32
|
/** RF4 — comment priority. `null` means deliberately unprioritised. */
|
|
33
33
|
export type CommentPriority = "high" | "medium" | "low";
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Aggregate figures over a corpus of comments. Every bucket is present even
|
|
37
|
+
* when empty, so a consumer can index it without guarding — an absent key and
|
|
38
|
+
* a zero would otherwise be indistinguishable.
|
|
39
|
+
*/
|
|
40
|
+
export interface CommentMetrics {
|
|
41
|
+
total: number;
|
|
42
|
+
byStatus: Record<CommentStatus, number>;
|
|
43
|
+
/** `unset` holds the comments left deliberately unclassified. */
|
|
44
|
+
byType: Record<CommentType | "unset", number>;
|
|
45
|
+
/** `unset` holds the comments left deliberately unprioritised. */
|
|
46
|
+
byPriority: Record<CommentPriority | "unset", number>;
|
|
47
|
+
/**
|
|
48
|
+
* Comments created per day, oldest first, in `YYYY-MM-DD`. Only days that
|
|
49
|
+
* saw activity get an entry: filling the gaps would put a year of empty
|
|
50
|
+
* buckets between two comments twelve months apart.
|
|
51
|
+
*/
|
|
52
|
+
overTime: Array<{ date: string; count: number }>;
|
|
53
|
+
resolution: {
|
|
54
|
+
resolvedCount: number;
|
|
55
|
+
/** Comments that were resolved, reopened and resolved again. */
|
|
56
|
+
reopenedCount: number;
|
|
57
|
+
/** Mean and median of the resolution currently in force, or null when nothing is resolved. */
|
|
58
|
+
averageMs: number | null;
|
|
59
|
+
medianMs: number | null;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Who performed an audited action, as the host declared them at the time. */
|
|
64
|
+
export interface AuditActor {
|
|
65
|
+
/** From `user.id`, when the host supplies one. Never rendered. */
|
|
66
|
+
id?: string;
|
|
67
|
+
/** The display name at the time of the action. */
|
|
68
|
+
name: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The four actions worth auditing. Replies carry their own author and
|
|
73
|
+
* timestamp already, and reactions are high-frequency signal with no audit
|
|
74
|
+
* value — neither produces an entry.
|
|
75
|
+
*/
|
|
76
|
+
export type AuditEventType = "created" | "edited" | "status" | "classified";
|
|
77
|
+
|
|
78
|
+
/** One entry of a comment's append-only audit trail. */
|
|
79
|
+
export interface AuditEvent {
|
|
80
|
+
type: AuditEventType;
|
|
81
|
+
/**
|
|
82
|
+
* ISO timestamp, from the acting client's clock. Merge corpora written on
|
|
83
|
+
* machines whose clocks disagree and an entry can predate the comment it
|
|
84
|
+
* belongs to; durations derived from these are clamped at zero rather than
|
|
85
|
+
* rendered negative.
|
|
86
|
+
*/
|
|
87
|
+
at: string;
|
|
88
|
+
actor: AuditActor;
|
|
89
|
+
/** "classified" only: which field moved. */
|
|
90
|
+
field?: "type" | "priority" | "tags";
|
|
91
|
+
/**
|
|
92
|
+
* Both ends of the transition, for "status" and for "classified" on type or
|
|
93
|
+
* priority. `null` is a value, not an absence — it is how type and priority
|
|
94
|
+
* read when deliberately unset. Absent for "created", "edited", and for a
|
|
95
|
+
* tag change, which is a list with no two-value transition.
|
|
96
|
+
*/
|
|
97
|
+
from?: string | null;
|
|
98
|
+
to?: string | null;
|
|
99
|
+
}
|
|
100
|
+
|
|
35
101
|
/** RF2 — environment snapshot taken when the comment was created. */
|
|
36
102
|
export interface CommentContext {
|
|
37
103
|
version: 1;
|
|
@@ -60,6 +126,11 @@ export interface CommentContext {
|
|
|
60
126
|
export type CommentId = string | number;
|
|
61
127
|
|
|
62
128
|
export interface SerializedComment {
|
|
129
|
+
/**
|
|
130
|
+
* Version of this serialized shape. Stamped as 1 by serializeComments;
|
|
131
|
+
* optional because payloads persisted before it existed have none.
|
|
132
|
+
*/
|
|
133
|
+
schemaVersion?: number;
|
|
63
134
|
id: CommentId;
|
|
64
135
|
text: string;
|
|
65
136
|
/** ISO timestamp of the last edit; null when never edited. */
|
|
@@ -67,8 +138,31 @@ export interface SerializedComment {
|
|
|
67
138
|
anchor: CommentAnchor | null;
|
|
68
139
|
/** location.pathname where the comment was created. */
|
|
69
140
|
page: string;
|
|
141
|
+
/**
|
|
142
|
+
* Append-only audit trail: who created, edited, moved or reclassified this
|
|
143
|
+
* comment, and when. Optional and absent by default — records written
|
|
144
|
+
* before it existed simply have none, so no migration is involved, and
|
|
145
|
+
* `null` rather than `[]` keeps an untouched corpus free of extra bytes.
|
|
146
|
+
*
|
|
147
|
+
* Every resolution the comment has had is derivable from the `status`
|
|
148
|
+
* entries, which is why no separate resolution history is stored.
|
|
149
|
+
*/
|
|
150
|
+
history?: AuditEvent[] | null;
|
|
70
151
|
replies: CommentReply[];
|
|
71
152
|
author: string;
|
|
153
|
+
/**
|
|
154
|
+
* Stable identifier of the author, from the `user.id` the host supplied at
|
|
155
|
+
* creation. Optional and absent by default: records written before it
|
|
156
|
+
* existed simply have none, so no migration is involved.
|
|
157
|
+
*
|
|
158
|
+
* Never rendered — `author` is the display name and stays what any UI
|
|
159
|
+
* shows — it travels with the record, so a store that holds nothing but
|
|
160
|
+
* comments renders every author without a lookup. The id is opaque to
|
|
161
|
+
* HellDots: whether it points into the host's user table, into a
|
|
162
|
+
* comments-only database, or nowhere at all is the host's business. What it
|
|
163
|
+
* buys is telling two teammates who share a display name apart.
|
|
164
|
+
*/
|
|
165
|
+
authorId?: string | null;
|
|
72
166
|
createdAt: string;
|
|
73
167
|
screenshots: string[];
|
|
74
168
|
status: CommentStatus;
|
|
@@ -89,30 +183,124 @@ export interface SerializedComment {
|
|
|
89
183
|
/** RF1 — automatic viewport capture (JPEG data-URL). */
|
|
90
184
|
contextScreenshot: string | null;
|
|
91
185
|
/**
|
|
92
|
-
* RF6 — emoji →
|
|
93
|
-
*
|
|
186
|
+
* RF6 — emoji → the actor keys that reacted (see the `user` option). Always
|
|
187
|
+
* one of the six emoji in the fixed set; anything else is dropped on load.
|
|
188
|
+
* Null when nobody has reacted, so an untouched corpus carries no extra
|
|
189
|
+
* payload.
|
|
94
190
|
*/
|
|
95
|
-
reactions
|
|
191
|
+
reactions: Record<string, string[]> | null;
|
|
96
192
|
}
|
|
97
193
|
|
|
194
|
+
/**
|
|
195
|
+
* Everything that can change, as one discriminated union. Switch on `type`
|
|
196
|
+
* and TypeScript narrows the rest of the fields for you.
|
|
197
|
+
*
|
|
198
|
+
* The ten specific callbacks below carry exactly the same events at
|
|
199
|
+
* exactly the same moments; subscribe either way, or both.
|
|
200
|
+
*/
|
|
201
|
+
export type ChangeEvent =
|
|
202
|
+
| { type: "comment:created"; comment: SerializedComment }
|
|
203
|
+
| { type: "comment:edited"; comment: SerializedComment }
|
|
204
|
+
| { type: "comment:deleted"; id: CommentId }
|
|
205
|
+
| { type: "comment:status-changed"; comment: SerializedComment }
|
|
206
|
+
/** Type, priority or tags changed. */
|
|
207
|
+
| { type: "comment:updated"; comment: SerializedComment }
|
|
208
|
+
| { type: "comment:anchor-lost"; comment: SerializedComment }
|
|
209
|
+
| {
|
|
210
|
+
type: "reply:added";
|
|
211
|
+
comment: SerializedComment;
|
|
212
|
+
reply: CommentReply;
|
|
213
|
+
}
|
|
214
|
+
| {
|
|
215
|
+
type: "reply:deleted";
|
|
216
|
+
comment: SerializedComment;
|
|
217
|
+
reply: CommentReply;
|
|
218
|
+
}
|
|
219
|
+
| {
|
|
220
|
+
type: "reply:edited";
|
|
221
|
+
comment: SerializedComment;
|
|
222
|
+
reply: CommentReply;
|
|
223
|
+
}
|
|
224
|
+
/** `reply` is null when the reaction is on the root comment. */
|
|
225
|
+
| {
|
|
226
|
+
type: "reaction:toggled";
|
|
227
|
+
comment: SerializedComment;
|
|
228
|
+
reply: CommentReply | null;
|
|
229
|
+
};
|
|
230
|
+
|
|
98
231
|
export interface CommentOverlayOptions {
|
|
99
232
|
shortcutKey?: string;
|
|
100
233
|
shortcutModifier?: "alt" | "ctrl" | "shift";
|
|
101
234
|
autoInit?: boolean;
|
|
102
|
-
/**
|
|
103
|
-
|
|
235
|
+
/**
|
|
236
|
+
* UI language. "en" and "es" ship today; any other value falls back to
|
|
237
|
+
* English (and a locale missing individual keys falls back per key).
|
|
238
|
+
* Typed as string so a host can pass a runtime-detected code without a
|
|
239
|
+
* cast — an unknown code degrades, it never breaks.
|
|
240
|
+
*/
|
|
241
|
+
locale?: string;
|
|
104
242
|
/** Auto save/restore comments. Default: "none" (host app persists via callbacks). */
|
|
105
243
|
persistence?: "localStorage" | "none";
|
|
106
244
|
/** Capture a viewport screenshot and environment snapshot on every new comment. Default: true. */
|
|
107
245
|
autoScreenshot?: boolean;
|
|
108
|
-
/**
|
|
109
|
-
|
|
246
|
+
/**
|
|
247
|
+
* Fetch stylesheets the renderer cannot read, so their web fonts survive
|
|
248
|
+
* into screenshots. Default: false.
|
|
249
|
+
*
|
|
250
|
+
* A cross-origin `<link>` (Google Fonts and friends) throws `SecurityError`
|
|
251
|
+
* on `cssRules`, so its `@font-face` never reaches the capture and the text
|
|
252
|
+
* is rendered in a fallback face. The fallback's metrics differ, which
|
|
253
|
+
* shifts glyphs sideways — a drag selection tight around a few letters then
|
|
254
|
+
* comes back holding the wrong ones. Enabling this re-fetches those sheets
|
|
255
|
+
* (the same URLs the page already loaded, cached per session) so the
|
|
256
|
+
* capture matches the page.
|
|
257
|
+
*
|
|
258
|
+
* Off by default because a comment widget making third-party requests
|
|
259
|
+
* should be the host's decision. Leave it off and captures of such a page
|
|
260
|
+
* stay misaligned; a host can also fix it at the source by self-hosting the
|
|
261
|
+
* font or adding `crossorigin` to the `<link>`.
|
|
262
|
+
*/
|
|
263
|
+
embedCrossOriginFonts?: boolean;
|
|
264
|
+
/**
|
|
265
|
+
* Identity used as the author of new comments and replies.
|
|
266
|
+
*
|
|
267
|
+
* `name` is what gets displayed. `id` is optional and never rendered: it
|
|
268
|
+
* is persisted as `authorId` on the comments and replies this user creates,
|
|
269
|
+
* and it is what a reaction is keyed on — so two teammates who share a
|
|
270
|
+
* display name are still told apart. Without it the name is used, and
|
|
271
|
+
* without any `user` at all every actor collapses into one.
|
|
272
|
+
*
|
|
273
|
+
* HellDots authenticates nobody: whatever the host declares here is taken
|
|
274
|
+
* at face value and recorded as-is.
|
|
275
|
+
*/
|
|
276
|
+
user?: { name: string; id?: string };
|
|
110
277
|
/**
|
|
111
278
|
* Query parameter carrying a comment id in "Copy link" URLs, and read back
|
|
112
279
|
* on startup to open that comment. Default: "helldotsComment". Override it
|
|
113
280
|
* when the host already routes on that name.
|
|
114
281
|
*/
|
|
115
282
|
linkParam?: string;
|
|
283
|
+
/**
|
|
284
|
+
* Called instead of a full-page load when the widget navigates to another
|
|
285
|
+
* page (the inbox's "view on its page" jump). Hand it your SPA router's
|
|
286
|
+
* push so the app's state survives; call `notifyNavigation()` after the
|
|
287
|
+
* route renders.
|
|
288
|
+
*/
|
|
289
|
+
navigate?: (page: string) => void;
|
|
290
|
+
/**
|
|
291
|
+
* Run `notifyNavigation()` automatically on popstate (back/forward).
|
|
292
|
+
* Opt-in and popstate-only: pushState routing still needs an explicit
|
|
293
|
+
* `notifyNavigation()` call from the router's hook. Default: false.
|
|
294
|
+
*/
|
|
295
|
+
autoDetectNavigation?: boolean;
|
|
296
|
+
/**
|
|
297
|
+
* Single subscription point: fires for every change, alongside whichever
|
|
298
|
+
* specific callback below carries the same event. Handy when a host syncs
|
|
299
|
+
* everything to one endpoint instead of wiring nine functions. A handler
|
|
300
|
+
* that throws is caught and warned about — it never rolls back the
|
|
301
|
+
* mutation that emitted it.
|
|
302
|
+
*/
|
|
303
|
+
onChange?: (event: ChangeEvent) => void;
|
|
116
304
|
/** Fired after a new comment is saved. */
|
|
117
305
|
onCommentCreated?: (comment: SerializedComment) => void;
|
|
118
306
|
/** Fired after a reply is added to any comment. */
|
|
@@ -131,21 +319,49 @@ export interface CommentOverlayOptions {
|
|
|
131
319
|
onCommentStatusChanged?: (comment: SerializedComment) => void;
|
|
132
320
|
/** Fired after type, priority or tags change on any comment. */
|
|
133
321
|
onCommentUpdated?: (comment: SerializedComment) => void;
|
|
322
|
+
/**
|
|
323
|
+
* Fired after a reaction is added to or removed from a comment or a reply.
|
|
324
|
+
* `reply` is null when the reaction is on the root comment.
|
|
325
|
+
*/
|
|
326
|
+
onReactionToggled?: (
|
|
327
|
+
comment: SerializedComment,
|
|
328
|
+
reply: CommentReply | null
|
|
329
|
+
) => void;
|
|
134
330
|
}
|
|
135
331
|
|
|
136
332
|
export interface CommentReply {
|
|
137
333
|
id: CommentId;
|
|
138
334
|
text: string;
|
|
139
335
|
author: string;
|
|
336
|
+
/**
|
|
337
|
+
* Stable identifier of the author, from the `user.id` the host supplied at
|
|
338
|
+
* creation. Optional and absent by default: records written before it
|
|
339
|
+
* existed simply have none, so no migration is involved.
|
|
340
|
+
*
|
|
341
|
+
* Never rendered — `author` is the display name and stays what any UI
|
|
342
|
+
* shows — it travels with the record, so a store that holds nothing but
|
|
343
|
+
* comments renders every author without a lookup. The id is opaque to
|
|
344
|
+
* HellDots: whether it points into the host's user table, into a
|
|
345
|
+
* comments-only database, or nowhere at all is the host's business. What it
|
|
346
|
+
* buys is telling two teammates who share a display name apart.
|
|
347
|
+
*/
|
|
348
|
+
authorId?: string | null;
|
|
140
349
|
timestamp: string;
|
|
141
350
|
screenshots?: string[];
|
|
142
351
|
/** ISO timestamp of the last edit; null when never edited. */
|
|
143
352
|
editedAt?: string | null;
|
|
353
|
+
/**
|
|
354
|
+
* RF6 — emoji → the actor keys that reacted. Same shape and same rules as a
|
|
355
|
+
* comment's; null when nobody has reacted.
|
|
356
|
+
*/
|
|
357
|
+
reactions?: Record<string, string[]> | null;
|
|
144
358
|
}
|
|
145
359
|
|
|
146
360
|
export interface Comment {
|
|
147
361
|
id: CommentId;
|
|
148
362
|
text: string;
|
|
363
|
+
/** ISO timestamp of the last edit; null when never edited. */
|
|
364
|
+
editedAt?: string | null;
|
|
149
365
|
/** Live anchor element; null while the comment is orphaned or inactive. */
|
|
150
366
|
container: HTMLElement | null;
|
|
151
367
|
relativeX: number;
|
|
@@ -158,8 +374,31 @@ export interface Comment {
|
|
|
158
374
|
target?: HTMLElement | null;
|
|
159
375
|
/** location.pathname where the comment was created. */
|
|
160
376
|
page: string;
|
|
377
|
+
/**
|
|
378
|
+
* Append-only audit trail: who created, edited, moved or reclassified this
|
|
379
|
+
* comment, and when. Optional and absent by default — records written
|
|
380
|
+
* before it existed simply have none, so no migration is involved, and
|
|
381
|
+
* `null` rather than `[]` keeps an untouched corpus free of extra bytes.
|
|
382
|
+
*
|
|
383
|
+
* Every resolution the comment has had is derivable from the `status`
|
|
384
|
+
* entries, which is why no separate resolution history is stored.
|
|
385
|
+
*/
|
|
386
|
+
history?: AuditEvent[] | null;
|
|
161
387
|
replies: CommentReply[];
|
|
162
388
|
author: string;
|
|
389
|
+
/**
|
|
390
|
+
* Stable identifier of the author, from the `user.id` the host supplied at
|
|
391
|
+
* creation. Optional and absent by default: records written before it
|
|
392
|
+
* existed simply have none, so no migration is involved.
|
|
393
|
+
*
|
|
394
|
+
* Never rendered — `author` is the display name and stays what any UI
|
|
395
|
+
* shows — it travels with the record, so a store that holds nothing but
|
|
396
|
+
* comments renders every author without a lookup. The id is opaque to
|
|
397
|
+
* HellDots: whether it points into the host's user table, into a
|
|
398
|
+
* comments-only database, or nowhere at all is the host's business. What it
|
|
399
|
+
* buys is telling two teammates who share a display name apart.
|
|
400
|
+
*/
|
|
401
|
+
authorId?: string | null;
|
|
163
402
|
createdAt: string;
|
|
164
403
|
screenshots: string[];
|
|
165
404
|
status: CommentStatus;
|
|
@@ -180,10 +419,12 @@ export interface Comment {
|
|
|
180
419
|
/** RF1 — automatic viewport capture (JPEG data-URL). */
|
|
181
420
|
contextScreenshot: string | null;
|
|
182
421
|
/**
|
|
183
|
-
* RF6 — emoji →
|
|
184
|
-
*
|
|
422
|
+
* RF6 — emoji → the actor keys that reacted (see the `user` option). Always
|
|
423
|
+
* one of the six emoji in the fixed set; anything else is dropped on load.
|
|
424
|
+
* Null when nobody has reacted, so an untouched corpus carries no extra
|
|
425
|
+
* payload.
|
|
185
426
|
*/
|
|
186
|
-
reactions
|
|
427
|
+
reactions: Record<string, string[]> | null;
|
|
187
428
|
}
|
|
188
429
|
|
|
189
430
|
export declare class CommentOverlay {
|
|
@@ -193,7 +434,15 @@ export declare class CommentOverlay {
|
|
|
193
434
|
constructor(options?: Omit<CommentOverlayOptions, "autoInit">);
|
|
194
435
|
|
|
195
436
|
toggleCommentMode(): void;
|
|
196
|
-
|
|
437
|
+
/**
|
|
438
|
+
* `screenshots` are data-URLs attached to the reply. Takes the live
|
|
439
|
+
* comment or its id; null when an id does not resolve.
|
|
440
|
+
*/
|
|
441
|
+
addReply(
|
|
442
|
+
comment: Comment | CommentId,
|
|
443
|
+
text: string,
|
|
444
|
+
screenshots?: string[]
|
|
445
|
+
): CommentReply | null;
|
|
197
446
|
deleteReply(commentId: CommentId, replyId: CommentId): boolean;
|
|
198
447
|
/** Rewrites a comment's text. False when the id is unknown, the text is blank, or nothing changed. */
|
|
199
448
|
editComment(id: CommentId, text: string): boolean;
|
|
@@ -207,11 +456,62 @@ export declare class CommentOverlay {
|
|
|
207
456
|
orphaned: number;
|
|
208
457
|
inactive: number;
|
|
209
458
|
};
|
|
459
|
+
/**
|
|
460
|
+
* Re-syncs the widget after a client-side navigation: reclassifies every
|
|
461
|
+
* comment against the new pathname, re-resolves anchors against the new
|
|
462
|
+
* DOM, rebuilds markers and moves the inbox onto the new page. Also the
|
|
463
|
+
* "re-anchor now" primitive for same-path re-renders.
|
|
464
|
+
*/
|
|
465
|
+
notifyNavigation(): {
|
|
466
|
+
anchored: number;
|
|
467
|
+
orphaned: number;
|
|
468
|
+
inactive: number;
|
|
469
|
+
};
|
|
210
470
|
deleteComment(id: CommentId): boolean;
|
|
471
|
+
/**
|
|
472
|
+
* Removes every comment at once (markers, memory, and their persisted
|
|
473
|
+
* entries in localStorage mode). A bulk reset for reconciling against a
|
|
474
|
+
* backend before loadComments — fires no per-comment callbacks.
|
|
475
|
+
*/
|
|
476
|
+
clearComments(): void;
|
|
477
|
+
/**
|
|
478
|
+
* Aggregate figures over every comment the widget holds. Unfiltered: the
|
|
479
|
+
* dashboard inside the inbox measures whatever that panel is showing, but a
|
|
480
|
+
* host has no notion of those filters.
|
|
481
|
+
*/
|
|
482
|
+
getMetrics(): CommentMetrics;
|
|
483
|
+
/**
|
|
484
|
+
* Downloads the corpus as CSV, one row per comment. Screenshots and the
|
|
485
|
+
* automatic context capture stay out. Defaults to every comment.
|
|
486
|
+
*/
|
|
487
|
+
exportCommentsCsv(comments?: SerializedComment[]): void;
|
|
488
|
+
/**
|
|
489
|
+
* Downloads the aggregate figures as CSV in long format — `section, key,
|
|
490
|
+
* value` — so the column count does not change with the corpus.
|
|
491
|
+
*/
|
|
492
|
+
exportMetricsCsv(comments?: SerializedComment[]): void;
|
|
493
|
+
/**
|
|
494
|
+
* Opens the browser's print dialog on a report of the figures, which is
|
|
495
|
+
* where "save as PDF" lives. The report is built in its own document, so
|
|
496
|
+
* what prints is the report rather than the host page.
|
|
497
|
+
*/
|
|
498
|
+
printMetricsReport(comments?: SerializedComment[], scope?: string): void;
|
|
211
499
|
setCommentStatus(id: CommentId, status: CommentStatus): boolean;
|
|
212
500
|
setCommentType(id: CommentId, type: CommentType | null): boolean;
|
|
213
501
|
setCommentPriority(id: CommentId, priority: CommentPriority | null): boolean;
|
|
214
502
|
setCommentTags(id: CommentId, tags: string[]): boolean;
|
|
503
|
+
/**
|
|
504
|
+
* RF6 — flips the current actor's reaction on a comment: present, it is
|
|
505
|
+
* removed; absent, it is added. The actor is `user.id ?? user.name`.
|
|
506
|
+
* Returns false when the id or the emoji is unknown.
|
|
507
|
+
*/
|
|
508
|
+
toggleCommentReaction(id: CommentId, emoji: string): boolean;
|
|
509
|
+
/** Same contract as toggleCommentReaction, one level down. */
|
|
510
|
+
toggleReplyReaction(
|
|
511
|
+
commentId: CommentId,
|
|
512
|
+
replyId: CommentId,
|
|
513
|
+
emoji: string
|
|
514
|
+
): boolean;
|
|
215
515
|
cleanup(): void;
|
|
216
516
|
}
|
|
217
517
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "helldots",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.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",
|
|
@@ -53,9 +53,11 @@
|
|
|
53
53
|
"build": "node scripts/build.mjs",
|
|
54
54
|
"size": "node scripts/check-size.mjs",
|
|
55
55
|
"verify": "npm run lint && npm run typecheck && npm run format:check && npm test && npm run build && npm run size",
|
|
56
|
+
"check:commit": "node scripts/check-commit-msg.mjs",
|
|
56
57
|
"prepublishOnly": "npm run verify",
|
|
57
58
|
"changeset": "changeset",
|
|
58
|
-
"release": "changeset version"
|
|
59
|
+
"release": "changeset version",
|
|
60
|
+
"prepare": "node scripts/install-hooks.mjs"
|
|
59
61
|
},
|
|
60
62
|
"devDependencies": {
|
|
61
63
|
"@changesets/cli": "^2.31.0",
|