@devaccel-labs/app-comments-toolbar 1.0.0 → 1.3.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 +152 -18
- package/dist/react.js +516 -61
- package/dist/server.js +342 -14
- package/dist/types/capture/api.d.ts +30 -0
- package/dist/types/capture/editor.d.ts +10 -0
- package/dist/types/capture/ignore.d.ts +19 -0
- package/dist/types/capture/index.d.ts +1 -0
- package/dist/types/capture/picker.d.ts +9 -0
- package/dist/types/capture/picture.d.ts +29 -0
- package/dist/types/capture/surface.d.ts +39 -0
- package/dist/types/core/index.d.ts +2 -2
- package/dist/types/core/resolve.d.ts +2 -1
- package/dist/types/core/types.d.ts +11 -0
- package/dist/types/debug-context.d.ts +7 -0
- package/dist/types/dictation.d.ts +9 -0
- package/dist/types/embed/controller.d.ts +61 -0
- package/dist/types/embed/index.d.ts +1 -0
- package/dist/types/embed/options.d.ts +35 -0
- package/dist/types/help/index.d.ts +1 -0
- package/dist/types/help/panel-index.d.ts +1 -0
- package/dist/types/help/panel-styles.d.ts +1 -0
- package/dist/types/help/panel.d.ts +4 -0
- package/dist/types/help/pill-styles.d.ts +11 -0
- package/dist/types/help/pill.d.ts +44 -0
- package/dist/types/help/react.d.ts +12 -0
- package/dist/types/help/requests.d.ts +2 -0
- package/dist/types/help/types.d.ts +119 -0
- package/dist/types/help/wire.d.ts +61 -0
- package/dist/types/native-wire.d.ts +63 -0
- package/dist/types/native.d.ts +43 -0
- package/dist/types/react.d.ts +8 -1
- package/dist/types/replay.d.ts +6 -0
- package/dist/types/runtime/api.d.ts +250 -0
- package/dist/types/runtime/attachment-model.d.ts +16 -0
- package/dist/types/runtime/attachments.d.ts +43 -7
- package/dist/types/runtime/boot.d.ts +39 -0
- package/dist/types/runtime/browser-label.d.ts +5 -0
- package/dist/types/runtime/build-id.d.ts +7 -0
- package/dist/types/runtime/capture-ui.d.ts +45 -21
- package/dist/types/runtime/clarity-model.d.ts +260 -0
- package/dist/types/runtime/clarity-ui.d.ts +62 -0
- package/dist/types/runtime/client.d.ts +6 -197
- package/dist/types/runtime/composer-size.d.ts +30 -0
- package/dist/types/runtime/dashboard.d.ts +17 -2
- package/dist/types/runtime/debug-context-core.d.ts +88 -0
- package/dist/types/runtime/debug-context-host.d.ts +39 -0
- package/dist/types/runtime/debug-context-model.d.ts +352 -0
- package/dist/types/runtime/debug-context-redact.d.ts +48 -0
- package/dist/types/runtime/debug-context.d.ts +36 -0
- package/dist/types/runtime/details-model.d.ts +7 -0
- package/dist/types/runtime/details.d.ts +7 -5
- package/dist/types/runtime/dictation-engine.d.ts +98 -0
- package/dist/types/runtime/dictation-model.d.ts +28 -0
- package/dist/types/runtime/dictation-ui.d.ts +56 -0
- package/dist/types/runtime/dictation.d.ts +66 -0
- package/dist/types/runtime/draft-dock.d.ts +32 -0
- package/dist/types/runtime/draft-model.d.ts +104 -0
- package/dist/types/runtime/draft-store.d.ts +15 -0
- package/dist/types/runtime/edits.d.ts +1 -1
- package/dist/types/runtime/font.d.ts +16 -0
- package/dist/types/runtime/format.d.ts +30 -1
- package/dist/types/runtime/host-watch.d.ts +20 -0
- package/dist/types/runtime/icons.d.ts +16 -2
- package/dist/types/runtime/index.d.ts +3 -1
- package/dist/types/runtime/ink.d.ts +8 -0
- package/dist/types/runtime/kind-model.d.ts +14 -0
- package/dist/types/runtime/live-model.d.ts +25 -0
- package/dist/types/runtime/loader.d.ts +5 -11
- package/dist/types/runtime/markup-editor.d.ts +54 -0
- package/dist/types/runtime/markup-model.d.ts +126 -0
- package/dist/types/runtime/markup.d.ts +69 -0
- package/dist/types/runtime/mention-parse.d.ts +18 -0
- package/dist/types/runtime/mentions.d.ts +4 -4
- package/dist/types/runtime/page-background.d.ts +9 -0
- package/dist/types/runtime/page-image.d.ts +123 -0
- package/dist/types/runtime/placement.d.ts +6 -3
- package/dist/types/runtime/record.d.ts +18 -2
- package/dist/types/runtime/related.d.ts +1 -1
- package/dist/types/runtime/replay-model.d.ts +80 -0
- package/dist/types/runtime/replay.d.ts +5 -38
- package/dist/types/runtime/runtime.d.ts +6 -0
- package/dist/types/runtime/screen.d.ts +47 -0
- package/dist/types/runtime/screenshot.d.ts +60 -6
- package/dist/types/runtime/session-source.d.ts +45 -0
- package/dist/types/runtime/session.d.ts +20 -18
- package/dist/types/runtime/shield.d.ts +9 -0
- package/dist/types/runtime/shot.d.ts +45 -0
- package/dist/types/runtime/sketch.d.ts +26 -0
- package/dist/types/runtime/styles.d.ts +1 -1
- package/dist/types/runtime/sync.d.ts +1 -0
- package/dist/types/runtime/thread-model.d.ts +18 -0
- package/dist/types/runtime/ticket-form-model.d.ts +57 -0
- package/dist/types/runtime/ticket-form.d.ts +9 -0
- package/dist/types/runtime/toolbar.d.ts +37 -1
- package/dist/types/runtime/ui-scale.d.ts +17 -0
- package/dist/types/runtime/update.d.ts +37 -0
- package/dist/types/runtime/use-debug-context.d.ts +27 -0
- package/dist/types/server/index.d.ts +22 -0
- package/dist/types/server/support.d.ts +20 -0
- package/dist/types/server.d.ts +2 -0
- package/dist/types/vite/plugin.d.ts +15 -0
- package/dist/vite.js +121 -41
- package/package.json +26 -13
- package/src/capture/api.ts +128 -0
- package/src/capture/editor.tsx +178 -0
- package/src/capture/ignore.ts +38 -0
- package/src/capture/index.ts +27 -0
- package/src/capture/picker.tsx +171 -0
- package/src/capture/picture.ts +90 -0
- package/src/capture/surface.tsx +185 -0
- package/src/compiler/annotate.ts +202 -0
- package/src/compiler/babel.d.ts +11 -0
- package/src/compiler/enabled.ts +55 -0
- package/src/compiler/index.ts +2 -0
- package/src/core/index.ts +8 -0
- package/src/core/resolve.ts +307 -0
- package/src/core/types.ts +58 -0
- package/src/debug-context.ts +47 -0
- package/src/dictation.ts +17 -0
- package/src/embed/controller.ts +215 -0
- package/src/embed/index.ts +68 -0
- package/src/embed/options.ts +100 -0
- package/src/help/index.ts +38 -0
- package/src/help/panel-index.ts +17 -0
- package/src/help/panel-styles.ts +123 -0
- package/src/help/panel.ts +840 -0
- package/src/help/pill-styles.ts +75 -0
- package/src/help/pill.ts +338 -0
- package/src/help/react.tsx +143 -0
- package/src/help/requests.ts +111 -0
- package/src/help/types.ts +124 -0
- package/src/help/wire.ts +55 -0
- package/src/native-wire.ts +124 -0
- package/src/native.ts +282 -0
- package/src/react.ts +27 -0
- package/src/replay.ts +13 -0
- package/src/runtime/api.ts +531 -0
- package/src/runtime/attachment-model.ts +42 -0
- package/src/runtime/attachments.tsx +1260 -0
- package/src/runtime/boot.ts +95 -0
- package/src/runtime/browser-label.ts +31 -0
- package/src/runtime/build-id.ts +10 -0
- package/src/runtime/capture-ui.tsx +306 -0
- package/src/runtime/capture.ts +508 -0
- package/src/runtime/clarity-model.ts +634 -0
- package/src/runtime/clarity-ui.tsx +454 -0
- package/src/runtime/client.ts +151 -0
- package/src/runtime/composer-size.tsx +146 -0
- package/src/runtime/dashboard.tsx +1130 -0
- package/src/runtime/debug-context-core.ts +681 -0
- package/src/runtime/debug-context-host.ts +56 -0
- package/src/runtime/debug-context-model.ts +1319 -0
- package/src/runtime/debug-context-redact.ts +259 -0
- package/src/runtime/debug-context.ts +613 -0
- package/src/runtime/details-model.ts +30 -0
- package/src/runtime/details.tsx +395 -0
- package/src/runtime/dictation-engine.ts +616 -0
- package/src/runtime/dictation-model.ts +79 -0
- package/src/runtime/dictation-ui.tsx +363 -0
- package/src/runtime/dictation.ts +271 -0
- package/src/runtime/dock.ts +108 -0
- package/src/runtime/draft-dock.tsx +124 -0
- package/src/runtime/draft-model.ts +251 -0
- package/src/runtime/draft-store.ts +149 -0
- package/src/runtime/edits.tsx +165 -0
- package/src/runtime/font.ts +42 -0
- package/src/runtime/format.ts +129 -0
- package/src/runtime/freshness.ts +23 -0
- package/src/runtime/handoff.ts +76 -0
- package/src/runtime/host-watch.ts +64 -0
- package/src/runtime/icons.tsx +295 -0
- package/src/runtime/idle.ts +20 -0
- package/src/runtime/index.ts +11 -0
- package/src/runtime/ink.ts +6 -0
- package/src/runtime/kind-model.ts +20 -0
- package/src/runtime/live-model.ts +32 -0
- package/src/runtime/loader.tsx +87 -0
- package/src/runtime/markup-editor.tsx +1333 -0
- package/src/runtime/markup-model.ts +485 -0
- package/src/runtime/markup.ts +382 -0
- package/src/runtime/members.ts +58 -0
- package/src/runtime/mention-parse.ts +56 -0
- package/src/runtime/mentions.tsx +205 -0
- package/src/runtime/page-background.ts +51 -0
- package/src/runtime/page-image.ts +1592 -0
- package/src/runtime/placement.ts +336 -0
- package/src/runtime/record.ts +402 -0
- package/src/runtime/redact.ts +30 -0
- package/src/runtime/related.ts +34 -0
- package/src/runtime/render-page.ts +2 -0
- package/src/runtime/replay-model.ts +232 -0
- package/src/runtime/replay.ts +173 -0
- package/src/runtime/runtime-version.ts +7 -0
- package/src/runtime/runtime.tsx +51 -0
- package/src/runtime/screen.ts +182 -0
- package/src/runtime/screenshot.ts +260 -0
- package/src/runtime/session-source.ts +112 -0
- package/src/runtime/session.ts +108 -0
- package/src/runtime/shield.ts +34 -0
- package/src/runtime/shot.tsx +422 -0
- package/src/runtime/sketch.ts +139 -0
- package/src/runtime/styles.ts +1541 -0
- package/src/runtime/sync.ts +300 -0
- package/src/runtime/thread-model.ts +71 -0
- package/src/runtime/ticket-form-model.ts +128 -0
- package/src/runtime/ticket-form.tsx +342 -0
- package/src/runtime/toolbar.tsx +4427 -0
- package/src/runtime/ui-scale.ts +75 -0
- package/src/runtime/update.ts +98 -0
- package/src/runtime/use-debug-context.ts +81 -0
- package/src/server/index.ts +133 -0
- package/src/server/support.ts +499 -0
- package/src/server.ts +4 -0
- package/src/vite/plugin.ts +102 -0
- package/src/vite.ts +1 -0
- package/dist/chunks/chunk-CSKXLF33.js +0 -153
- package/dist/chunks/chunk-HUM5FQII.js +0 -160
- package/dist/chunks/render-page-76MLIT6M.js +0 -1421
- package/dist/chunks/runtime-JX75TKER.js +0 -9267
- package/dist/chunks/screenshot-66ARTBGR.js +0 -12
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { type Piece } from "./dictation.js";
|
|
2
|
+
export { voiceRecordingName } from "./dictation-model.js";
|
|
3
|
+
/** A take stops itself after this long. */
|
|
4
|
+
export declare const MAX_TAKE_MS: number;
|
|
5
|
+
export type DictationPhase = "idle" | "starting" | "listening";
|
|
6
|
+
export type DictationState = {
|
|
7
|
+
phase: DictationPhase;
|
|
8
|
+
/** Pieces cut and not yet written, including the one being transcribed. */
|
|
9
|
+
queued: number;
|
|
10
|
+
/** The first piece that couldn't be transcribed; everything after it waits. */
|
|
11
|
+
stalled: string | null;
|
|
12
|
+
/**
|
|
13
|
+
* Rough words for what was said and isn't written yet (needs `DictationDeps.preview`). Each piece's
|
|
14
|
+
* part is replaced by its final text when that is written.
|
|
15
|
+
*/
|
|
16
|
+
preview: string;
|
|
17
|
+
};
|
|
18
|
+
export declare const idleDictation: DictationState;
|
|
19
|
+
export type DictationDeps = {
|
|
20
|
+
transcribe(wav: Blob, prompt: string, signal: AbortSignal): Promise<string>;
|
|
21
|
+
/** The context sent with the next piece; read when it is sent, so it includes earlier pieces. */
|
|
22
|
+
prompt(): string;
|
|
23
|
+
write(text: string): void;
|
|
24
|
+
onState(state: DictationState): void;
|
|
25
|
+
/** Why a take stopped or never started, for the person to read. */
|
|
26
|
+
note(text: string): void;
|
|
27
|
+
/** Optional: a quick read of the piece still being spoken, shown as it grows. Failures are ignored. */
|
|
28
|
+
preview?(wav: Blob, prompt: string, signal: AbortSignal): Promise<string>;
|
|
29
|
+
/**
|
|
30
|
+
* Optional: the take as a voice recording, once it ends. Only composers that can attach files give this;
|
|
31
|
+
* the mic is then recorded alongside the transcription. Not called for a cancelled take.
|
|
32
|
+
*/
|
|
33
|
+
audio?(file: File): void;
|
|
34
|
+
/** Whether to hand over the recording, read when the take ends so it can change mid-take. Default: yes. */
|
|
35
|
+
keepAudio?(): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Optional: a piece's final words with when they were spoken (`Date.now()` at the start of the piece, so a
|
|
38
|
+
* clip recording meanwhile can place them on its clock). Called right after `write`.
|
|
39
|
+
*/
|
|
40
|
+
said?(text: string, spokenAt: number): void;
|
|
41
|
+
};
|
|
42
|
+
/** Whether this browser can keep a dictation take as a voice recording. */
|
|
43
|
+
export declare function voiceRecordingSupported(): boolean;
|
|
44
|
+
export declare function dictationSupported(): boolean;
|
|
45
|
+
export declare class Dictation {
|
|
46
|
+
private state;
|
|
47
|
+
private capture;
|
|
48
|
+
private segmenter;
|
|
49
|
+
private queue;
|
|
50
|
+
private sending;
|
|
51
|
+
private stalled;
|
|
52
|
+
private abort;
|
|
53
|
+
/** Bumped by `cancel` and by every start, so an awaited step from an older take does nothing. */
|
|
54
|
+
private take;
|
|
55
|
+
private previewTimer;
|
|
56
|
+
private previewing;
|
|
57
|
+
/** Bumped when a piece is cut, so a preview of the old piece that lands late is dropped. */
|
|
58
|
+
private previewPiece;
|
|
59
|
+
private previewedSamples;
|
|
60
|
+
private live;
|
|
61
|
+
private readonly onOnline;
|
|
62
|
+
/** Nothing is wired until `connect`: a take started before then writes nowhere. */
|
|
63
|
+
private deps;
|
|
64
|
+
constructor(deps?: DictationDeps);
|
|
65
|
+
/** Points the take at the latest callbacks; the React hook calls this after every render. */
|
|
66
|
+
connect(deps: DictationDeps): void;
|
|
67
|
+
get current(): DictationState;
|
|
68
|
+
/** Live loudness (0–1), elapsed time and whether the mic seems dead, read by the meter every frame. */
|
|
69
|
+
meter(): {
|
|
70
|
+
level: number;
|
|
71
|
+
elapsedMs: number;
|
|
72
|
+
silentMic: boolean;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Must be called from the click or key press, so the browser lets the audio start. `recordVoice: false`
|
|
76
|
+
* skips the voice recording for this take (dictating over a screen recording, which has its own sound).
|
|
77
|
+
*/
|
|
78
|
+
start({ recordVoice }?: {
|
|
79
|
+
recordVoice?: boolean;
|
|
80
|
+
}): Promise<void>;
|
|
81
|
+
/** Stops the mic. What was said is still sent and written, and the recording handed over. */
|
|
82
|
+
stop(note?: string | null): void;
|
|
83
|
+
private endTake;
|
|
84
|
+
/** Stops everything and drops what wasn't written yet: the box it was writing into is gone. */
|
|
85
|
+
cancel(): void;
|
|
86
|
+
/** Tries the held piece again. */
|
|
87
|
+
retry(): void;
|
|
88
|
+
/** Drops the held piece and carries on with the rest. */
|
|
89
|
+
skip(): void;
|
|
90
|
+
/** Queues a cut piece for transcription. The mic tap calls this; so can a test, without a mic. */
|
|
91
|
+
enqueue(piece: Piece): void;
|
|
92
|
+
private drain;
|
|
93
|
+
private send;
|
|
94
|
+
private previewText;
|
|
95
|
+
/** Re-reads the piece still being spoken. Best-effort: a failed or late preview is dropped. */
|
|
96
|
+
private refreshPreview;
|
|
97
|
+
private set;
|
|
98
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dictation's DOM-free parts that native dictation (m4a takes) shares with the web toolbar: the input meter,
|
|
3
|
+
* placing dictated words into the writing box, the context that helps the transcriber, and voice note names.
|
|
4
|
+
* Re-exported from `./dictation.ts` and `./dictation-engine.ts`.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Where the dictation point moved to after someone edited the text it lives in. An edit wholly before it
|
|
8
|
+
* shifts it; an edit after it leaves it; an edit across it puts it at the end of the edit.
|
|
9
|
+
*/
|
|
10
|
+
export declare function rebaseAnchor(previous: string, next: string, anchor: number): number;
|
|
11
|
+
/**
|
|
12
|
+
* `text` written into `value` at `at`, spaced like typing: a space before it unless it starts a line, a
|
|
13
|
+
* space after it unless punctuation follows, and a capital when it starts a sentence.
|
|
14
|
+
*/
|
|
15
|
+
export declare function insertDictated(value: string, at: number, text: string): {
|
|
16
|
+
value: string;
|
|
17
|
+
caret: number;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Context for Whisper: the people who might be named, then the writing just before the dictation point.
|
|
21
|
+
* Both help it spell names and keep punctuation consistent across pieces.
|
|
22
|
+
*/
|
|
23
|
+
export declare function dictationPrompt(before: string, names: readonly string[]): string;
|
|
24
|
+
export declare function decibels(samples: Float32Array): number;
|
|
25
|
+
/** 0–1 for a meter: −60 dBFS and below is empty, −12 is full. */
|
|
26
|
+
export declare function meterLevel(db: number): number;
|
|
27
|
+
/** `voice-2026-10-31-13-56-37.webm`, after the screen recordings' `recording-…` names. */
|
|
28
|
+
export declare function voiceRecordingName(at: Date, type: string): string;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type KeyboardEvent as ReactKeyboardEvent } from "react";
|
|
2
|
+
import { Dictation, type DictationDeps, type DictationState } from "./dictation-engine.js";
|
|
3
|
+
type Options = {
|
|
4
|
+
transcribe: DictationDeps["transcribe"];
|
|
5
|
+
/** The writing box's text, and how to change it. Dictated words go through the same path as typing. */
|
|
6
|
+
value: string;
|
|
7
|
+
onChange: (next: string) => void;
|
|
8
|
+
/** People who may be named: Whisper spells them right when it knows them. */
|
|
9
|
+
names: readonly string[];
|
|
10
|
+
onNote: (note: string) => void;
|
|
11
|
+
/** The take as a voice file, attached to the box's message. Without it nothing is recorded. */
|
|
12
|
+
onAudio?: (file: File) => void;
|
|
13
|
+
/** "Keep voice": whether the recording is attached when the take ends. */
|
|
14
|
+
keepVoice?: boolean;
|
|
15
|
+
onKeepVoice?: (keep: boolean) => void;
|
|
16
|
+
/** Each piece's final words with when they were spoken, for a clip recording meanwhile. */
|
|
17
|
+
onSaid?: (text: string, spokenAt: number) => void;
|
|
18
|
+
};
|
|
19
|
+
export type DictationControl = ReturnType<typeof useDictation>;
|
|
20
|
+
/**
|
|
21
|
+
* Dictation into one writing box. Words land where the caret was when dictation started and keep landing
|
|
22
|
+
* after each other there, even while the person types elsewhere in the box (the point moves with their
|
|
23
|
+
* edits). The take is cancelled when the box's owner unmounts.
|
|
24
|
+
*/
|
|
25
|
+
export declare function useDictation(options: Options): {
|
|
26
|
+
engine: Dictation;
|
|
27
|
+
state: DictationState;
|
|
28
|
+
start: (box: HTMLTextAreaElement | null, recordVoice?: boolean) => void;
|
|
29
|
+
toggle: (box: HTMLTextAreaElement | null, recordVoice?: boolean) => void;
|
|
30
|
+
stop: () => void;
|
|
31
|
+
cancel: () => void;
|
|
32
|
+
/** The mic is open or being opened. */
|
|
33
|
+
listening: boolean;
|
|
34
|
+
/** Anything still to write: posting now would lose words. */
|
|
35
|
+
busy: boolean;
|
|
36
|
+
/** The pill replaces the attach buttons. */
|
|
37
|
+
shown: boolean;
|
|
38
|
+
/** The take is recorded too; the pill offers "Keep voice". */
|
|
39
|
+
recordsVoice: boolean;
|
|
40
|
+
keepVoice: boolean;
|
|
41
|
+
setKeepVoice: (keep: boolean) => void | undefined;
|
|
42
|
+
};
|
|
43
|
+
/** ⌘⇧Space / Ctrl+Shift+Space in a writing box starts or stops dictation. */
|
|
44
|
+
export declare function isDictationKey(event: ReactKeyboardEvent<HTMLTextAreaElement>): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* The mic button, and while dictating the pill that replaces it: stop, live level, time, and what is
|
|
47
|
+
* happening (listening, writing, or a piece that needs a retry). `field` is the `data-cs-ui` of the box
|
|
48
|
+
* in the same form that the words go into.
|
|
49
|
+
*/
|
|
50
|
+
export declare function DictateButton({ dictation, field, disabled, compact, }: {
|
|
51
|
+
dictation: DictationControl;
|
|
52
|
+
field: string;
|
|
53
|
+
disabled: boolean;
|
|
54
|
+
compact?: boolean;
|
|
55
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
56
|
+
export {};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dictation's pure parts (ADR-APPC-010): resample the microphone to 16 kHz, cut the take into pieces at
|
|
3
|
+
* pauses, write each piece as WAV, and place the words that come back into the writing box. No browser
|
|
4
|
+
* audio APIs here, so all of it runs under unit tests. `dictation-engine.ts` drives it from a live mic.
|
|
5
|
+
*/
|
|
6
|
+
export declare const SAMPLE_RATE = 16000;
|
|
7
|
+
/** Whisper reads 30 s windows; a piece is cut before that even when nobody pauses. */
|
|
8
|
+
export declare const MAX_PIECE_SECONDS = 28;
|
|
9
|
+
export type Piece = {
|
|
10
|
+
samples: Float32Array;
|
|
11
|
+
seconds: number;
|
|
12
|
+
speechSeconds: number;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Streaming sample-rate conversion. Downsampling averages every input sample an output sample covers (a
|
|
16
|
+
* box filter, enough low-pass for speech); upsampling interpolates. State carries across chunks, so the
|
|
17
|
+
* output is the same however the input is split.
|
|
18
|
+
*/
|
|
19
|
+
export declare class Resampler {
|
|
20
|
+
readonly from: number;
|
|
21
|
+
readonly to: number;
|
|
22
|
+
private readonly step;
|
|
23
|
+
private rest;
|
|
24
|
+
private offset;
|
|
25
|
+
constructor(from: number, to?: number);
|
|
26
|
+
push(input: Float32Array): Float32Array;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Cuts 16 kHz audio into pieces at pauses. Speech is a frame louder than the room: a noise floor that falls
|
|
30
|
+
* fast and rises slowly, plus a margin, never quieter than −55 dBFS. A piece ends after `END_PAUSE` of quiet,
|
|
31
|
+
* or is cut at `MAX_PIECE_SECONDS`; pieces with almost no speech are dropped, so silence never reaches
|
|
32
|
+
* Whisper (which turns silence into "Thank you.").
|
|
33
|
+
*/
|
|
34
|
+
export declare class Segmenter {
|
|
35
|
+
/** Loudness of the newest frame. */
|
|
36
|
+
lastDb: number;
|
|
37
|
+
/** Loudest frame so far: −100 means the mic delivered digital silence. */
|
|
38
|
+
peakDb: number;
|
|
39
|
+
private floor;
|
|
40
|
+
private partial;
|
|
41
|
+
private filled;
|
|
42
|
+
private preroll;
|
|
43
|
+
private active;
|
|
44
|
+
push(samples: Float32Array): Piece[];
|
|
45
|
+
/** The audio of the piece still being spoken (not yet cut), for a live preview; null between pieces. */
|
|
46
|
+
pending(): Float32Array | null;
|
|
47
|
+
/** The piece in progress, when the take ends. */
|
|
48
|
+
flush(): Piece | null;
|
|
49
|
+
private frame;
|
|
50
|
+
private piece;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 16-bit mono PCM WAV. Quiet takes are raised (up to 8x, to a 0.9 peak) so a far-away mic still reads
|
|
54
|
+
* clearly; loud ones are left alone.
|
|
55
|
+
*/
|
|
56
|
+
export declare function encodeWav(samples: Float32Array, rate?: number): ArrayBuffer;
|
|
57
|
+
export { decibels, dictationPrompt, insertDictated, meterLevel, rebaseAnchor, voiceRecordingName, } from "./dictation-model.js";
|
|
58
|
+
/**
|
|
59
|
+
* What to tell someone when the browser won't give us the microphone. A refusal can come from the site
|
|
60
|
+
* setting, from the operating system, or from a browser that never shows a prompt at all (an app's built-in
|
|
61
|
+
* browser, or Chrome after the prompt was dismissed a few times); `permission` (from the Permissions API, when
|
|
62
|
+
* the browser has it) and the error's text tell those apart, because each needs a different fix.
|
|
63
|
+
*/
|
|
64
|
+
export declare function microphoneError(error: unknown, permission?: PermissionState | null, userAgent?: string,
|
|
65
|
+
/** The page's Permissions-Policy verdict for `microphone`, when the browser exposes it. */
|
|
66
|
+
pageAllows?: boolean | null): "Couldn’t start the microphone." | "Microphone access is blocked for this site. Click the icon left of the address, set Microphone to Allow, then reload." | "No microphone found. Plug one in and try again." | "The microphone is in use by another app, or your system blocked it." | "This app’s built-in browser doesn’t allow the microphone. Open the page in Chrome, Safari or Edge to dictate." | "This browser didn’t let the page ask for the microphone. Allow it for this site from the address bar, or open the page in Chrome, Safari or Edge if you’re in an app’s built-in browser." | "This page’s Permissions-Policy turns the microphone off, so the browser can’t ask for it." | "Your computer blocks this browser from the microphone. Allow it in System Settings → Privacy & Security → Microphone, then try again.";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type DraftDockMode = "collecting" | "resume";
|
|
2
|
+
/**
|
|
3
|
+
* Which dock stands in for the bar, if any. An open page draft shows only while it is minimised to collect
|
|
4
|
+
* captures; with no page draft open, a draft found in storage offers to resume.
|
|
5
|
+
*/
|
|
6
|
+
export declare function draftDockMode(state: {
|
|
7
|
+
readonly signedIn: boolean;
|
|
8
|
+
readonly pageDraft: boolean;
|
|
9
|
+
readonly collecting: boolean;
|
|
10
|
+
readonly stored: boolean;
|
|
11
|
+
}): DraftDockMode | null;
|
|
12
|
+
/**
|
|
13
|
+
* The draft, minimised over the live app: a chip in the bar's place (the bar hides) that says what it holds and
|
|
14
|
+
* takes more captures.
|
|
15
|
+
* In `resume` mode it offers a draft found in storage after a reload (or from another visit) instead.
|
|
16
|
+
*/
|
|
17
|
+
export declare function DraftDock({ title, pictures, clips, savedAt, mode, note, recording, confirmDiscard, onCapture, onRecord, onOpen, onDiscard, }: {
|
|
18
|
+
title: string;
|
|
19
|
+
pictures: number;
|
|
20
|
+
clips: number;
|
|
21
|
+
savedAt: number | null;
|
|
22
|
+
mode: DraftDockMode;
|
|
23
|
+
/** Something the person should know about this draft (a recording cut short by a reload). */
|
|
24
|
+
note?: string | undefined;
|
|
25
|
+
recording: boolean;
|
|
26
|
+
/** The first Discard press asks; this is true until the second one, or until it times out. */
|
|
27
|
+
confirmDiscard: boolean;
|
|
28
|
+
onCapture: () => void;
|
|
29
|
+
onRecord: () => void;
|
|
30
|
+
onOpen: () => void;
|
|
31
|
+
onDiscard: () => void;
|
|
32
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The draft model and store, without a storage engine: the web toolbar keeps drafts in IndexedDB
|
|
3
|
+
* (`./draft-store.ts`), native clients in files. DOM-free.
|
|
4
|
+
*/
|
|
5
|
+
import type { Anchor } from "../core/index.js";
|
|
6
|
+
import type { Capture, Details } from "./api.js";
|
|
7
|
+
import { type ClarityHold } from "./clarity-model.js";
|
|
8
|
+
import { type ReportKind } from "./kind-model.js";
|
|
9
|
+
import type { MarkupShape } from "./markup-model.js";
|
|
10
|
+
import type { ReplayEvent } from "./replay-model.js";
|
|
11
|
+
import type { TicketValues } from "./ticket-form-model.js";
|
|
12
|
+
/**
|
|
13
|
+
* A draft that follows the person around the app until it is sent: everything in it is written here as it
|
|
14
|
+
* changes, so a reload, a crash, a closed laptop or another tab can offer to pick it up. Pictures and clips are
|
|
15
|
+
* kept as blobs; the browser's own storage (IndexedDB) holds them, and nothing leaves the device from here.
|
|
16
|
+
*/
|
|
17
|
+
export type StoredCapture = {
|
|
18
|
+
key: string;
|
|
19
|
+
name: string;
|
|
20
|
+
type: string;
|
|
21
|
+
blob: Blob;
|
|
22
|
+
capture?: Capture | undefined;
|
|
23
|
+
/** The unmarked original and the shapes flattened into `blob`, when the picture was marked up. */
|
|
24
|
+
markup?: {
|
|
25
|
+
blob: Blob;
|
|
26
|
+
name: string;
|
|
27
|
+
shapes: MarkupShape[];
|
|
28
|
+
} | undefined;
|
|
29
|
+
/** Shapes drawn since the last flatten (or ever), so a reload loses no stroke. */
|
|
30
|
+
shapes: MarkupShape[];
|
|
31
|
+
};
|
|
32
|
+
export type StoredDraft = {
|
|
33
|
+
v: 1;
|
|
34
|
+
id: string;
|
|
35
|
+
createdAt: number;
|
|
36
|
+
updatedAt: number;
|
|
37
|
+
/** The page the draft was started on; the comment is filed against it. */
|
|
38
|
+
href: string;
|
|
39
|
+
route: string;
|
|
40
|
+
anchor: Anchor;
|
|
41
|
+
body: string;
|
|
42
|
+
details: Details;
|
|
43
|
+
/** The kind the person chose, when they did. */
|
|
44
|
+
kind?: ReportKind;
|
|
45
|
+
ticket: TicketValues;
|
|
46
|
+
captures: StoredCapture[];
|
|
47
|
+
/** The capture open on the stage. */
|
|
48
|
+
selected: string | null;
|
|
49
|
+
/** Something the person should know when they pick the draft up (a recording cut short by a reload). */
|
|
50
|
+
note?: string;
|
|
51
|
+
/** The clarity check's open questions and the answers typed so far, when Send was held for them. */
|
|
52
|
+
clarity?: ClarityHold;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* A recording while it runs: every chunk so far and what happened on the page, written as they land, so a
|
|
56
|
+
* reload or a crash mid-take keeps the part that was filmed.
|
|
57
|
+
*/
|
|
58
|
+
export type StoredRecording = {
|
|
59
|
+
v: 1;
|
|
60
|
+
draftId: string;
|
|
61
|
+
mime: string;
|
|
62
|
+
startedAt: number;
|
|
63
|
+
url: string;
|
|
64
|
+
chunks: Blob[];
|
|
65
|
+
events: ReplayEvent[];
|
|
66
|
+
};
|
|
67
|
+
/** Where drafts are kept: the browser's IndexedDB on the web, files on native, a map in tests. */
|
|
68
|
+
export type DraftBackend = {
|
|
69
|
+
get(key: string): Promise<unknown>;
|
|
70
|
+
put(key: string, value: unknown): Promise<void>;
|
|
71
|
+
remove(key: string): Promise<void>;
|
|
72
|
+
};
|
|
73
|
+
/** Matches the composer's file cap so a recovered clip is not the row a resume drops. */
|
|
74
|
+
export declare const MAX_DRAFT_CAPTURES = 5;
|
|
75
|
+
export declare const MAX_DRAFT_BYTES: number;
|
|
76
|
+
export declare function memoryBackend(): DraftBackend;
|
|
77
|
+
export declare function readStoredDraft(value: unknown): StoredDraft | null;
|
|
78
|
+
/** What the dock and the resume offer say about a draft. */
|
|
79
|
+
export declare function describeDraft(draft: {
|
|
80
|
+
body: string;
|
|
81
|
+
captures: Array<{
|
|
82
|
+
type: string;
|
|
83
|
+
}>;
|
|
84
|
+
}): {
|
|
85
|
+
pictures: number;
|
|
86
|
+
clips: number;
|
|
87
|
+
title: string;
|
|
88
|
+
};
|
|
89
|
+
export type DraftStore = {
|
|
90
|
+
/** False when the browser has no IndexedDB, so a reload will not see this write. */
|
|
91
|
+
readonly durable: boolean;
|
|
92
|
+
load(): Promise<StoredDraft | null>;
|
|
93
|
+
save(draft: StoredDraft): Promise<void>;
|
|
94
|
+
clear(): Promise<void>;
|
|
95
|
+
loadRecording(): Promise<StoredRecording | null>;
|
|
96
|
+
saveRecording(recording: StoredRecording): Promise<void>;
|
|
97
|
+
clearRecording(): Promise<void>;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* One draft per `scope` (API, environment, project, and member). Saves are serialised so a fast burst can't
|
|
101
|
+
* land out of order. A draft or recording over the byte cap throws; other save failures reject too, and the
|
|
102
|
+
* toolbar tries again on the next change.
|
|
103
|
+
*/
|
|
104
|
+
export declare function createDraftStore(scope: string, backend: DraftBackend | null): DraftStore;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type DraftBackend, type DraftStore, type StoredDraft, type StoredRecording } from "./draft-model.js";
|
|
2
|
+
export { MAX_DRAFT_BYTES, MAX_DRAFT_CAPTURES, describeDraft, memoryBackend, readStoredDraft, } from "./draft-model.js";
|
|
3
|
+
export type { DraftBackend, DraftStore, StoredCapture, StoredDraft, StoredRecording, } from "./draft-model.js";
|
|
4
|
+
/** IndexedDB, or null where the browser has none (or refuses it, as in some private windows). */
|
|
5
|
+
export declare function idbBackend(factory?: IDBFactory | undefined): DraftBackend | null;
|
|
6
|
+
/**
|
|
7
|
+
* `draft` with a recording that was cut off (by a reload, a crash) put in as a clip, with its replay beside it,
|
|
8
|
+
* and a note saying so. Nothing changes when the recording belongs to another draft.
|
|
9
|
+
*/
|
|
10
|
+
export declare function recoverRecording(draft: StoredDraft, recording: StoredRecording): StoredDraft;
|
|
11
|
+
/**
|
|
12
|
+
* One draft per `scope` (API, environment, project, and member), in this browser's IndexedDB, or in memory
|
|
13
|
+
* where there is none.
|
|
14
|
+
*/
|
|
15
|
+
export declare function createDraftStore(scope: string, backend?: DraftBackend | null): DraftStore;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CommentMessage, Member } from "./client.js";
|
|
2
|
-
export
|
|
2
|
+
export { isMine } from "./thread-model.js";
|
|
3
3
|
export declare function MessageTools({ message, mine, historyOpen, onHistory, onEdit, }: {
|
|
4
4
|
message: CommentMessage;
|
|
5
5
|
mine: boolean;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The toolbar's typeface. It draws inside other people's pages, on every system, so it brings its own font
|
|
3
|
+
* instead of taking whichever one the system has: Inter's Latin cut, served beside the runtime
|
|
4
|
+
* (`scripts/build-toolbar.mjs` copies it there). Until it has loaded, the system's interface font stands in
|
|
5
|
+
* (`styles.ts`).
|
|
6
|
+
*
|
|
7
|
+
* The bytes are fetched like every other request to the service and handed to the page's fonts, rather than
|
|
8
|
+
* named in an `@font-face` rule: a page's Content-Security-Policy already lets the toolbar reach the service
|
|
9
|
+
* (`connect-src`), and a font built from bytes needs no `font-src` for it (`docs/integration`'s policy has none).
|
|
10
|
+
*/
|
|
11
|
+
export declare const FONT_FILE = "fonts/inter-latin-wght-normal.woff2";
|
|
12
|
+
export declare const FONT_FAMILY = "Comment Toolbar Inter";
|
|
13
|
+
/** Where the service at `apiUrl` serves the font; null when that is not an address. */
|
|
14
|
+
export declare function fontUrl(apiUrl: string): string | null;
|
|
15
|
+
/** Adds the toolbar's font to the page once; a build that replaced this one finds it already there. */
|
|
16
|
+
export declare function loadFont(apiUrl: string): void;
|
|
@@ -1,11 +1,40 @@
|
|
|
1
1
|
import type { Anchor } from "../core/index.js";
|
|
2
|
-
import type { Delivery } from "./
|
|
2
|
+
import type { Delivery } from "./api.js";
|
|
3
3
|
export declare function initials(name: string): string;
|
|
4
4
|
export declare function colorFor(name: string): string;
|
|
5
5
|
export declare function ago(iso: string): string;
|
|
6
6
|
export declare function targetName(anchor: Anchor): string;
|
|
7
7
|
/** "pending": on this page, but not looked up yet. */
|
|
8
8
|
export type PlacedStatus = "pinned" | "drifted" | "hidden" | "ambiguous" | "unavailable" | "resolved" | "pending";
|
|
9
|
+
/** Where the open pin card sits. A resolved thread leaves the screen. An open pin uses its
|
|
10
|
+
* current spot, and one that only lost its box for a moment keeps the last spot. */
|
|
11
|
+
export declare function openPinCardSpot(thread: {
|
|
12
|
+
id: string;
|
|
13
|
+
status: "open" | "resolved";
|
|
14
|
+
} | undefined, live: {
|
|
15
|
+
id: string;
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
} | null, held: {
|
|
19
|
+
id: string;
|
|
20
|
+
x: number;
|
|
21
|
+
y: number;
|
|
22
|
+
} | null): {
|
|
23
|
+
id: string;
|
|
24
|
+
x: number;
|
|
25
|
+
y: number;
|
|
26
|
+
} | null;
|
|
27
|
+
/**
|
|
28
|
+
* Keep a status the actor just set when a colder thread list still has the previous one.
|
|
29
|
+
* A list that already shows the painted status drops that pending entry.
|
|
30
|
+
*/
|
|
31
|
+
export declare function paintThreadStatuses<T extends {
|
|
32
|
+
id: string;
|
|
33
|
+
status: "open" | "resolved";
|
|
34
|
+
}>(threads: readonly T[], pending: ReadonlyMap<string, "open" | "resolved">): {
|
|
35
|
+
threads: T[];
|
|
36
|
+
pending: Map<string, "open" | "resolved">;
|
|
37
|
+
};
|
|
9
38
|
/** Plain-language reason a thread isn't pinned, or null when there's nothing to explain. */
|
|
10
39
|
export declare function statusNote(status: PlacedStatus, anchor: Anchor): {
|
|
11
40
|
text: string;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* When to ask the host app's session route again, so the toolbar follows a sign-in or a sign-out that did not
|
|
3
|
+
* load a page. The route is only asked when something a person does could have changed who is signed in: the
|
|
4
|
+
* page comes back into view or gets the focus, the app navigates (its router, the back button, a hash route),
|
|
5
|
+
* or the browser restores the page from its back-forward cache. Never on a timer, and never more often than
|
|
6
|
+
* once per `HOST_CHECK_GAP_MS`: a moment inside the gap is answered at its end.
|
|
7
|
+
*/
|
|
8
|
+
/** The shortest time between two questions to the host's session route. */
|
|
9
|
+
export declare const HOST_CHECK_GAP_MS = 10000;
|
|
10
|
+
/** Dispatched on `window` after the app calls `history.pushState` or `history.replaceState`. */
|
|
11
|
+
export declare const NAVIGATED = "cs-nav";
|
|
12
|
+
/** Makes the app's own `pushState` and `replaceState` dispatch `NAVIGATED`. Once per page, whoever asks. */
|
|
13
|
+
export declare function announceNavigation(): void;
|
|
14
|
+
export type HostWatch = {
|
|
15
|
+
/** Asks now, whatever the gap: the host said its sign-in changed. */
|
|
16
|
+
now(): void;
|
|
17
|
+
stop(): void;
|
|
18
|
+
};
|
|
19
|
+
/** Calls `check` at the moments above. The first one is a gap after this call: the caller has just asked. */
|
|
20
|
+
export declare function watchHost(check: () => void, gap?: number): HostWatch;
|
|
@@ -11,11 +11,17 @@ export declare const Check: () => import("react/jsx-runtime").JSX.Element;
|
|
|
11
11
|
export declare const Target: () => import("react/jsx-runtime").JSX.Element;
|
|
12
12
|
export declare const Relink: () => import("react/jsx-runtime").JSX.Element;
|
|
13
13
|
export declare const Undo: () => import("react/jsx-runtime").JSX.Element;
|
|
14
|
-
export declare const Pencil: (
|
|
14
|
+
export declare const Pencil: ({ size }: {
|
|
15
|
+
size?: number;
|
|
16
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export declare const Scribble: () => import("react/jsx-runtime").JSX.Element;
|
|
15
18
|
export declare const Cursor: () => import("react/jsx-runtime").JSX.Element;
|
|
16
19
|
export declare const Paperclip: () => import("react/jsx-runtime").JSX.Element;
|
|
17
20
|
export declare const Record: () => import("react/jsx-runtime").JSX.Element;
|
|
18
|
-
export declare const
|
|
21
|
+
export declare const Mic: () => import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
export declare const Camera: ({ size }: {
|
|
23
|
+
size?: number;
|
|
24
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
19
25
|
export declare const FileIcon: () => import("react/jsx-runtime").JSX.Element;
|
|
20
26
|
export declare const Back: () => import("react/jsx-runtime").JSX.Element;
|
|
21
27
|
export declare const Ellipsis: () => import("react/jsx-runtime").JSX.Element;
|
|
@@ -38,3 +44,11 @@ export declare const Search: () => import("react/jsx-runtime").JSX.Element;
|
|
|
38
44
|
export declare const ZoomOut: () => import("react/jsx-runtime").JSX.Element;
|
|
39
45
|
export declare const ZoomIn: () => import("react/jsx-runtime").JSX.Element;
|
|
40
46
|
export declare const Reply: () => import("react/jsx-runtime").JSX.Element;
|
|
47
|
+
export declare const Markup: () => import("react/jsx-runtime").JSX.Element;
|
|
48
|
+
export declare const Highlighter: () => import("react/jsx-runtime").JSX.Element;
|
|
49
|
+
export declare const ArrowTool: () => import("react/jsx-runtime").JSX.Element;
|
|
50
|
+
export declare const Square: () => import("react/jsx-runtime").JSX.Element;
|
|
51
|
+
export declare const Circle: () => import("react/jsx-runtime").JSX.Element;
|
|
52
|
+
export declare const TextTool: () => import("react/jsx-runtime").JSX.Element;
|
|
53
|
+
export declare const Redo: () => import("react/jsx-runtime").JSX.Element;
|
|
54
|
+
export declare const Trash: () => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
export { CommentToolbar
|
|
1
|
+
export { CommentToolbar } from "./loader.js";
|
|
2
2
|
export type { ToolbarPosition, ToolbarProps, ToolbarTheme } from "./toolbar.js";
|
|
3
|
+
export { queryCacheSummary, reportToolbarError } from "./debug-context-host.js";
|
|
4
|
+
export type { DebugContextConfig, DebugContextOptions, DebugSignal, HostContext, } from "./debug-context-model.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** A point in px, and the toolbar's ink colours. DOM-free; shared by sketches and markup. */
|
|
2
|
+
export type Point = {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
};
|
|
6
|
+
/** Ink colour, and the halo under it that keeps a stroke readable on dark and busy pages. */
|
|
7
|
+
export declare const INK = "#ff3b30";
|
|
8
|
+
export declare const INK_HALO = "rgba(255, 255, 255, 0.85)";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What kind of report a new comment is, when the person says: `POST /v1/threads` takes it as `kind`. Left
|
|
3
|
+
* unsaid, nothing is sent and the service decides with the title. DOM-free.
|
|
4
|
+
*
|
|
5
|
+
* The kinds mirror `ClarityKind` in `packages/contract/src/clarity.ts`; the toolbar bundle does not import the
|
|
6
|
+
* contract package. `tests/kind-composer.spec.tsx` holds the two in step.
|
|
7
|
+
*/
|
|
8
|
+
export type ReportKind = "bug" | "feedback" | "discussion";
|
|
9
|
+
export declare const REPORT_KINDS: readonly {
|
|
10
|
+
readonly kind: ReportKind;
|
|
11
|
+
readonly label: string;
|
|
12
|
+
}[];
|
|
13
|
+
/** `value` as a kind, or null: a stored draft holds whatever an older or newer build wrote. */
|
|
14
|
+
export declare function readReportKind(value: unknown): ReportKind | null;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The live socket's protocol and timing, shared by the web toolbar's `useThreadsSync` (`./sync.ts`) and native
|
|
3
|
+
* clients: what a message means, the keepalive, the push batch, and the reconnect backoff. DOM-free.
|
|
4
|
+
*/
|
|
5
|
+
export type LiveMessage = {
|
|
6
|
+
type: "changed";
|
|
7
|
+
} | {
|
|
8
|
+
type: "build";
|
|
9
|
+
build: string;
|
|
10
|
+
} | {
|
|
11
|
+
type: "pong";
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* What the worker sent over the live socket: "changed" (threads moved; also anything unrecognised, so an older
|
|
15
|
+
* worker's pushes still refresh), a build announcement, or the keepalive answer.
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseLiveMessage(data: unknown): LiveMessage;
|
|
18
|
+
/** If the live socket hasn't opened by then, fetch anyway instead of waiting on a slow handshake. */
|
|
19
|
+
export declare const OPEN_WAIT_MS = 2000;
|
|
20
|
+
/** After this many handshakes in a row that never opened (a CSP block, say), retry only every RETRY_LATER_MS. */
|
|
21
|
+
export declare const MAX_QUICK_RETRIES = 4;
|
|
22
|
+
export declare const RETRY_LATER_MS: number;
|
|
23
|
+
export declare const KEEPALIVE_MS = 25000;
|
|
24
|
+
/** Pushes that arrive together cause one refetch. */
|
|
25
|
+
export declare const PUSH_BATCH_MS = 120;
|
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
import type { ToolbarProps } from "./toolbar.js";
|
|
2
|
-
export type ToolbarSource = "latest" | "bundled";
|
|
3
2
|
/**
|
|
4
|
-
* Renders nothing and does nothing during render. Once the page is idle it asks the session route
|
|
5
|
-
*
|
|
3
|
+
* Renders nothing and does nothing during render. Once the page is idle it asks the session route whether
|
|
4
|
+
* comments are on, and only then loads and mounts the toolbar (`./boot.ts`, which the script-tag loader runs
|
|
5
|
+
* too). While the toolbar is not on the page the route is asked again when a sign-in may have happened
|
|
6
|
+
* (`./host-watch.ts`); once it is, the toolbar follows the host's sign-in itself.
|
|
6
7
|
*/
|
|
7
|
-
export declare function CommentToolbar({
|
|
8
|
-
/**
|
|
9
|
-
* "latest" (default) loads the newest compatible toolbar from the comment service, so fixes ship
|
|
10
|
-
* without a dependency upgrade, and falls back to the copy in this package if that fails.
|
|
11
|
-
* "bundled" always uses the copy in this package.
|
|
12
|
-
*/
|
|
13
|
-
source?: ToolbarSource;
|
|
14
|
-
}): null;
|
|
8
|
+
export declare function CommentToolbar({ sessionPath, pollMs, position, theme, navigate, screen, debugContext, }: ToolbarProps): null;
|