@rezi-ui/core 0.1.0-alpha.22 → 0.1.0-alpha.24
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/dist/app/createApp.d.ts +3 -0
- package/dist/app/createApp.d.ts.map +1 -1
- package/dist/app/createApp.js +346 -3
- package/dist/app/createApp.js.map +1 -1
- package/dist/app/inspectorOverlayHelper.d.ts.map +1 -1
- package/dist/app/inspectorOverlayHelper.js +15 -0
- package/dist/app/inspectorOverlayHelper.js.map +1 -1
- package/dist/app/runtimeBreadcrumbs.d.ts +1 -0
- package/dist/app/runtimeBreadcrumbs.d.ts.map +1 -1
- package/dist/app/runtimeBreadcrumbs.js +1 -0
- package/dist/app/runtimeBreadcrumbs.js.map +1 -1
- package/dist/app/widgetRenderer.d.ts +40 -2
- package/dist/app/widgetRenderer.d.ts.map +1 -1
- package/dist/app/widgetRenderer.js +492 -33
- package/dist/app/widgetRenderer.js.map +1 -1
- package/dist/backend.d.ts +10 -0
- package/dist/backend.d.ts.map +1 -1
- package/dist/backend.js +8 -0
- package/dist/backend.js.map +1 -1
- package/dist/forms/index.d.ts +1 -1
- package/dist/forms/index.d.ts.map +1 -1
- package/dist/forms/index.js.map +1 -1
- package/dist/forms/types.d.ts +39 -0
- package/dist/forms/types.d.ts.map +1 -1
- package/dist/forms/useForm.d.ts.map +1 -1
- package/dist/forms/useForm.js +53 -0
- package/dist/forms/useForm.js.map +1 -1
- package/dist/index.d.ts +51 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/dist/keybindings/index.d.ts +2 -2
- package/dist/keybindings/index.d.ts.map +1 -1
- package/dist/keybindings/index.js +1 -1
- package/dist/keybindings/index.js.map +1 -1
- package/dist/keybindings/manager.d.ts +21 -0
- package/dist/keybindings/manager.d.ts.map +1 -1
- package/dist/keybindings/manager.js +62 -4
- package/dist/keybindings/manager.js.map +1 -1
- package/dist/keybindings/types.d.ts +2 -0
- package/dist/keybindings/types.d.ts.map +1 -1
- package/dist/layout/constraints.d.ts +2 -2
- package/dist/layout/constraints.d.ts.map +1 -1
- package/dist/layout/constraints.js +4 -0
- package/dist/layout/constraints.js.map +1 -1
- package/dist/layout/engine/layoutEngine.d.ts.map +1 -1
- package/dist/layout/engine/layoutEngine.js +2 -0
- package/dist/layout/engine/layoutEngine.js.map +1 -1
- package/dist/layout/kinds/box.js +2 -2
- package/dist/layout/kinds/box.js.map +1 -1
- package/dist/layout/kinds/leaf.d.ts.map +1 -1
- package/dist/layout/kinds/leaf.js +7 -0
- package/dist/layout/kinds/leaf.js.map +1 -1
- package/dist/layout/kinds/navigation.js +2 -2
- package/dist/layout/kinds/navigation.js.map +1 -1
- package/dist/layout/kinds/overlays.js +2 -2
- package/dist/layout/kinds/overlays.js.map +1 -1
- package/dist/layout/responsive.d.ts +21 -0
- package/dist/layout/responsive.d.ts.map +1 -0
- package/dist/layout/responsive.js +86 -0
- package/dist/layout/responsive.js.map +1 -0
- package/dist/layout/spacing-scale.d.ts +4 -1
- package/dist/layout/spacing-scale.d.ts.map +1 -1
- package/dist/layout/spacing-scale.js +15 -8
- package/dist/layout/spacing-scale.js.map +1 -1
- package/dist/layout/types.d.ts +5 -2
- package/dist/layout/types.d.ts.map +1 -1
- package/dist/layout/types.js +0 -8
- package/dist/layout/types.js.map +1 -1
- package/dist/layout/validateProps.d.ts +3 -0
- package/dist/layout/validateProps.d.ts.map +1 -1
- package/dist/layout/validateProps.js +70 -30
- package/dist/layout/validateProps.js.map +1 -1
- package/dist/renderer/renderToDrawlist/renderTree.d.ts +1 -1
- package/dist/renderer/renderToDrawlist/renderTree.d.ts.map +1 -1
- package/dist/renderer/renderToDrawlist/renderTree.js +14 -2
- package/dist/renderer/renderToDrawlist/renderTree.js.map +1 -1
- package/dist/renderer/renderToDrawlist/spacing.d.ts.map +1 -1
- package/dist/renderer/renderToDrawlist/spacing.js +12 -8
- package/dist/renderer/renderToDrawlist/spacing.js.map +1 -1
- package/dist/renderer/renderToDrawlist/types.d.ts +2 -0
- package/dist/renderer/renderToDrawlist/types.d.ts.map +1 -1
- package/dist/renderer/renderToDrawlist/widgets/basic.d.ts +1 -1
- package/dist/renderer/renderToDrawlist/widgets/basic.d.ts.map +1 -1
- package/dist/renderer/renderToDrawlist/widgets/basic.js +218 -43
- package/dist/renderer/renderToDrawlist/widgets/basic.js.map +1 -1
- package/dist/renderer/renderToDrawlist/widgets/containers.d.ts.map +1 -1
- package/dist/renderer/renderToDrawlist/widgets/containers.js +6 -2
- package/dist/renderer/renderToDrawlist/widgets/containers.js.map +1 -1
- package/dist/renderer/renderToDrawlist.d.ts.map +1 -1
- package/dist/renderer/renderToDrawlist.js +1 -1
- package/dist/renderer/renderToDrawlist.js.map +1 -1
- package/dist/router/helpers.d.ts.map +1 -1
- package/dist/router/helpers.js +32 -4
- package/dist/router/helpers.js.map +1 -1
- package/dist/router/index.d.ts +1 -1
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/integration.d.ts +1 -0
- package/dist/router/integration.d.ts.map +1 -1
- package/dist/router/integration.js +109 -19
- package/dist/router/integration.js.map +1 -1
- package/dist/router/keybindings.d.ts.map +1 -1
- package/dist/router/keybindings.js +19 -12
- package/dist/router/keybindings.js.map +1 -1
- package/dist/router/router.d.ts +13 -0
- package/dist/router/router.d.ts.map +1 -1
- package/dist/router/router.js +37 -11
- package/dist/router/router.js.map +1 -1
- package/dist/router/types.d.ts +35 -0
- package/dist/router/types.d.ts.map +1 -1
- package/dist/runtime/commit.d.ts +21 -0
- package/dist/runtime/commit.d.ts.map +1 -1
- package/dist/runtime/commit.js +508 -326
- package/dist/runtime/commit.js.map +1 -1
- package/dist/runtime/focus.d.ts +2 -2
- package/dist/runtime/focus.js +2 -2
- package/dist/runtime/inputEditor.d.ts +22 -0
- package/dist/runtime/inputEditor.d.ts.map +1 -1
- package/dist/runtime/inputEditor.js +204 -10
- package/dist/runtime/inputEditor.js.map +1 -1
- package/dist/runtime/instances.d.ts +22 -0
- package/dist/runtime/instances.d.ts.map +1 -1
- package/dist/runtime/instances.js +64 -0
- package/dist/runtime/instances.js.map +1 -1
- package/dist/runtime/widgetMeta.d.ts +16 -0
- package/dist/runtime/widgetMeta.d.ts.map +1 -1
- package/dist/runtime/widgetMeta.js +231 -7
- package/dist/runtime/widgetMeta.js.map +1 -1
- package/dist/testing/events.d.ts +168 -0
- package/dist/testing/events.d.ts.map +1 -0
- package/dist/testing/events.js +445 -0
- package/dist/testing/events.js.map +1 -0
- package/dist/testing/index.d.ts +5 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +3 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/renderer.d.ts +59 -0
- package/dist/testing/renderer.d.ts.map +1 -0
- package/dist/testing/renderer.js +271 -0
- package/dist/testing/renderer.js.map +1 -0
- package/dist/ui.d.ts +1 -1
- package/dist/ui.d.ts.map +1 -1
- package/dist/widgets/canvas.d.ts.map +1 -1
- package/dist/widgets/canvas.js +136 -0
- package/dist/widgets/canvas.js.map +1 -1
- package/dist/widgets/collections.js +1 -1
- package/dist/widgets/collections.js.map +1 -1
- package/dist/widgets/composition.d.ts +58 -1
- package/dist/widgets/composition.d.ts.map +1 -1
- package/dist/widgets/composition.js +82 -1
- package/dist/widgets/composition.js.map +1 -1
- package/dist/widgets/dialogs/confirm.d.ts.map +1 -1
- package/dist/widgets/dialogs/confirm.js +8 -7
- package/dist/widgets/dialogs/confirm.js.map +1 -1
- package/dist/widgets/dialogs/dialog.d.ts +7 -0
- package/dist/widgets/dialogs/dialog.d.ts.map +1 -0
- package/dist/widgets/dialogs/dialog.js +8 -0
- package/dist/widgets/dialogs/dialog.js.map +1 -0
- package/dist/widgets/dialogs/index.d.ts +2 -1
- package/dist/widgets/dialogs/index.d.ts.map +1 -1
- package/dist/widgets/dialogs/index.js +1 -0
- package/dist/widgets/dialogs/index.js.map +1 -1
- package/dist/widgets/dialogs/types.d.ts +1 -0
- package/dist/widgets/dialogs/types.d.ts.map +1 -1
- package/dist/widgets/inspectorOverlay.d.ts.map +1 -1
- package/dist/widgets/inspectorOverlay.js +2 -0
- package/dist/widgets/inspectorOverlay.js.map +1 -1
- package/dist/widgets/types.d.ts +176 -0
- package/dist/widgets/types.d.ts.map +1 -1
- package/dist/widgets/ui.d.ts +104 -5
- package/dist/widgets/ui.d.ts.map +1 -1
- package/dist/widgets/ui.js +227 -9
- package/dist/widgets/ui.js.map +1 -1
- package/dist/widgets/useModalStack.d.ts +21 -0
- package/dist/widgets/useModalStack.d.ts.map +1 -0
- package/dist/widgets/useModalStack.js +107 -0
- package/dist/widgets/useModalStack.js.map +1 -0
- package/dist/widgets/useTable.d.ts +30 -0
- package/dist/widgets/useTable.d.ts.map +1 -0
- package/dist/widgets/useTable.js +184 -0
- package/dist/widgets/useTable.js.map +1 -0
- package/package.json +6 -2
package/dist/app/createApp.d.ts
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
*/
|
|
24
24
|
import { type RuntimeBackend } from "../backend.js";
|
|
25
25
|
import type { App, AppConfig, AppLayoutSnapshot, AppRenderMetrics } from "../index.js";
|
|
26
|
+
import { type ResponsiveBreakpointThresholds } from "../layout/responsive.js";
|
|
26
27
|
import type { RouteDefinition } from "../router/types.js";
|
|
27
28
|
import type { Theme } from "../theme/theme.js";
|
|
28
29
|
import type { ThemeDefinition } from "../theme/tokens.js";
|
|
@@ -31,6 +32,8 @@ type ResolvedAppConfig = Readonly<{
|
|
|
31
32
|
fpsCap: number;
|
|
32
33
|
maxEventBytes: number;
|
|
33
34
|
maxDrawlistBytes: number;
|
|
35
|
+
rootPadding: number;
|
|
36
|
+
breakpointThresholds: ResponsiveBreakpointThresholds;
|
|
34
37
|
useV2Cursor: boolean;
|
|
35
38
|
drawlistValidateParams: boolean;
|
|
36
39
|
drawlistReuseOutputBuffer: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createApp.d.ts","sourceRoot":"","sources":["../../src/app/createApp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EACV,GAAG,EACH,SAAS,EACT,iBAAiB,EACjB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"createApp.d.ts","sourceRoot":"","sources":["../../src/app/createApp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EACV,GAAG,EACH,SAAS,EACT,iBAAiB,EACjB,gBAAgB,EAKjB,MAAM,aAAa,CAAC;AAmBrB,OAAO,EACL,KAAK,8BAA8B,EAEpC,MAAM,yBAAyB,CAAC;AAMjC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAQ1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAsB1D,oDAAoD;AACpD,KAAK,iBAAiB,GAAG,QAAQ,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,EAAE,8BAA8B,CAAC;IACrD,WAAW,EAAE,OAAO,CAAC;IACrB,sBAAsB,EAAE,OAAO,CAAC;IAChC,yBAAyB,EAAE,OAAO,CAAC;IACnC,6BAA6B,EAAE,MAAM,CAAC;IACtC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACtE,iBAAiB,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACzE,CAAC,CAAC;AA0BH,eAAO,MAAM,uCAAuC,4BAA4B,CAAC;AACjF,eAAO,MAAM,gDAAgD,oCAAoC,CAAC;AAgIlG,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,iBAAiB,CA0DjF;AAuKD,KAAK,oBAAoB,GAAG,QAAQ,CAAC;IACnC,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,GAAG,eAAe,CAAC;CACjC,CAAC,CAAC;AAEH,KAAK,qBAAqB,CAAC,CAAC,IAAI,oBAAoB,GAClD,QAAQ,CAAC;IACP,YAAY,EAAE,CAAC,CAAC;IAChB,MAAM,CAAC,EAAE,SAAS,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC,CAAC;AAEL,KAAK,0BAA0B,GAAG,oBAAoB,GACpD,QAAQ,CAAC;IACP,MAAM,EAAE,SAAS,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;IAC1D,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACrC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC,CAAC;AAEL;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,0BAA0B,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AACxF,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC"}
|
package/dist/app/createApp.js
CHANGED
|
@@ -23,13 +23,16 @@
|
|
|
23
23
|
*/
|
|
24
24
|
import { ZrUiError } from "../abi.js";
|
|
25
25
|
import { BACKEND_DRAWLIST_V2_MARKER, BACKEND_DRAWLIST_VERSION_MARKER, BACKEND_FPS_CAP_MARKER, BACKEND_MAX_EVENT_BYTES_MARKER, FRAME_ACCEPTED_ACK_MARKER, } from "../backend.js";
|
|
26
|
-
import { createManagerState, getMode, registerBindings, registerModes, resetChordState, routeKeyEvent, setMode, } from "../keybindings/index.js";
|
|
26
|
+
import { createManagerState, getBindings, getMode, getPendingChord, registerBindings, registerModes, resetChordState, routeKeyEvent, setMode, } from "../keybindings/index.js";
|
|
27
|
+
import { ZR_MOD_ALT, ZR_MOD_CTRL, ZR_MOD_META } from "../keybindings/keyCodes.js";
|
|
28
|
+
import { normalizeBreakpointThresholds, } from "../layout/responsive.js";
|
|
27
29
|
import { PERF_ENABLED, perfMarkEnd, perfMarkStart, perfNow, perfRecord } from "../perf/perf.js";
|
|
28
30
|
import { parseEventBatchV1 } from "../protocol/zrev_v1.js";
|
|
29
31
|
import { createRouterIntegration } from "../router/integration.js";
|
|
30
32
|
import { DEFAULT_TERMINAL_PROFILE, terminalProfileFromCaps, } from "../terminalProfile.js";
|
|
31
33
|
import { defaultTheme } from "../theme/defaultTheme.js";
|
|
32
34
|
import { coerceToLegacyTheme } from "../theme/interop.js";
|
|
35
|
+
import { ui } from "../widgets/ui.js";
|
|
33
36
|
import { RawRenderer } from "./rawRenderer.js";
|
|
34
37
|
import { isRuntimeBreadcrumbEventKind, mergeRuntimeBreadcrumbSnapshot, toRuntimeBreadcrumbAction, } from "./runtimeBreadcrumbs.js";
|
|
35
38
|
import { AppStateMachine } from "./stateMachine.js";
|
|
@@ -41,6 +44,8 @@ const DEFAULT_CONFIG = Object.freeze({
|
|
|
41
44
|
fpsCap: 60,
|
|
42
45
|
maxEventBytes: 1 << 20 /* 1 MiB */,
|
|
43
46
|
maxDrawlistBytes: 2 << 20 /* 2 MiB */,
|
|
47
|
+
rootPadding: 0,
|
|
48
|
+
breakpointThresholds: normalizeBreakpointThresholds(undefined),
|
|
44
49
|
useV2Cursor: false,
|
|
45
50
|
drawlistValidateParams: true,
|
|
46
51
|
drawlistReuseOutputBuffer: true,
|
|
@@ -134,6 +139,27 @@ async function loadTerminalProfile(backend) {
|
|
|
134
139
|
return DEFAULT_TERMINAL_PROFILE;
|
|
135
140
|
}
|
|
136
141
|
}
|
|
142
|
+
function buildLayoutDebugOverlay(rectById) {
|
|
143
|
+
if (rectById.size === 0)
|
|
144
|
+
return null;
|
|
145
|
+
const rows = [...rectById.entries()]
|
|
146
|
+
.sort((a, b) => a[0].localeCompare(b[0]))
|
|
147
|
+
.slice(0, 18)
|
|
148
|
+
.map(([id, rect]) => ui.text(`${id} ${String(rect.x)},${String(rect.y)} ${String(rect.w)}x${String(rect.h)}`));
|
|
149
|
+
const panel = ui.box({ border: "single", title: `Layout (${String(rectById.size)})`, p: 1 }, [
|
|
150
|
+
ui.column({ gap: 0 }, rows),
|
|
151
|
+
]);
|
|
152
|
+
return ui.layer({
|
|
153
|
+
id: "rezi.layout.debug.overlay",
|
|
154
|
+
zIndex: 2_000_000_000,
|
|
155
|
+
modal: false,
|
|
156
|
+
backdrop: "none",
|
|
157
|
+
closeOnEscape: false,
|
|
158
|
+
content: ui.column({ width: "100%", height: "100%", justify: "end", p: 1 }, [
|
|
159
|
+
ui.row({ width: "100%", justify: "start" }, [panel]),
|
|
160
|
+
]),
|
|
161
|
+
});
|
|
162
|
+
}
|
|
137
163
|
/** Apply defaults to user-provided config, validating all values. */
|
|
138
164
|
export function resolveAppConfig(config) {
|
|
139
165
|
if (!config)
|
|
@@ -147,6 +173,10 @@ export function resolveAppConfig(config) {
|
|
|
147
173
|
const maxDrawlistBytes = config.maxDrawlistBytes === undefined
|
|
148
174
|
? DEFAULT_CONFIG.maxDrawlistBytes
|
|
149
175
|
: requirePositiveInt("maxDrawlistBytes", config.maxDrawlistBytes);
|
|
176
|
+
const rootPadding = config.rootPadding === undefined
|
|
177
|
+
? DEFAULT_CONFIG.rootPadding
|
|
178
|
+
: requireNonNegativeInt("rootPadding", config.rootPadding);
|
|
179
|
+
const breakpointThresholds = normalizeBreakpointThresholds(config.breakpoints);
|
|
150
180
|
const useV2Cursor = config.useV2Cursor === true;
|
|
151
181
|
const drawlistValidateParams = config.drawlistValidateParams === undefined
|
|
152
182
|
? DEFAULT_CONFIG.drawlistValidateParams
|
|
@@ -166,6 +196,8 @@ export function resolveAppConfig(config) {
|
|
|
166
196
|
fpsCap,
|
|
167
197
|
maxEventBytes,
|
|
168
198
|
maxDrawlistBytes,
|
|
199
|
+
rootPadding,
|
|
200
|
+
breakpointThresholds,
|
|
169
201
|
useV2Cursor,
|
|
170
202
|
drawlistValidateParams,
|
|
171
203
|
drawlistReuseOutputBuffer,
|
|
@@ -180,6 +212,83 @@ function describeThrown(v) {
|
|
|
180
212
|
return `${v.name}: ${v.message}`;
|
|
181
213
|
return String(v);
|
|
182
214
|
}
|
|
215
|
+
const KEY_Q = 81;
|
|
216
|
+
const KEY_R = 82;
|
|
217
|
+
function captureTopLevelViewError(value) {
|
|
218
|
+
if (value instanceof Error) {
|
|
219
|
+
return Object.freeze({
|
|
220
|
+
code: "ZRUI_USER_CODE_THROW",
|
|
221
|
+
detail: `${value.name}: ${value.message}`,
|
|
222
|
+
message: value.message,
|
|
223
|
+
...(typeof value.stack === "string" && value.stack.length > 0 ? { stack: value.stack } : {}),
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
const detail = String(value);
|
|
227
|
+
return Object.freeze({
|
|
228
|
+
code: "ZRUI_USER_CODE_THROW",
|
|
229
|
+
detail,
|
|
230
|
+
message: detail,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
function buildTopLevelViewErrorScreen(error) {
|
|
234
|
+
const lines = [`Code: ${error.code}`, `Message: ${error.message}`];
|
|
235
|
+
if (error.stack === undefined || error.stack.length === 0) {
|
|
236
|
+
lines.push(`Detail: ${error.detail}`);
|
|
237
|
+
}
|
|
238
|
+
return ui.column({ width: "100%", height: "100%", justify: "center", align: "center", p: 1 }, [
|
|
239
|
+
ui.box({
|
|
240
|
+
width: "100%",
|
|
241
|
+
height: "100%",
|
|
242
|
+
border: "single",
|
|
243
|
+
title: "Runtime Error",
|
|
244
|
+
p: 1,
|
|
245
|
+
}, [
|
|
246
|
+
ui.errorDisplay(lines.join("\n"), {
|
|
247
|
+
title: "Top-level view() threw",
|
|
248
|
+
...(error.stack === undefined || error.stack.length === 0
|
|
249
|
+
? {}
|
|
250
|
+
: { stack: error.stack, showStack: true }),
|
|
251
|
+
}),
|
|
252
|
+
ui.callout("Press R to retry, Q to quit", { variant: "warning" }),
|
|
253
|
+
]),
|
|
254
|
+
]);
|
|
255
|
+
}
|
|
256
|
+
function isUnmodifiedLetterKey(mods) {
|
|
257
|
+
return (mods & (ZR_MOD_CTRL | ZR_MOD_ALT | ZR_MOD_META)) === 0;
|
|
258
|
+
}
|
|
259
|
+
function isTopLevelRetryEvent(ev) {
|
|
260
|
+
if (ev.kind === "key") {
|
|
261
|
+
return ev.action === "down" && isUnmodifiedLetterKey(ev.mods) && ev.key === KEY_R;
|
|
262
|
+
}
|
|
263
|
+
if (ev.kind === "text") {
|
|
264
|
+
return ev.codepoint === KEY_R || ev.codepoint === 114;
|
|
265
|
+
}
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
function isTopLevelQuitEvent(ev) {
|
|
269
|
+
if (ev.kind === "key") {
|
|
270
|
+
return ev.action === "down" && isUnmodifiedLetterKey(ev.mods) && ev.key === KEY_Q;
|
|
271
|
+
}
|
|
272
|
+
if (ev.kind === "text") {
|
|
273
|
+
return ev.codepoint === KEY_Q || ev.codepoint === 113;
|
|
274
|
+
}
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
277
|
+
function readProcessLike() {
|
|
278
|
+
const processRef = globalThis.process;
|
|
279
|
+
if (!processRef || typeof processRef !== "object")
|
|
280
|
+
return null;
|
|
281
|
+
return processRef;
|
|
282
|
+
}
|
|
283
|
+
function removeSignalHandler(proc, signal, handler) {
|
|
284
|
+
if (typeof proc.off === "function") {
|
|
285
|
+
proc.off(signal, handler);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
if (typeof proc.removeListener === "function") {
|
|
289
|
+
proc.removeListener(signal, handler);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
183
292
|
/**
|
|
184
293
|
* Convert a text codepoint to a key code for keybinding matching.
|
|
185
294
|
* Letters are normalized to uppercase (A-Z = 65-90).
|
|
@@ -240,10 +349,14 @@ export function createApp(opts) {
|
|
|
240
349
|
let mode = null;
|
|
241
350
|
let drawFn = null;
|
|
242
351
|
let viewFn = null;
|
|
352
|
+
let topLevelViewError = null;
|
|
353
|
+
let debugLayoutEnabled = false;
|
|
243
354
|
const hasInitialState = "initialState" in opts;
|
|
244
355
|
let committedState = hasInitialState ? opts.initialState : Object.freeze({});
|
|
245
356
|
const updates = new UpdateQueue();
|
|
246
357
|
const handlers = [];
|
|
358
|
+
const focusHandlers = [];
|
|
359
|
+
let lastEmittedFocusId = null;
|
|
247
360
|
const DIRTY_RENDER = 1 << 0;
|
|
248
361
|
const DIRTY_LAYOUT = 1 << 1;
|
|
249
362
|
const DIRTY_VIEW = 1 << 2;
|
|
@@ -264,6 +377,7 @@ export function createApp(opts) {
|
|
|
264
377
|
let inEventHandlerDepth = 0;
|
|
265
378
|
let lifecycleBusy = null;
|
|
266
379
|
let pollToken = 0;
|
|
380
|
+
let settleActiveRun = null;
|
|
267
381
|
let userCommitScheduled = false;
|
|
268
382
|
// Perf tracking: submit time for backend_ack calculation
|
|
269
383
|
let submitFrameStartMs = null;
|
|
@@ -337,6 +451,8 @@ export function createApp(opts) {
|
|
|
337
451
|
backend,
|
|
338
452
|
drawlistVersion,
|
|
339
453
|
maxDrawlistBytes: config.maxDrawlistBytes,
|
|
454
|
+
rootPadding: config.rootPadding,
|
|
455
|
+
breakpointThresholds: config.breakpointThresholds,
|
|
340
456
|
terminalProfile,
|
|
341
457
|
useV2Cursor: config.useV2Cursor,
|
|
342
458
|
...(opts.config?.drawlistValidateParams === undefined
|
|
@@ -348,6 +464,7 @@ export function createApp(opts) {
|
|
|
348
464
|
requestView: requestViewFromRenderer,
|
|
349
465
|
collectRuntimeBreadcrumbs: runtimeBreadcrumbsEnabled,
|
|
350
466
|
});
|
|
467
|
+
lastEmittedFocusId = widgetRenderer.getFocusedId();
|
|
351
468
|
let routeStateUpdater = null;
|
|
352
469
|
let routerIntegration = null;
|
|
353
470
|
if (routes !== undefined) {
|
|
@@ -390,9 +507,13 @@ export function createApp(opts) {
|
|
|
390
507
|
return false;
|
|
391
508
|
}
|
|
392
509
|
function applyRoutedKeybindingState(routeInputState, routeNextState) {
|
|
510
|
+
const previousChordState = keybindingState.chordState;
|
|
393
511
|
// If handlers did not mutate keybinding state, take the routed state directly.
|
|
394
512
|
if (keybindingState === routeInputState) {
|
|
395
513
|
keybindingState = routeNextState;
|
|
514
|
+
if (keybindingState.chordState !== previousChordState) {
|
|
515
|
+
markDirty(DIRTY_VIEW);
|
|
516
|
+
}
|
|
396
517
|
return;
|
|
397
518
|
}
|
|
398
519
|
// Preserve handler-triggered mode changes (for example app.setMode() in a binding).
|
|
@@ -405,6 +526,9 @@ export function createApp(opts) {
|
|
|
405
526
|
...keybindingState,
|
|
406
527
|
chordState: routeNextState.chordState,
|
|
407
528
|
});
|
|
529
|
+
if (keybindingState.chordState !== previousChordState) {
|
|
530
|
+
markDirty(DIRTY_VIEW);
|
|
531
|
+
}
|
|
408
532
|
}
|
|
409
533
|
function noteBreadcrumbEvent(kind) {
|
|
410
534
|
breadcrumbEventTracked = false;
|
|
@@ -430,6 +554,33 @@ export function createApp(opts) {
|
|
|
430
554
|
return;
|
|
431
555
|
breadcrumbLastAction = toRuntimeBreadcrumbAction(action);
|
|
432
556
|
}
|
|
557
|
+
function retryTopLevelViewError() {
|
|
558
|
+
topLevelViewError = null;
|
|
559
|
+
markDirty(DIRTY_VIEW | DIRTY_LAYOUT);
|
|
560
|
+
}
|
|
561
|
+
function quitFromTopLevelViewError() {
|
|
562
|
+
let stopPromise;
|
|
563
|
+
try {
|
|
564
|
+
stopPromise = app.stop();
|
|
565
|
+
}
|
|
566
|
+
catch {
|
|
567
|
+
try {
|
|
568
|
+
app.dispose();
|
|
569
|
+
}
|
|
570
|
+
catch {
|
|
571
|
+
// ignore
|
|
572
|
+
}
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
void stopPromise.finally(() => {
|
|
576
|
+
try {
|
|
577
|
+
app.dispose();
|
|
578
|
+
}
|
|
579
|
+
catch {
|
|
580
|
+
// ignore
|
|
581
|
+
}
|
|
582
|
+
});
|
|
583
|
+
}
|
|
433
584
|
function buildRuntimeBreadcrumbSnapshot(renderTimeMs) {
|
|
434
585
|
if (!runtimeBreadcrumbsEnabled)
|
|
435
586
|
return null;
|
|
@@ -476,6 +627,7 @@ export function createApp(opts) {
|
|
|
476
627
|
...(opts.routeHistoryMaxDepth === undefined
|
|
477
628
|
? {}
|
|
478
629
|
: { maxHistoryDepth: opts.routeHistoryMaxDepth }),
|
|
630
|
+
getState: () => committedState,
|
|
479
631
|
// Route transitions can swap the entire screen tree; force both commit
|
|
480
632
|
// and layout so id->rect indexes and focus metadata stay in sync.
|
|
481
633
|
requestRouteRender: () => markDirty(DIRTY_VIEW | DIRTY_LAYOUT),
|
|
@@ -507,6 +659,28 @@ export function createApp(opts) {
|
|
|
507
659
|
inEventHandlerDepth--;
|
|
508
660
|
}
|
|
509
661
|
}
|
|
662
|
+
function emitFocusChangeIfNeeded() {
|
|
663
|
+
const focusedId = widgetRenderer.getFocusedId();
|
|
664
|
+
if (focusedId === lastEmittedFocusId)
|
|
665
|
+
return true;
|
|
666
|
+
lastEmittedFocusId = focusedId;
|
|
667
|
+
const info = widgetRenderer.getCurrentFocusInfo();
|
|
668
|
+
const snapshot = [];
|
|
669
|
+
for (const slot of focusHandlers) {
|
|
670
|
+
if (slot.active.value)
|
|
671
|
+
snapshot.push(slot.fn);
|
|
672
|
+
}
|
|
673
|
+
for (const fn of snapshot) {
|
|
674
|
+
try {
|
|
675
|
+
fn(info);
|
|
676
|
+
}
|
|
677
|
+
catch (e) {
|
|
678
|
+
enqueueFatal("ZRUI_USER_CODE_THROW", `onFocusChange handler threw: ${describeThrown(e)}`);
|
|
679
|
+
return false;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
return true;
|
|
683
|
+
}
|
|
510
684
|
function doFatal(code, detail) {
|
|
511
685
|
if (sm.state !== "Running")
|
|
512
686
|
return;
|
|
@@ -546,6 +720,7 @@ export function createApp(opts) {
|
|
|
546
720
|
catch {
|
|
547
721
|
// ignore
|
|
548
722
|
}
|
|
723
|
+
settleActiveRun?.();
|
|
549
724
|
});
|
|
550
725
|
}
|
|
551
726
|
catch {
|
|
@@ -555,6 +730,7 @@ export function createApp(opts) {
|
|
|
555
730
|
catch {
|
|
556
731
|
// ignore
|
|
557
732
|
}
|
|
733
|
+
settleActiveRun?.();
|
|
558
734
|
}
|
|
559
735
|
}
|
|
560
736
|
function releaseOnce(batch) {
|
|
@@ -609,7 +785,13 @@ export function createApp(opts) {
|
|
|
609
785
|
const prev = viewport;
|
|
610
786
|
if (prev === null || prev.cols !== ev.cols || prev.rows !== ev.rows) {
|
|
611
787
|
viewport = Object.freeze({ cols: ev.cols, rows: ev.rows });
|
|
612
|
-
|
|
788
|
+
if (widgetRenderer.hasViewportAwareComposites()) {
|
|
789
|
+
widgetRenderer.invalidateCompositeWidgets();
|
|
790
|
+
markDirty(DIRTY_LAYOUT | DIRTY_VIEW);
|
|
791
|
+
}
|
|
792
|
+
else {
|
|
793
|
+
markDirty(DIRTY_LAYOUT);
|
|
794
|
+
}
|
|
613
795
|
}
|
|
614
796
|
}
|
|
615
797
|
if (ev.kind === "tick" && mode === "widget") {
|
|
@@ -635,6 +817,25 @@ export function createApp(opts) {
|
|
|
635
817
|
}
|
|
636
818
|
}
|
|
637
819
|
}
|
|
820
|
+
if (mode === "widget" && topLevelViewError !== null) {
|
|
821
|
+
if (isTopLevelRetryEvent(ev)) {
|
|
822
|
+
noteBreadcrumbConsumptionPath("widgetRouting");
|
|
823
|
+
retryTopLevelViewError();
|
|
824
|
+
continue;
|
|
825
|
+
}
|
|
826
|
+
if (isTopLevelQuitEvent(ev)) {
|
|
827
|
+
noteBreadcrumbConsumptionPath("widgetRouting");
|
|
828
|
+
quitFromTopLevelViewError();
|
|
829
|
+
continue;
|
|
830
|
+
}
|
|
831
|
+
if (ev.kind === "key" ||
|
|
832
|
+
ev.kind === "text" ||
|
|
833
|
+
ev.kind === "paste" ||
|
|
834
|
+
ev.kind === "mouse") {
|
|
835
|
+
noteBreadcrumbConsumptionPath("widgetRouting");
|
|
836
|
+
continue;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
638
839
|
const isWidgetRoutableEvent = ev.kind === "key" || ev.kind === "text" || ev.kind === "paste" || ev.kind === "mouse";
|
|
639
840
|
if (mode === "widget" && isWidgetRoutableEvent) {
|
|
640
841
|
if (keybindingsEnabled) {
|
|
@@ -708,6 +909,8 @@ export function createApp(opts) {
|
|
|
708
909
|
enqueueFatal("ZRUI_USER_CODE_THROW", `widget routing threw: ${describeThrown(e)}`);
|
|
709
910
|
return;
|
|
710
911
|
}
|
|
912
|
+
if (!emitFocusChangeIfNeeded())
|
|
913
|
+
return;
|
|
711
914
|
if (routed.needsRender)
|
|
712
915
|
markDirty(DIRTY_RENDER);
|
|
713
916
|
if (routed.action) {
|
|
@@ -914,14 +1117,37 @@ export function createApp(opts) {
|
|
|
914
1117
|
// newly-committed tree against stale layout nodes until the next resize.
|
|
915
1118
|
checkLayoutStability: (pendingDirtyFlags & DIRTY_LAYOUT) === 0 && (pendingDirtyFlags & DIRTY_VIEW) !== 0,
|
|
916
1119
|
};
|
|
1120
|
+
const resilientView = (state) => {
|
|
1121
|
+
if (topLevelViewError !== null) {
|
|
1122
|
+
return buildTopLevelViewErrorScreen(topLevelViewError);
|
|
1123
|
+
}
|
|
1124
|
+
try {
|
|
1125
|
+
return vf(state);
|
|
1126
|
+
}
|
|
1127
|
+
catch (e) {
|
|
1128
|
+
topLevelViewError = captureTopLevelViewError(e);
|
|
1129
|
+
return buildTopLevelViewErrorScreen(topLevelViewError);
|
|
1130
|
+
}
|
|
1131
|
+
};
|
|
917
1132
|
const renderStart = perfNow();
|
|
918
1133
|
const submitToken = perfMarkStart("submit_frame");
|
|
919
|
-
const
|
|
1134
|
+
const frameView = debugLayoutEnabled
|
|
1135
|
+
? (state) => {
|
|
1136
|
+
const root = resilientView(state);
|
|
1137
|
+
const overlay = buildLayoutDebugOverlay(widgetRenderer.getRectByIdIndex());
|
|
1138
|
+
if (!overlay)
|
|
1139
|
+
return root;
|
|
1140
|
+
return ui.layers([root, overlay]);
|
|
1141
|
+
}
|
|
1142
|
+
: resilientView;
|
|
1143
|
+
const res = widgetRenderer.submitFrame(frameView, snapshot, viewport, theme, hooks, plan);
|
|
920
1144
|
perfMarkEnd("submit_frame", submitToken);
|
|
921
1145
|
if (!res.ok) {
|
|
922
1146
|
fatalNowOrEnqueue(res.code, res.detail);
|
|
923
1147
|
return;
|
|
924
1148
|
}
|
|
1149
|
+
if (!emitFocusChangeIfNeeded())
|
|
1150
|
+
return;
|
|
925
1151
|
const renderTime = perfNow() - renderStart;
|
|
926
1152
|
const runtimeBreadcrumbs = buildRuntimeBreadcrumbSnapshot(Math.max(0, renderTime));
|
|
927
1153
|
if (!emitInternalRenderMetrics(renderTime, runtimeBreadcrumbs))
|
|
@@ -1079,6 +1305,17 @@ export function createApp(opts) {
|
|
|
1079
1305
|
active.value = false;
|
|
1080
1306
|
};
|
|
1081
1307
|
},
|
|
1308
|
+
onFocusChange(handler) {
|
|
1309
|
+
assertOperational("onFocusChange");
|
|
1310
|
+
if (inCommit || inRender) {
|
|
1311
|
+
throwCode("ZRUI_REENTRANT_CALL", "onFocusChange: re-entrant call");
|
|
1312
|
+
}
|
|
1313
|
+
const active = { value: true };
|
|
1314
|
+
focusHandlers.push({ fn: handler, active });
|
|
1315
|
+
return () => {
|
|
1316
|
+
active.value = false;
|
|
1317
|
+
};
|
|
1318
|
+
},
|
|
1082
1319
|
update(updater) {
|
|
1083
1320
|
assertOperational("update");
|
|
1084
1321
|
if (inCommit)
|
|
@@ -1103,6 +1340,18 @@ export function createApp(opts) {
|
|
|
1103
1340
|
theme = nextTheme;
|
|
1104
1341
|
requestRenderFromRenderer();
|
|
1105
1342
|
},
|
|
1343
|
+
debugLayout(enabled) {
|
|
1344
|
+
assertOperational("debugLayout");
|
|
1345
|
+
if (mode === "raw") {
|
|
1346
|
+
throwCode("ZRUI_MODE_CONFLICT", "debugLayout: not available in draw mode");
|
|
1347
|
+
}
|
|
1348
|
+
const next = enabled === undefined ? !debugLayoutEnabled : enabled === true;
|
|
1349
|
+
if (next === debugLayoutEnabled)
|
|
1350
|
+
return debugLayoutEnabled;
|
|
1351
|
+
debugLayoutEnabled = next;
|
|
1352
|
+
requestViewFromRenderer();
|
|
1353
|
+
return debugLayoutEnabled;
|
|
1354
|
+
},
|
|
1106
1355
|
start() {
|
|
1107
1356
|
assertOperational("start");
|
|
1108
1357
|
assertNotReentrant("start");
|
|
@@ -1122,6 +1371,7 @@ export function createApp(opts) {
|
|
|
1122
1371
|
}
|
|
1123
1372
|
return p.then(async () => {
|
|
1124
1373
|
lifecycleBusy = null;
|
|
1374
|
+
topLevelViewError = null;
|
|
1125
1375
|
terminalProfile = await loadTerminalProfile(backend);
|
|
1126
1376
|
widgetRenderer.setTerminalProfile(terminalProfile);
|
|
1127
1377
|
sm.toRunning();
|
|
@@ -1134,6 +1384,91 @@ export function createApp(opts) {
|
|
|
1134
1384
|
throw new ZrUiError("ZRUI_BACKEND_ERROR", `backend.start rejected: ${describeThrown(e)}`);
|
|
1135
1385
|
});
|
|
1136
1386
|
},
|
|
1387
|
+
run() {
|
|
1388
|
+
assertOperational("run");
|
|
1389
|
+
assertNotReentrant("run");
|
|
1390
|
+
if (lifecycleBusy)
|
|
1391
|
+
throwCode("ZRUI_INVALID_STATE", "run: lifecycle operation already in flight");
|
|
1392
|
+
sm.assertOneOf(["Created", "Stopped"], "run: must be Created or Stopped");
|
|
1393
|
+
if (mode === null)
|
|
1394
|
+
throwCode("ZRUI_NO_RENDER_MODE", "run: no render mode selected");
|
|
1395
|
+
const proc = readProcessLike();
|
|
1396
|
+
const addSignalHandler = proc !== null && typeof proc.on === "function" ? proc.on.bind(proc) : null;
|
|
1397
|
+
const canRegisterSignals = addSignalHandler !== null;
|
|
1398
|
+
const signals = ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
1399
|
+
const handlers = [];
|
|
1400
|
+
let runSettled = false;
|
|
1401
|
+
let resolveRun;
|
|
1402
|
+
const runPromise = new Promise((resolve) => {
|
|
1403
|
+
resolveRun = resolve;
|
|
1404
|
+
});
|
|
1405
|
+
const cleanupSignalHandlers = () => {
|
|
1406
|
+
if (!proc)
|
|
1407
|
+
return;
|
|
1408
|
+
for (const entry of handlers) {
|
|
1409
|
+
removeSignalHandler(proc, entry.signal, entry.handler);
|
|
1410
|
+
}
|
|
1411
|
+
handlers.length = 0;
|
|
1412
|
+
};
|
|
1413
|
+
const settleRun = () => {
|
|
1414
|
+
if (runSettled)
|
|
1415
|
+
return;
|
|
1416
|
+
runSettled = true;
|
|
1417
|
+
cleanupSignalHandlers();
|
|
1418
|
+
if (settleActiveRun === settleRun)
|
|
1419
|
+
settleActiveRun = null;
|
|
1420
|
+
resolveRun();
|
|
1421
|
+
};
|
|
1422
|
+
const onSignal = () => {
|
|
1423
|
+
if (runSettled)
|
|
1424
|
+
return;
|
|
1425
|
+
runSettled = true;
|
|
1426
|
+
cleanupSignalHandlers();
|
|
1427
|
+
if (settleActiveRun === settleRun)
|
|
1428
|
+
settleActiveRun = null;
|
|
1429
|
+
void (async () => {
|
|
1430
|
+
try {
|
|
1431
|
+
if (sm.state === "Running")
|
|
1432
|
+
await app.stop();
|
|
1433
|
+
}
|
|
1434
|
+
catch {
|
|
1435
|
+
// ignore
|
|
1436
|
+
}
|
|
1437
|
+
try {
|
|
1438
|
+
app.dispose();
|
|
1439
|
+
}
|
|
1440
|
+
catch {
|
|
1441
|
+
// ignore
|
|
1442
|
+
}
|
|
1443
|
+
try {
|
|
1444
|
+
proc?.exit?.(0);
|
|
1445
|
+
}
|
|
1446
|
+
catch {
|
|
1447
|
+
// ignore
|
|
1448
|
+
}
|
|
1449
|
+
resolveRun();
|
|
1450
|
+
})();
|
|
1451
|
+
};
|
|
1452
|
+
if (canRegisterSignals) {
|
|
1453
|
+
for (const signal of signals) {
|
|
1454
|
+
const handler = () => onSignal();
|
|
1455
|
+
handlers.push(Object.freeze({ signal, handler }));
|
|
1456
|
+
addSignalHandler(signal, handler);
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
settleActiveRun = settleRun;
|
|
1460
|
+
return app.start().then(() => {
|
|
1461
|
+
if (!canRegisterSignals) {
|
|
1462
|
+
settleRun();
|
|
1463
|
+
}
|
|
1464
|
+
return runPromise;
|
|
1465
|
+
}, (e) => {
|
|
1466
|
+
cleanupSignalHandlers();
|
|
1467
|
+
if (settleActiveRun === settleRun)
|
|
1468
|
+
settleActiveRun = null;
|
|
1469
|
+
throw e;
|
|
1470
|
+
});
|
|
1471
|
+
},
|
|
1137
1472
|
stop() {
|
|
1138
1473
|
assertOperational("stop");
|
|
1139
1474
|
assertNotReentrant("stop");
|
|
@@ -1158,6 +1493,7 @@ export function createApp(opts) {
|
|
|
1158
1493
|
return p.then(() => {
|
|
1159
1494
|
lifecycleBusy = null;
|
|
1160
1495
|
sm.toStopped();
|
|
1496
|
+
settleActiveRun?.();
|
|
1161
1497
|
}, (e) => {
|
|
1162
1498
|
lifecycleBusy = null;
|
|
1163
1499
|
throw new ZrUiError("ZRUI_BACKEND_ERROR", `backend.stop rejected: ${describeThrown(e)}`);
|
|
@@ -1191,6 +1527,7 @@ export function createApp(opts) {
|
|
|
1191
1527
|
catch {
|
|
1192
1528
|
// ignore
|
|
1193
1529
|
}
|
|
1530
|
+
settleActiveRun?.();
|
|
1194
1531
|
},
|
|
1195
1532
|
/* --- Keybinding API --- */
|
|
1196
1533
|
keys(bindings) {
|
|
@@ -1210,6 +1547,12 @@ export function createApp(opts) {
|
|
|
1210
1547
|
getMode() {
|
|
1211
1548
|
return getMode(keybindingState);
|
|
1212
1549
|
},
|
|
1550
|
+
getBindings(mode) {
|
|
1551
|
+
return getBindings(keybindingState, mode);
|
|
1552
|
+
},
|
|
1553
|
+
get pendingChord() {
|
|
1554
|
+
return getPendingChord(keybindingState);
|
|
1555
|
+
},
|
|
1213
1556
|
getTerminalProfile() {
|
|
1214
1557
|
return terminalProfile;
|
|
1215
1558
|
},
|