@develemit/web-hooks 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/README.md +64 -0
- package/dist/{chunk-UJ366T3Y.js → chunk-R2PFNE3U.js} +12 -4
- package/dist/chunk-TE2FRIPF.js +616 -0
- package/dist/{chunk-JG3GPTMY.js → chunk-UVJBJETY.js} +26 -6
- package/dist/index.cjs +677 -17
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +44 -2
- package/dist/push.cjs +12 -4
- package/dist/push.d.cts +2 -1
- package/dist/push.d.ts +2 -1
- package/dist/push.js +1 -1
- package/dist/service-worker.cjs +26 -6
- package/dist/service-worker.d.cts +2 -1
- package/dist/service-worker.d.ts +2 -1
- package/dist/service-worker.js +1 -1
- package/dist/terminal-output.cjs +660 -0
- package/dist/terminal-output.d.cts +186 -0
- package/dist/terminal-output.d.ts +186 -0
- package/dist/terminal-output.js +45 -0
- package/package.json +7 -1
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
type AnsiColor = {
|
|
4
|
+
kind: 'ansi';
|
|
5
|
+
index: number;
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'rgb';
|
|
8
|
+
r: number;
|
|
9
|
+
g: number;
|
|
10
|
+
b: number;
|
|
11
|
+
};
|
|
12
|
+
interface AnsiStyle {
|
|
13
|
+
fg?: AnsiColor;
|
|
14
|
+
bg?: AnsiColor;
|
|
15
|
+
bold?: boolean;
|
|
16
|
+
dim?: boolean;
|
|
17
|
+
italic?: boolean;
|
|
18
|
+
underline?: boolean;
|
|
19
|
+
inverse?: boolean;
|
|
20
|
+
}
|
|
21
|
+
interface AnsiSegment extends AnsiStyle {
|
|
22
|
+
text: string;
|
|
23
|
+
href?: string;
|
|
24
|
+
}
|
|
25
|
+
type AnsiLine = AnsiSegment[];
|
|
26
|
+
interface ParseAnsiOptions {
|
|
27
|
+
/** URL schemes kept on OSC 8 hyperlinks. Default `['http', 'https', 'file']`. */
|
|
28
|
+
linkSchemes?: readonly string[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Removes CSI, OSC and two-byte escape sequences. Leaves `\r` and `\n` alone. */
|
|
32
|
+
declare function stripAnsi(text: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Turns raw terminal text into lines of styled segments. `\r` and cursor-up
|
|
35
|
+
* redraws overwrite earlier text the way a terminal would. Cursor-up/down,
|
|
36
|
+
* column set (`G`), erase-line and erase-below are emulated; every other
|
|
37
|
+
* escape sequence is dropped. Text is never interpreted as markup.
|
|
38
|
+
*/
|
|
39
|
+
declare function parseAnsi(text: string, options?: ParseAnsiOptions): AnsiLine[];
|
|
40
|
+
/** Like `parseAnsi`, but colour and link state carry from one call to the next. */
|
|
41
|
+
declare function createAnsiParser(options?: ParseAnsiOptions): {
|
|
42
|
+
parse: (chunk: string) => AnsiLine[];
|
|
43
|
+
reset: () => void;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
type StreamCursor = number | string;
|
|
47
|
+
interface LineBufferOptions {
|
|
48
|
+
/** Most complete lines kept. Older ones are dropped and counted. */
|
|
49
|
+
maxLines: number;
|
|
50
|
+
}
|
|
51
|
+
interface LineBufferUpdate {
|
|
52
|
+
/** Complete raw lines from this push, escape codes intact. */
|
|
53
|
+
lines: string[];
|
|
54
|
+
/** The unfinished line, raw, without an escape code still being written. */
|
|
55
|
+
partial: string;
|
|
56
|
+
/** Lines this push pushed out of the buffer. */
|
|
57
|
+
dropped: number;
|
|
58
|
+
}
|
|
59
|
+
interface LineBuffer {
|
|
60
|
+
push(chunk: string | Uint8Array, options?: {
|
|
61
|
+
cursor?: StreamCursor;
|
|
62
|
+
}): LineBufferUpdate;
|
|
63
|
+
/** Ends the stream: the unfinished line becomes a complete one. */
|
|
64
|
+
flush(): LineBufferUpdate;
|
|
65
|
+
reset(): void;
|
|
66
|
+
/** The lines still held, oldest first. */
|
|
67
|
+
readonly lines: readonly string[];
|
|
68
|
+
readonly partial: string;
|
|
69
|
+
/** The server's cursor from the last push that had one. Ask for `since: cursor` on reconnect. */
|
|
70
|
+
readonly cursor: StreamCursor | undefined;
|
|
71
|
+
/** Lines dropped over the buffer's life. */
|
|
72
|
+
readonly dropped: number;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Turns stream chunks (strings or bytes) into complete lines. Resuming is the
|
|
76
|
+
* server's job: pass its cursor to `push` and read `cursor` back on reconnect.
|
|
77
|
+
* The buffer never compares text, so a log that repeats a line keeps both.
|
|
78
|
+
*/
|
|
79
|
+
declare function createLineBuffer({ maxLines }: LineBufferOptions): LineBuffer;
|
|
80
|
+
|
|
81
|
+
interface AnsiStreamOptions extends ParseAnsiOptions {
|
|
82
|
+
/** Rendered lines above the cursor that a redraw can still overwrite. Default 50. */
|
|
83
|
+
tailLines?: number;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Rows from `from` on are replaced by `lines`. Row numbers count from the first
|
|
87
|
+
* row of the stream. Truncate your list to `from` rows, then append `lines`.
|
|
88
|
+
*/
|
|
89
|
+
interface AnsiStreamUpdate {
|
|
90
|
+
replaced?: {
|
|
91
|
+
from: number;
|
|
92
|
+
lines: AnsiLine[];
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
interface AnsiStream {
|
|
96
|
+
/** Feeds newly completed raw lines and the current unfinished line. */
|
|
97
|
+
push(lines: readonly string[], partial?: string): AnsiStreamUpdate;
|
|
98
|
+
/**
|
|
99
|
+
* Ends the stream. Renders the unfinished line without adding a newline;
|
|
100
|
+
* pass `partial` to replace the one given to the last `push`. Pushes after
|
|
101
|
+
* this are ignored until `reset()`.
|
|
102
|
+
*/
|
|
103
|
+
finish(partial?: string): AnsiStreamUpdate;
|
|
104
|
+
reset(): void;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Renders a stream the way `parseAnsi` renders the whole text, line by line.
|
|
108
|
+
* It keeps a small screen tail so cursor-up redraws reach rows already shown,
|
|
109
|
+
* and says which rows changed. Older rows are frozen and forgotten.
|
|
110
|
+
*/
|
|
111
|
+
declare function createAnsiStream(options?: AnsiStreamOptions): AnsiStream;
|
|
112
|
+
|
|
113
|
+
interface TextSegment {
|
|
114
|
+
text: string;
|
|
115
|
+
match: boolean;
|
|
116
|
+
}
|
|
117
|
+
type FailureTool = 'vitest' | 'nx' | 'tsc' | 'pnpm' | 'npm' | 'docker' | 'generic';
|
|
118
|
+
interface FailurePattern {
|
|
119
|
+
tool: FailureTool;
|
|
120
|
+
kind: string;
|
|
121
|
+
pattern: RegExp;
|
|
122
|
+
}
|
|
123
|
+
interface Failure {
|
|
124
|
+
index: number;
|
|
125
|
+
tool: FailureTool;
|
|
126
|
+
kind: string;
|
|
127
|
+
}
|
|
128
|
+
declare function filterLines(lines: readonly string[], query: string): number[];
|
|
129
|
+
declare function splitByMatch(line: string, query: string): TextSegment[];
|
|
130
|
+
declare const FAILURE_PATTERNS: readonly FailurePattern[];
|
|
131
|
+
declare function findFailures(lines: readonly string[], patterns?: readonly FailurePattern[]): Failure[];
|
|
132
|
+
declare function firstFailureIndex(lines: readonly string[], patterns?: readonly FailurePattern[]): number;
|
|
133
|
+
declare const NOISE_PATTERNS: readonly RegExp[];
|
|
134
|
+
declare function isNoise(line: string, patterns?: readonly RegExp[]): boolean;
|
|
135
|
+
declare function tailMeaningful(lines: readonly string[], n: number, patterns?: readonly RegExp[]): string[];
|
|
136
|
+
|
|
137
|
+
interface ScrollMetrics {
|
|
138
|
+
scrollTop: number;
|
|
139
|
+
scrollHeight: number;
|
|
140
|
+
clientHeight: number;
|
|
141
|
+
}
|
|
142
|
+
declare const DEFAULT_TAIL_THRESHOLD = 24;
|
|
143
|
+
declare function distanceFromEnd({ scrollTop, scrollHeight, clientHeight }: ScrollMetrics): number;
|
|
144
|
+
/** Within `threshold` px of the end; negative distances (iOS rubber-band past the end) count. */
|
|
145
|
+
declare function isNearEnd(metrics: ScrollMetrics, threshold?: number): boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Whether the view should keep following after a scroll event. A scroll the hook made itself
|
|
148
|
+
* never changes the answer; a user scroll follows only while it ends near the end.
|
|
149
|
+
*/
|
|
150
|
+
declare function shouldStick(prevAtBottom: boolean, metrics: ScrollMetrics, userInitiated: boolean, threshold?: number): boolean;
|
|
151
|
+
type ScrollEventKind = 'scroll' | 'wheel' | 'touch' | 'gutter';
|
|
152
|
+
interface ScrollEventInfo {
|
|
153
|
+
kind: ScrollEventKind;
|
|
154
|
+
/** wheel: `deltaY`. touch: how far the finger moved down since touchstart. Unused otherwise. */
|
|
155
|
+
delta?: number;
|
|
156
|
+
/** Where the hook last scrolled to, or null when it hasn't since the user last took over. */
|
|
157
|
+
lastTarget: number | null;
|
|
158
|
+
scrollTop: number;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Whether an event is the user reading upward, whichever frame it lands in. Wheel-up, a finger
|
|
162
|
+
* dragging down and a press on the scrollbar are intent; a scroll event counts only when it sits
|
|
163
|
+
* below where the hook last scrolled to, because the hook only ever scrolls down.
|
|
164
|
+
*/
|
|
165
|
+
declare function isUserScrollUp({ kind, delta, lastTarget, scrollTop }: ScrollEventInfo, threshold?: number): boolean;
|
|
166
|
+
/** Items to add to the unread count after the list grew while the user is reading above the end. */
|
|
167
|
+
declare function unreadDelta(prevCount: number, nextCount: number, attached: boolean): number;
|
|
168
|
+
|
|
169
|
+
interface UseFollowTailOptions {
|
|
170
|
+
scrollRef: RefObject<HTMLElement | null>;
|
|
171
|
+
itemCount: number;
|
|
172
|
+
/** Scroll to the last item. A virtualizer passes `() => virtualizer.scrollToIndex(count - 1, { align: 'end' })`. */
|
|
173
|
+
scrollToEnd?: () => void;
|
|
174
|
+
/** Snap back to the bottom whenever this changes (a project switch). */
|
|
175
|
+
resetKey?: unknown;
|
|
176
|
+
/** Distance from the end that still counts as the bottom. Default 24. */
|
|
177
|
+
threshold?: number;
|
|
178
|
+
}
|
|
179
|
+
interface UseFollowTailResult {
|
|
180
|
+
atBottom: boolean;
|
|
181
|
+
unread: number;
|
|
182
|
+
jumpToBottom: () => void;
|
|
183
|
+
}
|
|
184
|
+
declare function useFollowTail({ scrollRef, itemCount, scrollToEnd, resetKey, threshold, }: UseFollowTailOptions): UseFollowTailResult;
|
|
185
|
+
|
|
186
|
+
export { type AnsiColor, type AnsiLine, type AnsiSegment, type AnsiStream, type AnsiStreamOptions, type AnsiStreamUpdate, type AnsiStyle, DEFAULT_TAIL_THRESHOLD, FAILURE_PATTERNS, type Failure, type FailurePattern, type FailureTool, type LineBuffer, type LineBufferOptions, type LineBufferUpdate, NOISE_PATTERNS, type ParseAnsiOptions, type ScrollEventInfo, type ScrollEventKind, type ScrollMetrics, type StreamCursor, type TextSegment, type UseFollowTailOptions, type UseFollowTailResult, createAnsiParser, createAnsiStream, createLineBuffer, distanceFromEnd, filterLines, findFailures, firstFailureIndex, isNearEnd, isNoise, isUserScrollUp, parseAnsi, shouldStick, splitByMatch, stripAnsi, tailMeaningful, unreadDelta, useFollowTail };
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
type AnsiColor = {
|
|
4
|
+
kind: 'ansi';
|
|
5
|
+
index: number;
|
|
6
|
+
} | {
|
|
7
|
+
kind: 'rgb';
|
|
8
|
+
r: number;
|
|
9
|
+
g: number;
|
|
10
|
+
b: number;
|
|
11
|
+
};
|
|
12
|
+
interface AnsiStyle {
|
|
13
|
+
fg?: AnsiColor;
|
|
14
|
+
bg?: AnsiColor;
|
|
15
|
+
bold?: boolean;
|
|
16
|
+
dim?: boolean;
|
|
17
|
+
italic?: boolean;
|
|
18
|
+
underline?: boolean;
|
|
19
|
+
inverse?: boolean;
|
|
20
|
+
}
|
|
21
|
+
interface AnsiSegment extends AnsiStyle {
|
|
22
|
+
text: string;
|
|
23
|
+
href?: string;
|
|
24
|
+
}
|
|
25
|
+
type AnsiLine = AnsiSegment[];
|
|
26
|
+
interface ParseAnsiOptions {
|
|
27
|
+
/** URL schemes kept on OSC 8 hyperlinks. Default `['http', 'https', 'file']`. */
|
|
28
|
+
linkSchemes?: readonly string[];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Removes CSI, OSC and two-byte escape sequences. Leaves `\r` and `\n` alone. */
|
|
32
|
+
declare function stripAnsi(text: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Turns raw terminal text into lines of styled segments. `\r` and cursor-up
|
|
35
|
+
* redraws overwrite earlier text the way a terminal would. Cursor-up/down,
|
|
36
|
+
* column set (`G`), erase-line and erase-below are emulated; every other
|
|
37
|
+
* escape sequence is dropped. Text is never interpreted as markup.
|
|
38
|
+
*/
|
|
39
|
+
declare function parseAnsi(text: string, options?: ParseAnsiOptions): AnsiLine[];
|
|
40
|
+
/** Like `parseAnsi`, but colour and link state carry from one call to the next. */
|
|
41
|
+
declare function createAnsiParser(options?: ParseAnsiOptions): {
|
|
42
|
+
parse: (chunk: string) => AnsiLine[];
|
|
43
|
+
reset: () => void;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
type StreamCursor = number | string;
|
|
47
|
+
interface LineBufferOptions {
|
|
48
|
+
/** Most complete lines kept. Older ones are dropped and counted. */
|
|
49
|
+
maxLines: number;
|
|
50
|
+
}
|
|
51
|
+
interface LineBufferUpdate {
|
|
52
|
+
/** Complete raw lines from this push, escape codes intact. */
|
|
53
|
+
lines: string[];
|
|
54
|
+
/** The unfinished line, raw, without an escape code still being written. */
|
|
55
|
+
partial: string;
|
|
56
|
+
/** Lines this push pushed out of the buffer. */
|
|
57
|
+
dropped: number;
|
|
58
|
+
}
|
|
59
|
+
interface LineBuffer {
|
|
60
|
+
push(chunk: string | Uint8Array, options?: {
|
|
61
|
+
cursor?: StreamCursor;
|
|
62
|
+
}): LineBufferUpdate;
|
|
63
|
+
/** Ends the stream: the unfinished line becomes a complete one. */
|
|
64
|
+
flush(): LineBufferUpdate;
|
|
65
|
+
reset(): void;
|
|
66
|
+
/** The lines still held, oldest first. */
|
|
67
|
+
readonly lines: readonly string[];
|
|
68
|
+
readonly partial: string;
|
|
69
|
+
/** The server's cursor from the last push that had one. Ask for `since: cursor` on reconnect. */
|
|
70
|
+
readonly cursor: StreamCursor | undefined;
|
|
71
|
+
/** Lines dropped over the buffer's life. */
|
|
72
|
+
readonly dropped: number;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Turns stream chunks (strings or bytes) into complete lines. Resuming is the
|
|
76
|
+
* server's job: pass its cursor to `push` and read `cursor` back on reconnect.
|
|
77
|
+
* The buffer never compares text, so a log that repeats a line keeps both.
|
|
78
|
+
*/
|
|
79
|
+
declare function createLineBuffer({ maxLines }: LineBufferOptions): LineBuffer;
|
|
80
|
+
|
|
81
|
+
interface AnsiStreamOptions extends ParseAnsiOptions {
|
|
82
|
+
/** Rendered lines above the cursor that a redraw can still overwrite. Default 50. */
|
|
83
|
+
tailLines?: number;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Rows from `from` on are replaced by `lines`. Row numbers count from the first
|
|
87
|
+
* row of the stream. Truncate your list to `from` rows, then append `lines`.
|
|
88
|
+
*/
|
|
89
|
+
interface AnsiStreamUpdate {
|
|
90
|
+
replaced?: {
|
|
91
|
+
from: number;
|
|
92
|
+
lines: AnsiLine[];
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
interface AnsiStream {
|
|
96
|
+
/** Feeds newly completed raw lines and the current unfinished line. */
|
|
97
|
+
push(lines: readonly string[], partial?: string): AnsiStreamUpdate;
|
|
98
|
+
/**
|
|
99
|
+
* Ends the stream. Renders the unfinished line without adding a newline;
|
|
100
|
+
* pass `partial` to replace the one given to the last `push`. Pushes after
|
|
101
|
+
* this are ignored until `reset()`.
|
|
102
|
+
*/
|
|
103
|
+
finish(partial?: string): AnsiStreamUpdate;
|
|
104
|
+
reset(): void;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Renders a stream the way `parseAnsi` renders the whole text, line by line.
|
|
108
|
+
* It keeps a small screen tail so cursor-up redraws reach rows already shown,
|
|
109
|
+
* and says which rows changed. Older rows are frozen and forgotten.
|
|
110
|
+
*/
|
|
111
|
+
declare function createAnsiStream(options?: AnsiStreamOptions): AnsiStream;
|
|
112
|
+
|
|
113
|
+
interface TextSegment {
|
|
114
|
+
text: string;
|
|
115
|
+
match: boolean;
|
|
116
|
+
}
|
|
117
|
+
type FailureTool = 'vitest' | 'nx' | 'tsc' | 'pnpm' | 'npm' | 'docker' | 'generic';
|
|
118
|
+
interface FailurePattern {
|
|
119
|
+
tool: FailureTool;
|
|
120
|
+
kind: string;
|
|
121
|
+
pattern: RegExp;
|
|
122
|
+
}
|
|
123
|
+
interface Failure {
|
|
124
|
+
index: number;
|
|
125
|
+
tool: FailureTool;
|
|
126
|
+
kind: string;
|
|
127
|
+
}
|
|
128
|
+
declare function filterLines(lines: readonly string[], query: string): number[];
|
|
129
|
+
declare function splitByMatch(line: string, query: string): TextSegment[];
|
|
130
|
+
declare const FAILURE_PATTERNS: readonly FailurePattern[];
|
|
131
|
+
declare function findFailures(lines: readonly string[], patterns?: readonly FailurePattern[]): Failure[];
|
|
132
|
+
declare function firstFailureIndex(lines: readonly string[], patterns?: readonly FailurePattern[]): number;
|
|
133
|
+
declare const NOISE_PATTERNS: readonly RegExp[];
|
|
134
|
+
declare function isNoise(line: string, patterns?: readonly RegExp[]): boolean;
|
|
135
|
+
declare function tailMeaningful(lines: readonly string[], n: number, patterns?: readonly RegExp[]): string[];
|
|
136
|
+
|
|
137
|
+
interface ScrollMetrics {
|
|
138
|
+
scrollTop: number;
|
|
139
|
+
scrollHeight: number;
|
|
140
|
+
clientHeight: number;
|
|
141
|
+
}
|
|
142
|
+
declare const DEFAULT_TAIL_THRESHOLD = 24;
|
|
143
|
+
declare function distanceFromEnd({ scrollTop, scrollHeight, clientHeight }: ScrollMetrics): number;
|
|
144
|
+
/** Within `threshold` px of the end; negative distances (iOS rubber-band past the end) count. */
|
|
145
|
+
declare function isNearEnd(metrics: ScrollMetrics, threshold?: number): boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Whether the view should keep following after a scroll event. A scroll the hook made itself
|
|
148
|
+
* never changes the answer; a user scroll follows only while it ends near the end.
|
|
149
|
+
*/
|
|
150
|
+
declare function shouldStick(prevAtBottom: boolean, metrics: ScrollMetrics, userInitiated: boolean, threshold?: number): boolean;
|
|
151
|
+
type ScrollEventKind = 'scroll' | 'wheel' | 'touch' | 'gutter';
|
|
152
|
+
interface ScrollEventInfo {
|
|
153
|
+
kind: ScrollEventKind;
|
|
154
|
+
/** wheel: `deltaY`. touch: how far the finger moved down since touchstart. Unused otherwise. */
|
|
155
|
+
delta?: number;
|
|
156
|
+
/** Where the hook last scrolled to, or null when it hasn't since the user last took over. */
|
|
157
|
+
lastTarget: number | null;
|
|
158
|
+
scrollTop: number;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Whether an event is the user reading upward, whichever frame it lands in. Wheel-up, a finger
|
|
162
|
+
* dragging down and a press on the scrollbar are intent; a scroll event counts only when it sits
|
|
163
|
+
* below where the hook last scrolled to, because the hook only ever scrolls down.
|
|
164
|
+
*/
|
|
165
|
+
declare function isUserScrollUp({ kind, delta, lastTarget, scrollTop }: ScrollEventInfo, threshold?: number): boolean;
|
|
166
|
+
/** Items to add to the unread count after the list grew while the user is reading above the end. */
|
|
167
|
+
declare function unreadDelta(prevCount: number, nextCount: number, attached: boolean): number;
|
|
168
|
+
|
|
169
|
+
interface UseFollowTailOptions {
|
|
170
|
+
scrollRef: RefObject<HTMLElement | null>;
|
|
171
|
+
itemCount: number;
|
|
172
|
+
/** Scroll to the last item. A virtualizer passes `() => virtualizer.scrollToIndex(count - 1, { align: 'end' })`. */
|
|
173
|
+
scrollToEnd?: () => void;
|
|
174
|
+
/** Snap back to the bottom whenever this changes (a project switch). */
|
|
175
|
+
resetKey?: unknown;
|
|
176
|
+
/** Distance from the end that still counts as the bottom. Default 24. */
|
|
177
|
+
threshold?: number;
|
|
178
|
+
}
|
|
179
|
+
interface UseFollowTailResult {
|
|
180
|
+
atBottom: boolean;
|
|
181
|
+
unread: number;
|
|
182
|
+
jumpToBottom: () => void;
|
|
183
|
+
}
|
|
184
|
+
declare function useFollowTail({ scrollRef, itemCount, scrollToEnd, resetKey, threshold, }: UseFollowTailOptions): UseFollowTailResult;
|
|
185
|
+
|
|
186
|
+
export { type AnsiColor, type AnsiLine, type AnsiSegment, type AnsiStream, type AnsiStreamOptions, type AnsiStreamUpdate, type AnsiStyle, DEFAULT_TAIL_THRESHOLD, FAILURE_PATTERNS, type Failure, type FailurePattern, type FailureTool, type LineBuffer, type LineBufferOptions, type LineBufferUpdate, NOISE_PATTERNS, type ParseAnsiOptions, type ScrollEventInfo, type ScrollEventKind, type ScrollMetrics, type StreamCursor, type TextSegment, type UseFollowTailOptions, type UseFollowTailResult, createAnsiParser, createAnsiStream, createLineBuffer, distanceFromEnd, filterLines, findFailures, firstFailureIndex, isNearEnd, isNoise, isUserScrollUp, parseAnsi, shouldStick, splitByMatch, stripAnsi, tailMeaningful, unreadDelta, useFollowTail };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
DEFAULT_TAIL_THRESHOLD,
|
|
4
|
+
FAILURE_PATTERNS,
|
|
5
|
+
NOISE_PATTERNS,
|
|
6
|
+
createAnsiParser,
|
|
7
|
+
createAnsiStream,
|
|
8
|
+
createLineBuffer,
|
|
9
|
+
distanceFromEnd,
|
|
10
|
+
filterLines,
|
|
11
|
+
findFailures,
|
|
12
|
+
firstFailureIndex,
|
|
13
|
+
isNearEnd,
|
|
14
|
+
isNoise,
|
|
15
|
+
isUserScrollUp,
|
|
16
|
+
parseAnsi,
|
|
17
|
+
shouldStick,
|
|
18
|
+
splitByMatch,
|
|
19
|
+
stripAnsi,
|
|
20
|
+
tailMeaningful,
|
|
21
|
+
unreadDelta,
|
|
22
|
+
useFollowTail
|
|
23
|
+
} from "./chunk-TE2FRIPF.js";
|
|
24
|
+
export {
|
|
25
|
+
DEFAULT_TAIL_THRESHOLD,
|
|
26
|
+
FAILURE_PATTERNS,
|
|
27
|
+
NOISE_PATTERNS,
|
|
28
|
+
createAnsiParser,
|
|
29
|
+
createAnsiStream,
|
|
30
|
+
createLineBuffer,
|
|
31
|
+
distanceFromEnd,
|
|
32
|
+
filterLines,
|
|
33
|
+
findFailures,
|
|
34
|
+
firstFailureIndex,
|
|
35
|
+
isNearEnd,
|
|
36
|
+
isNoise,
|
|
37
|
+
isUserScrollUp,
|
|
38
|
+
parseAnsi,
|
|
39
|
+
shouldStick,
|
|
40
|
+
splitByMatch,
|
|
41
|
+
stripAnsi,
|
|
42
|
+
tailMeaningful,
|
|
43
|
+
unreadDelta,
|
|
44
|
+
useFollowTail
|
|
45
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@develemit/web-hooks",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Shared React behavior hooks for develemit web apps: drawer swipe, focus trap, escape key and clipboard.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Emit Dutcher",
|
|
@@ -109,6 +109,11 @@
|
|
|
109
109
|
"types": "./dist/push.d.ts",
|
|
110
110
|
"import": "./dist/push.js",
|
|
111
111
|
"require": "./dist/push.cjs"
|
|
112
|
+
},
|
|
113
|
+
"./terminal-output": {
|
|
114
|
+
"types": "./dist/terminal-output.d.ts",
|
|
115
|
+
"import": "./dist/terminal-output.js",
|
|
116
|
+
"require": "./dist/terminal-output.cjs"
|
|
112
117
|
}
|
|
113
118
|
},
|
|
114
119
|
"main": "./dist/index.cjs",
|
|
@@ -128,6 +133,7 @@
|
|
|
128
133
|
"devDependencies": {
|
|
129
134
|
"@eslint/js": "^9.0.0",
|
|
130
135
|
"@testing-library/react": "^16.0.0",
|
|
136
|
+
"@types/node": "^20.19.43",
|
|
131
137
|
"@types/react": "^19.0.0",
|
|
132
138
|
"@types/react-18": "npm:@types/react@^18.3.31",
|
|
133
139
|
"@types/react-dom": "^19.0.0",
|