helldots 0.6.0 → 0.8.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 +321 -25
- package/dist/helldots.esm.js +6 -6
- package/dist/helldots.esm.js.map +4 -4
- package/dist/helldots.umd.js +12 -12
- package/dist/index.d.ts +317 -34
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -191,42 +191,104 @@ export interface SerializedComment {
|
|
|
191
191
|
reactions: Record<string, string[]> | null;
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
+
/**
|
|
195
|
+
* Who caused a change.
|
|
196
|
+
*
|
|
197
|
+
* `"user"` is somebody acting inside the widget — a marker, the thread
|
|
198
|
+
* popover, the inbox. `"host"` is the app's own code calling a method.
|
|
199
|
+
*
|
|
200
|
+
* The distinction exists for multi-user apps. Applying a change that arrived
|
|
201
|
+
* over a socket means calling the same method the UI calls, so without this
|
|
202
|
+
* every host has to wrap its own writes in a flag to avoid echoing them
|
|
203
|
+
* straight back to the server. `if (meta.origin === "host") return;` is that
|
|
204
|
+
* flag, and it is now the library's job to provide it.
|
|
205
|
+
*/
|
|
206
|
+
export type ChangeOrigin = "user" | "host";
|
|
207
|
+
|
|
208
|
+
/** Which part of the widget a reported failure came from. */
|
|
209
|
+
export type ErrorContext =
|
|
210
|
+
/** A screenshot render failed; the comment saves without one. */
|
|
211
|
+
| "capture"
|
|
212
|
+
/** localStorage could not be written; this browser's copy now diverges. */
|
|
213
|
+
| "storage"
|
|
214
|
+
/** A record handed to loadComments was malformed and was skipped. */
|
|
215
|
+
| "load"
|
|
216
|
+
/** An `onCommentRequested` handler threw or rejected. */
|
|
217
|
+
| "link"
|
|
218
|
+
/** A `transformScreenshot` handler failed; the data URL was kept. */
|
|
219
|
+
| "transform";
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* What every change carries, whatever its type. Delivered as one trailing
|
|
223
|
+
* argument to the specific callbacks, and flattened onto the `onChange`
|
|
224
|
+
* event next to `comment`/`reply`/`id`.
|
|
225
|
+
*/
|
|
226
|
+
export interface ChangeMeta {
|
|
227
|
+
origin: ChangeOrigin;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/** `comment:status-changed` — both ends of the move along the lifecycle. */
|
|
231
|
+
export interface StatusChangeMeta extends ChangeMeta {
|
|
232
|
+
from: CommentStatus;
|
|
233
|
+
to: CommentStatus;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* `comment:updated` — which of the three fields moved, and both ends of the
|
|
238
|
+
* move. Discriminated on `field`, so narrowing gives you correctly typed
|
|
239
|
+
* `from`/`to` for each.
|
|
240
|
+
*/
|
|
241
|
+
export type UpdateMeta = ChangeMeta &
|
|
242
|
+
(
|
|
243
|
+
| { field: "type"; from: CommentType | null; to: CommentType | null }
|
|
244
|
+
| {
|
|
245
|
+
field: "priority";
|
|
246
|
+
from: CommentPriority | null;
|
|
247
|
+
to: CommentPriority | null;
|
|
248
|
+
}
|
|
249
|
+
| { field: "tags"; from: string[]; to: string[] }
|
|
250
|
+
);
|
|
251
|
+
|
|
194
252
|
/**
|
|
195
253
|
* Everything that can change, as one discriminated union. Switch on `type`
|
|
196
254
|
* and TypeScript narrows the rest of the fields for you.
|
|
197
255
|
*
|
|
198
256
|
* The ten specific callbacks below carry exactly the same events at
|
|
199
|
-
* exactly the same moments; subscribe either way,
|
|
257
|
+
* exactly the same moments, with the same metadata; subscribe either way,
|
|
258
|
+
* or both.
|
|
200
259
|
*/
|
|
201
260
|
export type ChangeEvent =
|
|
202
|
-
| { type: "comment:created"; comment: SerializedComment }
|
|
203
|
-
| { type: "comment:edited"; comment: SerializedComment }
|
|
204
|
-
| { type: "comment:deleted"; id: CommentId }
|
|
205
|
-
| {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
261
|
+
| ({ type: "comment:created"; comment: SerializedComment } & ChangeMeta)
|
|
262
|
+
| ({ type: "comment:edited"; comment: SerializedComment } & ChangeMeta)
|
|
263
|
+
| ({ type: "comment:deleted"; id: CommentId } & ChangeMeta)
|
|
264
|
+
| ({
|
|
265
|
+
type: "comment:status-changed";
|
|
266
|
+
comment: SerializedComment;
|
|
267
|
+
} & StatusChangeMeta)
|
|
268
|
+
/** Type, priority or tags changed; `field` says which. */
|
|
269
|
+
| ({ type: "comment:updated"; comment: SerializedComment } & UpdateMeta)
|
|
270
|
+
| ({ type: "comment:anchor-lost"; comment: SerializedComment } & ChangeMeta)
|
|
271
|
+
| ({
|
|
210
272
|
type: "reply:added";
|
|
211
273
|
comment: SerializedComment;
|
|
212
274
|
reply: CommentReply;
|
|
213
|
-
}
|
|
214
|
-
| {
|
|
275
|
+
} & ChangeMeta)
|
|
276
|
+
| ({
|
|
215
277
|
type: "reply:deleted";
|
|
216
278
|
comment: SerializedComment;
|
|
217
279
|
reply: CommentReply;
|
|
218
|
-
}
|
|
219
|
-
| {
|
|
280
|
+
} & ChangeMeta)
|
|
281
|
+
| ({
|
|
220
282
|
type: "reply:edited";
|
|
221
283
|
comment: SerializedComment;
|
|
222
284
|
reply: CommentReply;
|
|
223
|
-
}
|
|
285
|
+
} & ChangeMeta)
|
|
224
286
|
/** `reply` is null when the reaction is on the root comment. */
|
|
225
|
-
| {
|
|
287
|
+
| ({
|
|
226
288
|
type: "reaction:toggled";
|
|
227
289
|
comment: SerializedComment;
|
|
228
290
|
reply: CommentReply | null;
|
|
229
|
-
};
|
|
291
|
+
} & ChangeMeta);
|
|
230
292
|
|
|
231
293
|
export interface CommentOverlayOptions {
|
|
232
294
|
shortcutKey?: string;
|
|
@@ -261,6 +323,68 @@ export interface CommentOverlayOptions {
|
|
|
261
323
|
* font or adding `crossorigin` to the `<link>`.
|
|
262
324
|
*/
|
|
263
325
|
embedCrossOriginFonts?: boolean;
|
|
326
|
+
/**
|
|
327
|
+
* Narrows the screenshot renderer's computed-style enumeration to a
|
|
328
|
+
* curated allow-list instead of every property the browser exposes.
|
|
329
|
+
*
|
|
330
|
+
* The enumeration IS the render: it is ~91% of a capture's cost and it
|
|
331
|
+
* scales with element count, so on a page with a few thousand live nodes
|
|
332
|
+
* it is the difference between a capture that finishes and one that
|
|
333
|
+
* visibly stalls. Measured at ~2.7x off that phase.
|
|
334
|
+
*
|
|
335
|
+
* Off by default because the list is a fidelity contract, and no list can
|
|
336
|
+
* be complete for a page this library has never seen: a property it does
|
|
337
|
+
* not name is simply absent from the image. Turn it on for a heavy page,
|
|
338
|
+
* then look at a capture before trusting it — and report anything that
|
|
339
|
+
* comes out wrong, since the fix is one more entry in the list.
|
|
340
|
+
*/
|
|
341
|
+
fastCapture?: boolean;
|
|
342
|
+
/**
|
|
343
|
+
* Renders embedded documents as blank instead of cloning their contents.
|
|
344
|
+
*
|
|
345
|
+
* An iframe's cost is invisible from the outside: the renderer walks into
|
|
346
|
+
* a same-origin frame and clones its whole document, so a page reporting
|
|
347
|
+
* 242 elements can be a capture of 9 245. Measured at 2374 ms against
|
|
348
|
+
* 82 ms on one 9 000-node embedded frame.
|
|
349
|
+
*
|
|
350
|
+
* The `<iframe>` element itself is kept — its box, its border and the
|
|
351
|
+
* space it occupies. Removing the element instead would slide everything
|
|
352
|
+
* below it up by the frame's height and misalign the crop.
|
|
353
|
+
*
|
|
354
|
+
* Nothing to gain on a cross-origin frame: the renderer cannot read it,
|
|
355
|
+
* so it is already blank in the output (it does not stall or wait on it
|
|
356
|
+
* either). This is for same-origin frames, where the trade is real —
|
|
357
|
+
* their content is what you lose.
|
|
358
|
+
*/
|
|
359
|
+
skipIframeContent?: boolean;
|
|
360
|
+
/**
|
|
361
|
+
* Milliseconds a single remote asset may hold a capture up.
|
|
362
|
+
*
|
|
363
|
+
* The renderer re-fetches the page's images, fonts and `@import`s so it can
|
|
364
|
+
* inline them, and gives each one an `AbortController` set to 30 000 ms by
|
|
365
|
+
* default. A URL that never answers stalls the capture until that fires —
|
|
366
|
+
* the capture still succeeds, with that asset replaced by a transparent
|
|
367
|
+
* placeholder, but it waits first.
|
|
368
|
+
*
|
|
369
|
+
* The wait is **bounded, not multiplied**: measured at the same ~2x the
|
|
370
|
+
* timeout whether one asset is dead or ten, because they are waited on
|
|
371
|
+
* concurrently. It is 2x rather than 1x because this one number drives two
|
|
372
|
+
* waits in sequence on the same asset — first for the image already on the
|
|
373
|
+
* page to finish loading, then for the fetch that inlines it. Budget
|
|
374
|
+
* accordingly: 5000 here means roughly ten seconds.
|
|
375
|
+
*
|
|
376
|
+
* Left at the renderer's default because lowering it trades a slow capture
|
|
377
|
+
* for a silently incomplete one: an asset that was merely slow, rather than
|
|
378
|
+
* dead, is dropped and leaves a hole in the image with nothing to say so.
|
|
379
|
+
* Set it only if you have measured your own page and decided which way you
|
|
380
|
+
* want that to fail.
|
|
381
|
+
*
|
|
382
|
+
* Only a finite positive number is honoured. The two values a host would
|
|
383
|
+
* reach for to mean "no deadline" both do the opposite and are ignored: the
|
|
384
|
+
* renderer reads 0 as "never give up", and `Infinity` is coerced by
|
|
385
|
+
* `setTimeout` to 0, aborting every asset immediately.
|
|
386
|
+
*/
|
|
387
|
+
captureTimeout?: number;
|
|
264
388
|
/**
|
|
265
389
|
* Identity used as the author of new comments and replies.
|
|
266
390
|
*
|
|
@@ -293,39 +417,155 @@ export interface CommentOverlayOptions {
|
|
|
293
417
|
* `notifyNavigation()` call from the router's hook. Default: false.
|
|
294
418
|
*/
|
|
295
419
|
autoDetectNavigation?: boolean;
|
|
420
|
+
/**
|
|
421
|
+
* Called once the widget has mounted and every method on it is safe to
|
|
422
|
+
* drive. Receives the instance, because when the document is already
|
|
423
|
+
* parsed the mount happens inside the constructor — before
|
|
424
|
+
* `createCommentOverlay()` has returned anything to assign.
|
|
425
|
+
*
|
|
426
|
+
* This is the right place to `loadComments()`: a call made earlier is held
|
|
427
|
+
* and replayed here, but it can only return zeroes until then.
|
|
428
|
+
*/
|
|
429
|
+
onReady?: (overlay: CommentOverlay) => void;
|
|
430
|
+
/**
|
|
431
|
+
* Called when something the widget survived nonetheless went wrong: a
|
|
432
|
+
* screenshot that failed to render, a localStorage write that could not be
|
|
433
|
+
* made, a malformed record skipped on load, a rejected
|
|
434
|
+
* `onCommentRequested`. Each of these already warns on the console and the
|
|
435
|
+
* widget carries on regardless — this is how they reach the host's own
|
|
436
|
+
* logging instead of only a devtools panel nobody has open.
|
|
437
|
+
*/
|
|
438
|
+
onError?: (error: unknown, context: ErrorContext) => void;
|
|
439
|
+
/**
|
|
440
|
+
* Called when a "Copy link" URL points at a comment the widget does not
|
|
441
|
+
* hold — once per id, not once per attempt.
|
|
442
|
+
*
|
|
443
|
+
* This is what makes lazy loading work: fetch that one comment and hand it
|
|
444
|
+
* to `loadComments()`, and the inbox opens on it. Return a promise and the
|
|
445
|
+
* link is retried once it settles. Without a handler the inbox still opens
|
|
446
|
+
* and says the comment was not found.
|
|
447
|
+
*/
|
|
448
|
+
onCommentRequested?: (id: CommentId) => void | Promise<unknown>;
|
|
449
|
+
/**
|
|
450
|
+
* Called for every image the widget acquires — the automatic viewport
|
|
451
|
+
* capture, a drag-crop region, and anything attached through the file
|
|
452
|
+
* picker. Return the string to store in its place, typically a URL into
|
|
453
|
+
* your own object storage.
|
|
454
|
+
*
|
|
455
|
+
* Without it, a ~33KB base64 data URL travels inside every comment: into
|
|
456
|
+
* localStorage, where it is the first thing shed under quota pressure, and
|
|
457
|
+
* into whatever your backend persists.
|
|
458
|
+
*
|
|
459
|
+
* Everything on a comment is transformed as the comment is saved; an
|
|
460
|
+
* attachment on a *reply* is transformed when the file is picked, because
|
|
461
|
+
* `addReply()` is synchronous. Either way the record may never arrive —
|
|
462
|
+
* an abandoned reply draft, or a comment box dismissed while its upload is
|
|
463
|
+
* in flight — so treat a URL you hand back as an upload, not as a record,
|
|
464
|
+
* and sweep for unreferenced blobs.
|
|
465
|
+
*
|
|
466
|
+
* `kind` separates the automatic capture ("context" — disposable and
|
|
467
|
+
* regenerable) from something a person chose to include ("attachment"), so
|
|
468
|
+
* the two can go to different buckets with different retention. It does
|
|
469
|
+
* not distinguish the two moments above: both arrive as "attachment".
|
|
470
|
+
* `commentId` is the comment the image will belong to — for an attachment
|
|
471
|
+
* on a reply, the parent comment.
|
|
472
|
+
*
|
|
473
|
+
* Fail-open: a rejection, a throw, or a resolved value that is not a
|
|
474
|
+
* non-empty string leaves the original data URL in place and reports
|
|
475
|
+
* `onError(error, "transform")`. Losing the user's comment would be worse
|
|
476
|
+
* than sending you a large one.
|
|
477
|
+
*
|
|
478
|
+
* Not called for records passed to `loadComments()`, nor for screenshots
|
|
479
|
+
* you hand to `addReply()` yourself — in both cases the strings are
|
|
480
|
+
* already yours.
|
|
481
|
+
*/
|
|
482
|
+
transformScreenshot?: (
|
|
483
|
+
dataUrl: string,
|
|
484
|
+
info: { kind: "context" | "attachment"; commentId: CommentId }
|
|
485
|
+
) => Promise<string>;
|
|
486
|
+
/**
|
|
487
|
+
* Called whenever comment mode turns on or off, however it was flipped —
|
|
488
|
+
* the toolbar button, the keyboard shortcut, the inbox empty state, or the
|
|
489
|
+
* automatic switch-off after a comment is saved.
|
|
490
|
+
*
|
|
491
|
+
* The shortcut is the reason this exists: the host never sees that
|
|
492
|
+
* keystroke, so an app that needs to stand down while the user is picking
|
|
493
|
+
* an element — pause a carousel, disable its own drag-and-drop, dim a
|
|
494
|
+
* layer — has no other way to know.
|
|
495
|
+
*/
|
|
496
|
+
onCommentModeChanged?: (active: boolean) => void;
|
|
497
|
+
/**
|
|
498
|
+
* Called when somebody opens a comment's full thread, from its marker or
|
|
499
|
+
* from the inbox detail — the only two places the replies are readable.
|
|
500
|
+
*
|
|
501
|
+
* This is what an unread count is built on. HellDots keeps no read state
|
|
502
|
+
* of its own: whose "read" it is depends on an identity only the host can
|
|
503
|
+
* persist.
|
|
504
|
+
*/
|
|
505
|
+
onCommentOpened?: (comment: SerializedComment) => void;
|
|
296
506
|
/**
|
|
297
507
|
* Single subscription point: fires for every change, alongside whichever
|
|
298
508
|
* specific callback below carries the same event. Handy when a host syncs
|
|
299
509
|
* everything to one endpoint instead of wiring nine functions. A handler
|
|
300
510
|
* that throws is caught and warned about — it never rolls back the
|
|
301
511
|
* mutation that emitted it.
|
|
512
|
+
*
|
|
513
|
+
* The event carries `origin` (and, where there is one, the transition that
|
|
514
|
+
* caused it) flattened onto it — see `ChangeMeta`.
|
|
302
515
|
*/
|
|
303
516
|
onChange?: (event: ChangeEvent) => void;
|
|
304
517
|
/** Fired after a new comment is saved. */
|
|
305
|
-
onCommentCreated?: (comment: SerializedComment) => void;
|
|
518
|
+
onCommentCreated?: (comment: SerializedComment, meta: ChangeMeta) => void;
|
|
306
519
|
/** Fired after a reply is added to any comment. */
|
|
307
|
-
onReplyAdded?: (
|
|
520
|
+
onReplyAdded?: (
|
|
521
|
+
comment: SerializedComment,
|
|
522
|
+
reply: CommentReply,
|
|
523
|
+
meta: ChangeMeta
|
|
524
|
+
) => void;
|
|
308
525
|
/** Fired after deleteReply removes a reply. */
|
|
309
|
-
onReplyDeleted?: (
|
|
526
|
+
onReplyDeleted?: (
|
|
527
|
+
comment: SerializedComment,
|
|
528
|
+
reply: CommentReply,
|
|
529
|
+
meta: ChangeMeta
|
|
530
|
+
) => void;
|
|
310
531
|
/** Fired after editComment rewrites a comment's text. */
|
|
311
|
-
onCommentEdited?: (comment: SerializedComment) => void;
|
|
532
|
+
onCommentEdited?: (comment: SerializedComment, meta: ChangeMeta) => void;
|
|
312
533
|
/** Fired after editReply rewrites a reply's text. */
|
|
313
|
-
onReplyEdited?: (
|
|
314
|
-
|
|
315
|
-
|
|
534
|
+
onReplyEdited?: (
|
|
535
|
+
comment: SerializedComment,
|
|
536
|
+
reply: CommentReply,
|
|
537
|
+
meta: ChangeMeta
|
|
538
|
+
) => void;
|
|
539
|
+
/**
|
|
540
|
+
* Fired for each comment that could not be re-anchored — by loadComments,
|
|
541
|
+
* and again by every notifyNavigation that lands somewhere its element
|
|
542
|
+
* does not exist. Those repeats always carry `origin: "host"`.
|
|
543
|
+
*/
|
|
544
|
+
onAnchorLost?: (comment: SerializedComment, meta: ChangeMeta) => void;
|
|
316
545
|
/** Fired after deleteComment removes a comment. */
|
|
317
|
-
onCommentDeleted?: (id: CommentId) => void;
|
|
318
|
-
/**
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
546
|
+
onCommentDeleted?: (id: CommentId, meta: ChangeMeta) => void;
|
|
547
|
+
/**
|
|
548
|
+
* Fired after setCommentStatus changes a comment's lifecycle state.
|
|
549
|
+
* `meta.from`/`meta.to` are both ends of the move, so "reopened" and
|
|
550
|
+
* "resolved" are told apart without diffing against a previous copy.
|
|
551
|
+
*/
|
|
552
|
+
onCommentStatusChanged?: (
|
|
553
|
+
comment: SerializedComment,
|
|
554
|
+
meta: StatusChangeMeta
|
|
555
|
+
) => void;
|
|
556
|
+
/**
|
|
557
|
+
* Fired after type, priority or tags change on any comment. `meta.field`
|
|
558
|
+
* says which one moved, and narrows `meta.from`/`meta.to` with it.
|
|
559
|
+
*/
|
|
560
|
+
onCommentUpdated?: (comment: SerializedComment, meta: UpdateMeta) => void;
|
|
322
561
|
/**
|
|
323
562
|
* Fired after a reaction is added to or removed from a comment or a reply.
|
|
324
563
|
* `reply` is null when the reaction is on the root comment.
|
|
325
564
|
*/
|
|
326
565
|
onReactionToggled?: (
|
|
327
566
|
comment: SerializedComment,
|
|
328
|
-
reply: CommentReply | null
|
|
567
|
+
reply: CommentReply | null,
|
|
568
|
+
meta: ChangeMeta
|
|
329
569
|
) => void;
|
|
330
570
|
}
|
|
331
571
|
|
|
@@ -451,6 +691,12 @@ export declare class CommentOverlay {
|
|
|
451
691
|
/** The shareable URL for a comment, or null when the id is unknown. */
|
|
452
692
|
commentLink(id: CommentId): string | null;
|
|
453
693
|
serializeComments(): SerializedComment[];
|
|
694
|
+
/**
|
|
695
|
+
* Called before the widget has mounted — possible when a fetch resolves
|
|
696
|
+
* while the document is still parsing — the data is held and applied at
|
|
697
|
+
* mount, and the counts come back as zeroes because nothing has been
|
|
698
|
+
* resolved yet. Load from `onReady` when the counts matter.
|
|
699
|
+
*/
|
|
454
700
|
loadComments(data: SerializedComment[]): {
|
|
455
701
|
anchored: number;
|
|
456
702
|
orphaned: number;
|
|
@@ -481,21 +727,40 @@ export declare class CommentOverlay {
|
|
|
481
727
|
*/
|
|
482
728
|
getMetrics(): CommentMetrics;
|
|
483
729
|
/**
|
|
484
|
-
* Downloads the corpus as CSV, one row per comment
|
|
485
|
-
* automatic context capture stay out. Defaults
|
|
730
|
+
* Downloads the corpus as CSV, one row per comment, and returns the same
|
|
731
|
+
* text. Screenshots and the automatic context capture stay out. Defaults
|
|
732
|
+
* to every comment.
|
|
733
|
+
*
|
|
734
|
+
* The return value is for a host that wanted to POST those rows somewhere
|
|
735
|
+
* or attach them to a message: a browser download is a dead end, and
|
|
736
|
+
* building the CSV a second time is the only alternative.
|
|
486
737
|
*/
|
|
487
|
-
exportCommentsCsv(comments?: SerializedComment[]):
|
|
738
|
+
exportCommentsCsv(comments?: SerializedComment[]): string;
|
|
488
739
|
/**
|
|
489
740
|
* Downloads the aggregate figures as CSV in long format — `section, key,
|
|
490
|
-
* value` — so the column count does not change with the corpus.
|
|
741
|
+
* value` — so the column count does not change with the corpus. Returns
|
|
742
|
+
* the same text, for the same reason as above.
|
|
491
743
|
*/
|
|
492
|
-
exportMetricsCsv(comments?: SerializedComment[]):
|
|
744
|
+
exportMetricsCsv(comments?: SerializedComment[]): string;
|
|
493
745
|
/**
|
|
494
746
|
* Opens the browser's print dialog on a report of the figures, which is
|
|
495
747
|
* where "save as PDF" lives. The report is built in its own document, so
|
|
496
748
|
* what prints is the report rather than the host page.
|
|
497
749
|
*/
|
|
498
750
|
printMetricsReport(comments?: SerializedComment[], scope?: string): void;
|
|
751
|
+
/**
|
|
752
|
+
* Replaces the identity new comments, replies and reactions are attributed
|
|
753
|
+
* to. Everything already recorded keeps the author it was written with.
|
|
754
|
+
*
|
|
755
|
+
* For the common case where identity resolves after the widget mounts, or
|
|
756
|
+
* where the user switches account or workspace — the alternative was
|
|
757
|
+
* `cleanup()` and a rebuild, which throws away every loaded comment and
|
|
758
|
+
* whatever panel was open. `null` returns to the anonymous author.
|
|
759
|
+
*
|
|
760
|
+
* Returns false, changing nothing, for anything that is neither null nor
|
|
761
|
+
* an object with a non-blank `name`.
|
|
762
|
+
*/
|
|
763
|
+
setUser(user: { name: string; id?: string } | null): boolean;
|
|
499
764
|
setCommentStatus(id: CommentId, status: CommentStatus): boolean;
|
|
500
765
|
setCommentType(id: CommentId, type: CommentType | null): boolean;
|
|
501
766
|
setCommentPriority(id: CommentId, priority: CommentPriority | null): boolean;
|
|
@@ -530,4 +795,22 @@ export declare function createCommentOverlay(
|
|
|
530
795
|
options: CommentOverlayOptions & { autoInit: false }
|
|
531
796
|
): () => CommentOverlay;
|
|
532
797
|
|
|
798
|
+
/**
|
|
799
|
+
* Default name of the query parameter carrying a comment id in "Copy link"
|
|
800
|
+
* URLs. Exported so a host reading the id itself — before the widget is up,
|
|
801
|
+
* to fetch just that comment — does not have to hardcode a second copy of
|
|
802
|
+
* it. Override it per instance with the `linkParam` option.
|
|
803
|
+
*/
|
|
804
|
+
export declare const DEFAULT_LINK_PARAM: string;
|
|
805
|
+
|
|
806
|
+
/**
|
|
807
|
+
* The comment id the given URL asks for, or null. Pass the same `param` the
|
|
808
|
+
* widget was configured with; both default to `DEFAULT_LINK_PARAM`. A
|
|
809
|
+
* malformed URL yields null rather than throwing.
|
|
810
|
+
*/
|
|
811
|
+
export declare function readCommentLinkParam(
|
|
812
|
+
param?: string,
|
|
813
|
+
href?: string
|
|
814
|
+
): string | null;
|
|
815
|
+
|
|
533
816
|
export default createCommentOverlay;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "helldots",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.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",
|