ranuts 0.3.0-alpha.1 → 0.4.0-alpha.2
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/CLAUDE.md +23 -12
- package/dist/{color-Dohr9BXX.js → color-Bh_QUad2.js} +1 -1
- package/dist/i18n-D1p8_7wC.js +1 -0
- package/dist/index.js +1 -1
- package/dist/src/node/index.js +1 -1
- package/dist/src/sw/index.d.ts +109 -0
- package/dist/src/sw/index.js +1 -0
- package/dist/src/utils/dom.d.ts +23 -0
- package/dist/src/utils/file.d.ts +7 -2
- package/dist/src/utils/i18n/index.js +1 -1
- package/dist/src/utils/i18n.d.ts +64 -14
- package/dist/src/utils/idb.d.ts +40 -0
- package/dist/src/utils/index.d.ts +15 -10
- package/dist/src/utils/index.js +1 -1
- package/dist/src/utils/paginate.d.ts +73 -0
- package/dist/src/utils/speech.d.ts +86 -0
- package/dist/src/utils/str.d.ts +35 -0
- package/dist/src/utils/time.d.ts +73 -3
- package/dist/src/utils/worker.d.ts +49 -0
- package/dist/test/sw.test.d.ts +1 -0
- package/dist/test/utils/autosize.test.d.ts +1 -0
- package/dist/test/utils/i18n.test.d.ts +1 -0
- package/dist/test/utils/idb-collection.test.d.ts +1 -0
- package/dist/test/utils/paginate.test.d.ts +1 -0
- package/dist/test/utils/speech.test.d.ts +1 -0
- package/dist/test/utils/time.test.d.ts +1 -0
- package/dist/test/utils/truncate.test.d.ts +1 -0
- package/dist/test/utils/worker-serve.test.d.ts +1 -0
- package/dist/umd/index.umd.cjs +1 -1
- package/dist/umd/utils/utils.umd.cjs +1 -1
- package/dist/utils-vTF6lLZZ.js +1 -0
- package/docs/API.md +65 -13
- package/package.json +5 -1
- package/dist/i18n-Cf5TtRb4.js +0 -1
- package/dist/utils-BDtXHcK8.js +0 -1
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Paginate plain text into fixed-size boxes — the layout a reader, a teleprompter or a
|
|
3
|
+
* printable preview needs, where the same text must be cut into pages of a known size.
|
|
4
|
+
*
|
|
5
|
+
* The whole thing is **pure arithmetic**: it takes the box dimensions and the type metrics as
|
|
6
|
+
* numbers and never touches the DOM. That is what lets it run inside a Worker, on the server,
|
|
7
|
+
* or in a test — measure the container once on the main thread, then paginate anywhere.
|
|
8
|
+
*
|
|
9
|
+
* It assumes a **monospaced grid**: every character advances either one cell (CJK, full-width)
|
|
10
|
+
* or `narrowRatio` of one (ASCII). That is exactly true for a monospaced font and close enough
|
|
11
|
+
* for the CJK-dominant body text this was built for; it is *not* a substitute for real shaping
|
|
12
|
+
* on proportional Latin text.
|
|
13
|
+
*/
|
|
14
|
+
/** The box each page must fit into, in px. */
|
|
15
|
+
export interface TextBox {
|
|
16
|
+
width: number;
|
|
17
|
+
height: number;
|
|
18
|
+
}
|
|
19
|
+
export interface TextGridMetrics {
|
|
20
|
+
/** Advance width of one full-width character, px (font size + letter spacing). */
|
|
21
|
+
charWidth: number;
|
|
22
|
+
/** Distance between baselines, px. */
|
|
23
|
+
lineHeight: number;
|
|
24
|
+
/**
|
|
25
|
+
* Advance of a narrow (ASCII) character as a fraction of `charWidth`. Default `0.5625`
|
|
26
|
+
* (9/16), the usual half-width-plus-spacing ratio.
|
|
27
|
+
*/
|
|
28
|
+
narrowRatio?: number;
|
|
29
|
+
}
|
|
30
|
+
export interface PaginateOptions {
|
|
31
|
+
/**
|
|
32
|
+
* Below this, in either dimension, the box is treated as not yet laid out and pagination
|
|
33
|
+
* returns nothing. Default `30`. Guards against paginating during first paint, when a
|
|
34
|
+
* container still measures 0 and a naive `floor(0 / charWidth)` would loop forever.
|
|
35
|
+
*/
|
|
36
|
+
minBox?: number;
|
|
37
|
+
}
|
|
38
|
+
export interface TextPage {
|
|
39
|
+
text: string;
|
|
40
|
+
/** Offset of this page's first character in the source text. */
|
|
41
|
+
start: number;
|
|
42
|
+
/** Offset one past this page's last character. */
|
|
43
|
+
end: number;
|
|
44
|
+
index: number;
|
|
45
|
+
}
|
|
46
|
+
export interface PaginateResult {
|
|
47
|
+
pages: TextPage[];
|
|
48
|
+
/** Length of the normalized source text. */
|
|
49
|
+
total: number;
|
|
50
|
+
charsPerLine: number;
|
|
51
|
+
linesPerPage: number;
|
|
52
|
+
/** `charsPerLine * linesPerPage` — the budget one page spends. */
|
|
53
|
+
charsPerPage: number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* @description: Cut text into pages that fit `box`, given the type metrics.
|
|
57
|
+
*
|
|
58
|
+
* ASCII words are kept whole: a page never ends mid-word unless the word is longer than a
|
|
59
|
+
* line. Newlines start a new line and are charged one character.
|
|
60
|
+
*
|
|
61
|
+
* @param {string} text source text; `\r\n` / `\r` are normalized to `\n` first
|
|
62
|
+
* @param {TextBox} box page box in px — measure the container once, then call this anywhere
|
|
63
|
+
* @param {TextGridMetrics} metrics character advance and line height, px
|
|
64
|
+
* @param {PaginateOptions} options
|
|
65
|
+
* @return {PaginateResult} pages plus the grid it derived
|
|
66
|
+
* @example
|
|
67
|
+
* ```ts
|
|
68
|
+
* const { width, height } = container.getBoundingClientRect();
|
|
69
|
+
* const result = paginateText(book, { width, height }, { charWidth: 18.4, lineHeight: 40 });
|
|
70
|
+
* render(result.pages[0].text);
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export declare const paginateText: (text: string, box: TextBox, metrics: TextGridMetrics, options?: PaginateOptions) => PaginateResult;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Speech recognition (dictation) over the Web Speech API.
|
|
3
|
+
*
|
|
4
|
+
* This is the counterpart to `AudioRecorder`, which captures audio *bytes*; this one asks the
|
|
5
|
+
* platform to turn speech into *text*. The browser API is still prefixed on WebKit, is absent
|
|
6
|
+
* from `lib.dom`, and reports several routine non-events (a silent pause, a programmatic stop)
|
|
7
|
+
* through the same error channel as a denied microphone — so it is worth wrapping once.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* `denied` means the user or the browser refused the microphone — worth surfacing.
|
|
11
|
+
* `noSpeech` and `aborted` are routine (a silent pause, a programmatic `stop()`) and are
|
|
12
|
+
* usually not worth showing anyone; they are reported rather than swallowed so the caller
|
|
13
|
+
* decides. Everything else is `failed`.
|
|
14
|
+
*/
|
|
15
|
+
export type SpeechErrorKind = 'denied' | 'noSpeech' | 'aborted' | 'failed';
|
|
16
|
+
export interface SpeechError {
|
|
17
|
+
kind: SpeechErrorKind;
|
|
18
|
+
/** The raw `error` string from the platform event. */
|
|
19
|
+
detail: string;
|
|
20
|
+
}
|
|
21
|
+
export interface SpeechRecognizerOptions {
|
|
22
|
+
/**
|
|
23
|
+
* BCP 47 tag for the language being spoken, e.g. `'en-US'`, `'zh-CN'`. Pass a function to
|
|
24
|
+
* have it read at the start of each capture, which is what an app whose UI language can
|
|
25
|
+
* change mid-session wants.
|
|
26
|
+
*/
|
|
27
|
+
lang?: string | (() => string);
|
|
28
|
+
/** Keep listening across pauses instead of stopping at the first one. Default `true`. */
|
|
29
|
+
continuous?: boolean;
|
|
30
|
+
/** Emit partial results as the speaker talks. Default `true`. */
|
|
31
|
+
interimResults?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Called as text arrives, with the transcript of the **whole capture so far** — not just
|
|
34
|
+
* the newest fragment — because interim results are revised as recognition firms up.
|
|
35
|
+
*/
|
|
36
|
+
onResult?: (transcript: string, isFinal: boolean) => void;
|
|
37
|
+
onError?: (error: SpeechError) => void;
|
|
38
|
+
onStart?: () => void;
|
|
39
|
+
/** Fires once per capture, however it ended: stopped, timed out, or errored. */
|
|
40
|
+
onEnd?: () => void;
|
|
41
|
+
}
|
|
42
|
+
export interface SpeechRecognizer {
|
|
43
|
+
/** `false` when the platform has no speech recognition; every method is then a no-op. */
|
|
44
|
+
readonly supported: boolean;
|
|
45
|
+
/** Whether a capture is currently running. */
|
|
46
|
+
readonly active: boolean;
|
|
47
|
+
/** Begin a capture. Ignored if one is already running. */
|
|
48
|
+
start(): void;
|
|
49
|
+
/** End the current capture; results already recognized are kept. `onEnd` follows. */
|
|
50
|
+
stop(): void;
|
|
51
|
+
/** End the current capture and discard pending results. */
|
|
52
|
+
abort(): void;
|
|
53
|
+
/** Start if idle, stop if running — the behaviour a single microphone button wants. */
|
|
54
|
+
toggle(): void;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* @description: Whether this runtime can recognize speech. Checked at call time, so it is safe
|
|
58
|
+
* to import this module during server-side rendering.
|
|
59
|
+
* @return {boolean}
|
|
60
|
+
*/
|
|
61
|
+
export declare const isSpeechRecognitionSupported: () => boolean;
|
|
62
|
+
/**
|
|
63
|
+
* @description: Create a dictation session over the Web Speech API.
|
|
64
|
+
*
|
|
65
|
+
* A recognizer is reusable: `start` builds a fresh native instance each time, so options read
|
|
66
|
+
* through a function (notably `lang`) are re-read per capture.
|
|
67
|
+
*
|
|
68
|
+
* On a platform without speech recognition this returns an inert recognizer with
|
|
69
|
+
* `supported === false` rather than throwing — check that field to hide your microphone button.
|
|
70
|
+
*
|
|
71
|
+
* @param {SpeechRecognizerOptions} options
|
|
72
|
+
* @return {SpeechRecognizer}
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* const mic = createSpeechRecognizer({
|
|
76
|
+
* lang: () => currentLocale(),
|
|
77
|
+
* onResult: (text) => { input.value = text; },
|
|
78
|
+
* onError: (e) => { if (e.kind === 'denied') toast('Microphone access was refused'); },
|
|
79
|
+
* onEnd: () => button.classList.remove('recording'),
|
|
80
|
+
* onStart: () => button.classList.add('recording'),
|
|
81
|
+
* });
|
|
82
|
+
* if (!mic.supported) button.style.display = 'none';
|
|
83
|
+
* button.addEventListener('click', () => mic.toggle());
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export declare const createSpeechRecognizer: (options?: SpeechRecognizerOptions) => SpeechRecognizer;
|
package/dist/src/utils/str.d.ts
CHANGED
|
@@ -64,6 +64,41 @@ export declare const toHalfWidth: (value: string) => string;
|
|
|
64
64
|
* @return {string}
|
|
65
65
|
*/
|
|
66
66
|
export declare const toFullWidth: (value: string) => string;
|
|
67
|
+
/** Which end of the string gets dropped when it is too long. */
|
|
68
|
+
export type TruncatePosition = 'end' | 'start' | 'middle';
|
|
69
|
+
export interface TruncateOptions {
|
|
70
|
+
/** Ceiling for the returned string, ellipsis included. */
|
|
71
|
+
length: number;
|
|
72
|
+
/** Default `'end'`. */
|
|
73
|
+
position?: TruncatePosition;
|
|
74
|
+
/** Default `'…'`. */
|
|
75
|
+
ellipsis?: string;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* @description: Shorten a string to a maximum length, marking the cut with an ellipsis.
|
|
79
|
+
*
|
|
80
|
+
* `position` decides which end survives, and that choice carries real information:
|
|
81
|
+
*
|
|
82
|
+
* - `'end'` (default) keeps the beginning — right for prose and titles.
|
|
83
|
+
* - `'start'` keeps the **tail**, which is what a file path wants. `/Users/someone/work/…`
|
|
84
|
+
* are the bytes a reader already knows; `…/src/utils/str.ts` is the part they need.
|
|
85
|
+
* - `'middle'` keeps both ends, for identifiers whose head *and* tail are meaningful, such as
|
|
86
|
+
* a hash or an account number.
|
|
87
|
+
*
|
|
88
|
+
* The result never exceeds `length`, so a `length` shorter than the ellipsis returns a
|
|
89
|
+
* truncated ellipsis rather than overflowing.
|
|
90
|
+
*
|
|
91
|
+
* @param {string} value
|
|
92
|
+
* @param {TruncateOptions | number} options a bare number is shorthand for `{ length }`
|
|
93
|
+
* @return {string}
|
|
94
|
+
* @example
|
|
95
|
+
* ```ts
|
|
96
|
+
* truncate('the quick brown fox', 12); // 'the quick b…'
|
|
97
|
+
* truncate('/Users/me/code/app/src/index.ts', { length: 20, position: 'start' }); // '…de/app/src/index.ts'
|
|
98
|
+
* truncate('0xabcdef0123456789', { length: 11, position: 'middle' }); // '0xabc…56789'
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
export declare const truncate: (value: string, options: TruncateOptions | number) => string;
|
|
67
102
|
export interface TransformText {
|
|
68
103
|
encoding: string;
|
|
69
104
|
content: string;
|
package/dist/src/utils/time.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/** Accepted everywhere a moment in time is taken; `undefined` means "now". */
|
|
2
|
+
export type DateInput = number | string | Date;
|
|
1
3
|
/**
|
|
2
4
|
* @description: Format a date with a token pattern. Accepts a timestamp, a date string, a
|
|
3
5
|
* `Date`, or nothing (meaning now). Wrap literal text in `[]` to keep it out of the substitution.
|
|
@@ -23,10 +25,10 @@
|
|
|
23
25
|
* ```ts
|
|
24
26
|
* formatDate(); // '2026-07-25 14:30:00'
|
|
25
27
|
* formatDate(1753425000000, 'YYYY/MM/DD'); // '2026/07/25'
|
|
26
|
-
* formatDate(new Date(), 'YYYY[年]MM[月]DD[日] hh:mm a'); // '2026年07月25日 02:30 pm' (escaped literals)
|
|
28
|
+
* formatDate(new Date(), 'YYYY[年]MM[月]DD[日] hh:mm a'); // '2026 年 07 月 25 日 02:30 pm' (escaped literals)
|
|
27
29
|
* ```
|
|
28
30
|
*/
|
|
29
|
-
export declare const formatDate: (value?:
|
|
31
|
+
export declare const formatDate: (value?: DateInput, pattern?: string) => string;
|
|
30
32
|
/**
|
|
31
33
|
* @description: Turn a timestamp into a `Date` carrying a `format` method.
|
|
32
34
|
* @deprecated Use [`formatDate`](#formatdate). This returns a `Date` with an extra method
|
|
@@ -39,12 +41,80 @@ export declare const formatDate: (value?: number | string | Date, pattern?: stri
|
|
|
39
41
|
export declare function timestampToTime(timestamp?: number | string): Date & {
|
|
40
42
|
format?: Function;
|
|
41
43
|
};
|
|
44
|
+
/**
|
|
45
|
+
* @description: Format an elapsed number of **seconds** as a colon-separated clock duration,
|
|
46
|
+
* the shape media players use for a playhead: `mm:ss`, widening to `hh:mm:ss` past an hour.
|
|
47
|
+
*
|
|
48
|
+
* This is a length of time, not a point in time — for the latter see
|
|
49
|
+
* [`formatDate`](#formatdate) (absolute) and [`formatRelative`](#formatrelative) (relative).
|
|
50
|
+
*
|
|
51
|
+
* @param {number} seconds elapsed seconds; negatives clamp to `0`
|
|
52
|
+
* @return {string} the duration, or `''` when the input is not a finite number — a player
|
|
53
|
+
* asks for `video.duration` before metadata loads and gets `NaN`, and an empty label reads
|
|
54
|
+
* better there than `NaN:NaN`
|
|
55
|
+
* @example
|
|
56
|
+
* ```ts
|
|
57
|
+
* formatDuration(0); // '00:00'
|
|
58
|
+
* formatDuration(65); // '01:05'
|
|
59
|
+
* formatDuration(3661); // '01:01:01'
|
|
60
|
+
* formatDuration(NaN); // ''
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare const formatDuration: (seconds: number) => string;
|
|
42
64
|
/**
|
|
43
65
|
* @description: Format a number of seconds as a colon-separated duration
|
|
66
|
+
* @deprecated Renamed to [`formatDuration`](#formatduration) — `timeFormat` said nothing about
|
|
67
|
+
* *which* of the three time formats it was, and read backwards from its `formatDate` sibling.
|
|
68
|
+
* This alias stays for compatibility and behaves identically.
|
|
44
69
|
* @param {number} time
|
|
45
|
-
* @return {
|
|
70
|
+
* @return {string}
|
|
46
71
|
*/
|
|
47
72
|
export declare const timeFormat: (time: number) => string;
|
|
73
|
+
/** `'compact'` is ours; the other three are `Intl.RelativeTimeFormat` styles. */
|
|
74
|
+
export type RelativeStyle = 'long' | 'short' | 'narrow' | 'compact';
|
|
75
|
+
export interface FormatRelativeOptions {
|
|
76
|
+
/** What to measure against. Defaults to the current time. */
|
|
77
|
+
now?: DateInput;
|
|
78
|
+
/** BCP 47 tag(s); defaults to the runtime's locale. Ignored by the `compact` style. */
|
|
79
|
+
locale?: string | string[];
|
|
80
|
+
/** Defaults to `'long'` (`'3 days ago'`). */
|
|
81
|
+
style?: RelativeStyle;
|
|
82
|
+
/**
|
|
83
|
+
* `'auto'` (the default here) swaps in idioms where a language has them — `yesterday`
|
|
84
|
+
* rather than `1 day ago`, `now` rather than `in 0 seconds`. `'always'` keeps the number.
|
|
85
|
+
*/
|
|
86
|
+
numeric?: 'always' | 'auto';
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* @description: Format a point in time relative to another — "3 days ago", "in 2 hours".
|
|
90
|
+
*
|
|
91
|
+
* Localization is delegated to the platform's `Intl.RelativeTimeFormat`, which has been
|
|
92
|
+
* available in every major browser since 2020 and knows each language's plural and
|
|
93
|
+
* inflection rules. This function supplies only the part `Intl` deliberately leaves out:
|
|
94
|
+
* picking *which* unit to express the gap in.
|
|
95
|
+
*
|
|
96
|
+
* Like `Intl` itself it reports a **single** unit — a gap of 3 days and 6 hours is
|
|
97
|
+
* "3 days ago", never "3 days and 6 hours ago".
|
|
98
|
+
*
|
|
99
|
+
* The extra `compact` style is the dense badge form seen next to list items (`5m`, `3h`,
|
|
100
|
+
* `2d`). It is a magnitude only: it carries **no direction**, so a future timestamp reads
|
|
101
|
+
* the same as a past one. Use it for feeds of past events, and any other style when the
|
|
102
|
+
* reader has to tell past from future.
|
|
103
|
+
*
|
|
104
|
+
* @param {DateInput} value the moment to describe
|
|
105
|
+
* @param {FormatRelativeOptions} options
|
|
106
|
+
* @return {string} the description, or `''` when either end cannot be parsed
|
|
107
|
+
* @example
|
|
108
|
+
* ```ts
|
|
109
|
+
* const twoHoursAgo = Date.now() - 2 * 3600_000;
|
|
110
|
+
* formatRelative(twoHoursAgo); // '2 hours ago'
|
|
111
|
+
* formatRelative(twoHoursAgo, { style: 'short' }); // '2 hr. ago'
|
|
112
|
+
* formatRelative(twoHoursAgo, { style: 'compact' }); // '2h'
|
|
113
|
+
* formatRelative(twoHoursAgo, { locale: 'zh-CN' }); // '2 小时前'
|
|
114
|
+
* formatRelative(Date.now() + 60_000); // 'in 1 minute'
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
export declare const formatRelative: (value: DateInput, options?: FormatRelativeOptions) => string;
|
|
48
118
|
/**
|
|
49
119
|
* @description: Current timestamp
|
|
50
120
|
* @return {*}
|
|
@@ -74,3 +74,52 @@ export declare class WorkerClient<Req extends object, Res extends WorkerResponse
|
|
|
74
74
|
private handleMessage;
|
|
75
75
|
private rejectAll;
|
|
76
76
|
}
|
|
77
|
+
/** A request always carries the id the client stamped on it */
|
|
78
|
+
export interface WorkerRequestBase {
|
|
79
|
+
operationId: number;
|
|
80
|
+
type?: string;
|
|
81
|
+
}
|
|
82
|
+
/** Handed to the handler so it can stream progress for the request it is currently serving */
|
|
83
|
+
export interface WorkerHandlerContext<Progress> {
|
|
84
|
+
/** Post a progress update. Does not settle the request; may be called any number of times. */
|
|
85
|
+
progress: (payload: Progress) => void;
|
|
86
|
+
}
|
|
87
|
+
export interface ServeWorkerOptions {
|
|
88
|
+
/**
|
|
89
|
+
* Where to listen. Defaults to `self` — override for a `MessagePort`, a nested worker, or
|
|
90
|
+
* a test double.
|
|
91
|
+
*/
|
|
92
|
+
scope?: {
|
|
93
|
+
addEventListener: (type: 'message', listener: (event: MessageEvent) => void) => void;
|
|
94
|
+
removeEventListener: (type: 'message', listener: (event: MessageEvent) => void) => void;
|
|
95
|
+
postMessage: (message: unknown, transfer?: Transferable[]) => void;
|
|
96
|
+
};
|
|
97
|
+
/** Response `type` for a successful reply that the handler returned bare (non-object). Default `'result'`. */
|
|
98
|
+
resultType?: string;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* @description: Serve requests inside a Web Worker, mirroring {@link WorkerClient} on the
|
|
102
|
+
* other end. Reads `operationId` off each request, awaits your handler, and posts the reply
|
|
103
|
+
* back with that same id.
|
|
104
|
+
*
|
|
105
|
+
* Failures become `{ operationId, type: 'error', message }` — the envelope `WorkerClient`
|
|
106
|
+
* rejects on by default. **Both synchronous throws and rejected promises are caught**: a sync
|
|
107
|
+
* throw inside `onmessage` would otherwise escape to the worker's error handler, which carries
|
|
108
|
+
* no id, so the client could only fail *every* in-flight request instead of the one that broke.
|
|
109
|
+
*
|
|
110
|
+
* @param {Function} handler receives the request and a context whose `progress()` streams updates
|
|
111
|
+
* @param {ServeWorkerOptions} options
|
|
112
|
+
* @return {Function} stop — removes the listener
|
|
113
|
+
* @example
|
|
114
|
+
* ```ts
|
|
115
|
+
* // my.worker.ts
|
|
116
|
+
* serveWorker<MyRequest, MyResponse, ModelProgress>(async (request, { progress }) => {
|
|
117
|
+
* if (request.type === 'load') {
|
|
118
|
+
* const device = await load(request.modelId, (p) => progress(p));
|
|
119
|
+
* return { type: 'loaded', device };
|
|
120
|
+
* }
|
|
121
|
+
* return { type: 'result', scores: await classify(request.lines) };
|
|
122
|
+
* });
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
export declare const serveWorker: <Req extends WorkerRequestBase, Res extends object = object, Progress = unknown>(handler: (request: Req, context: WorkerHandlerContext<Progress>) => Promise<Res> | Res, options?: ServeWorkerOptions) => (() => void);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|