@orkestrel/terminal 0.0.13 → 0.0.15
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 +11 -16
- package/dist/src/core/index.cjs +458 -281
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +728 -369
- package/dist/src/core/index.d.ts +728 -369
- package/dist/src/core/index.js +443 -264
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +268 -258
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +217 -201
- package/dist/src/server/index.d.ts +217 -201
- package/dist/src/server/index.js +257 -242
- package/dist/src/server/index.js.map +1 -1
- package/package.json +18 -20
|
@@ -1,30 +1,32 @@
|
|
|
1
|
-
import { CheckboxField } from '@orkestrel/form';
|
|
2
|
-
import { ConfirmField } from '@orkestrel/form';
|
|
3
|
-
import { DriverInterface } from '@orkestrel/database';
|
|
4
|
-
import { EditorField } from '@orkestrel/form';
|
|
5
|
-
import { EmitterErrorHandler } from '@orkestrel/emitter';
|
|
6
|
-
import { EmitterHooks } from '@orkestrel/emitter';
|
|
7
|
-
import { EmitterInterface } from '@orkestrel/emitter';
|
|
8
|
-
import { FieldChoice } from '@orkestrel/form';
|
|
9
|
-
import { FieldError } from '@orkestrel/form';
|
|
10
|
-
import { FormInterface } from '@orkestrel/form';
|
|
11
|
-
import { FormSchema } from '@orkestrel/form';
|
|
12
|
-
import { FormValues } from '@orkestrel/form';
|
|
13
|
-
import { Guard } from '@orkestrel/contract';
|
|
14
|
-
import { JSONRecord } from '@orkestrel/contract';
|
|
15
|
-
import { PasswordField } from '@orkestrel/form';
|
|
16
|
-
import { Result } from '@orkestrel/contract';
|
|
17
|
-
import { SelectField } from '@orkestrel/form';
|
|
18
|
-
import { Style } from '@orkestrel/console';
|
|
19
|
-
import { StylerInterface } from '@orkestrel/console';
|
|
20
|
-
import { TableInterface } from '@orkestrel/database';
|
|
21
|
-
import { TextField } from '@orkestrel/form';
|
|
22
|
-
|
|
23
|
-
/**
|
|
1
|
+
import type { CheckboxField } from '@orkestrel/form';
|
|
2
|
+
import type { ConfirmField } from '@orkestrel/form';
|
|
3
|
+
import type { DriverInterface } from '@orkestrel/database';
|
|
4
|
+
import type { EditorField } from '@orkestrel/form';
|
|
5
|
+
import type { EmitterErrorHandler } from '@orkestrel/emitter';
|
|
6
|
+
import type { EmitterHooks } from '@orkestrel/emitter';
|
|
7
|
+
import type { EmitterInterface } from '@orkestrel/emitter';
|
|
8
|
+
import type { FieldChoice } from '@orkestrel/form';
|
|
9
|
+
import type { FieldError } from '@orkestrel/form';
|
|
10
|
+
import type { FormInterface } from '@orkestrel/form';
|
|
11
|
+
import type { FormSchema } from '@orkestrel/form';
|
|
12
|
+
import type { FormValues } from '@orkestrel/form';
|
|
13
|
+
import type { Guard } from '@orkestrel/contract';
|
|
14
|
+
import type { JSONRecord } from '@orkestrel/contract';
|
|
15
|
+
import type { PasswordField } from '@orkestrel/form';
|
|
16
|
+
import type { Result } from '@orkestrel/contract';
|
|
17
|
+
import type { SelectField } from '@orkestrel/form';
|
|
18
|
+
import type { Style } from '@orkestrel/console';
|
|
19
|
+
import type { StylerInterface } from '@orkestrel/console';
|
|
20
|
+
import type { TableInterface } from '@orkestrel/database';
|
|
21
|
+
import type { TextField } from '@orkestrel/form';
|
|
22
|
+
|
|
23
|
+
/** Names the `Accept` header value that opens the broker's SSE stream — `text/event-stream`. */
|
|
24
24
|
export declare const ACCEPT_EVENT_STREAM = "text/event-stream";
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
27
|
+
* Explains why {@link PromptInterface.answer} refused — `unknown` for an id no form is parked
|
|
28
|
+
* under, `rejected` for values the authoritative form itself refused, carrying the `FieldError`
|
|
29
|
+
* list it reported. Names its axis with `reason`.
|
|
28
30
|
*
|
|
29
31
|
* @remarks
|
|
30
32
|
* - `unknown` — no form is parked under that id, or the one that was has already settled.
|
|
@@ -41,42 +43,55 @@ export declare type AnswerError = {
|
|
|
41
43
|
readonly errors: readonly FieldError[];
|
|
42
44
|
};
|
|
43
45
|
|
|
44
|
-
/**
|
|
46
|
+
/** Names the backspace byte (BS, U+0008) — Ctrl+H / some terminals' Backspace. */
|
|
45
47
|
export declare const BACKSPACE: string;
|
|
46
48
|
|
|
47
49
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
50
|
+
* Represents the immutable state a checkbox field's reducer carries — the select state plus the ticked set.
|
|
51
|
+
*
|
|
52
|
+
* @remarks
|
|
53
|
+
* - `message` — the sanitized label the header renders.
|
|
54
|
+
* - `choices` — the choices the list offers, in declared order.
|
|
55
|
+
* - `styler` / `theme` — the console styler and the resolved {@link PromptTheme}.
|
|
56
|
+
* - `focused` — the index the cursor sits on.
|
|
57
|
+
* - `checked` — the ticked indices, in the order they were ticked; the reducer sorts them into
|
|
58
|
+
* choice order when it submits.
|
|
59
|
+
*/
|
|
60
|
+
export declare interface CheckboxState {
|
|
61
|
+
readonly message: string;
|
|
62
|
+
readonly choices: readonly FieldChoice[];
|
|
63
|
+
readonly styler: StylerInterface;
|
|
64
|
+
readonly theme: PromptTheme;
|
|
65
|
+
readonly focused: number;
|
|
66
|
+
readonly checked: readonly number[];
|
|
67
|
+
}
|
|
64
68
|
|
|
65
69
|
/**
|
|
66
|
-
*
|
|
67
|
-
|
|
68
|
-
|
|
70
|
+
* Represents the immutable state a confirm field's reducer carries. It holds no typed value, because the
|
|
71
|
+
* answer is the key itself.
|
|
72
|
+
*
|
|
73
|
+
* @remarks
|
|
74
|
+
* - `message` — the sanitized label the header renders.
|
|
75
|
+
* - `default` — the answer a bare return submits, and the letter the view capitalizes.
|
|
76
|
+
* - `styler` / `theme` — the console styler and the resolved {@link PromptTheme}.
|
|
77
|
+
*/
|
|
78
|
+
export declare interface ConfirmState {
|
|
79
|
+
readonly message: string;
|
|
80
|
+
readonly default: boolean;
|
|
81
|
+
readonly styler: StylerInterface;
|
|
82
|
+
readonly theme: PromptTheme;
|
|
83
|
+
}
|
|
69
84
|
|
|
70
85
|
/**
|
|
71
|
-
*
|
|
72
|
-
* consults for the one-byte keys and the two-byte CRLF
|
|
73
|
-
* canonical `name` and whether it is a `ctrl` combination. The
|
|
74
|
-
* frozen.
|
|
86
|
+
* Holds the control byte (or CRLF pair) to key descriptor table
|
|
87
|
+
* {@link import('./helpers.js').parseKey} consults for the one-byte keys and the two-byte CRLF
|
|
88
|
+
* Enter chunk. Each entry carries the canonical `name` and whether it is a `ctrl` combination. The
|
|
89
|
+
* source of truth for that decode; frozen.
|
|
75
90
|
*
|
|
76
91
|
* @remarks
|
|
77
92
|
* `return` / `newline` / `return + newline` all map to `return` (one canonical Enter name) — a
|
|
78
93
|
* terminal or a paste can deliver Enter as `\r`, `\n`, or the `\r\n` pair in one chunk;
|
|
79
|
-
* `delete` / `backspace` both map to `backspace` (the
|
|
94
|
+
* `delete` / `backspace` both map to `backspace` (the Backspace bytes); the Ctrl combos
|
|
80
95
|
* (`c` / `d` / `u` / `a` / `e`) carry `ctrl: true` so a reducer can match
|
|
81
96
|
* `key.ctrl && key.name === 'c'`. `escape` / `tab` / `space` are plain named keys.
|
|
82
97
|
*/
|
|
@@ -86,48 +101,39 @@ export declare const CONTROL_NAMES: Readonly<Record<string, {
|
|
|
86
101
|
}>>;
|
|
87
102
|
|
|
88
103
|
/**
|
|
89
|
-
*
|
|
104
|
+
* Builds the initial checkbox-field reducer state — the offered choices, with every value in the
|
|
105
|
+
* field's `default` list pre-checked.
|
|
90
106
|
*
|
|
91
107
|
* @param field - The checkbox field to render
|
|
92
108
|
* @param styler - The styler used to render the view
|
|
93
109
|
* @param theme - The optional terminal theme
|
|
94
110
|
* @returns The initial immutable key state
|
|
95
111
|
*/
|
|
96
|
-
export declare function createCheckboxState(field: CheckboxField, styler?: StylerInterface, theme?: PromptThemeOptions):
|
|
97
|
-
message: string;
|
|
98
|
-
choices: FieldChoice[];
|
|
99
|
-
styler: StylerInterface;
|
|
100
|
-
theme: PromptTheme;
|
|
101
|
-
focused: number;
|
|
102
|
-
checked: readonly number[];
|
|
103
|
-
};
|
|
112
|
+
export declare function createCheckboxState(field: CheckboxField, styler?: StylerInterface, theme?: PromptThemeOptions): CheckboxState;
|
|
104
113
|
|
|
105
114
|
/**
|
|
106
|
-
*
|
|
115
|
+
* Builds the initial confirm-field reducer state — the sanitized label and the declared default
|
|
116
|
+
* answer.
|
|
107
117
|
*
|
|
108
118
|
* @param field - The confirm field to render
|
|
109
119
|
* @param styler - The styler used to render the view
|
|
110
120
|
* @param theme - The optional terminal theme
|
|
111
121
|
* @returns The initial immutable key state
|
|
112
122
|
*/
|
|
113
|
-
export declare function createConfirmState(field: ConfirmField, styler?: StylerInterface, theme?: PromptThemeOptions):
|
|
114
|
-
message: string;
|
|
115
|
-
default: boolean;
|
|
116
|
-
styler: StylerInterface;
|
|
117
|
-
theme: PromptTheme;
|
|
118
|
-
};
|
|
123
|
+
export declare function createConfirmState(field: ConfirmField, styler?: StylerInterface, theme?: PromptThemeOptions): ConfirmState;
|
|
119
124
|
|
|
120
125
|
/**
|
|
121
|
-
*
|
|
126
|
+
* Creates a {@link TerminalStoreInterface} backed by one table of the `databases` layer — the
|
|
122
127
|
* driver-pluggable twin of {@link createMemoryTerminalStore}, storing each endpoint's config
|
|
123
|
-
* snapshot as one opaque JSON column.
|
|
128
|
+
* snapshot as one opaque JSON column. The default driver is an in-memory `@orkestrel/database`
|
|
129
|
+
* driver.
|
|
124
130
|
*
|
|
125
131
|
* @param driver - The {@link DriverInterface} backing the table (default an in-memory driver)
|
|
126
132
|
* @returns A {@link TerminalStoreInterface}
|
|
127
133
|
*
|
|
128
134
|
* @example
|
|
129
135
|
* ```ts
|
|
130
|
-
* import { createDatabaseTerminalStore } from '@
|
|
136
|
+
* import { createDatabaseTerminalStore } from '@orkestrel/terminal'
|
|
131
137
|
*
|
|
132
138
|
* const store = createDatabaseTerminalStore() // in-memory by default
|
|
133
139
|
* ```
|
|
@@ -135,47 +141,36 @@ export declare function createConfirmState(field: ConfirmField, styler?: StylerI
|
|
|
135
141
|
export declare function createDatabaseTerminalStore(driver?: DriverInterface): TerminalStoreInterface;
|
|
136
142
|
|
|
137
143
|
/**
|
|
138
|
-
*
|
|
144
|
+
* Builds the initial editor-field reducer state — the committed lines empty, and the declared
|
|
145
|
+
* default held for a finish with nothing typed.
|
|
139
146
|
*
|
|
140
147
|
* @param field - The editor field to render
|
|
141
148
|
* @param styler - The styler used to render the view
|
|
142
149
|
* @param theme - The optional terminal theme
|
|
143
150
|
* @returns The initial immutable key state
|
|
144
151
|
*/
|
|
145
|
-
export declare function createEditorState(field: EditorField, styler?: StylerInterface, theme?: PromptThemeOptions):
|
|
146
|
-
message: string;
|
|
147
|
-
default: string;
|
|
148
|
-
styler: StylerInterface;
|
|
149
|
-
theme: PromptTheme;
|
|
150
|
-
lines: readonly string[];
|
|
151
|
-
current: string;
|
|
152
|
-
};
|
|
152
|
+
export declare function createEditorState(field: EditorField, styler?: StylerInterface, theme?: PromptThemeOptions): EditorState;
|
|
153
153
|
|
|
154
154
|
/**
|
|
155
|
-
*
|
|
155
|
+
* Builds the initial text-field reducer state — the sanitized label, the declared default, the
|
|
156
|
+
* styler, and the resolved theme.
|
|
156
157
|
*
|
|
157
158
|
* @param field - The text field to render
|
|
158
159
|
* @param styler - The styler used to render the view
|
|
159
160
|
* @param theme - The optional terminal theme
|
|
160
161
|
* @returns The initial immutable key state
|
|
161
162
|
*/
|
|
162
|
-
export declare function createInputState(field: TextField, styler?: StylerInterface, theme?: PromptThemeOptions):
|
|
163
|
-
message: string;
|
|
164
|
-
default: string;
|
|
165
|
-
styler: StylerInterface;
|
|
166
|
-
theme: PromptTheme;
|
|
167
|
-
value: string;
|
|
168
|
-
};
|
|
163
|
+
export declare function createInputState(field: TextField, styler?: StylerInterface, theme?: PromptThemeOptions): InputState;
|
|
169
164
|
|
|
170
165
|
/**
|
|
171
|
-
*
|
|
166
|
+
* Creates the in-memory {@link TerminalStoreInterface} — a process-lifetime `Map` of endpoint
|
|
172
167
|
* config snapshots, the default store backing a {@link TerminalManagerInterface}'s `open` / `save`.
|
|
173
168
|
*
|
|
174
169
|
* @returns A {@link TerminalStoreInterface}
|
|
175
170
|
*
|
|
176
171
|
* @example
|
|
177
172
|
* ```ts
|
|
178
|
-
* import { createMemoryTerminalStore } from '@
|
|
173
|
+
* import { createMemoryTerminalStore } from '@orkestrel/terminal'
|
|
179
174
|
*
|
|
180
175
|
* const store = createMemoryTerminalStore()
|
|
181
176
|
* ```
|
|
@@ -183,23 +178,18 @@ export declare function createInputState(field: TextField, styler?: StylerInterf
|
|
|
183
178
|
export declare function createMemoryTerminalStore(): TerminalStoreInterface;
|
|
184
179
|
|
|
185
180
|
/**
|
|
186
|
-
*
|
|
181
|
+
* Builds the initial password-field reducer state — the text-field state, plus the mask glyph each
|
|
182
|
+
* typed character renders as.
|
|
187
183
|
*
|
|
188
184
|
* @param field - The password field to render
|
|
189
185
|
* @param styler - The styler used to render the view
|
|
190
186
|
* @param theme - The optional terminal theme
|
|
191
187
|
* @returns The initial immutable key state
|
|
192
188
|
*/
|
|
193
|
-
export declare function createPasswordState(field: PasswordField, styler?: StylerInterface, theme?: PromptThemeOptions):
|
|
194
|
-
message: string;
|
|
195
|
-
mask: string;
|
|
196
|
-
styler: StylerInterface;
|
|
197
|
-
theme: PromptTheme;
|
|
198
|
-
value: string;
|
|
199
|
-
};
|
|
189
|
+
export declare function createPasswordState(field: PasswordField, styler?: StylerInterface, theme?: PromptThemeOptions): PasswordState;
|
|
200
190
|
|
|
201
191
|
/**
|
|
202
|
-
*
|
|
192
|
+
* Creates the headless {@link PromptInterface} broker. It parks live forms and applies remote
|
|
203
193
|
* answers to the authoritative instances.
|
|
204
194
|
*
|
|
205
195
|
* @param options - See {@link PromptOptions}
|
|
@@ -212,7 +202,7 @@ export declare function createPasswordState(field: PasswordField, styler?: Style
|
|
|
212
202
|
*
|
|
213
203
|
* @example
|
|
214
204
|
* ```ts
|
|
215
|
-
* import { createPrompt } from '@
|
|
205
|
+
* import { createPrompt } from '@orkestrel/terminal'
|
|
216
206
|
* import { createForm } from '@orkestrel/form'
|
|
217
207
|
*
|
|
218
208
|
* const prompt = createPrompt()
|
|
@@ -224,9 +214,10 @@ export declare function createPasswordState(field: PasswordField, styler?: Style
|
|
|
224
214
|
export declare function createPrompt(options?: PromptOptions): PromptInterface;
|
|
225
215
|
|
|
226
216
|
/**
|
|
227
|
-
*
|
|
228
|
-
* endpoint, dispatches each received form to a local
|
|
229
|
-
* and POSTs the answer back. Universal — `fetch`
|
|
217
|
+
* Creates the SSE prompt {@link PromptClientInterface} bridge — it connects to a remote broker's
|
|
218
|
+
* SSE endpoint, dispatches each received form to a local
|
|
219
|
+
* {@link import('./types.js').TerminalInterface}, and POSTs the answer back. Universal — `fetch`
|
|
220
|
+
* and SSE are web standards.
|
|
230
221
|
*
|
|
231
222
|
* @param options - See {@link PromptClientOptions} (`url` + `terminal` required)
|
|
232
223
|
* @returns A {@link PromptClientInterface}
|
|
@@ -236,11 +227,11 @@ export declare function createPrompt(options?: PromptOptions): PromptInterface;
|
|
|
236
227
|
* ends; it reconnects with the `delay` backoff unless `reconnect` is `false` / the client was
|
|
237
228
|
* `destroy`ed. Inject `options.fetch` (a scripted `fetch`) and `options.timer` to drive it
|
|
238
229
|
* deterministically in tests — no real network.
|
|
239
|
-
* -
|
|
230
|
+
* - **Wire narrowing.** Every decoded prompt is guard-narrowed before dispatch (never an `as`).
|
|
240
231
|
*
|
|
241
232
|
* @example
|
|
242
233
|
* ```ts
|
|
243
|
-
* import { createPromptClient } from '@
|
|
234
|
+
* import { createPromptClient } from '@orkestrel/terminal'
|
|
244
235
|
*
|
|
245
236
|
* const client = createPromptClient({ url: 'http://host/prompts', terminal })
|
|
246
237
|
* await client.connect()
|
|
@@ -249,7 +240,7 @@ export declare function createPrompt(options?: PromptOptions): PromptInterface;
|
|
|
249
240
|
export declare function createPromptClient(options: PromptClientOptions): PromptClientInterface;
|
|
250
241
|
|
|
251
242
|
/**
|
|
252
|
-
*
|
|
243
|
+
* Builds a complete {@link PromptTheme} by merging a partial one over
|
|
253
244
|
* {@link DEFAULT_PROMPT_THEME}, leaf by leaf — each supplied icon replaces that glyph, each
|
|
254
245
|
* supplied role replaces that {@link Style}, and everything else keeps its default. Each supplied
|
|
255
246
|
* style is snapshotted through the console module's own
|
|
@@ -271,32 +262,27 @@ export declare function createPromptClient(options: PromptClientOptions): Prompt
|
|
|
271
262
|
export declare function createPromptTheme(options?: PromptThemeOptions): PromptTheme;
|
|
272
263
|
|
|
273
264
|
/**
|
|
274
|
-
*
|
|
265
|
+
* Builds the initial select-field reducer state — the offered choices, with the focus pre-placed on
|
|
266
|
+
* the declared default.
|
|
275
267
|
*
|
|
276
268
|
* @param field - The select field to render
|
|
277
269
|
* @param styler - The styler used to render the view
|
|
278
270
|
* @param theme - The optional terminal theme
|
|
279
271
|
* @returns The initial immutable key state
|
|
280
272
|
*/
|
|
281
|
-
export declare function createSelectState(field: SelectField, styler?: StylerInterface, theme?: PromptThemeOptions):
|
|
282
|
-
message: string;
|
|
283
|
-
choices: FieldChoice[];
|
|
284
|
-
styler: StylerInterface;
|
|
285
|
-
theme: PromptTheme;
|
|
286
|
-
focused: number;
|
|
287
|
-
};
|
|
273
|
+
export declare function createSelectState(field: SelectField, styler?: StylerInterface, theme?: PromptThemeOptions): SelectState;
|
|
288
274
|
|
|
289
275
|
/**
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
*
|
|
276
|
+
* Creates the multi-endpoint {@link TerminalManager} — a named registry of {@link PromptInterface}
|
|
277
|
+
* brokers so several parties can `ask` forms of each other by name, with a transitive cycle check
|
|
278
|
+
* that refuses `DEADLOCK` across every in-flight ask.
|
|
293
279
|
*
|
|
294
280
|
* @param options - See {@link TerminalManagerOptions}
|
|
295
281
|
* @returns A {@link TerminalManager}
|
|
296
282
|
*
|
|
297
283
|
* @example
|
|
298
284
|
* ```ts
|
|
299
|
-
* import { createTerminalManager } from '@
|
|
285
|
+
* import { createTerminalManager } from '@orkestrel/terminal'
|
|
300
286
|
*
|
|
301
287
|
* const manager = createTerminalManager()
|
|
302
288
|
* manager.add('agent')
|
|
@@ -304,33 +290,34 @@ export declare function createSelectState(field: SelectField, styler?: StylerInt
|
|
|
304
290
|
*/
|
|
305
291
|
export declare function createTerminalManager(options?: TerminalManagerOptions): TerminalManagerInterface;
|
|
306
292
|
|
|
307
|
-
/** Ctrl+A (SOH, U+0001) — move to start of line. */
|
|
293
|
+
/** Names the Ctrl+A byte (SOH, U+0001) — move to start of line. */
|
|
308
294
|
export declare const CTRL_A: string;
|
|
309
295
|
|
|
310
|
-
/** Ctrl+C (ETX, U+0003) — interrupt / cancel. */
|
|
296
|
+
/** Names the Ctrl+C byte (ETX, U+0003) — interrupt / cancel. */
|
|
311
297
|
export declare const CTRL_C: string;
|
|
312
298
|
|
|
313
|
-
/** Ctrl+D (EOT, U+0004) — end-of-transmission / finish (the editor's commit key). */
|
|
299
|
+
/** Names the Ctrl+D byte (EOT, U+0004) — end-of-transmission / finish (the editor's commit key). */
|
|
314
300
|
export declare const CTRL_D: string;
|
|
315
301
|
|
|
316
|
-
/** Ctrl+E (ENQ, U+0005) — move to end of line. */
|
|
302
|
+
/** Names the Ctrl+E byte (ENQ, U+0005) — move to end of line. */
|
|
317
303
|
export declare const CTRL_E: string;
|
|
318
304
|
|
|
319
|
-
/** Ctrl+U (NAK, U+0015) — clear the current line. */
|
|
305
|
+
/** Names the Ctrl+U byte (NAK, U+0015) — clear the current line. */
|
|
320
306
|
export declare const CTRL_U: string;
|
|
321
307
|
|
|
322
308
|
/**
|
|
323
|
-
*
|
|
324
|
-
* durable
|
|
325
|
-
* `delete`) over a {@link TableInterface}, the driver-pluggable twin of the plain-`Map`
|
|
326
|
-
* {@link import('./MemoryTerminalStore.js').MemoryTerminalStore}.
|
|
309
|
+
* Implements a {@link TerminalStoreInterface} backed by one table of the `databases` layer — an
|
|
310
|
+
* endpoint's durable config state is a row, so persistence reduces to keyed point-access (`get` /
|
|
311
|
+
* `set` / `delete`) over a {@link TableInterface}, the driver-pluggable twin of the plain-`Map`
|
|
312
|
+
* {@link import('./MemoryTerminalStore.js').MemoryTerminalStore}. A stored `snapshot` is narrowed
|
|
313
|
+
* with {@link import('../validators.js').isTerminalSnapshot} on read.
|
|
327
314
|
*
|
|
328
315
|
* @remarks
|
|
329
316
|
* The store is driver-agnostic: it holds a single {@link TableInterface} whose backend (memory,
|
|
330
317
|
* JSON, SQLite, IndexedDB) is chosen by whoever builds it (the factories), so a JSON / SQLite /
|
|
331
318
|
* IndexedDB backend swaps in WITHOUT touching the manager — the same seam as
|
|
332
319
|
* {@link import('./MemoryTerminalStore.js').MemoryTerminalStore}. The driver defaults to memory
|
|
333
|
-
* ({@link import('
|
|
320
|
+
* ({@link import('../factories.js').createDatabaseTerminalStore} passes `createMemoryDriver()`), so
|
|
334
321
|
* it ALSO works in memory out of the box; you opt into the durable plumbing by passing a JSON /
|
|
335
322
|
* SQLite / IndexedDB driver.
|
|
336
323
|
*
|
|
@@ -342,18 +329,19 @@ export declare const CTRL_U: string;
|
|
|
342
329
|
* - **`set(snapshot)` upserts under the snapshot's OWN `id`** (no separate id param) — it writes
|
|
343
330
|
* the row `{ id: snapshot.id, snapshot }`.
|
|
344
331
|
* - **`get(id)` resolves the stored snapshot for an id**, narrowing the opaque JSON column back to
|
|
345
|
-
* a {@link TerminalSnapshot} ({@link import('
|
|
346
|
-
*
|
|
332
|
+
* a {@link TerminalSnapshot} ({@link import('../validators.js').isTerminalSnapshot} — the total
|
|
333
|
+
* guard that narrows an untrusted storage read), or `undefined` if none is stored.
|
|
347
334
|
* - **`delete(id)` drops a snapshot by id**; an absent id is a no-op (no throw).
|
|
348
335
|
*
|
|
349
336
|
* There is NO idle-TTL / eviction — a persisted config lives until an explicit `delete`. The public
|
|
350
|
-
* surface is EXACTLY `get` / `set` / `delete` — no extra members
|
|
351
|
-
* {@link TerminalStoreInterface}
|
|
337
|
+
* surface is EXACTLY `get` / `set` / `delete` — no extra members, so the class and
|
|
338
|
+
* {@link TerminalStoreInterface} carry the same methods. Hydration stays a caller concern: `open` always restores an EMPTY
|
|
352
339
|
* broker — parked Promises are process-bound and never resurrected.
|
|
353
340
|
*
|
|
354
341
|
* @example
|
|
355
342
|
* ```ts
|
|
356
|
-
* import { createDatabaseTerminalStore
|
|
343
|
+
* import { createDatabaseTerminalStore } from '@orkestrel/terminal'
|
|
344
|
+
* import { createMemoryDriver } from '@orkestrel/database'
|
|
357
345
|
*
|
|
358
346
|
* const store = createDatabaseTerminalStore(createMemoryDriver()) // a durable driver swaps in here
|
|
359
347
|
* await store.set({ id: 'shell', timeout: 5000 }) // persist the config (one JSON column)
|
|
@@ -364,25 +352,42 @@ export declare const CTRL_U: string;
|
|
|
364
352
|
export declare class DatabaseTerminalStore implements TerminalStoreInterface {
|
|
365
353
|
#private;
|
|
366
354
|
/**
|
|
367
|
-
*
|
|
355
|
+
* Wraps a table as a terminal store.
|
|
368
356
|
*
|
|
369
357
|
* @param table - The {@link TableInterface} holding the snapshots — its row is the
|
|
370
358
|
* {@link TerminalSnapshotRow} `{ id; snapshot }` shape (the snapshot one opaque JSON column)
|
|
371
359
|
*/
|
|
372
360
|
constructor(table: TableInterface<TerminalSnapshotRow>);
|
|
373
|
-
/**
|
|
361
|
+
/**
|
|
362
|
+
* Resolves the persisted snapshot for `id`, narrowing the opaque JSON column back to a
|
|
363
|
+
* `TerminalSnapshot`.
|
|
364
|
+
*
|
|
365
|
+
* @param id - The endpoint name the row is keyed by
|
|
366
|
+
* @returns The stored snapshot, or `undefined` when none is held or the column is off-shape
|
|
367
|
+
*/
|
|
374
368
|
get(id: string): Promise<TerminalSnapshot | undefined>;
|
|
375
|
-
/**
|
|
369
|
+
/**
|
|
370
|
+
* Inserts or replaces under the snapshot's OWN `id` (no separate id param) — the row is
|
|
371
|
+
* `{ id, snapshot }`.
|
|
372
|
+
*
|
|
373
|
+
* @param snapshot - The config snapshot to persist, carrying its own `id`
|
|
374
|
+
* @returns A promise that settles once the row is written
|
|
375
|
+
*/
|
|
376
376
|
set(snapshot: TerminalSnapshot): Promise<void>;
|
|
377
|
-
/**
|
|
377
|
+
/**
|
|
378
|
+
* Drops a snapshot by id; an absent id is a no-op (no throw).
|
|
379
|
+
*
|
|
380
|
+
* @param id - The endpoint name to drop
|
|
381
|
+
* @returns A promise that settles once the row is gone
|
|
382
|
+
*/
|
|
378
383
|
delete(id: string): Promise<void>;
|
|
379
384
|
}
|
|
380
385
|
|
|
381
|
-
/**
|
|
386
|
+
/** Names the default mask glyph {@link import('./helpers.js').createPasswordState} uses — `*`. */
|
|
382
387
|
export declare const DEFAULT_MASK = "*";
|
|
383
388
|
|
|
384
389
|
/**
|
|
385
|
-
*
|
|
390
|
+
* Holds the {@link import('./types.js').PromptTheme} every prompt renders with unless its options supply
|
|
386
391
|
* another — the glyph set assembled from {@link PROMPT_ICONS} plus the console
|
|
387
392
|
* {@link import('@orkestrel/console').STATUS_ICONS} `success` / `error` marks, and the console
|
|
388
393
|
* {@link import('@orkestrel/console').Style} each role is painted with. Deeply frozen through the
|
|
@@ -398,60 +403,70 @@ export declare const DEFAULT_MASK = "*";
|
|
|
398
403
|
*/
|
|
399
404
|
export declare const DEFAULT_PROMPT_THEME: PromptTheme;
|
|
400
405
|
|
|
401
|
-
/**
|
|
406
|
+
/** Holds how long (ms) the {@link import('./types.js').PromptInterface} broker parks an unanswered form before it expires — 5 minutes. */
|
|
402
407
|
export declare const DEFAULT_PROMPT_TIMEOUT_MS = 300000;
|
|
403
408
|
|
|
404
|
-
/**
|
|
409
|
+
/** Holds how long (ms) the {@link import('./types.js').PromptClientInterface} waits before each reconnect attempt — 2 seconds. */
|
|
405
410
|
export declare const DEFAULT_RECONNECT_DELAY_MS = 2000;
|
|
406
411
|
|
|
407
412
|
/**
|
|
408
|
-
*
|
|
409
|
-
* wrapper that arms `callback` after `ms` and returns a {@link
|
|
413
|
+
* Implements the default {@link import('./types.js').TimerHandler} — a thin host `setTimeout` / `clearTimeout`
|
|
414
|
+
* wrapper that arms `callback` after `ms` and returns a {@link TimerCancelFunction}. The deadline seam
|
|
410
415
|
* behind both the {@link import('./Prompt.js').Prompt} broker (its expiry) and the
|
|
411
416
|
* {@link import('./PromptClient.js').PromptClient} (its reconnect backoff); a test injects a
|
|
412
417
|
* deterministic timer instead, so neither entity touches real time.
|
|
418
|
+
*
|
|
419
|
+
* @param callback - The deadline callback to arm
|
|
420
|
+
* @param ms - How long to wait before firing it, in milliseconds
|
|
421
|
+
* @returns The {@link TimerCancelFunction} that clears the armed deadline
|
|
413
422
|
*/
|
|
414
|
-
export declare function defaultTimer(callback: () => void, ms: number):
|
|
423
|
+
export declare function defaultTimer(callback: () => void, ms: number): TimerCancelFunction;
|
|
415
424
|
|
|
416
|
-
/**
|
|
425
|
+
/** Names the delete byte (DEL, U+007F) — the usual Backspace byte on a Unix TTY. */
|
|
417
426
|
export declare const DELETE: string;
|
|
418
427
|
|
|
419
428
|
/**
|
|
420
|
-
*
|
|
421
|
-
* password
|
|
422
|
-
* `space` appends a space; ctrl-u clears the line
|
|
423
|
-
*
|
|
429
|
+
* Applies a single line-editing {@link KeyEvent} to a text buffer — the editing shared by input,
|
|
430
|
+
* password, and editor. A printable key appends its character; `backspace` drops the last
|
|
431
|
+
* character; `space` appends a space; ctrl-u clears the line; a key that edits nothing returns
|
|
432
|
+
* `undefined`.
|
|
433
|
+
*
|
|
434
|
+
* @param value - The buffer the field holds so far
|
|
435
|
+
* @param key - The decoded keypress to apply
|
|
436
|
+
* @returns The new buffer, or `undefined` when the key does not edit the line, so the caller can
|
|
437
|
+
* leave the state untouched
|
|
424
438
|
*/
|
|
425
439
|
export declare function editLine(value: string, key: KeyEvent): string | undefined;
|
|
426
440
|
|
|
427
441
|
/**
|
|
428
|
-
*
|
|
429
|
-
*
|
|
430
|
-
*
|
|
431
|
-
*
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
*
|
|
437
|
-
*/
|
|
438
|
-
export declare
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
442
|
+
* Represents the immutable state an editor field's reducer carries — the committed lines and the line still
|
|
443
|
+
* being typed, kept apart so a return commits one without ending the field.
|
|
444
|
+
*
|
|
445
|
+
* @remarks
|
|
446
|
+
* - `message` — the sanitized label the header renders.
|
|
447
|
+
* - `default` — the text an empty finish falls back to.
|
|
448
|
+
* - `styler` / `theme` — the console styler and the resolved {@link PromptTheme}.
|
|
449
|
+
* - `lines` — the lines already committed with a return.
|
|
450
|
+
* - `current` — the line in progress.
|
|
451
|
+
*/
|
|
452
|
+
export declare interface EditorState {
|
|
453
|
+
readonly message: string;
|
|
454
|
+
readonly default: string;
|
|
455
|
+
readonly styler: StylerInterface;
|
|
456
|
+
readonly theme: PromptTheme;
|
|
457
|
+
readonly lines: readonly string[];
|
|
458
|
+
readonly current: string;
|
|
459
|
+
}
|
|
445
460
|
|
|
446
461
|
/**
|
|
447
|
-
*
|
|
462
|
+
* Represents a minimal `fetch` — the subset of the global `fetch` a {@link PromptClientInterface} uses: open
|
|
448
463
|
* the SSE stream, POST an answer. Injected so a test drives the client with a scripted `Response`
|
|
449
464
|
* instead of a real network.
|
|
450
465
|
*/
|
|
451
466
|
export declare type FetchHandler = (input: string, init?: FetchInit) => Promise<Response>;
|
|
452
467
|
|
|
453
468
|
/**
|
|
454
|
-
*
|
|
469
|
+
* Represents the request init a {@link PromptClientInterface} passes to its {@link FetchHandler} — the
|
|
455
470
|
* `RequestInit` fields it actually sets.
|
|
456
471
|
*/
|
|
457
472
|
export declare interface FetchInit {
|
|
@@ -461,44 +476,58 @@ export declare interface FetchInit {
|
|
|
461
476
|
readonly signal?: AbortSignal;
|
|
462
477
|
}
|
|
463
478
|
|
|
464
|
-
/** The default {@link import('./types.js').FetchHandler} — the global `fetch`, adapted to the minimal injected shape the {@link import('./PromptClient.js').PromptClient} uses. */
|
|
465
|
-
export declare function globalFetch(input: string, init?: FetchInit): Promise<Response>;
|
|
466
|
-
|
|
467
|
-
/** The auth-token request header the {@link import('./types.js').PromptClientInterface} sends. */
|
|
468
|
-
export declare const HEADER_TOKEN = "x-orkestrel-token";
|
|
469
|
-
|
|
470
479
|
/**
|
|
471
|
-
*
|
|
472
|
-
*
|
|
480
|
+
* Implements the default {@link import('./types.js').FetchHandler} — the global `fetch`, adapted to
|
|
481
|
+
* the minimal injected shape the {@link import('./PromptClient.js').PromptClient} uses.
|
|
473
482
|
*
|
|
474
|
-
* @param
|
|
475
|
-
* @param
|
|
476
|
-
* @
|
|
477
|
-
* @param hint - The optional key hint to append
|
|
478
|
-
* @returns The rendered header with the optional hint
|
|
483
|
+
* @param input - The request URL
|
|
484
|
+
* @param init - The request init the client sets — method, headers, body, and abort signal
|
|
485
|
+
* @returns The host `fetch` promise for that request
|
|
479
486
|
*/
|
|
480
|
-
export declare function
|
|
487
|
+
export declare function globalFetch(input: string, init?: FetchInit): Promise<Response>;
|
|
481
488
|
|
|
482
489
|
/**
|
|
483
|
-
*
|
|
484
|
-
*
|
|
485
|
-
* cancels; return produces the candidate value, with an empty line falling back to the default.
|
|
490
|
+
* Names the auth-token request header the {@link import('./types.js').PromptClientInterface} sends
|
|
491
|
+
* when a `token` is configured — `x-orkestrel-token`.
|
|
486
492
|
*/
|
|
487
|
-
export declare
|
|
493
|
+
export declare const HEADER_TOKEN = "x-orkestrel-token";
|
|
488
494
|
|
|
489
|
-
/**
|
|
490
|
-
|
|
495
|
+
/**
|
|
496
|
+
* Represents the immutable state a text field's reducer carries — built by
|
|
497
|
+
* {@link import('./helpers.js').createInputState}, rendered by
|
|
498
|
+
* {@link import('./helpers.js').renderInputView}, and advanced by
|
|
499
|
+
* {@link import('./helpers.js').reduceInput}.
|
|
500
|
+
*
|
|
501
|
+
* @remarks
|
|
502
|
+
* - `message` — the sanitized label the header renders.
|
|
503
|
+
* - `default` — the declared default a bare return submits.
|
|
504
|
+
* - `styler` — the console styler every role is painted through.
|
|
505
|
+
* - `theme` — the resolved {@link PromptTheme}.
|
|
506
|
+
* - `value` — the characters typed so far.
|
|
507
|
+
*/
|
|
508
|
+
export declare interface InputState {
|
|
509
|
+
readonly message: string;
|
|
510
|
+
readonly default: string;
|
|
511
|
+
readonly styler: StylerInterface;
|
|
512
|
+
readonly theme: PromptTheme;
|
|
513
|
+
readonly value: string;
|
|
514
|
+
}
|
|
491
515
|
|
|
492
516
|
/**
|
|
493
|
-
*
|
|
517
|
+
* Checks whether a caught value is an `AbortError` — the {@link import('./PromptClient.js').PromptClient}
|
|
494
518
|
* distinguishes a deliberate `disconnect` / teardown (an aborted `fetch`) from a real fault, so it
|
|
495
519
|
* exits its connect loop quietly instead of emitting `error` / reconnecting.
|
|
520
|
+
*
|
|
521
|
+
* @param error - The caught value to test
|
|
522
|
+
* @returns True if the value is a host `Error` or `DOMException` named `AbortError`; false otherwise
|
|
496
523
|
*/
|
|
497
524
|
export declare function isAbortError(error: unknown): boolean;
|
|
498
525
|
|
|
499
526
|
/**
|
|
500
|
-
*
|
|
501
|
-
* loopback address. Pure string parsing (no `URL` global), so it stays total on malformed input
|
|
527
|
+
* Checks whether `url` is an insecure remote endpoint — a plain `http://` URL whose host is not a
|
|
528
|
+
* loopback address. Pure string parsing (no `URL` global), so it stays total on malformed input;
|
|
529
|
+
* the {@link import('./PromptClient.js').PromptClient} warns once when a `token` would cross such
|
|
530
|
+
* an endpoint in cleartext.
|
|
502
531
|
*
|
|
503
532
|
* @remarks
|
|
504
533
|
* A loopback host (`localhost`, `127.0.0.1`, `[::1]`) over `http://` is exempt (local
|
|
@@ -506,7 +535,7 @@ export declare function isAbortError(error: unknown): boolean;
|
|
|
506
535
|
* An `https://` URL (or any non-`http://` scheme) is never flagged.
|
|
507
536
|
*
|
|
508
537
|
* @param url - The candidate endpoint URL
|
|
509
|
-
* @returns
|
|
538
|
+
* @returns True if `url` is a non-loopback `http://` endpoint; false otherwise
|
|
510
539
|
*
|
|
511
540
|
* @example
|
|
512
541
|
* ```ts
|
|
@@ -518,28 +547,40 @@ export declare function isAbortError(error: unknown): boolean;
|
|
|
518
547
|
export declare function isInsecureRemote(url: string): boolean;
|
|
519
548
|
|
|
520
549
|
/**
|
|
521
|
-
*
|
|
550
|
+
* Narrows an unknown wire value to a {@link PendingForm} envelope — the envelope alone, because the
|
|
551
|
+
* form package's `parseForm` owns the schema payload.
|
|
522
552
|
*
|
|
523
553
|
* @remarks
|
|
524
554
|
* This guard checks the transport record and proves only that `schema` is a record. The Form
|
|
525
555
|
* package's `parseForm` owns the schema payload and its semantic audit.
|
|
526
556
|
*
|
|
527
557
|
* @param value - The decoded wire value to inspect
|
|
528
|
-
* @returns
|
|
558
|
+
* @returns True if the value is a complete pending-form envelope; false otherwise
|
|
529
559
|
*/
|
|
530
560
|
export declare function isPendingForm(value: unknown): value is PendingForm;
|
|
531
561
|
|
|
532
|
-
/**
|
|
562
|
+
/**
|
|
563
|
+
* Narrows an unknown value to a {@link PendingFormStatus}.
|
|
564
|
+
*
|
|
565
|
+
* @param value - The candidate ticket status
|
|
566
|
+
* @returns True if the value is one of the declared ticket statuses; false otherwise
|
|
567
|
+
*/
|
|
533
568
|
export declare const isPendingFormStatus: Guard<PendingFormStatus>;
|
|
534
569
|
|
|
535
|
-
/**
|
|
570
|
+
/**
|
|
571
|
+
* Checks whether a single character is printable — the fallback test {@link parseKey} applies after
|
|
572
|
+
* the control bytes and the escape sequences, so the C0 controls and DEL are excluded.
|
|
573
|
+
*
|
|
574
|
+
* @param character - The single character to test
|
|
575
|
+
* @returns True if the character is at or above space and is not DEL; false otherwise
|
|
576
|
+
*/
|
|
536
577
|
export declare function isPrintable(character: string): boolean;
|
|
537
578
|
|
|
538
579
|
/**
|
|
539
|
-
*
|
|
580
|
+
* Narrows an unknown caught value to a {@link TerminalError}, so a caller can branch on its `code`.
|
|
540
581
|
*
|
|
541
582
|
* @param value - The value to test (typically a `catch` binding or a rejected prompt call)
|
|
542
|
-
* @returns
|
|
583
|
+
* @returns True if `value` is a {@link TerminalError}; false otherwise
|
|
543
584
|
*
|
|
544
585
|
* @example
|
|
545
586
|
* ```ts
|
|
@@ -554,30 +595,34 @@ export declare function isPrintable(character: string): boolean;
|
|
|
554
595
|
*/
|
|
555
596
|
export declare function isTerminalError(value: unknown): value is TerminalError;
|
|
556
597
|
|
|
557
|
-
/**
|
|
598
|
+
/**
|
|
599
|
+
* Narrows an unknown value to a {@link TerminalSnapshot} — a non-empty `id` and an optional numeric
|
|
600
|
+
* `timeout`, the read boundary a store applies to an untrusted persisted row.
|
|
601
|
+
*
|
|
602
|
+
* @param value - The candidate snapshot read back from storage
|
|
603
|
+
* @returns True if the value carries a non-empty `id` and an optional numeric `timeout`; false otherwise
|
|
604
|
+
*/
|
|
558
605
|
export declare const isTerminalSnapshot: Guard<TerminalSnapshot>;
|
|
559
606
|
|
|
560
607
|
/**
|
|
561
|
-
*
|
|
608
|
+
* Narrows an unknown value to a transport-neutral {@link WireEvent} — the guard a consumer's own
|
|
609
|
+
* transport applies to an inbound frame.
|
|
562
610
|
*
|
|
563
611
|
* @param value - The candidate wire event
|
|
564
|
-
* @returns
|
|
612
|
+
* @returns True if the value carries an event name, serialized data, and an optional id; false otherwise
|
|
565
613
|
*/
|
|
566
614
|
export declare const isWireEvent: Guard<WireEvent>;
|
|
567
615
|
|
|
568
616
|
/**
|
|
569
|
-
*
|
|
570
|
-
*
|
|
571
|
-
*
|
|
572
|
-
*
|
|
617
|
+
* Names the Single Shift Three lead (`ESCO`) — the alternate arrow-key prefix some terminals emit
|
|
618
|
+
* (`ESC O A`). Built from the console module's own {@link import('@orkestrel/console').ESC}; the
|
|
619
|
+
* navigation keys' CSI lead is that module's {@link import('@orkestrel/console').CSI}, which this
|
|
620
|
+
* package reuses rather than redeclaring.
|
|
573
621
|
*/
|
|
574
|
-
export declare const KEY_CSI: string;
|
|
575
|
-
|
|
576
|
-
/** The Single Shift Three lead (`ESCO`) — the alternate arrow-key prefix some terminals emit (`ESC O A`). */
|
|
577
622
|
export declare const KEY_SS3: string;
|
|
578
623
|
|
|
579
624
|
/**
|
|
580
|
-
*
|
|
625
|
+
* Represents one decoded keypress — the TTY-agnostic representation of a single key, the output of
|
|
581
626
|
* {@link import('./helpers.js').parseKey}. A driver reads `name` and the modifier flags to decide
|
|
582
627
|
* its transition; `sequence` is preserved so a printable character round-trips and an unknown
|
|
583
628
|
* escape is never lost.
|
|
@@ -586,15 +631,15 @@ export declare const KEY_SS3: string;
|
|
|
586
631
|
* - `name` — the canonical key name: a control or navigation key (`return`, `backspace`, `tab`,
|
|
587
632
|
* `escape`, `up` / `down` / `left` / `right`, `space`, `home`, `end`, `delete`), a named ctrl
|
|
588
633
|
* combo (`c` with `ctrl` true for ctrl-c, likewise `d` / `u` / `a` / `e`), or the printable
|
|
589
|
-
* character itself (`'a'`, `'7'`, `'?'`). An unrecognized sequence
|
|
590
|
-
*
|
|
634
|
+
* character itself (`'a'`, `'7'`, `'?'`). An unrecognized sequence carries NO `name` — absence,
|
|
635
|
+
* never an empty string — and the decoder stays total and never throws.
|
|
591
636
|
* - `sequence` — the exact input bytes as a string (a `Uint8Array` is decoded UTF-8). The driver
|
|
592
637
|
* writes this verbatim for a printable key.
|
|
593
638
|
* - `ctrl` / `meta` / `shift` — the modifier flags. `ctrl` is true for a C0 control byte, `meta`
|
|
594
639
|
* for an ESC-prefixed (Alt) sequence, `shift` for an uppercase-letter printable.
|
|
595
640
|
*/
|
|
596
641
|
export declare interface KeyEvent {
|
|
597
|
-
readonly name
|
|
642
|
+
readonly name?: string;
|
|
598
643
|
readonly sequence: string;
|
|
599
644
|
readonly ctrl: boolean;
|
|
600
645
|
readonly meta: boolean;
|
|
@@ -602,14 +647,15 @@ export declare interface KeyEvent {
|
|
|
602
647
|
}
|
|
603
648
|
|
|
604
649
|
/**
|
|
605
|
-
*
|
|
606
|
-
* {@link TerminalSnapshot}
|
|
607
|
-
* {@link import('
|
|
608
|
-
* {@link import('./DatabaseTerminalStore.js').DatabaseTerminalStore}.
|
|
650
|
+
* Implements the in-memory {@link TerminalStoreInterface} — a process-lifetime `Map` of
|
|
651
|
+
* {@link TerminalSnapshot} records keyed by endpoint id, the default store
|
|
652
|
+
* {@link import('../factories.js').createMemoryTerminalStore} builds and the exact twin of
|
|
653
|
+
* {@link import('./DatabaseTerminalStore.js').DatabaseTerminalStore}. It carries no idle expiry and
|
|
654
|
+
* no eviction.
|
|
609
655
|
*
|
|
610
656
|
* @remarks
|
|
611
|
-
* A plain `Map<string, TerminalSnapshot>`
|
|
612
|
-
*
|
|
657
|
+
* A plain `Map<string, TerminalSnapshot>` — the snapshot is already pure, self-contained CONFIG-only
|
|
658
|
+
* JSON, so the memory tier needs no encoding. There is NO idle-TTL and NO
|
|
613
659
|
* eviction: a persisted config lives until an explicit `delete`. A durable backend (JSON / SQLite /
|
|
614
660
|
* IndexedDB) swaps in through the SAME interface without touching the manager — its
|
|
615
661
|
* driver-pluggable twin is {@link import('./DatabaseTerminalStore.js').DatabaseTerminalStore} (the
|
|
@@ -619,13 +665,13 @@ export declare interface KeyEvent {
|
|
|
619
665
|
* - **`set` inserts / replaces under the snapshot's OWN `id`** (no separate id param).
|
|
620
666
|
* - **`delete` drops a snapshot by id**; an absent id is a no-op (no throw).
|
|
621
667
|
*
|
|
622
|
-
* The public surface is EXACTLY `get` / `set` / `delete` — no extra members
|
|
623
|
-
*
|
|
668
|
+
* The public surface is EXACTLY `get` / `set` / `delete` — no extra members, so the class and
|
|
669
|
+
* {@link TerminalStoreInterface} carry the same methods. Hydration is a caller concern: `open` always
|
|
624
670
|
* restores an EMPTY broker — parked Promises are process-bound and never resurrected.
|
|
625
671
|
*
|
|
626
672
|
* @example
|
|
627
673
|
* ```ts
|
|
628
|
-
* import { createMemoryTerminalStore } from '@
|
|
674
|
+
* import { createMemoryTerminalStore } from '@orkestrel/terminal'
|
|
629
675
|
*
|
|
630
676
|
* const store = createMemoryTerminalStore()
|
|
631
677
|
* await store.set({ id: 'shell', timeout: 5000 }) // persist a config
|
|
@@ -635,36 +681,55 @@ export declare interface KeyEvent {
|
|
|
635
681
|
*/
|
|
636
682
|
export declare class MemoryTerminalStore implements TerminalStoreInterface {
|
|
637
683
|
#private;
|
|
684
|
+
/**
|
|
685
|
+
* Resolves the persisted snapshot for `id`.
|
|
686
|
+
*
|
|
687
|
+
* @param id - The endpoint name the snapshot is keyed by
|
|
688
|
+
* @returns The stored snapshot, or `undefined` when none is held
|
|
689
|
+
*/
|
|
638
690
|
get(id: string): Promise<TerminalSnapshot | undefined>;
|
|
691
|
+
/**
|
|
692
|
+
* Inserts or replaces under the snapshot's OWN `id` (no separate id param).
|
|
693
|
+
*
|
|
694
|
+
* @param snapshot - The config snapshot to persist, carrying its own `id`
|
|
695
|
+
* @returns A promise that settles once the snapshot is held
|
|
696
|
+
*/
|
|
639
697
|
set(snapshot: TerminalSnapshot): Promise<void>;
|
|
698
|
+
/**
|
|
699
|
+
* Drops a snapshot by id; an absent id is a no-op (no throw).
|
|
700
|
+
*
|
|
701
|
+
* @param id - The endpoint name to drop
|
|
702
|
+
* @returns A promise that settles once the snapshot is gone
|
|
703
|
+
*/
|
|
640
704
|
delete(id: string): Promise<void>;
|
|
641
705
|
}
|
|
642
706
|
|
|
643
|
-
/**
|
|
707
|
+
/** Names the line feed byte (`\n`, U+000A) — Enter on some terminals / pasted input. */
|
|
644
708
|
export declare const NEWLINE: string;
|
|
645
709
|
|
|
646
710
|
/**
|
|
647
|
-
*
|
|
711
|
+
* Represents one parked form's runtime state inside the broker — the live form, the wire-safe record the
|
|
648
712
|
* broker exposes, and the cancel for its expiry timer.
|
|
649
713
|
*
|
|
650
714
|
* @remarks
|
|
651
|
-
* `form` is the
|
|
715
|
+
* `form` is the authoritative form the caller parked, not a copy: an answer fills and submits this
|
|
652
716
|
* one, so a `custom` rule that never crossed the wire still decides. Expiry destroys it, which
|
|
653
717
|
* abandons it and settles the caller's promise through the form's own lifecycle. `pending` is the
|
|
654
718
|
* wire record, whose `status` tracks the ticket.
|
|
655
719
|
*/
|
|
656
|
-
export declare interface
|
|
720
|
+
export declare interface ParkedForm {
|
|
657
721
|
readonly form: FormInterface;
|
|
722
|
+
/** Lists every parked record (`pending()`), or looks one up by id (`pending(id)`). */
|
|
658
723
|
readonly pending: PendingForm;
|
|
659
|
-
readonly cancel:
|
|
724
|
+
readonly cancel: TimerCancelFunction;
|
|
660
725
|
}
|
|
661
726
|
|
|
662
727
|
/**
|
|
663
|
-
*
|
|
728
|
+
* Represents the parking envelope — everything the broker needs about a park that the form itself does not
|
|
664
729
|
* say.
|
|
665
730
|
*
|
|
666
731
|
* @remarks
|
|
667
|
-
* `from` and `to` are the attribution edge, set
|
|
732
|
+
* `from` and `to` are the attribution edge, set only by a {@link TerminalManagerInterface}: which
|
|
668
733
|
* endpoint asked, which endpoint must answer. A direct broker caller passes no request at all.
|
|
669
734
|
*/
|
|
670
735
|
export declare interface ParkRequest {
|
|
@@ -673,24 +738,24 @@ export declare interface ParkRequest {
|
|
|
673
738
|
}
|
|
674
739
|
|
|
675
740
|
/**
|
|
676
|
-
*
|
|
677
|
-
* read as UTF-8; the resulting string is matched against the known control bytes and the CRLF
|
|
678
|
-
*
|
|
679
|
-
*
|
|
741
|
+
* Decodes one keypress's bytes into a {@link KeyEvent} — total, never throws. A `Uint8Array` is
|
|
742
|
+
* read as UTF-8; the resulting string is matched against the known control bytes and the CRLF pair
|
|
743
|
+
* ({@link CONTROL_NAMES}) and escape sequences ({@link SEQUENCE_NAMES}), falling back to a single
|
|
744
|
+
* printable character. An unrecognized sequence carries no `name`, with the raw `sequence`
|
|
680
745
|
* preserved.
|
|
681
746
|
*
|
|
682
747
|
* @remarks
|
|
683
748
|
* - **Single control byte.** A one-character control input (`return` / `backspace` / `tab` /
|
|
684
749
|
* `escape` / `space`, or a Ctrl combo `c` / `d` / `u` / `a` / `e`), or the two-byte `\r\n`
|
|
685
750
|
* CRLF pair, is looked up in {@link CONTROL_NAMES}, carrying its `ctrl` flag.
|
|
686
|
-
* - **Escape sequence.** A multi-byte ESC sequence (`up` / `down` / `left` / `right` in
|
|
751
|
+
* - **Escape sequence.** A multi-byte ESC sequence (`up` / `down` / `left` / `right` in both the
|
|
687
752
|
* `ESC[A` and `ESCOA` forms, plus `home` / `end` / `delete`) is looked up in
|
|
688
753
|
* {@link SEQUENCE_NAMES} and flagged `meta`.
|
|
689
754
|
* - **Printable character.** A single printable character becomes `name` = that character, with
|
|
690
755
|
* `shift` set when it is an uppercase letter. A multi-code-point printable (an emoji, a pasted
|
|
691
756
|
* run) keeps its first code point as the name and the whole input as `sequence`.
|
|
692
|
-
* - **Unknown.** Anything else (an unrecognized escape, an empty input) yields
|
|
693
|
-
* total, so the driver never crashes on a stray byte.
|
|
757
|
+
* - **Unknown.** Anything else (an unrecognized escape, an empty input) yields an event with NO
|
|
758
|
+
* `name` — absence, never an empty string — total, so the driver never crashes on a stray byte.
|
|
694
759
|
*
|
|
695
760
|
* @param input - The raw keypress bytes, as a string or `Uint8Array`
|
|
696
761
|
* @returns The decoded {@link KeyEvent}
|
|
@@ -707,18 +772,26 @@ export declare interface ParkRequest {
|
|
|
707
772
|
export declare function parseKey(input: string | Uint8Array): KeyEvent;
|
|
708
773
|
|
|
709
774
|
/**
|
|
710
|
-
*
|
|
711
|
-
*
|
|
712
|
-
*
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
775
|
+
* Represents the immutable state a password field's reducer carries — the text state with the mask glyph in
|
|
776
|
+
* place of a default, because a secret is never seeded from the schema.
|
|
777
|
+
*
|
|
778
|
+
* @remarks
|
|
779
|
+
* - `message` — the sanitized label the header renders.
|
|
780
|
+
* - `mask` — the glyph each typed character renders as.
|
|
781
|
+
* - `styler` / `theme` — the console styler and the resolved {@link PromptTheme}.
|
|
782
|
+
* - `value` — the characters typed so far, rendered only as the mask repeated.
|
|
783
|
+
*/
|
|
784
|
+
export declare interface PasswordState {
|
|
785
|
+
readonly message: string;
|
|
786
|
+
readonly mask: string;
|
|
787
|
+
readonly styler: StylerInterface;
|
|
788
|
+
readonly theme: PromptTheme;
|
|
789
|
+
readonly value: string;
|
|
790
|
+
}
|
|
718
791
|
|
|
719
792
|
/**
|
|
720
|
-
*
|
|
721
|
-
* answer. The value a `pending` listener receives and the broker serializes over SSE to a
|
|
793
|
+
* Represents one form parked by the broker — an id-keyed, wire-safe record of a live form awaiting
|
|
794
|
+
* a remote answer. The value a `pending` listener receives and the broker serializes over SSE to a
|
|
722
795
|
* {@link PromptClientInterface}.
|
|
723
796
|
*
|
|
724
797
|
* @remarks
|
|
@@ -743,9 +816,9 @@ export declare interface PendingForm {
|
|
|
743
816
|
}
|
|
744
817
|
|
|
745
818
|
/**
|
|
746
|
-
*
|
|
747
|
-
* where the form stands. A ticket is `pending` until somebody answers it; the form it carries
|
|
748
|
-
* its own status, and
|
|
819
|
+
* Names the lifecycle status of a parked {@link PendingForm} — where the ticket stands, which is
|
|
820
|
+
* not where the form stands. A ticket is `pending` until somebody answers it; the form it carries
|
|
821
|
+
* has its own status, and each is a separate fact about a separate entity.
|
|
749
822
|
*
|
|
750
823
|
* @remarks
|
|
751
824
|
* - `pending` — parked, awaiting {@link PromptInterface.answer}.
|
|
@@ -755,8 +828,9 @@ export declare interface PendingForm {
|
|
|
755
828
|
export declare type PendingFormStatus = 'pending' | 'answered' | 'expired';
|
|
756
829
|
|
|
757
830
|
/**
|
|
758
|
-
*
|
|
759
|
-
* remote answers to the authoritative form
|
|
831
|
+
* Implements the headless form broker. It parks live forms, exposes their serialized schemas,
|
|
832
|
+
* applies remote answers to the authoritative form, and abandons a parked form on timeout, release,
|
|
833
|
+
* or teardown.
|
|
760
834
|
*
|
|
761
835
|
* @remarks
|
|
762
836
|
* A parked record carries one call to `serializeForm`. A failed fill or submit leaves the record
|
|
@@ -789,8 +863,9 @@ export declare class Prompt implements PromptInterface {
|
|
|
789
863
|
}
|
|
790
864
|
|
|
791
865
|
/**
|
|
792
|
-
*
|
|
793
|
-
* the
|
|
866
|
+
* Holds the terminal-owned glyphs {@link DEFAULT_PROMPT_THEME} assembles its `icons` from, beside
|
|
867
|
+
* the console module's own success and error marks. Read only when the default theme is assembled;
|
|
868
|
+
* a view reads its resolved theme and never this constant. Frozen.
|
|
794
869
|
*
|
|
795
870
|
* @remarks
|
|
796
871
|
* - `question` — the leading mark on a prompt's message line.
|
|
@@ -808,15 +883,16 @@ export declare const PROMPT_ICONS: Readonly<{
|
|
|
808
883
|
}>;
|
|
809
884
|
|
|
810
885
|
/**
|
|
811
|
-
*
|
|
886
|
+
* Holds every {@link import('./types.js').PromptRole}, in one frozen list — the role axis's source of
|
|
812
887
|
* truth. {@link import('./helpers.js').createPromptTheme} walks it to merge a partial theme, and
|
|
813
888
|
* a consumer building a complete role map reads it rather than retyping every name.
|
|
814
889
|
*/
|
|
815
890
|
export declare const PROMPT_ROLES: readonly PromptRole[];
|
|
816
891
|
|
|
817
892
|
/**
|
|
818
|
-
*
|
|
819
|
-
* local terminal,
|
|
893
|
+
* Implements the SSE form bridge. It ingests serialized forms from a remote broker without waiting
|
|
894
|
+
* on a render, drives one form at a time through a local terminal, posts each answer back, and asks
|
|
895
|
+
* again when the authoritative form refuses one.
|
|
820
896
|
*
|
|
821
897
|
* @remarks
|
|
822
898
|
* - **Connect + reconnect.** {@link connect} opens the SSE stream and reconnects after a transport
|
|
@@ -824,12 +900,13 @@ export declare const PROMPT_ROLES: readonly PromptRole[];
|
|
|
824
900
|
* {@link disconnect} deliberately stopped it.
|
|
825
901
|
* - **Ingest + render.** Each `pending` envelope passes through `isPendingForm`, Form's `parseForm`,
|
|
826
902
|
* and terminal's `sanitizeSchema`, then enters a serial render queue. The SSE reader never awaits
|
|
827
|
-
* that queue, so `expire` and `
|
|
903
|
+
* that queue, so `expire` and `destroy` remain live while a person is answering.
|
|
828
904
|
* - **Safe local form.** The rendering copy omits every wire `pattern`, because Form compiles a
|
|
829
905
|
* pattern during local evaluation. The broker's parked form retains it and remains authoritative.
|
|
830
906
|
* - **Refusal retry.** A structured `rejected` response seeds a new rendering form with the values
|
|
831
|
-
*
|
|
832
|
-
* counter truncates the loop; acceptance, expiry, and
|
|
907
|
+
* the refused attempt submitted, applies every {@link FieldError} through `invalidate`, and asks
|
|
908
|
+
* again. No retry counter truncates the loop; acceptance, expiry, and the broker's own teardown
|
|
909
|
+
* are its bounds.
|
|
833
910
|
* - **Replay safety.** A replayed id is skipped while it is queued, rendering, or posting. Once an
|
|
834
911
|
* attempt ends, a later delivery of that id may be rendered again.
|
|
835
912
|
*
|
|
@@ -854,7 +931,7 @@ export declare class PromptClient implements PromptClientInterface {
|
|
|
854
931
|
}
|
|
855
932
|
|
|
856
933
|
/**
|
|
857
|
-
*
|
|
934
|
+
* Declares the client's event map — lean, errors `unknown`, no listener-error event.
|
|
858
935
|
*
|
|
859
936
|
* @remarks
|
|
860
937
|
* - `connect` — the SSE stream opened.
|
|
@@ -872,10 +949,10 @@ export declare type PromptClientEventMap = {
|
|
|
872
949
|
};
|
|
873
950
|
|
|
874
951
|
/**
|
|
875
|
-
*
|
|
876
|
-
* serialized {@link PendingForm} records from a remote broker, rebuilds each schema
|
|
877
|
-
* it through a {@link TerminalInterface}, and POSTs the answer back, so a human at
|
|
878
|
-
* answers forms a broker parked elsewhere.
|
|
952
|
+
* Declares the SSE form bridge — the client-side counterpart to {@link PromptInterface}. It
|
|
953
|
+
* receives serialized {@link PendingForm} records from a remote broker, rebuilds each schema
|
|
954
|
+
* locally, drives it through a {@link TerminalInterface}, and POSTs the answer back, so a human at
|
|
955
|
+
* this machine answers forms a broker parked elsewhere.
|
|
879
956
|
*
|
|
880
957
|
* @remarks
|
|
881
958
|
* - **Connect.** {@link connect} opens the SSE stream through the injected `fetch` and resolves
|
|
@@ -888,25 +965,40 @@ export declare type PromptClientEventMap = {
|
|
|
888
965
|
* the wire is never executed locally. The authoritative form decides.
|
|
889
966
|
* - **Refusal retries.** A rejected answer comes back with the parked form's own errors; the client
|
|
890
967
|
* applies them to the local form and asks again until the answer is accepted or the form expires.
|
|
891
|
-
* - **`connected`** reflects whether the stream is
|
|
968
|
+
* - **`connected`** reflects whether the stream is open.
|
|
892
969
|
*/
|
|
893
970
|
export declare interface PromptClientInterface {
|
|
971
|
+
/** Holds the typed emitter every client event is published on. */
|
|
894
972
|
readonly emitter: EmitterInterface<PromptClientEventMap>;
|
|
973
|
+
/** Holds the remote broker's SSE endpoint this client reads from and answers to. */
|
|
895
974
|
readonly url: string;
|
|
975
|
+
/** Reports whether the SSE stream is open. */
|
|
896
976
|
readonly connected: boolean;
|
|
977
|
+
/**
|
|
978
|
+
* Opens the stream and pumps it, queueing each received form for the local terminal; reconnects
|
|
979
|
+
* on the `delay` backoff.
|
|
980
|
+
*/
|
|
897
981
|
connect(): Promise<void>;
|
|
982
|
+
/**
|
|
983
|
+
* Stops the current connection and the reconnect loop. An active local render continues, and a
|
|
984
|
+
* later `connect()` can restart the stream.
|
|
985
|
+
*/
|
|
898
986
|
disconnect(): void;
|
|
987
|
+
/**
|
|
988
|
+
* Tears the client down permanently — disconnects, drops the queue, abandons the active local
|
|
989
|
+
* form, and destroys the emitter.
|
|
990
|
+
*/
|
|
899
991
|
destroy(): void;
|
|
900
992
|
}
|
|
901
993
|
|
|
902
994
|
/**
|
|
903
|
-
*
|
|
995
|
+
* Configures {@link import('./factories.js').createPromptClient} and the
|
|
904
996
|
* {@link PromptClientInterface}.
|
|
905
997
|
*
|
|
906
998
|
* @remarks
|
|
907
999
|
* - `url` — the remote broker's SSE endpoint. A GET opens the stream; answers POST back to it.
|
|
908
|
-
* - `terminal` — the
|
|
909
|
-
* at
|
|
1000
|
+
* - `terminal` — the local {@link TerminalInterface} each remote form is driven through, so a human
|
|
1001
|
+
* at this machine answers a form parked elsewhere.
|
|
910
1002
|
* - `token` — an optional auth token, sent as the {@link import('./constants.js').HEADER_TOKEN}
|
|
911
1003
|
* header on every request.
|
|
912
1004
|
* - `reconnect` — whether to reconnect after the stream drops, default true.
|
|
@@ -931,7 +1023,7 @@ export declare interface PromptClientOptions {
|
|
|
931
1023
|
}
|
|
932
1024
|
|
|
933
1025
|
/**
|
|
934
|
-
*
|
|
1026
|
+
* Declares the broker's event map — lean, errors `unknown`, no listener-error event.
|
|
935
1027
|
*
|
|
936
1028
|
* @remarks
|
|
937
1029
|
* - `pending` — a form was parked; a transport forwards the wire record to remote clients.
|
|
@@ -940,15 +1032,15 @@ export declare interface PromptClientOptions {
|
|
|
940
1032
|
*/
|
|
941
1033
|
export declare type PromptEventMap = {
|
|
942
1034
|
readonly pending: readonly [form: PendingForm];
|
|
1035
|
+
/**
|
|
1036
|
+
* Reports an accepted answer, carrying the parked form id and settled values.
|
|
1037
|
+
*/
|
|
943
1038
|
readonly answer: readonly [id: string, values: FormValues];
|
|
944
1039
|
readonly expire: readonly [id: string];
|
|
945
1040
|
};
|
|
946
1041
|
|
|
947
|
-
/** The styled prompt-message header (`? message`) — the leading line every active prompt view shares, themed by the `question` + `message` roles. */
|
|
948
|
-
export declare function promptHeader(styler: StylerInterface, theme: PromptTheme, message: string): string;
|
|
949
|
-
|
|
950
1042
|
/**
|
|
951
|
-
*
|
|
1043
|
+
* Names one glyph slot a rendered field draws — the icon axis of a {@link PromptTheme}. A named value
|
|
952
1044
|
* set, not a toggle, so it stays a union.
|
|
953
1045
|
*
|
|
954
1046
|
* @remarks
|
|
@@ -961,16 +1053,16 @@ export declare function promptHeader(styler: StylerInterface, theme: PromptTheme
|
|
|
961
1053
|
export declare type PromptIcon = 'question' | 'pointer' | 'dot' | 'selected' | 'checked' | 'unchecked' | 'success' | 'error';
|
|
962
1054
|
|
|
963
1055
|
/**
|
|
964
|
-
*
|
|
965
|
-
* arm of the local-TTY
|
|
966
|
-
* each `pending` record to whoever can answer, and {@link answer} drives the
|
|
967
|
-
* settlement.
|
|
1056
|
+
* Declares the headless form broker — parks a live form until somebody elsewhere answers it. The
|
|
1057
|
+
* headless arm of the local-TTY, headless, and remote trio: there is no terminal here, so a
|
|
1058
|
+
* transport forwards each `pending` record to whoever can answer, and {@link answer} drives the
|
|
1059
|
+
* parked form to settlement.
|
|
968
1060
|
*
|
|
969
1061
|
* @remarks
|
|
970
1062
|
* - **The form is the unit.** {@link park} takes a live form, mints an id, emits `pending`, and
|
|
971
1063
|
* returns the id. It wraps no promise, because the caller already holds one: the form's own
|
|
972
1064
|
* `answer`.
|
|
973
|
-
* - **The parked form is authoritative.** {@link answer} fills and submits
|
|
1065
|
+
* - **The parked form is authoritative.** {@link answer} fills and submits that form, so every rule
|
|
974
1066
|
* it carries decides, including a `custom` validator the wire dropped. A refusal returns the
|
|
975
1067
|
* form's own errors and leaves the form parked.
|
|
976
1068
|
* - **Timeout abandons.** An unanswered form is destroyed after `timeout` ms; `expire` fires and
|
|
@@ -991,20 +1083,39 @@ export declare type PromptIcon = 'question' | 'pointer' | 'dot' | 'selected' | '
|
|
|
991
1083
|
* ```
|
|
992
1084
|
*/
|
|
993
1085
|
export declare interface PromptInterface {
|
|
1086
|
+
/** Holds the typed emitter every broker event is published on. */
|
|
994
1087
|
readonly emitter: EmitterInterface<PromptEventMap>;
|
|
1088
|
+
/** Reports how many forms this broker holds parked. */
|
|
995
1089
|
readonly count: number;
|
|
1090
|
+
/**
|
|
1091
|
+
* Parks a live form, mints its id, emits `pending`, and arms the expiry deadline. Returns the id;
|
|
1092
|
+
* the caller already holds the promise.
|
|
1093
|
+
*/
|
|
996
1094
|
park(form: FormInterface, request?: ParkRequest): string;
|
|
1095
|
+
/** Lists every parked record (`pending()`), or looks one up by id (`pending(id)`). */
|
|
997
1096
|
pending(): readonly PendingForm[];
|
|
998
1097
|
pending(id: string): PendingForm | undefined;
|
|
1098
|
+
/**
|
|
1099
|
+
* Fills and submits the authoritative parked form. Accepted, it settles and the record is
|
|
1100
|
+
* dropped; refused, the form stays parked.
|
|
1101
|
+
*/
|
|
999
1102
|
answer(id: string, values: FormValues): Result<FormValues, AnswerError>;
|
|
1103
|
+
/**
|
|
1104
|
+
* Releases a batch (`stop(ids)`, the array overload declared first), one id, or every parked
|
|
1105
|
+
* form. The broker stays usable.
|
|
1106
|
+
*/
|
|
1000
1107
|
stop(ids: readonly string[]): boolean;
|
|
1001
1108
|
stop(id: string): boolean;
|
|
1002
1109
|
stop(): void;
|
|
1110
|
+
/**
|
|
1111
|
+
* Tears the broker down — abandons every parked form, cancels every deadline, then destroys the
|
|
1112
|
+
* emitter. Idempotent.
|
|
1113
|
+
*/
|
|
1003
1114
|
destroy(): void;
|
|
1004
1115
|
}
|
|
1005
1116
|
|
|
1006
1117
|
/**
|
|
1007
|
-
*
|
|
1118
|
+
* Configures {@link import('./factories.js').createPrompt} and every {@link PromptInterface}
|
|
1008
1119
|
* broker, including one a {@link TerminalManagerInterface} mounts per endpoint.
|
|
1009
1120
|
*
|
|
1010
1121
|
* @remarks
|
|
@@ -1028,9 +1139,9 @@ export declare interface PromptOptions {
|
|
|
1028
1139
|
}
|
|
1029
1140
|
|
|
1030
1141
|
/**
|
|
1031
|
-
*
|
|
1032
|
-
* role says what a fragment
|
|
1033
|
-
* re-maps styled output by naming roles rather than reimplementing a renderer.
|
|
1142
|
+
* Names one styling slot a rendered field paints through — the semantic axis of a
|
|
1143
|
+
* {@link PromptTheme}. A role says what a fragment means; the theme decides what that meaning looks
|
|
1144
|
+
* like, so a consumer re-maps styled output by naming roles rather than reimplementing a renderer.
|
|
1034
1145
|
*
|
|
1035
1146
|
* @remarks
|
|
1036
1147
|
* - `question` — the leading mark on an active field's line.
|
|
@@ -1051,16 +1162,17 @@ export declare interface PromptOptions {
|
|
|
1051
1162
|
export declare type PromptRole = 'question' | 'pointer' | 'message' | 'content' | 'success' | 'error' | 'selected' | 'focus' | 'hint' | 'muted' | 'description';
|
|
1052
1163
|
|
|
1053
1164
|
/**
|
|
1054
|
-
*
|
|
1165
|
+
* Names where one field's reducer stands after a key. `active`: keep asking, because the key was
|
|
1055
1166
|
* consumed or the answer was refused. `submit`: the field resolved with its `value`. `cancel`: the
|
|
1056
1167
|
* user aborted with ctrl-c. Names its axis, never `kind`.
|
|
1057
1168
|
*/
|
|
1058
1169
|
export declare type PromptStatus = 'active' | 'submit' | 'cancel';
|
|
1059
1170
|
|
|
1060
1171
|
/**
|
|
1061
|
-
*
|
|
1062
|
-
* `submit
|
|
1063
|
-
* the driver applies the next `state`, writes the `view`, and reads `value` on
|
|
1172
|
+
* Represents the result of one reducer step — the next `state`, the rendered `view`, the `status`,
|
|
1173
|
+
* and, on `submit` alone, the candidate `value`. The whole contract between a pure reducer and the
|
|
1174
|
+
* impure driver: the driver applies the next `state`, writes the `view`, and reads `value` on
|
|
1175
|
+
* `submit`.
|
|
1064
1176
|
*
|
|
1065
1177
|
* @typeParam T - The value this field resolves to, as its control admits it.
|
|
1066
1178
|
* @typeParam S - The reducer's concrete state shape, carried directly so `state` stays precisely
|
|
@@ -1071,7 +1183,7 @@ export declare type PromptStatus = 'active' | 'submit' | 'cancel';
|
|
|
1071
1183
|
* is the final state.
|
|
1072
1184
|
* - `view` — the styled string to render now, possibly multi-line. On a refused `submit` it carries
|
|
1073
1185
|
* the failure; the driver re-renders it each step.
|
|
1074
|
-
* - `value` — present
|
|
1186
|
+
* - `value` — present only on a `submit` step.
|
|
1075
1187
|
*/
|
|
1076
1188
|
export declare interface PromptStep<T, S> {
|
|
1077
1189
|
readonly state: S;
|
|
@@ -1081,9 +1193,9 @@ export declare interface PromptStep<T, S> {
|
|
|
1081
1193
|
}
|
|
1082
1194
|
|
|
1083
1195
|
/**
|
|
1084
|
-
*
|
|
1085
|
-
* for every {@link PromptRole}. Plain JSON data with no functions, so it crosses the
|
|
1086
|
-
* form it decorates. Built by {@link import('./helpers.js').createPromptTheme}.
|
|
1196
|
+
* Represents a resolved presentation — the glyph for every {@link PromptIcon} and the console
|
|
1197
|
+
* {@link Style} for every {@link PromptRole}. Plain JSON data with no functions, so it crosses the
|
|
1198
|
+
* wire with the form it decorates. Built by {@link import('./helpers.js').createPromptTheme}.
|
|
1087
1199
|
*
|
|
1088
1200
|
* @remarks
|
|
1089
1201
|
* A role's value is the console module's own {@link Style} — the one style model the whole console
|
|
@@ -1098,8 +1210,8 @@ export declare interface PromptTheme {
|
|
|
1098
1210
|
}
|
|
1099
1211
|
|
|
1100
1212
|
/**
|
|
1101
|
-
*
|
|
1102
|
-
* and {@link import('./helpers.js').createPromptTheme} merges what is supplied over
|
|
1213
|
+
* Represents the partial {@link PromptTheme} an option bag carries — every icon and every role is
|
|
1214
|
+
* optional, and {@link import('./helpers.js').createPromptTheme} merges what is supplied over
|
|
1103
1215
|
* {@link import('./constants.js').DEFAULT_PROMPT_THEME} leaf by leaf. Supplying one icon or one
|
|
1104
1216
|
* role leaves every other slot at its default.
|
|
1105
1217
|
*/
|
|
@@ -1108,11 +1220,179 @@ export declare interface PromptThemeOptions {
|
|
|
1108
1220
|
readonly roles?: Readonly<Partial<Record<PromptRole, Style>>>;
|
|
1109
1221
|
}
|
|
1110
1222
|
|
|
1111
|
-
/**
|
|
1223
|
+
/**
|
|
1224
|
+
* Advances a checkbox prompt by one {@link KeyEvent} — the pure
|
|
1225
|
+
* `(state, key) → PromptStep<readonly string[]>` reducer. `up` / `down` (and `k` / `j`) move the
|
|
1226
|
+
* focus (wrapping); `space` toggles the focused index in the checked set; return submits the
|
|
1227
|
+
* checked values in choice order; ctrl-c cancels. The form applies selection-count rules.
|
|
1228
|
+
*
|
|
1229
|
+
* @param state - The checkbox field's current reducer state
|
|
1230
|
+
* @param key - The decoded keypress to apply
|
|
1231
|
+
* @returns The next step — the state, the rendered view, the status, and the ticked values on submit
|
|
1232
|
+
*/
|
|
1233
|
+
export declare function reduceCheckbox(state: CheckboxState, key: KeyEvent): PromptStep<readonly string[], CheckboxState>;
|
|
1234
|
+
|
|
1235
|
+
/**
|
|
1236
|
+
* Advances a confirm prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<boolean>`
|
|
1237
|
+
* reducer. `y` / `Y` submits `true`, `n` / `N` submits `false`, return on an empty line submits
|
|
1238
|
+
* the `default`, ctrl-c cancels; any other key is ignored (stays active).
|
|
1239
|
+
*
|
|
1240
|
+
* @param state - The confirm field's current reducer state
|
|
1241
|
+
* @param key - The decoded keypress to apply
|
|
1242
|
+
* @returns The next step — the state, the rendered view, the status, and the answer on submit
|
|
1243
|
+
*/
|
|
1244
|
+
export declare function reduceConfirm(state: ConfirmState, key: KeyEvent): PromptStep<boolean, ConfirmState>;
|
|
1245
|
+
|
|
1246
|
+
/**
|
|
1247
|
+
* Advances an editor prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<string>`
|
|
1248
|
+
* reducer. Printable characters extend the current line; backspace shrinks it; return commits the
|
|
1249
|
+
* current line and starts a fresh one; ctrl-d finishes, joining every line and falling back to the
|
|
1250
|
+
* default when empty; ctrl-c cancels. The form validates the candidate after the driver fills it.
|
|
1251
|
+
*
|
|
1252
|
+
* @param state - The editor field's current reducer state
|
|
1253
|
+
* @param key - The decoded keypress to apply
|
|
1254
|
+
* @returns The next step — the state, the rendered view, the status, and the joined text on submit
|
|
1255
|
+
*/
|
|
1256
|
+
export declare function reduceEditor(state: EditorState, key: KeyEvent): PromptStep<string, EditorState>;
|
|
1257
|
+
|
|
1258
|
+
/**
|
|
1259
|
+
* Advances an input prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<string>`
|
|
1260
|
+
* reducer. Printable characters extend the value; backspace shrinks it; ctrl-u clears it; ctrl-c
|
|
1261
|
+
* cancels; return produces the candidate value, with an empty line falling back to the default.
|
|
1262
|
+
*
|
|
1263
|
+
* @param state - The text field's current reducer state
|
|
1264
|
+
* @param key - The decoded keypress to apply
|
|
1265
|
+
* @returns The next step — the new state, the rendered view, the status, and the value on submit
|
|
1266
|
+
*/
|
|
1267
|
+
export declare function reduceInput(state: InputState, key: KeyEvent): PromptStep<string, InputState>;
|
|
1268
|
+
|
|
1269
|
+
/**
|
|
1270
|
+
* Advances a password prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<string>`
|
|
1271
|
+
* reducer. Identical line-editing to {@link reduceInput} (printable extends, backspace shrinks,
|
|
1272
|
+
* ctrl-u clears, ctrl-c cancels) but the view masks the value. Return produces the candidate value.
|
|
1273
|
+
*
|
|
1274
|
+
* @param state - The password field's current reducer state
|
|
1275
|
+
* @param key - The decoded keypress to apply
|
|
1276
|
+
* @returns The next step — the new state, the masked view, the status, and the value on submit
|
|
1277
|
+
*/
|
|
1278
|
+
export declare function reducePassword(state: PasswordState, key: KeyEvent): PromptStep<string, PasswordState>;
|
|
1279
|
+
|
|
1280
|
+
/**
|
|
1281
|
+
* Advances a select prompt by one {@link KeyEvent} — the pure `(state, key) → PromptStep<string>`
|
|
1282
|
+
* reducer. `up` / `down` (and `k` / `j`) move the focus, wrapping at the ends; return submits the
|
|
1283
|
+
* focused choice's `value`; ctrl-c cancels. An empty choice list can never submit (a higher layer
|
|
1284
|
+
* guards against it); any other key is ignored.
|
|
1285
|
+
*
|
|
1286
|
+
* @param state - The select field's current reducer state
|
|
1287
|
+
* @param key - The decoded keypress to apply
|
|
1288
|
+
* @returns The next step — the state, the rendered view, the status, and the chosen value on submit
|
|
1289
|
+
*/
|
|
1290
|
+
export declare function reduceSelect(state: SelectState, key: KeyEvent): PromptStep<string, SelectState>;
|
|
1291
|
+
|
|
1292
|
+
/**
|
|
1293
|
+
* Renders a checkbox-field reducer state as a multi-line styled view — one box per choice, and the
|
|
1294
|
+
* selected count beneath them.
|
|
1295
|
+
*
|
|
1296
|
+
* @param state - The checkbox field's current reducer state
|
|
1297
|
+
* @returns The rendered view — the header, one box per choice, and the selected count
|
|
1298
|
+
*/
|
|
1299
|
+
export declare function renderCheckboxView(state: CheckboxState): string;
|
|
1300
|
+
|
|
1301
|
+
/**
|
|
1302
|
+
* Renders a confirm-field reducer state as a styled view — the header and the yes/no group, with
|
|
1303
|
+
* the default letter capitalized and painted by the `selected` role.
|
|
1304
|
+
*
|
|
1305
|
+
* @param state - The confirm field's current reducer state
|
|
1306
|
+
* @returns The rendered view — the header and the yes/no group with the default capitalized
|
|
1307
|
+
*/
|
|
1308
|
+
export declare function renderConfirmView(state: ConfirmState): string;
|
|
1309
|
+
|
|
1310
|
+
/**
|
|
1311
|
+
* Renders an editor-field reducer state as a multi-line styled view — the finish hint, the
|
|
1312
|
+
* committed lines, and the line in progress.
|
|
1313
|
+
*
|
|
1314
|
+
* @param state - The editor field's current reducer state
|
|
1315
|
+
* @returns The rendered view — the hinted header, the committed lines, and the line in progress
|
|
1316
|
+
*/
|
|
1317
|
+
export declare function renderEditorView(state: EditorState): string;
|
|
1318
|
+
|
|
1319
|
+
/**
|
|
1320
|
+
* Renders the styled failure line (`✖ message`) a form driver writes for each refused field before
|
|
1321
|
+
* it asks that field again.
|
|
1322
|
+
*
|
|
1323
|
+
* @param styler - The console styler that renders each role
|
|
1324
|
+
* @param theme - The resolved prompt theme
|
|
1325
|
+
* @param message - The failure text, normally the field's label and the reason
|
|
1326
|
+
* @returns The rendered failure line
|
|
1327
|
+
*/
|
|
1328
|
+
export declare function renderErrorLine(styler: StylerInterface, theme: PromptTheme, message: string): string;
|
|
1329
|
+
|
|
1330
|
+
/**
|
|
1331
|
+
* Renders a question header followed by a key hint painted with the `hint` role, or the header
|
|
1332
|
+
* alone when no hint is supplied.
|
|
1333
|
+
*
|
|
1334
|
+
* @param styler - The console styler that renders each role
|
|
1335
|
+
* @param theme - The resolved prompt theme
|
|
1336
|
+
* @param message - The prompt's question text
|
|
1337
|
+
* @param hint - The optional key hint to append
|
|
1338
|
+
* @returns The rendered header with the optional hint
|
|
1339
|
+
*/
|
|
1340
|
+
export declare function renderHintedHeader(styler: StylerInterface, theme: PromptTheme, message: string, hint?: string): string;
|
|
1341
|
+
|
|
1342
|
+
/**
|
|
1343
|
+
* Renders a text-field reducer state as a styled view — the header, the pointer, and the typed
|
|
1344
|
+
* value, or the default shown as a hint while nothing is typed.
|
|
1345
|
+
*
|
|
1346
|
+
* @param state - The text field's current reducer state
|
|
1347
|
+
* @returns The rendered single-line view — header, pointer, and the typed value or the default
|
|
1348
|
+
*/
|
|
1349
|
+
export declare function renderInputView(state: InputState): string;
|
|
1350
|
+
|
|
1351
|
+
/**
|
|
1352
|
+
* Renders a password-field reducer state as a styled view, with the value replaced by the mask
|
|
1353
|
+
* repeated so the secret is never echoed.
|
|
1354
|
+
*
|
|
1355
|
+
* @param state - The password field's current reducer state
|
|
1356
|
+
* @returns The rendered view, with the mask repeated in place of the typed value
|
|
1357
|
+
*/
|
|
1358
|
+
export declare function renderPasswordView(state: PasswordState): string;
|
|
1359
|
+
|
|
1360
|
+
/**
|
|
1361
|
+
* Renders the styled question header (`? message`) — the leading line every active prompt view
|
|
1362
|
+
* shares, themed by the `question` + `message` roles.
|
|
1363
|
+
*
|
|
1364
|
+
* @param styler - The console styler that renders each role
|
|
1365
|
+
* @param theme - The resolved prompt theme
|
|
1366
|
+
* @param message - The prompt's question text
|
|
1367
|
+
* @returns The rendered question header
|
|
1368
|
+
*/
|
|
1369
|
+
export declare function renderPromptHeader(styler: StylerInterface, theme: PromptTheme, message: string): string;
|
|
1370
|
+
|
|
1371
|
+
/**
|
|
1372
|
+
* Renders a select-field reducer state as a multi-line styled view — one row per choice, with the
|
|
1373
|
+
* focused row marked and its help shown.
|
|
1374
|
+
*
|
|
1375
|
+
* @param state - The select field's current reducer state
|
|
1376
|
+
* @returns The rendered view — the header, then one row per choice with the focused row marked
|
|
1377
|
+
*/
|
|
1378
|
+
export declare function renderSelectView(state: SelectState): string;
|
|
1379
|
+
|
|
1380
|
+
/**
|
|
1381
|
+
* Renders the styled submit line (`✔ message`) — the committed header an interactive prompt shows
|
|
1382
|
+
* after it resolves, themed by the `success` + `message` roles.
|
|
1383
|
+
*
|
|
1384
|
+
* @param styler - The console styler that renders each role
|
|
1385
|
+
* @param theme - The resolved prompt theme
|
|
1386
|
+
* @param message - The settled prompt's question text
|
|
1387
|
+
* @returns The rendered committed header
|
|
1388
|
+
*/
|
|
1389
|
+
export declare function renderSubmitHeader(styler: StylerInterface, theme: PromptTheme, message: string): string;
|
|
1390
|
+
|
|
1391
|
+
/** Names the carriage return byte (`\r`, U+000D) — Enter on most terminals. */
|
|
1112
1392
|
export declare const RETURN: string;
|
|
1113
1393
|
|
|
1114
1394
|
/**
|
|
1115
|
-
*
|
|
1395
|
+
* Sanitizes text for one single-line display slot. Composes console's ANSI {@link strip} and C0
|
|
1116
1396
|
* {@link stripControls} passes with removal of tab, line feed, and carriage return.
|
|
1117
1397
|
*
|
|
1118
1398
|
* @param text - The text to sanitize for a glyph or hint slot
|
|
@@ -1126,7 +1406,8 @@ export declare const RETURN: string;
|
|
|
1126
1406
|
export declare function sanitizeDisplayText(text: string): string;
|
|
1127
1407
|
|
|
1128
1408
|
/**
|
|
1129
|
-
*
|
|
1409
|
+
* Sanitizes every terminal-readable string in a parsed form schema, keeping every identity and
|
|
1410
|
+
* answer string verbatim and dropping field metadata.
|
|
1130
1411
|
*
|
|
1131
1412
|
* @remarks
|
|
1132
1413
|
* Display strings pass through {@link sanitizeDisplayText}: labels, help, placeholders, masks,
|
|
@@ -1148,7 +1429,7 @@ export declare function sanitizeDisplayText(text: string): string;
|
|
|
1148
1429
|
export declare function sanitizeSchema(schema: FormSchema): FormSchema;
|
|
1149
1430
|
|
|
1150
1431
|
/**
|
|
1151
|
-
*
|
|
1432
|
+
* Sanitizes every glyph a wire-supplied {@link PromptThemeOptions} carries for a single-line display
|
|
1152
1433
|
* slot. Only the icons need it: a role is guard-narrowed to a console {@link Style}, whose colors
|
|
1153
1434
|
* and attributes are fixed name sets, so no role can carry a byte a terminal would act on.
|
|
1154
1435
|
*
|
|
@@ -1158,21 +1439,29 @@ export declare function sanitizeSchema(schema: FormSchema): FormSchema;
|
|
|
1158
1439
|
export declare function sanitizeThemeIcons(theme: PromptThemeOptions): PromptThemeOptions;
|
|
1159
1440
|
|
|
1160
1441
|
/**
|
|
1161
|
-
*
|
|
1162
|
-
*
|
|
1163
|
-
*
|
|
1164
|
-
*
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1442
|
+
* Represents the immutable state a select field's reducer carries — the choices the list offers and
|
|
1443
|
+
* the index the cursor sits on.
|
|
1444
|
+
*
|
|
1445
|
+
* @remarks
|
|
1446
|
+
* - `message` — the sanitized label the header renders.
|
|
1447
|
+
* - `choices` — the choices the list offers, in declared order.
|
|
1448
|
+
* - `styler` / `theme` — the console styler and the resolved {@link PromptTheme}.
|
|
1449
|
+
* - `focused` — the index the cursor sits on, pre-placed on the declared default.
|
|
1450
|
+
*/
|
|
1451
|
+
export declare interface SelectState {
|
|
1452
|
+
readonly message: string;
|
|
1453
|
+
readonly choices: readonly FieldChoice[];
|
|
1454
|
+
readonly styler: StylerInterface;
|
|
1455
|
+
readonly theme: PromptTheme;
|
|
1456
|
+
readonly focused: number;
|
|
1457
|
+
}
|
|
1170
1458
|
|
|
1171
1459
|
/**
|
|
1172
|
-
*
|
|
1173
|
-
* consults for the navigation
|
|
1174
|
-
* form (`ESCOA`…) of the
|
|
1175
|
-
* their numeric-tilde variants
|
|
1460
|
+
* Holds the exact escape sequence to canonical key name table
|
|
1461
|
+
* {@link import('./helpers.js').parseKey} consults for the navigation and editing keys. Covers the
|
|
1462
|
+
* CSI form (`ESC[A`…) and the SS3 form (`ESCOA`…) of the arrows, plus the `home` / `end` / `delete`
|
|
1463
|
+
* CSI sequences with their numeric-tilde variants. The source of truth for the multi-byte key
|
|
1464
|
+
* decode; frozen.
|
|
1176
1465
|
*
|
|
1177
1466
|
* @remarks
|
|
1178
1467
|
* Terminals disagree on these: a cursor key is `ESC[A` (normal) or `ESCOA` (application mode),
|
|
@@ -1182,20 +1471,37 @@ export declare function selectView(state: ReturnType<typeof createSelectState>):
|
|
|
1182
1471
|
*/
|
|
1183
1472
|
export declare const SEQUENCE_NAMES: Readonly<Record<string, string>>;
|
|
1184
1473
|
|
|
1185
|
-
/**
|
|
1474
|
+
/**
|
|
1475
|
+
* Serializes the `destroy` {@link WireEvent} a broker or manager sends when it is going away, which
|
|
1476
|
+
* carries no payload.
|
|
1477
|
+
*
|
|
1478
|
+
* @returns The `destroy` frame, whose `data` is empty because the signal carries no payload
|
|
1479
|
+
*/
|
|
1480
|
+
export declare function serializeDestroy(): WireEvent;
|
|
1481
|
+
|
|
1482
|
+
/**
|
|
1483
|
+
* Serializes a parked form's expiry or release into an `expire` {@link WireEvent}, whose `data` is
|
|
1484
|
+
* the JSON `{ id }` payload.
|
|
1485
|
+
*
|
|
1486
|
+
* @param id - The id of the parked form that expired or was released
|
|
1487
|
+
* @returns The `expire` frame, carrying the JSON-stringified `{ id }` payload as `data`
|
|
1488
|
+
*/
|
|
1186
1489
|
export declare function serializeExpire(id: string): WireEvent;
|
|
1187
1490
|
|
|
1188
|
-
/**
|
|
1491
|
+
/**
|
|
1492
|
+
* Serializes a parked {@link PendingForm} into a `pending` {@link WireEvent}, whose frame `id` is
|
|
1493
|
+
* the form's own id.
|
|
1494
|
+
*
|
|
1495
|
+
* @param form - The parked form's wire-safe record
|
|
1496
|
+
* @returns The `pending` frame — the JSON-stringified record as `data`, and the form's own `id`
|
|
1497
|
+
*/
|
|
1189
1498
|
export declare function serializePending(form: PendingForm): WireEvent;
|
|
1190
1499
|
|
|
1191
|
-
/**
|
|
1192
|
-
export declare function serializeShutdown(): WireEvent;
|
|
1193
|
-
|
|
1194
|
-
/** Space (U+0020). */
|
|
1500
|
+
/** Names the space byte (U+0020). */
|
|
1195
1501
|
export declare const SPACE = " ";
|
|
1196
1502
|
|
|
1197
1503
|
/**
|
|
1198
|
-
*
|
|
1504
|
+
* Sets the maximum number of characters the {@link import('./types.js').PromptClientInterface} lets its
|
|
1199
1505
|
* SSE parser buffer before treating the stream as hostile — 1 MiB, comfortably above any
|
|
1200
1506
|
* legitimate prompt payload. Passed as the `limit` to `createSSEParser` so an unterminated
|
|
1201
1507
|
* or oversized `data:` field cannot grow the buffer without bound (a memory-exhaustion guard).
|
|
@@ -1203,37 +1509,36 @@ export declare const SPACE = " ";
|
|
|
1203
1509
|
export declare const SSE_BUFFER_LIMIT = 1048576;
|
|
1204
1510
|
|
|
1205
1511
|
/**
|
|
1206
|
-
*
|
|
1207
|
-
*
|
|
1512
|
+
* Holds the SSE `event:` names the broker emits and the
|
|
1513
|
+
* {@link import('./types.js').PromptClientInterface} dispatches on — `pending`, `expire`, and
|
|
1514
|
+
* `destroy`. Frozen; the source of truth for the wire event vocabulary.
|
|
1208
1515
|
*
|
|
1209
1516
|
* @remarks
|
|
1210
1517
|
* - `pending` — a serialized {@link import('./types.js').PendingForm} to dispatch and answer.
|
|
1211
|
-
* - `expire` — an `{ id }` payload: the broker expired or released a parked
|
|
1212
|
-
* - `
|
|
1518
|
+
* - `expire` — an `{ id }` payload: the broker expired or released a parked form (the client drops it).
|
|
1519
|
+
* - `destroy` — the broker is going away; the client disconnects (no auto-reconnect) but stays reusable.
|
|
1213
1520
|
*/
|
|
1214
1521
|
export declare const SSE_EVENTS: Readonly<{
|
|
1215
1522
|
pending: "pending";
|
|
1216
1523
|
expire: "expire";
|
|
1217
|
-
|
|
1524
|
+
destroy: "destroy";
|
|
1218
1525
|
}>;
|
|
1219
1526
|
|
|
1220
|
-
/**
|
|
1221
|
-
export declare function submitHeader(styler: StylerInterface, theme: PromptTheme, message: string): string;
|
|
1222
|
-
|
|
1223
|
-
/** Tab (`\t`, U+0009). */
|
|
1527
|
+
/** Names the tab byte (`\t`, U+0009). */
|
|
1224
1528
|
export declare const TAB: string;
|
|
1225
1529
|
|
|
1226
1530
|
/**
|
|
1227
|
-
*
|
|
1228
|
-
* endpoint's own broker, or `
|
|
1229
|
-
*
|
|
1531
|
+
* Explains why a {@link TerminalManagerInterface.answer} call refused — an {@link AnswerError} from the
|
|
1532
|
+
* endpoint's own broker, or `target` when no endpoint is mounted under that name. That is the same
|
|
1533
|
+
* condition {@link TerminalErrorCode}'s `TARGET` names for {@link TerminalManagerInterface.ask}, so
|
|
1534
|
+
* one word carries it on both doors. One discriminant, `reason`, across every member.
|
|
1230
1535
|
*/
|
|
1231
1536
|
export declare type TerminalAnswerError = AnswerError | {
|
|
1232
|
-
readonly reason: '
|
|
1537
|
+
readonly reason: 'target';
|
|
1233
1538
|
};
|
|
1234
1539
|
|
|
1235
1540
|
/**
|
|
1236
|
-
*
|
|
1541
|
+
* Represents the error the terminal surfaces for its own refusals: parking on a destroyed or full broker, an
|
|
1237
1542
|
* unusable driver stream, a manager routing fault, or a ctrl-c cancellation. A parked form's own
|
|
1238
1543
|
* lifecycle failures reject through the form's `answer` with the form package's error, never with
|
|
1239
1544
|
* this one.
|
|
@@ -1244,15 +1549,22 @@ export declare type TerminalAnswerError = AnswerError | {
|
|
|
1244
1549
|
* a caught value with {@link isTerminalError} and branch on `error.code`.
|
|
1245
1550
|
*/
|
|
1246
1551
|
export declare class TerminalError extends Error {
|
|
1247
|
-
/**
|
|
1552
|
+
/** Holds the machine-readable condition — see {@link TerminalErrorCode}. */
|
|
1248
1553
|
readonly code: TerminalErrorCode;
|
|
1249
|
-
/**
|
|
1554
|
+
/** Holds an optional context bag naming the offending values — see the class {@link TerminalError remarks}. */
|
|
1250
1555
|
readonly context?: Readonly<Record<string, unknown>>;
|
|
1556
|
+
/**
|
|
1557
|
+
* Builds one terminal refusal.
|
|
1558
|
+
*
|
|
1559
|
+
* @param code - The machine-readable {@link TerminalErrorCode} a caller branches on
|
|
1560
|
+
* @param message - The human-readable reason
|
|
1561
|
+
* @param context - The optional bag naming the offending values — see the class {@link TerminalError remarks}
|
|
1562
|
+
*/
|
|
1251
1563
|
constructor(code: TerminalErrorCode, message: string, context?: Readonly<Record<string, unknown>>);
|
|
1252
1564
|
}
|
|
1253
1565
|
|
|
1254
1566
|
/**
|
|
1255
|
-
*
|
|
1567
|
+
* Names the machine-readable condition carried by a {@link import('./errors.js').TerminalError} — the
|
|
1256
1568
|
* axis a `catch` branches on. Names its axis (the failure condition), never `kind`.
|
|
1257
1569
|
*
|
|
1258
1570
|
* @remarks
|
|
@@ -1275,15 +1587,15 @@ export declare class TerminalError extends Error {
|
|
|
1275
1587
|
export declare type TerminalErrorCode = 'EXPIRE' | 'CANCEL' | 'DRIVER' | 'DEADLOCK' | 'TARGET' | 'LIMIT' | 'DESTROYED';
|
|
1276
1588
|
|
|
1277
1589
|
/**
|
|
1278
|
-
*
|
|
1279
|
-
* question however many fields it holds. The server `Terminal` implements it
|
|
1280
|
-
* a {@link PromptClientInterface} holds one to answer forms parked elsewhere.
|
|
1590
|
+
* Declares the contract for asking a form of a human at a keyboard — `ask` and nothing beside it,
|
|
1591
|
+
* because a form is one question however many fields it holds. The server `Terminal` implements it
|
|
1592
|
+
* against a real TTY; a {@link PromptClientInterface} holds one to answer forms parked elsewhere.
|
|
1281
1593
|
*
|
|
1282
1594
|
* @remarks
|
|
1283
1595
|
* `ask` drives the form the caller passes: it walks the schema's fields in order, binds each
|
|
1284
1596
|
* keystroke through the form's own `fill`, submits, and returns the settled values. The returned
|
|
1285
1597
|
* promise is the form's `answer`, so a caller holding the form can await either one. Ctrl-c at an
|
|
1286
|
-
* interactive driver is the one exception: it rejects
|
|
1598
|
+
* interactive driver is the one exception: it rejects this promise with a `TerminalError` coded
|
|
1287
1599
|
* `CANCEL` and leaves the form `editing`, so the form's own `answer` stays pending for its owner.
|
|
1288
1600
|
*
|
|
1289
1601
|
* A driver never owns the form's lifetime. To interrupt an active walk, destroy the form: it
|
|
@@ -1291,29 +1603,32 @@ export declare type TerminalErrorCode = 'EXPIRE' | 'CANCEL' | 'DRIVER' | 'DEADLO
|
|
|
1291
1603
|
* is the only cancellation channel, which is why this contract needs no second method.
|
|
1292
1604
|
*/
|
|
1293
1605
|
export declare interface TerminalInterface {
|
|
1606
|
+
/**
|
|
1607
|
+
* Walks the given form to settlement and resolves its values. The Contract section names the
|
|
1608
|
+
* ctrl-c exception.
|
|
1609
|
+
*/
|
|
1294
1610
|
ask(form: FormInterface): Promise<FormValues>;
|
|
1295
1611
|
}
|
|
1296
1612
|
|
|
1297
1613
|
/**
|
|
1298
|
-
*
|
|
1299
|
-
*
|
|
1300
|
-
*
|
|
1301
|
-
* asks.
|
|
1614
|
+
* Registers named {@link PromptInterface} brokers, one per endpoint, so several parties can `ask`
|
|
1615
|
+
* forms of each other by name with a `from` → `to` attribution edge on every parked form, and
|
|
1616
|
+
* refuses `DEADLOCK` on a transitive cycle across every in-flight ask.
|
|
1302
1617
|
*
|
|
1303
1618
|
* @remarks
|
|
1304
1619
|
* - **Registry.** `add(name, options?)` mints (or, if `name` is already mounted, returns the
|
|
1305
|
-
*
|
|
1620
|
+
* existing broker unchanged — idempotent, never clobbers a live/parked endpoint). Every mounted
|
|
1306
1621
|
* broker's `pending` / `answer` / `expire` events are re-emitted on the manager, attributed by
|
|
1307
1622
|
* `name`.
|
|
1308
|
-
* - **`ask`.** The target must already be mounted
|
|
1623
|
+
* - **`ask`.** The target must already be mounted through {@link add} — `ask` never auto-adds it;
|
|
1309
1624
|
* rejects `TARGET` for an unknown `to` (listing the known names). Rejects `DEADLOCK` when parking
|
|
1310
|
-
* `from → to` would close a cycle over the
|
|
1625
|
+
* `from → to` would close a cycle over the current in-flight edge set (walked transitively);
|
|
1311
1626
|
* otherwise parks the caller's live form through the target's broker and returns that form's own
|
|
1312
1627
|
* `answer` promise. Edge cleanup never alters the value or rejection the caller observes.
|
|
1313
1628
|
* - **Durable open / save.** `open(name)` restores an EMPTY broker from the `store` (parked
|
|
1314
1629
|
* Promises are process-bound and never resurrected); `save(name)` persists the endpoint's
|
|
1315
1630
|
* configured `timeout`.
|
|
1316
|
-
* - **Removal.** `remove` drops one endpoint, a batch (
|
|
1631
|
+
* - **Removal.** `remove` drops one endpoint, a batch (the array overload declared first), or every
|
|
1317
1632
|
* endpoint when called without an argument. It destroys each broker, which expires every form
|
|
1318
1633
|
* still parked on it. `destroy` is idempotent.
|
|
1319
1634
|
*
|
|
@@ -1333,7 +1648,7 @@ export declare class TerminalManager implements TerminalManagerInterface {
|
|
|
1333
1648
|
get emitter(): EmitterInterface<TerminalManagerEventMap>;
|
|
1334
1649
|
get count(): number;
|
|
1335
1650
|
terminal(name: string): PromptInterface | undefined;
|
|
1336
|
-
terminals(): readonly
|
|
1651
|
+
terminals(): readonly PromptInterface[];
|
|
1337
1652
|
add(name: string, options?: PromptOptions): PromptInterface;
|
|
1338
1653
|
ask(from: string, to: string, form: FormInterface): Promise<FormValues>;
|
|
1339
1654
|
pending(): readonly PendingForm[];
|
|
@@ -1348,8 +1663,8 @@ export declare class TerminalManager implements TerminalManagerInterface {
|
|
|
1348
1663
|
}
|
|
1349
1664
|
|
|
1350
1665
|
/**
|
|
1351
|
-
*
|
|
1352
|
-
* caller subscribes once for
|
|
1666
|
+
* Declares the manager's event map — the name-attributed re-emission of every mounted broker's
|
|
1667
|
+
* events, so a caller subscribes once for every endpoint instead of once per broker.
|
|
1353
1668
|
*
|
|
1354
1669
|
* @remarks
|
|
1355
1670
|
* - `pending` — an endpoint parked a form; the record itself carries `from` and `to`.
|
|
@@ -1363,47 +1678,81 @@ export declare type TerminalManagerEventMap = {
|
|
|
1363
1678
|
};
|
|
1364
1679
|
|
|
1365
1680
|
/**
|
|
1366
|
-
*
|
|
1367
|
-
*
|
|
1368
|
-
*
|
|
1681
|
+
* Declares a registry of named {@link PromptInterface} brokers, one per endpoint, so several
|
|
1682
|
+
* parties (agents, tools, humans) can ask forms of each other by name, attributed with a `from` →
|
|
1683
|
+
* `to` edge on every parked record.
|
|
1369
1684
|
*
|
|
1370
1685
|
* @remarks
|
|
1371
1686
|
* - **Accessors.** `terminal(name)` looks up one endpoint's broker; `terminals()` lists every
|
|
1372
|
-
* mounted
|
|
1687
|
+
* mounted broker, in insertion order. `terminals()` returns brokers, not keys; a name is an
|
|
1688
|
+
* argument the `terminal`, `add`, `ask`, `pending`, `answer`, `open`, `save`, and `remove`
|
|
1689
|
+
* methods take.
|
|
1373
1690
|
* - **`add`** mints, or returns, the broker for `name`. Idempotent; it never clobbers a live
|
|
1374
1691
|
* endpoint.
|
|
1375
|
-
* - **`ask`** is the attributed convenience: it parks `form` from `from` to `to
|
|
1376
|
-
*
|
|
1692
|
+
* - **`ask`** is the attributed convenience: it parks `form` from `from` to `to` and resolves with
|
|
1693
|
+
* the settled values. It never mounts `to` — an unmounted target rejects with a
|
|
1694
|
+
* {@link import('./errors.js').TerminalError} coded `TARGET`, so `add` the endpoint first.
|
|
1377
1695
|
* - **`pending()`** lists every endpoint's parked records; `pending(to)` scopes to one endpoint.
|
|
1378
1696
|
* - **`answer`** routes to the named endpoint's broker.
|
|
1379
1697
|
* - **`open`** restores, or returns the live, broker for `name` from the `store`.
|
|
1380
1698
|
* - **`save`** persists an endpoint's config snapshot; false when there is no store, or `name` is
|
|
1381
1699
|
* unknown.
|
|
1382
|
-
* - **Batch `remove`.** The array overload is declared
|
|
1383
|
-
* endpoint and reports
|
|
1700
|
+
* - **Batch `remove`.** The array overload is declared first: `remove(names)` removes every listed
|
|
1701
|
+
* endpoint and reports true only when all of them were mounted; `remove(name)` removes one;
|
|
1384
1702
|
* `remove()` removes every endpoint without destroying the manager.
|
|
1385
1703
|
* - **`destroy`** tears down every broker, then the manager's own emitter.
|
|
1386
1704
|
*/
|
|
1387
1705
|
export declare interface TerminalManagerInterface {
|
|
1706
|
+
/**
|
|
1707
|
+
* Holds the typed emitter every mounted broker's events are re-published on, attributed by name.
|
|
1708
|
+
*/
|
|
1388
1709
|
readonly emitter: EmitterInterface<TerminalManagerEventMap>;
|
|
1710
|
+
/** Reports how many endpoints are mounted. */
|
|
1389
1711
|
readonly count: number;
|
|
1712
|
+
/** Looks up one endpoint's broker by name. */
|
|
1390
1713
|
terminal(name: string): PromptInterface | undefined;
|
|
1391
|
-
|
|
1714
|
+
/** Lists every mounted broker, in insertion order. */
|
|
1715
|
+
terminals(): readonly PromptInterface[];
|
|
1716
|
+
/**
|
|
1717
|
+
* Mints, or returns unchanged, the broker for `name`. Idempotent; it never clobbers a live
|
|
1718
|
+
* endpoint.
|
|
1719
|
+
*/
|
|
1392
1720
|
add(name: string, options?: PromptOptions): PromptInterface;
|
|
1721
|
+
/**
|
|
1722
|
+
* Parks `form` from `from` to `to` and resolves with the settled values. Rejects `TARGET` or
|
|
1723
|
+
* `DEADLOCK`.
|
|
1724
|
+
*/
|
|
1393
1725
|
ask(from: string, to: string, form: FormInterface): Promise<FormValues>;
|
|
1726
|
+
/**
|
|
1727
|
+
* Lists every endpoint's parked records (`pending()`), or scopes to one endpoint (`pending(to)`).
|
|
1728
|
+
*/
|
|
1394
1729
|
pending(): readonly PendingForm[];
|
|
1395
1730
|
pending(to: string): readonly PendingForm[];
|
|
1731
|
+
/**
|
|
1732
|
+
* Routes an answer to the named endpoint's broker; `{ reason: 'target' }` when no endpoint
|
|
1733
|
+
* carries that name.
|
|
1734
|
+
*/
|
|
1396
1735
|
answer(to: string, id: string, values: FormValues): Result<FormValues, TerminalAnswerError>;
|
|
1736
|
+
/**
|
|
1737
|
+
* Returns the live broker for `name`, or restores an empty one from the `store`. Parked forms are
|
|
1738
|
+
* never resurrected.
|
|
1739
|
+
*/
|
|
1397
1740
|
open(name: string): Promise<PromptInterface | undefined>;
|
|
1741
|
+
/** Persists an endpoint's config snapshot; false with no store, or an unknown name. */
|
|
1398
1742
|
save(name: string): Promise<boolean>;
|
|
1743
|
+
/**
|
|
1744
|
+
* Removes a batch (`remove(names)`, the array overload declared first, true only when every name
|
|
1745
|
+
* was mounted), one endpoint, or every endpoint.
|
|
1746
|
+
*/
|
|
1399
1747
|
remove(names: readonly string[]): boolean;
|
|
1400
1748
|
remove(name: string): boolean;
|
|
1401
1749
|
remove(): void;
|
|
1750
|
+
/** Tears down every broker, then the manager's own emitter. */
|
|
1402
1751
|
destroy(): void;
|
|
1403
1752
|
}
|
|
1404
1753
|
|
|
1405
1754
|
/**
|
|
1406
|
-
*
|
|
1755
|
+
* Configures {@link import('./factories.js').createTerminalManager} and the
|
|
1407
1756
|
* {@link TerminalManagerInterface}.
|
|
1408
1757
|
*
|
|
1409
1758
|
* @remarks
|
|
@@ -1422,9 +1771,9 @@ export declare interface TerminalManagerOptions {
|
|
|
1422
1771
|
}
|
|
1423
1772
|
|
|
1424
1773
|
/**
|
|
1425
|
-
*
|
|
1426
|
-
* default. Parked forms are process-bound and are never resurrected, so `open` always
|
|
1427
|
-
*
|
|
1774
|
+
* Represents one endpoint's persisted config snapshot — `id` is the endpoint name and `timeout` its
|
|
1775
|
+
* configured default. Parked forms are process-bound and are never resurrected, so `open` always
|
|
1776
|
+
* restores an empty broker.
|
|
1428
1777
|
*/
|
|
1429
1778
|
export declare interface TerminalSnapshot {
|
|
1430
1779
|
readonly id: string;
|
|
@@ -1432,9 +1781,9 @@ export declare interface TerminalSnapshot {
|
|
|
1432
1781
|
}
|
|
1433
1782
|
|
|
1434
1783
|
/**
|
|
1435
|
-
*
|
|
1436
|
-
*
|
|
1437
|
-
* read.
|
|
1784
|
+
* Represents one opaque persisted row — the shape a table-backed store reads and writes. The store
|
|
1785
|
+
* is a `TableInterface<TerminalSnapshotRow>`, and `snapshot` is narrowed with
|
|
1786
|
+
* {@link import('./validators.js').isTerminalSnapshot} on read.
|
|
1438
1787
|
*/
|
|
1439
1788
|
export declare interface TerminalSnapshotRow {
|
|
1440
1789
|
readonly id: string;
|
|
@@ -1442,35 +1791,45 @@ export declare interface TerminalSnapshotRow {
|
|
|
1442
1791
|
}
|
|
1443
1792
|
|
|
1444
1793
|
/**
|
|
1445
|
-
*
|
|
1794
|
+
* Declares the point-access persistence seam for a {@link TerminalManagerInterface}'s endpoint configs.
|
|
1446
1795
|
* Every primitive is async; deleting an absent id is a no-op.
|
|
1447
1796
|
*/
|
|
1448
1797
|
export declare interface TerminalStoreInterface {
|
|
1798
|
+
/** Resolves the snapshot stored for `id`, or `undefined` when none is. */
|
|
1449
1799
|
get(id: string): Promise<TerminalSnapshot | undefined>;
|
|
1800
|
+
/** Inserts or replaces under the snapshot's own `id`; there is no id argument. */
|
|
1450
1801
|
set(snapshot: TerminalSnapshot): Promise<void>;
|
|
1802
|
+
/** Drops a snapshot by id. An absent id is a no-op, never a throw. */
|
|
1451
1803
|
delete(id: string): Promise<void>;
|
|
1452
1804
|
}
|
|
1453
1805
|
|
|
1454
|
-
/**
|
|
1455
|
-
export declare type
|
|
1806
|
+
/** Cancels a pending {@link TimerHandler} deadline — idempotent, safe to call after the timer fired. */
|
|
1807
|
+
export declare type TimerCancelFunction = () => void;
|
|
1456
1808
|
|
|
1457
1809
|
/**
|
|
1458
|
-
*
|
|
1459
|
-
* {@link
|
|
1810
|
+
* Represents one injected timer — arms a deadline `callback` to fire after `ms`, returning a
|
|
1811
|
+
* {@link TimerCancelFunction} that cancels it. The broker's timeout seam: the default wraps the host
|
|
1460
1812
|
* `setTimeout` and `clearTimeout`; a test injects a deterministic timer that captures the callback
|
|
1461
1813
|
* and fires it on demand, with no real time and no global patching.
|
|
1462
1814
|
*/
|
|
1463
|
-
declare type TimerHandler_2 = (callback: () => void, ms: number) =>
|
|
1815
|
+
declare type TimerHandler_2 = (callback: () => void, ms: number) => TimerCancelFunction;
|
|
1464
1816
|
export { TimerHandler_2 as TimerHandler }
|
|
1465
1817
|
|
|
1466
|
-
/**
|
|
1818
|
+
/**
|
|
1819
|
+
* Toggles `index` in a readonly index list — copy-on-write, returning the new sorted-by-insertion
|
|
1820
|
+
* list; the primitive {@link reduceCheckbox} calls.
|
|
1821
|
+
*
|
|
1822
|
+
* @param indices - The ticked indices, in tick order
|
|
1823
|
+
* @param index - The index to add when absent, or drop when present
|
|
1824
|
+
* @returns A new list carrying the toggled membership; the input is never mutated
|
|
1825
|
+
*/
|
|
1467
1826
|
export declare function toggleIndex(indices: readonly number[], index: number): readonly number[];
|
|
1468
1827
|
|
|
1469
1828
|
/**
|
|
1470
|
-
*
|
|
1829
|
+
* Represents one SSE-shaped wire frame — the `event` name, its already-stringified `data` payload, and an
|
|
1471
1830
|
* optional `id`. The transport-neutral shape {@link import('./helpers.js').serializePending},
|
|
1472
1831
|
* {@link import('./helpers.js').serializeExpire}, and
|
|
1473
|
-
* {@link import('./helpers.js').
|
|
1832
|
+
* {@link import('./helpers.js').serializeDestroy} build, with no `http` dependency.
|
|
1474
1833
|
*/
|
|
1475
1834
|
export declare interface WireEvent {
|
|
1476
1835
|
readonly event: string;
|