@opentui/keymap 0.2.1 → 0.2.3
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 +64 -30
- package/chunks/index-frk6sdcd.js +409 -0
- package/chunks/index-frk6sdcd.js.map +14 -0
- package/package.json +43 -23
- package/src/addons/index.js +1130 -0
- package/src/addons/index.js.map +25 -0
- package/src/addons/opentui/edit-buffer-bindings.d.ts +6 -2
- package/src/addons/opentui/index.d.ts +2 -2
- package/src/addons/opentui/index.js +467 -0
- package/src/addons/opentui/index.js.map +12 -0
- package/src/addons/universal/binding-overrides.d.ts +6 -0
- package/src/addons/universal/dead-bindings.d.ts +1 -1
- package/src/addons/universal/default-parser.d.ts +2 -2
- package/src/addons/universal/ex-commands.d.ts +11 -8
- package/src/addons/universal/index.d.ts +3 -1
- package/src/addons/universal/leader.d.ts +1 -1
- package/src/addons/universal/metadata.d.ts +2 -2
- package/src/addons/universal/mod-bindings.d.ts +6 -0
- package/src/addons/universal/unresolved-commands.d.ts +1 -1
- package/src/extras/binding-sections.d.ts +18 -0
- package/src/extras/command-bindings.d.ts +19 -0
- package/src/extras/formatting.d.ts +27 -0
- package/src/extras/graph.d.ts +9 -0
- package/src/extras/graph.js +373 -0
- package/src/extras/graph.js.map +11 -0
- package/src/extras/index.d.ts +6 -0
- package/src/extras/index.js +239 -0
- package/src/extras/index.js.map +12 -0
- package/src/extras/lib/graph-snapshot.d.ts +14 -0
- package/src/extras/lib/graph-types.d.ts +83 -0
- package/src/html.d.ts +3 -3
- package/src/html.js +297 -0
- package/src/html.js.map +10 -0
- package/src/index.d.ts +3 -1
- package/src/index.js +4492 -0
- package/src/index.js.map +34 -0
- package/src/keymap.d.ts +23 -35
- package/src/lib/emitter.d.ts +1 -2
- package/src/lib/registry.d.ts +2 -2
- package/src/lib/runtime-utils.d.ts +34 -0
- package/src/opentui.d.ts +1 -3
- package/src/opentui.js +133 -0
- package/src/opentui.js.map +10 -0
- package/src/react/index.d.ts +5 -19
- package/{react → src/react}/index.js +3 -0
- package/src/react/index.js.map +10 -0
- package/src/runtime-modules.d.ts +20 -0
- package/src/runtime-modules.js +28 -0
- package/src/runtime-modules.js.map +10 -0
- package/src/services/activation.d.ts +7 -33
- package/src/services/active-key-cache.d.ts +29 -0
- package/src/services/command-catalog.d.ts +28 -45
- package/src/services/command-executor.d.ts +7 -13
- package/src/services/compiler.d.ts +6 -12
- package/src/services/conditions.d.ts +4 -16
- package/src/services/dispatch-decisions.d.ts +21 -0
- package/src/services/dispatch-patterns.d.ts +5 -0
- package/src/services/dispatch.d.ts +6 -42
- package/src/services/environment.d.ts +6 -21
- package/src/services/extension-context.d.ts +16 -0
- package/src/services/layer-diagnostics.d.ts +10 -0
- package/src/services/layers.d.ts +15 -23
- package/src/services/notify.d.ts +6 -8
- package/src/services/pending-sequence.d.ts +4 -0
- package/src/services/primitives/active-layers.d.ts +2 -3
- package/src/services/primitives/bindings.d.ts +4 -0
- package/src/services/primitives/command-normalization.d.ts +3 -0
- package/src/services/primitives/field-invariants.d.ts +16 -1
- package/src/services/primitives/pending-captures.d.ts +5 -0
- package/src/services/runtime-view.d.ts +5 -0
- package/src/services/runtime.d.ts +2 -7
- package/src/services/sequence-index.d.ts +24 -0
- package/src/services/state.d.ts +46 -91
- package/src/solid/index.d.ts +5 -19
- package/{solid → src/solid}/index.js +3 -0
- package/src/solid/index.js.map +10 -0
- package/src/testing/index.d.ts +90 -0
- package/src/testing/index.js +276 -0
- package/src/testing/index.js.map +10 -0
- package/src/types.d.ts +194 -126
- package/addons/index.js +0 -5240
- package/addons/opentui/index.js +0 -5632
- package/html.js +0 -5042
- package/index.js +0 -4411
- package/opentui.js +0 -4887
- package/src/services/primitives/binding-inputs.d.ts +0 -4
package/src/services/state.d.ts
CHANGED
|
@@ -1,115 +1,70 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import {
|
|
3
|
-
export interface CoreState {
|
|
4
|
-
order: number;
|
|
5
|
-
}
|
|
6
|
-
export interface EnvironmentState<TTarget extends object, TEvent extends KeymapEvent> {
|
|
7
|
-
tokens: Map<string, import("../types.js").ResolvedKeyToken>;
|
|
8
|
-
layerFields: Map<string, LayerFieldCompiler>;
|
|
9
|
-
bindingExpanders: OrderedRegistry<BindingExpander>;
|
|
10
|
-
bindingParsers: OrderedRegistry<BindingParser>;
|
|
11
|
-
bindingTransformers: OrderedRegistry<BindingTransformer<TTarget, TEvent>>;
|
|
12
|
-
bindingFields: Map<string, BindingFieldCompiler>;
|
|
13
|
-
commandFields: Map<string, CommandFieldCompiler>;
|
|
14
|
-
}
|
|
15
|
-
export interface DispatchState<TTarget extends object, TEvent extends KeymapEvent> {
|
|
16
|
-
eventMatchResolvers: OrderedRegistry<EventMatchResolver<TEvent>>;
|
|
17
|
-
disambiguationResolvers: OrderedRegistry<KeyDisambiguationResolver<TTarget, TEvent>>;
|
|
18
|
-
keyHooks: PriorityRegistry<(ctx: KeyInputContext<TEvent>) => void, {
|
|
19
|
-
priority: number;
|
|
20
|
-
release: boolean;
|
|
21
|
-
}>;
|
|
22
|
-
rawHooks: PriorityRegistry<(ctx: RawInputContext) => void, {
|
|
23
|
-
priority: number;
|
|
24
|
-
}>;
|
|
25
|
-
}
|
|
26
|
-
export interface LayersState<TTarget extends object, TEvent extends KeymapEvent> {
|
|
27
|
-
layers: Set<RegisteredLayer<TTarget, TEvent>>;
|
|
28
|
-
sortedLayers: RegisteredLayer<TTarget, TEvent>[];
|
|
29
|
-
activeLayersVersion: number;
|
|
30
|
-
activeLayersCacheVersion: number;
|
|
31
|
-
activeLayersCacheFocused: TTarget | null | undefined;
|
|
32
|
-
activeLayersCache: readonly RegisteredLayer<TTarget, TEvent>[];
|
|
33
|
-
layersWithConditions: number;
|
|
34
|
-
layersWithCommands: number;
|
|
35
|
-
layerAnalyzers: OrderedRegistry<LayerAnalyzer<TTarget, TEvent>>;
|
|
36
|
-
}
|
|
1
|
+
import type { Attributes, BindingExpander, BindingFieldCompiler, LayerBindingsTransformer, BindingParser, BindingTransformer, Command, CommandFieldCompiler, CommandTransformer, CommandResolver, EventData, KeyDisambiguationResolver, EventMatchResolver, KeyAfterInputContext, KeyInputContext, KeymapEvent, LayerFieldCompiler, PendingSequenceState, RawInputContext, ResolvedSequencePattern, CommandState, RegisteredLayer } from "../types.js";
|
|
2
|
+
import { type RuntimeOrderedRegistry, type RuntimePriorityRegistry } from "../lib/runtime-utils.js";
|
|
37
3
|
export interface LayerCommandEntry<TTarget extends object, TEvent extends KeymapEvent> {
|
|
38
4
|
layer: RegisteredLayer<TTarget, TEvent>;
|
|
39
|
-
|
|
5
|
+
commandState: CommandState<TTarget, TEvent>;
|
|
40
6
|
}
|
|
41
7
|
export interface ResolvedCommandEntry<TTarget extends object, TEvent extends KeymapEvent> {
|
|
42
8
|
target?: TTarget;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
resolvedWithRecordChains: Map<string, readonly ResolvedCommandEntry<TTarget, TEvent>[]>;
|
|
48
|
-
fallbackWithoutRecord: Map<string, ResolvedBindingCommand<TTarget, TEvent> | null>;
|
|
49
|
-
fallbackWithRecord: Map<string, ResolvedBindingCommand<TTarget, TEvent> | null>;
|
|
50
|
-
fallbackWithoutRecordErrors: Set<string>;
|
|
51
|
-
fallbackWithRecordErrors: Set<string>;
|
|
9
|
+
command: Command<TTarget, TEvent>;
|
|
10
|
+
attrs?: Readonly<Attributes>;
|
|
11
|
+
input?: string;
|
|
12
|
+
payload?: unknown;
|
|
52
13
|
}
|
|
53
|
-
export interface ActiveCommandView<TTarget extends object, TEvent extends KeymapEvent>
|
|
54
|
-
|
|
14
|
+
export interface ActiveCommandView<TTarget extends object, TEvent extends KeymapEvent> {
|
|
15
|
+
layers: readonly RegisteredLayer<TTarget, TEvent>[];
|
|
55
16
|
entries: readonly LayerCommandEntry<TTarget, TEvent>[];
|
|
56
17
|
reachable: readonly LayerCommandEntry<TTarget, TEvent>[];
|
|
57
18
|
reachableByName: ReadonlyMap<string, LayerCommandEntry<TTarget, TEvent>>;
|
|
58
19
|
chainsByName: ReadonlyMap<string, readonly LayerCommandEntry<TTarget, TEvent>[]>;
|
|
59
20
|
}
|
|
60
|
-
export interface
|
|
21
|
+
export interface CommandView<TTarget extends object, TEvent extends KeymapEvent> {
|
|
61
22
|
entries: readonly LayerCommandEntry<TTarget, TEvent>[];
|
|
62
23
|
chainsByName: ReadonlyMap<string, readonly LayerCommandEntry<TTarget, TEvent>[]>;
|
|
63
24
|
}
|
|
64
|
-
export interface
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
25
|
+
export interface State<TTarget extends object, TEvent extends KeymapEvent> {
|
|
26
|
+
order: number;
|
|
27
|
+
tokens: Map<string, import("../types.js").ResolvedKeyToken>;
|
|
28
|
+
patterns: Map<string, ResolvedSequencePattern<TEvent>>;
|
|
29
|
+
layerFields: Map<string, LayerFieldCompiler>;
|
|
30
|
+
layerBindingsTransformers: RuntimeOrderedRegistry<LayerBindingsTransformer<TTarget, TEvent>>;
|
|
31
|
+
bindingExpanders: RuntimeOrderedRegistry<BindingExpander>;
|
|
32
|
+
bindingParsers: RuntimeOrderedRegistry<BindingParser>;
|
|
33
|
+
bindingTransformers: RuntimeOrderedRegistry<BindingTransformer<TTarget, TEvent>>;
|
|
34
|
+
bindingFields: Map<string, BindingFieldCompiler>;
|
|
35
|
+
commandTransformers: RuntimeOrderedRegistry<CommandTransformer<TTarget, TEvent>>;
|
|
36
|
+
commandFields: Map<string, CommandFieldCompiler>;
|
|
37
|
+
eventMatchResolvers: RuntimeOrderedRegistry<EventMatchResolver<TEvent>>;
|
|
38
|
+
disambiguationResolvers: RuntimeOrderedRegistry<KeyDisambiguationResolver<TTarget, TEvent>>;
|
|
39
|
+
keyHooks: RuntimePriorityRegistry<(ctx: KeyInputContext<TEvent>) => void, {
|
|
40
|
+
priority: number;
|
|
41
|
+
release: boolean;
|
|
42
|
+
}>;
|
|
43
|
+
keyAfterHooks: RuntimePriorityRegistry<(ctx: KeyAfterInputContext<TTarget, TEvent>) => void, {
|
|
44
|
+
priority: number;
|
|
45
|
+
release: boolean;
|
|
46
|
+
}>;
|
|
47
|
+
rawHooks: RuntimePriorityRegistry<(ctx: RawInputContext) => void, {
|
|
48
|
+
priority: number;
|
|
49
|
+
}>;
|
|
50
|
+
layers: Set<RegisteredLayer<TTarget, TEvent>>;
|
|
51
|
+
sortedLayers: RegisteredLayer<TTarget, TEvent>[];
|
|
52
|
+
activeLayersCacheVersion: number;
|
|
53
|
+
activeLayersCacheFocused: TTarget | null | undefined;
|
|
54
|
+
activeLayersCache: RegisteredLayer<TTarget, TEvent>[];
|
|
55
|
+
activeKeyCacheBlockers: number;
|
|
56
|
+
activeCommandViewCacheBlockers: number;
|
|
57
|
+
commandResolvers: RuntimeOrderedRegistry<CommandResolver<TTarget, TEvent>>;
|
|
58
|
+
pending: PendingSequenceState<TTarget, TEvent> | null;
|
|
92
59
|
data: EventData;
|
|
93
60
|
dataVersion: number;
|
|
94
61
|
readonlyDataVersion: number;
|
|
95
62
|
readonlyData: Readonly<EventData>;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
derivedStateVersion: number;
|
|
63
|
+
cacheVersion: number;
|
|
64
|
+
derivedVersion: number;
|
|
99
65
|
stateChangeDepth: number;
|
|
100
66
|
stateChangePending: boolean;
|
|
101
67
|
flushingStateChange: boolean;
|
|
102
68
|
usedWarningKeys: Set<string>;
|
|
103
69
|
}
|
|
104
|
-
export interface State<TTarget extends object, TEvent extends KeymapEvent> {
|
|
105
|
-
core: CoreState;
|
|
106
|
-
environment: EnvironmentState<TTarget, TEvent>;
|
|
107
|
-
dispatch: DispatchState<TTarget, TEvent>;
|
|
108
|
-
layers: LayersState<TTarget, TEvent>;
|
|
109
|
-
commands: CommandsState<TTarget, TEvent>;
|
|
110
|
-
projection: ProjectionState<TTarget, TEvent>;
|
|
111
|
-
conditions: ConditionsState;
|
|
112
|
-
runtime: RuntimeState;
|
|
113
|
-
notify: NotifyState;
|
|
114
|
-
}
|
|
115
70
|
export declare function createKeymapState<TTarget extends object, TEvent extends KeymapEvent>(): State<TTarget, TEvent>;
|
package/src/solid/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { KeyEvent, Renderable } from "@opentui/core";
|
|
2
|
-
import { type Keymap, type
|
|
2
|
+
import { type Keymap, type Layer, type ReactiveMatcher, type TargetMode } from "../index.js";
|
|
3
3
|
import { type Accessor, type JSX } from "solid-js";
|
|
4
4
|
type OpenTuiKeymap = Keymap<Renderable, KeyEvent>;
|
|
5
5
|
export interface KeymapProviderProps {
|
|
@@ -8,31 +8,17 @@ export interface KeymapProviderProps {
|
|
|
8
8
|
}
|
|
9
9
|
export declare function KeymapProvider(props: KeymapProviderProps): JSX.Element;
|
|
10
10
|
export type UseBindingsTarget<TRenderable extends Renderable = Renderable> = () => TRenderable | null | undefined;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
export interface UseBindingsLayer<TRenderable extends Renderable = Renderable> extends Omit<Layer<Renderable, KeyEvent>, "target" | "targetMode"> {
|
|
12
|
+
target?: UseBindingsTarget<TRenderable>;
|
|
13
|
+
targetMode?: TargetMode;
|
|
14
14
|
}
|
|
15
|
-
export interface UseFocusBindingsLayer<TRenderable extends Renderable = Renderable> extends UseBindingsLayerBase {
|
|
16
|
-
targetMode: "focus";
|
|
17
|
-
target: UseBindingsTarget<TRenderable>;
|
|
18
|
-
}
|
|
19
|
-
export interface UseFocusWithinBindingsLayer<TRenderable extends Renderable = Renderable> extends UseBindingsLayerBase {
|
|
20
|
-
targetMode?: "focus-within";
|
|
21
|
-
target: UseBindingsTarget<TRenderable>;
|
|
22
|
-
}
|
|
23
|
-
export interface UseInferredFocusWithinBindingsLayer<TRenderable extends Renderable = Renderable> extends UseBindingsLayerBase {
|
|
24
|
-
target: UseBindingsTarget<TRenderable>;
|
|
25
|
-
}
|
|
26
|
-
export type UseTargetBindingsLayer<TRenderable extends Renderable = Renderable> = UseFocusBindingsLayer<TRenderable> | UseFocusWithinBindingsLayer<TRenderable> | UseInferredFocusWithinBindingsLayer<TRenderable>;
|
|
27
|
-
export type UseBindingsLayer<TRenderable extends Renderable = Renderable> = UseGlobalBindingsLayer | UseTargetBindingsLayer<TRenderable>;
|
|
28
15
|
export declare const useKeymap: () => OpenTuiKeymap;
|
|
29
16
|
/**
|
|
30
17
|
* Reactively derives any view from the current keymap by re-running `selector`
|
|
31
18
|
* on each batched keymap state change.
|
|
32
19
|
*/
|
|
33
20
|
export declare const useKeymapSelector: <T>(selector: (keymap: OpenTuiKeymap) => T) => Accessor<T>;
|
|
34
|
-
export declare function useBindings<TRenderable extends Renderable = Renderable>(createLayer: () =>
|
|
35
|
-
export declare function useBindings<TRenderable extends Renderable = Renderable>(createLayer: () => UseTargetBindingsLayer<TRenderable>): void;
|
|
21
|
+
export declare function useBindings<TRenderable extends Renderable = Renderable>(createLayer: () => UseBindingsLayer<TRenderable>): void;
|
|
36
22
|
/**
|
|
37
23
|
* Adapts a Solid accessor to `ReactiveMatcher`. The subscription
|
|
38
24
|
* lives in a disposable reactive root so unregistering the layer tears it
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/solid/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { KeyEvent, Renderable } from \"@opentui/core\"\nimport { type Keymap, type Layer, type ReactiveMatcher, type TargetMode } from \"../index.js\"\nimport {\n createComponent,\n createContext,\n createEffect,\n createMemo,\n createRoot,\n createSignal,\n on,\n onCleanup,\n onMount,\n useContext,\n type Accessor,\n type JSX,\n} from \"solid-js\"\n\ntype OpenTuiKeymap = Keymap<Renderable, KeyEvent>\n\nconst KeymapContext = createContext<OpenTuiKeymap>()\n\nexport interface KeymapProviderProps {\n keymap: OpenTuiKeymap\n children: JSX.Element\n}\n\nexport function KeymapProvider(props: KeymapProviderProps): JSX.Element {\n return createComponent(KeymapContext.Provider, {\n get value() {\n return props.keymap\n },\n get children() {\n return props.children\n },\n })\n}\n\nexport type UseBindingsTarget<TRenderable extends Renderable = Renderable> = () => TRenderable | null | undefined\n\nexport interface UseBindingsLayer<TRenderable extends Renderable = Renderable> extends Omit<\n Layer<Renderable, KeyEvent>,\n \"target\" | \"targetMode\"\n> {\n target?: UseBindingsTarget<TRenderable>\n targetMode?: TargetMode\n}\n\nfunction resolveBindingsTarget(target: UseBindingsTarget | undefined): Renderable | undefined {\n return target?.() ?? undefined\n}\n\nexport const useKeymap = (): OpenTuiKeymap => {\n const keymap = useContext(KeymapContext)\n\n if (!keymap) {\n throw new Error(\"Keymap not found. Wrap the tree in <KeymapProvider>.\")\n }\n\n return keymap\n}\n\nfunction useKeymapStateVersion(keymap: OpenTuiKeymap): Accessor<number> {\n const [version, setVersion] = createSignal(0)\n let dispose: (() => void) | undefined\n\n onMount(() => {\n dispose = keymap.on(\"state\", () => {\n setVersion((value) => value + 1)\n })\n\n setVersion((value) => value + 1)\n })\n\n onCleanup(() => {\n dispose?.()\n })\n\n return version\n}\n\n/**\n * Reactively derives any view from the current keymap by re-running `selector`\n * on each batched keymap state change.\n */\nexport const useKeymapSelector = <T>(selector: (keymap: OpenTuiKeymap) => T): Accessor<T> => {\n const keymap = useKeymap()\n const version = useKeymapStateVersion(keymap)\n\n return createMemo((previous) => {\n version()\n try {\n return selector(keymap)\n } catch (error) {\n if (\n previous !== undefined &&\n error instanceof Error &&\n error.message === \"Cannot use a keymap after its host was destroyed\"\n ) {\n return previous\n }\n\n throw error\n }\n })\n}\n\nexport function useBindings<TRenderable extends Renderable = Renderable>(\n createLayer: () => UseBindingsLayer<TRenderable>,\n): void {\n const keymap = useKeymap()\n\n createEffect(() => {\n const layer = createLayer()\n const hasExplicitTarget = layer.target !== undefined\n const explicitTarget = resolveBindingsTarget(layer.target)\n const nextTargetMode: TargetMode | undefined = layer.targetMode ?? (hasExplicitTarget ? \"focus-within\" : undefined)\n\n const { target: _target, targetMode: _targetMode, ...baseLayer } = layer\n if (!nextTargetMode) {\n const dispose = keymap.registerLayer({\n ...baseLayer,\n })\n\n onCleanup(() => {\n dispose()\n })\n\n return\n }\n\n if (!hasExplicitTarget) {\n throw new Error(\"useBindings local bindings need a target accessor\")\n }\n\n if (!explicitTarget) {\n return\n }\n\n const dispose = keymap.registerLayer({\n ...baseLayer,\n target: explicitTarget,\n targetMode: nextTargetMode,\n })\n\n onCleanup(() => {\n dispose()\n })\n })\n}\n\n/**\n * Adapts a Solid accessor to `ReactiveMatcher`. The subscription\n * lives in a disposable reactive root so unregistering the layer tears it\n * down. Pass `predicate` when the accessor value is not already boolean.\n */\nexport function reactiveMatcherFromSignal<T>(\n accessor: Accessor<T>,\n predicate?: (value: T) => boolean,\n): ReactiveMatcher {\n return {\n get() {\n return predicate ? predicate(accessor()) : Boolean(accessor())\n },\n subscribe(onChange) {\n return createRoot((dispose) => {\n createEffect(on(accessor, () => onChange(), { defer: true }))\n return dispose\n })\n },\n }\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBA,IAAM,gBAAgB,cAA6B;AAO5C,SAAS,cAAc,CAAC,OAAyC;AAAA,EACtE,OAAO,gBAAgB,cAAc,UAAU;AAAA,QACzC,KAAK,GAAG;AAAA,MACV,OAAO,MAAM;AAAA;AAAA,QAEX,QAAQ,GAAG;AAAA,MACb,OAAO,MAAM;AAAA;AAAA,EAEjB,CAAC;AAAA;AAaH,SAAS,qBAAqB,CAAC,QAA+D;AAAA,EAC5F,OAAO,SAAS,KAAK;AAAA;AAGhB,IAAM,YAAY,MAAqB;AAAA,EAC5C,MAAM,SAAS,WAAW,aAAa;AAAA,EAEvC,IAAI,CAAC,QAAQ;AAAA,IACX,MAAM,IAAI,MAAM,sDAAsD;AAAA,EACxE;AAAA,EAEA,OAAO;AAAA;AAGT,SAAS,qBAAqB,CAAC,QAAyC;AAAA,EACtE,OAAO,SAAS,cAAc,aAAa,CAAC;AAAA,EAC5C,IAAI;AAAA,EAEJ,QAAQ,MAAM;AAAA,IACZ,UAAU,OAAO,GAAG,SAAS,MAAM;AAAA,MACjC,WAAW,CAAC,UAAU,QAAQ,CAAC;AAAA,KAChC;AAAA,IAED,WAAW,CAAC,UAAU,QAAQ,CAAC;AAAA,GAChC;AAAA,EAED,UAAU,MAAM;AAAA,IACd,UAAU;AAAA,GACX;AAAA,EAED,OAAO;AAAA;AAOF,IAAM,oBAAoB,CAAI,aAAwD;AAAA,EAC3F,MAAM,SAAS,UAAU;AAAA,EACzB,MAAM,UAAU,sBAAsB,MAAM;AAAA,EAE5C,OAAO,WAAW,CAAC,aAAa;AAAA,IAC9B,QAAQ;AAAA,IACR,IAAI;AAAA,MACF,OAAO,SAAS,MAAM;AAAA,MACtB,OAAO,OAAO;AAAA,MACd,IACE,aAAa,aACb,iBAAiB,SACjB,MAAM,YAAY,oDAClB;AAAA,QACA,OAAO;AAAA,MACT;AAAA,MAEA,MAAM;AAAA;AAAA,GAET;AAAA;AAGI,SAAS,WAAwD,CACtE,aACM;AAAA,EACN,MAAM,SAAS,UAAU;AAAA,EAEzB,aAAa,MAAM;AAAA,IACjB,MAAM,QAAQ,YAAY;AAAA,IAC1B,MAAM,oBAAoB,MAAM,WAAW;AAAA,IAC3C,MAAM,iBAAiB,sBAAsB,MAAM,MAAM;AAAA,IACzD,MAAM,iBAAyC,MAAM,eAAe,oBAAoB,iBAAiB;AAAA,IAEzG,QAAQ,QAAQ,SAAS,YAAY,gBAAgB,cAAc;AAAA,IACnE,IAAI,CAAC,gBAAgB;AAAA,MACnB,MAAM,WAAU,OAAO,cAAc;AAAA,WAChC;AAAA,MACL,CAAC;AAAA,MAED,UAAU,MAAM;AAAA,QACd,SAAQ;AAAA,OACT;AAAA,MAED;AAAA,IACF;AAAA,IAEA,IAAI,CAAC,mBAAmB;AAAA,MACtB,MAAM,IAAI,MAAM,mDAAmD;AAAA,IACrE;AAAA,IAEA,IAAI,CAAC,gBAAgB;AAAA,MACnB;AAAA,IACF;AAAA,IAEA,MAAM,UAAU,OAAO,cAAc;AAAA,SAChC;AAAA,MACH,QAAQ;AAAA,MACR,YAAY;AAAA,IACd,CAAC;AAAA,IAED,UAAU,MAAM;AAAA,MACd,QAAQ;AAAA,KACT;AAAA,GACF;AAAA;AAQI,SAAS,yBAA4B,CAC1C,UACA,WACiB;AAAA,EACjB,OAAO;AAAA,IACL,GAAG,GAAG;AAAA,MACJ,OAAO,YAAY,UAAU,SAAS,CAAC,IAAI,QAAQ,SAAS,CAAC;AAAA;AAAA,IAE/D,SAAS,CAAC,UAAU;AAAA,MAClB,OAAO,WAAW,CAAC,YAAY;AAAA,QAC7B,aAAa,GAAG,UAAU,MAAM,SAAS,GAAG,EAAE,OAAO,KAAK,CAAC,CAAC;AAAA,QAC5D,OAAO;AAAA,OACR;AAAA;AAAA,EAEL;AAAA;",
|
|
8
|
+
"debugId": "A624A2E448C2557164756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Keymap } from "@opentui/keymap";
|
|
2
|
+
import type { ErrorEvent, HostMetadata, KeymapEvent, KeymapHost, WarningEvent } from "@opentui/keymap";
|
|
3
|
+
export type TestKeyModifierOptions = Partial<Pick<KeymapEvent, "ctrl" | "shift" | "meta" | "super" | "hyper">>;
|
|
4
|
+
export type TestHostMetadataOptions = Partial<Omit<HostMetadata, "modifiers">> & {
|
|
5
|
+
modifiers?: Partial<HostMetadata["modifiers"]>;
|
|
6
|
+
};
|
|
7
|
+
export interface CreateTestKeymapHostOptions {
|
|
8
|
+
metadata?: HostMetadata | TestHostMetadataOptions;
|
|
9
|
+
}
|
|
10
|
+
export interface CreateTestKeymapOptions extends CreateTestKeymapHostOptions {
|
|
11
|
+
defaultKeys?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface TestDiagnosticCapture {
|
|
14
|
+
readonly warnings: readonly string[];
|
|
15
|
+
readonly errors: readonly string[];
|
|
16
|
+
readonly warningEvents: readonly WarningEvent[];
|
|
17
|
+
readonly errorEvents: readonly ErrorEvent[];
|
|
18
|
+
takeWarnings(): {
|
|
19
|
+
warnings: string[];
|
|
20
|
+
warningEvents: WarningEvent[];
|
|
21
|
+
};
|
|
22
|
+
takeErrors(): {
|
|
23
|
+
errors: string[];
|
|
24
|
+
errorEvents: ErrorEvent[];
|
|
25
|
+
};
|
|
26
|
+
clear(): void;
|
|
27
|
+
dispose(): void;
|
|
28
|
+
}
|
|
29
|
+
export interface TestKeymapHarness {
|
|
30
|
+
keymap: Keymap<TestKeymapTarget, TestKeymapEvent>;
|
|
31
|
+
host: TestKeymapHost;
|
|
32
|
+
root: TestKeymapTarget;
|
|
33
|
+
diagnostics: TestDiagnosticCapture;
|
|
34
|
+
cleanup(): void;
|
|
35
|
+
}
|
|
36
|
+
export declare const DEFAULT_TEST_HOST_METADATA: HostMetadata;
|
|
37
|
+
export declare class TestKeymapTarget {
|
|
38
|
+
readonly id: string;
|
|
39
|
+
parent: TestKeymapTarget | null;
|
|
40
|
+
isDestroyed: boolean;
|
|
41
|
+
constructor(id: string);
|
|
42
|
+
append(child: TestKeymapTarget): TestKeymapTarget;
|
|
43
|
+
}
|
|
44
|
+
export declare class TestKeymapEvent implements KeymapEvent {
|
|
45
|
+
readonly name: string;
|
|
46
|
+
readonly ctrl: boolean;
|
|
47
|
+
readonly shift: boolean;
|
|
48
|
+
readonly meta: boolean;
|
|
49
|
+
readonly super: boolean;
|
|
50
|
+
readonly hyper?: boolean;
|
|
51
|
+
propagationStopped: boolean;
|
|
52
|
+
defaultPrevented: boolean;
|
|
53
|
+
constructor(name: string, modifiers?: TestKeyModifierOptions);
|
|
54
|
+
preventDefault(): void;
|
|
55
|
+
stopPropagation(): void;
|
|
56
|
+
}
|
|
57
|
+
export declare class TestKeymapHost implements KeymapHost<TestKeymapTarget, TestKeymapEvent> {
|
|
58
|
+
readonly metadata: HostMetadata;
|
|
59
|
+
readonly rootTarget: TestKeymapTarget;
|
|
60
|
+
isDestroyed: boolean;
|
|
61
|
+
private focusedTarget;
|
|
62
|
+
private readonly keyPressListeners;
|
|
63
|
+
private readonly keyReleaseListeners;
|
|
64
|
+
private readonly focusListeners;
|
|
65
|
+
private readonly destroyListeners;
|
|
66
|
+
private readonly rawListeners;
|
|
67
|
+
private readonly targetDestroyListeners;
|
|
68
|
+
constructor(options?: CreateTestKeymapHostOptions);
|
|
69
|
+
createTarget(id: string): TestKeymapTarget;
|
|
70
|
+
getFocusedTarget(): TestKeymapTarget | null;
|
|
71
|
+
getParentTarget(target: TestKeymapTarget): TestKeymapTarget | null;
|
|
72
|
+
isTargetDestroyed(target: TestKeymapTarget): boolean;
|
|
73
|
+
onKeyPress(listener: (event: TestKeymapEvent) => void): () => void;
|
|
74
|
+
onKeyRelease(listener: (event: TestKeymapEvent) => void): () => void;
|
|
75
|
+
onFocusChange(listener: (target: TestKeymapTarget | null) => void): () => void;
|
|
76
|
+
onDestroy(listener: () => void): () => void;
|
|
77
|
+
onTargetDestroy(target: TestKeymapTarget, listener: () => void): () => void;
|
|
78
|
+
onRawInput(listener: (sequence: string) => boolean): () => void;
|
|
79
|
+
createCommandEvent(): TestKeymapEvent;
|
|
80
|
+
focus(target: TestKeymapTarget | null): void;
|
|
81
|
+
press(name: string, modifiers?: TestKeyModifierOptions): TestKeymapEvent;
|
|
82
|
+
release(name: string, modifiers?: TestKeyModifierOptions): TestKeymapEvent;
|
|
83
|
+
raw(sequence: string): boolean;
|
|
84
|
+
destroyTarget(target: TestKeymapTarget): void;
|
|
85
|
+
destroy(): void;
|
|
86
|
+
}
|
|
87
|
+
export declare function createTestHostMetadata(options?: HostMetadata | TestHostMetadataOptions): HostMetadata;
|
|
88
|
+
export declare function createTestKeymapHost(options?: CreateTestKeymapHostOptions): TestKeymapHost;
|
|
89
|
+
export declare function createTestKeymap(options?: CreateTestKeymapOptions): TestKeymapHarness;
|
|
90
|
+
export declare function captureKeymapDiagnostics(keymap: Keymap<any, any>): TestDiagnosticCapture;
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/testing/index.ts
|
|
3
|
+
import { Keymap } from "@opentui/keymap";
|
|
4
|
+
import { registerDefaultKeys } from "@opentui/keymap/addons";
|
|
5
|
+
var DEFAULT_TEST_HOST_METADATA = Object.freeze({
|
|
6
|
+
platform: "unknown",
|
|
7
|
+
primaryModifier: "unknown",
|
|
8
|
+
modifiers: Object.freeze({
|
|
9
|
+
ctrl: "unknown",
|
|
10
|
+
shift: "unknown",
|
|
11
|
+
meta: "unknown",
|
|
12
|
+
super: "unknown",
|
|
13
|
+
hyper: "unknown"
|
|
14
|
+
})
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
class TestKeymapTarget {
|
|
18
|
+
id;
|
|
19
|
+
parent = null;
|
|
20
|
+
isDestroyed = false;
|
|
21
|
+
constructor(id) {
|
|
22
|
+
this.id = id;
|
|
23
|
+
}
|
|
24
|
+
append(child) {
|
|
25
|
+
child.parent = this;
|
|
26
|
+
return child;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
class TestKeymapEvent {
|
|
31
|
+
name;
|
|
32
|
+
ctrl;
|
|
33
|
+
shift;
|
|
34
|
+
meta;
|
|
35
|
+
super;
|
|
36
|
+
hyper;
|
|
37
|
+
propagationStopped = false;
|
|
38
|
+
defaultPrevented = false;
|
|
39
|
+
constructor(name, modifiers) {
|
|
40
|
+
this.name = name;
|
|
41
|
+
this.ctrl = modifiers?.ctrl ?? false;
|
|
42
|
+
this.shift = modifiers?.shift ?? false;
|
|
43
|
+
this.meta = modifiers?.meta ?? false;
|
|
44
|
+
this.super = modifiers?.super ?? false;
|
|
45
|
+
this.hyper = modifiers?.hyper || undefined;
|
|
46
|
+
}
|
|
47
|
+
preventDefault() {
|
|
48
|
+
this.defaultPrevented = true;
|
|
49
|
+
}
|
|
50
|
+
stopPropagation() {
|
|
51
|
+
this.propagationStopped = true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
class TestKeymapHost {
|
|
56
|
+
metadata;
|
|
57
|
+
rootTarget;
|
|
58
|
+
isDestroyed = false;
|
|
59
|
+
focusedTarget = null;
|
|
60
|
+
keyPressListeners = new Set;
|
|
61
|
+
keyReleaseListeners = new Set;
|
|
62
|
+
focusListeners = new Set;
|
|
63
|
+
destroyListeners = new Set;
|
|
64
|
+
rawListeners = new Set;
|
|
65
|
+
targetDestroyListeners = new WeakMap;
|
|
66
|
+
constructor(options) {
|
|
67
|
+
this.metadata = normalizeTestHostMetadata(options?.metadata);
|
|
68
|
+
this.rootTarget = new TestKeymapTarget("root");
|
|
69
|
+
}
|
|
70
|
+
createTarget(id) {
|
|
71
|
+
return new TestKeymapTarget(id);
|
|
72
|
+
}
|
|
73
|
+
getFocusedTarget() {
|
|
74
|
+
return this.focusedTarget && !this.focusedTarget.isDestroyed ? this.focusedTarget : null;
|
|
75
|
+
}
|
|
76
|
+
getParentTarget(target) {
|
|
77
|
+
return target.parent;
|
|
78
|
+
}
|
|
79
|
+
isTargetDestroyed(target) {
|
|
80
|
+
return target.isDestroyed;
|
|
81
|
+
}
|
|
82
|
+
onKeyPress(listener) {
|
|
83
|
+
this.keyPressListeners.add(listener);
|
|
84
|
+
return () => {
|
|
85
|
+
this.keyPressListeners.delete(listener);
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
onKeyRelease(listener) {
|
|
89
|
+
this.keyReleaseListeners.add(listener);
|
|
90
|
+
return () => {
|
|
91
|
+
this.keyReleaseListeners.delete(listener);
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
onFocusChange(listener) {
|
|
95
|
+
this.focusListeners.add(listener);
|
|
96
|
+
return () => {
|
|
97
|
+
this.focusListeners.delete(listener);
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
onDestroy(listener) {
|
|
101
|
+
this.destroyListeners.add(listener);
|
|
102
|
+
return () => {
|
|
103
|
+
this.destroyListeners.delete(listener);
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
onTargetDestroy(target, listener) {
|
|
107
|
+
let listeners = this.targetDestroyListeners.get(target);
|
|
108
|
+
if (!listeners) {
|
|
109
|
+
listeners = new Set;
|
|
110
|
+
this.targetDestroyListeners.set(target, listeners);
|
|
111
|
+
}
|
|
112
|
+
listeners.add(listener);
|
|
113
|
+
return () => {
|
|
114
|
+
listeners?.delete(listener);
|
|
115
|
+
if (listeners && listeners.size === 0) {
|
|
116
|
+
this.targetDestroyListeners.delete(target);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
onRawInput(listener) {
|
|
121
|
+
this.rawListeners.add(listener);
|
|
122
|
+
return () => {
|
|
123
|
+
this.rawListeners.delete(listener);
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
createCommandEvent() {
|
|
127
|
+
return new TestKeymapEvent("synthetic");
|
|
128
|
+
}
|
|
129
|
+
focus(target) {
|
|
130
|
+
this.focusedTarget = target;
|
|
131
|
+
for (const listener of this.focusListeners) {
|
|
132
|
+
listener(target);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
press(name, modifiers) {
|
|
136
|
+
const event = new TestKeymapEvent(name, modifiers);
|
|
137
|
+
for (const listener of this.keyPressListeners) {
|
|
138
|
+
listener(event);
|
|
139
|
+
}
|
|
140
|
+
return event;
|
|
141
|
+
}
|
|
142
|
+
release(name, modifiers) {
|
|
143
|
+
const event = new TestKeymapEvent(name, modifiers);
|
|
144
|
+
for (const listener of this.keyReleaseListeners) {
|
|
145
|
+
listener(event);
|
|
146
|
+
}
|
|
147
|
+
return event;
|
|
148
|
+
}
|
|
149
|
+
raw(sequence) {
|
|
150
|
+
let handled = false;
|
|
151
|
+
for (const listener of this.rawListeners) {
|
|
152
|
+
handled = listener(sequence) || handled;
|
|
153
|
+
}
|
|
154
|
+
return handled;
|
|
155
|
+
}
|
|
156
|
+
destroyTarget(target) {
|
|
157
|
+
target.isDestroyed = true;
|
|
158
|
+
const listeners = this.targetDestroyListeners.get(target);
|
|
159
|
+
if (!listeners) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
for (const listener of [...listeners]) {
|
|
163
|
+
listener();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
destroy() {
|
|
167
|
+
if (this.isDestroyed) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
this.isDestroyed = true;
|
|
171
|
+
for (const listener of [...this.destroyListeners]) {
|
|
172
|
+
listener();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function createTestHostMetadata(options) {
|
|
177
|
+
return normalizeTestHostMetadata(options);
|
|
178
|
+
}
|
|
179
|
+
function createTestKeymapHost(options) {
|
|
180
|
+
return new TestKeymapHost(options);
|
|
181
|
+
}
|
|
182
|
+
function createTestKeymap(options) {
|
|
183
|
+
const host = createTestKeymapHost(options);
|
|
184
|
+
const keymap = new Keymap(host);
|
|
185
|
+
const diagnostics = captureKeymapDiagnostics(keymap);
|
|
186
|
+
if (options?.defaultKeys === true) {
|
|
187
|
+
registerDefaultKeys(keymap);
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
keymap,
|
|
191
|
+
host,
|
|
192
|
+
root: host.rootTarget,
|
|
193
|
+
diagnostics,
|
|
194
|
+
cleanup() {
|
|
195
|
+
host.destroy();
|
|
196
|
+
diagnostics.dispose();
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
function captureKeymapDiagnostics(keymap) {
|
|
201
|
+
const warnings = [];
|
|
202
|
+
const errors = [];
|
|
203
|
+
const warningEvents = [];
|
|
204
|
+
const errorEvents = [];
|
|
205
|
+
const offWarning = keymap.on("warning", (event) => {
|
|
206
|
+
warnings.push(event.message);
|
|
207
|
+
warningEvents.push(event);
|
|
208
|
+
});
|
|
209
|
+
const offError = keymap.on("error", (event) => {
|
|
210
|
+
errors.push(event.message);
|
|
211
|
+
errorEvents.push(event);
|
|
212
|
+
});
|
|
213
|
+
return {
|
|
214
|
+
warnings,
|
|
215
|
+
errors,
|
|
216
|
+
warningEvents,
|
|
217
|
+
errorEvents,
|
|
218
|
+
takeWarnings() {
|
|
219
|
+
const snapshot = {
|
|
220
|
+
warnings: [...warnings],
|
|
221
|
+
warningEvents: [...warningEvents]
|
|
222
|
+
};
|
|
223
|
+
warnings.length = 0;
|
|
224
|
+
warningEvents.length = 0;
|
|
225
|
+
return snapshot;
|
|
226
|
+
},
|
|
227
|
+
takeErrors() {
|
|
228
|
+
const snapshot = {
|
|
229
|
+
errors: [...errors],
|
|
230
|
+
errorEvents: [...errorEvents]
|
|
231
|
+
};
|
|
232
|
+
errors.length = 0;
|
|
233
|
+
errorEvents.length = 0;
|
|
234
|
+
return snapshot;
|
|
235
|
+
},
|
|
236
|
+
clear() {
|
|
237
|
+
warnings.length = 0;
|
|
238
|
+
errors.length = 0;
|
|
239
|
+
warningEvents.length = 0;
|
|
240
|
+
errorEvents.length = 0;
|
|
241
|
+
},
|
|
242
|
+
dispose() {
|
|
243
|
+
offWarning();
|
|
244
|
+
offError();
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
function normalizeTestHostMetadata(metadata) {
|
|
249
|
+
if (isHostMetadata(metadata)) {
|
|
250
|
+
return metadata;
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
platform: metadata?.platform ?? DEFAULT_TEST_HOST_METADATA.platform,
|
|
254
|
+
primaryModifier: metadata?.primaryModifier ?? DEFAULT_TEST_HOST_METADATA.primaryModifier,
|
|
255
|
+
modifiers: {
|
|
256
|
+
...DEFAULT_TEST_HOST_METADATA.modifiers,
|
|
257
|
+
...metadata?.modifiers
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
function isHostMetadata(value) {
|
|
262
|
+
return !!value && !!value.modifiers && "ctrl" in value.modifiers && "shift" in value.modifiers;
|
|
263
|
+
}
|
|
264
|
+
export {
|
|
265
|
+
createTestKeymapHost,
|
|
266
|
+
createTestKeymap,
|
|
267
|
+
createTestHostMetadata,
|
|
268
|
+
captureKeymapDiagnostics,
|
|
269
|
+
TestKeymapTarget,
|
|
270
|
+
TestKeymapHost,
|
|
271
|
+
TestKeymapEvent,
|
|
272
|
+
DEFAULT_TEST_HOST_METADATA
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
//# debugId=AC56D442CF81C26564756E2164756E21
|
|
276
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/testing/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { Keymap } from \"@opentui/keymap\"\nimport { registerDefaultKeys } from \"@opentui/keymap/addons\"\nimport type { ErrorEvent, HostMetadata, KeymapEvent, KeymapHost, WarningEvent } from \"@opentui/keymap\"\n\nexport type TestKeyModifierOptions = Partial<Pick<KeymapEvent, \"ctrl\" | \"shift\" | \"meta\" | \"super\" | \"hyper\">>\n\nexport type TestHostMetadataOptions = Partial<Omit<HostMetadata, \"modifiers\">> & {\n modifiers?: Partial<HostMetadata[\"modifiers\"]>\n}\n\nexport interface CreateTestKeymapHostOptions {\n metadata?: HostMetadata | TestHostMetadataOptions\n}\n\nexport interface CreateTestKeymapOptions extends CreateTestKeymapHostOptions {\n defaultKeys?: boolean\n}\n\nexport interface TestDiagnosticCapture {\n readonly warnings: readonly string[]\n readonly errors: readonly string[]\n readonly warningEvents: readonly WarningEvent[]\n readonly errorEvents: readonly ErrorEvent[]\n takeWarnings(): { warnings: string[]; warningEvents: WarningEvent[] }\n takeErrors(): { errors: string[]; errorEvents: ErrorEvent[] }\n clear(): void\n dispose(): void\n}\n\nexport interface TestKeymapHarness {\n keymap: Keymap<TestKeymapTarget, TestKeymapEvent>\n host: TestKeymapHost\n root: TestKeymapTarget\n diagnostics: TestDiagnosticCapture\n cleanup(): void\n}\n\nexport const DEFAULT_TEST_HOST_METADATA: HostMetadata = Object.freeze({\n platform: \"unknown\",\n primaryModifier: \"unknown\",\n modifiers: Object.freeze({\n ctrl: \"unknown\",\n shift: \"unknown\",\n meta: \"unknown\",\n super: \"unknown\",\n hyper: \"unknown\",\n }),\n})\n\nexport class TestKeymapTarget {\n public parent: TestKeymapTarget | null = null\n public isDestroyed = false\n\n constructor(public readonly id: string) {}\n\n public append(child: TestKeymapTarget): TestKeymapTarget {\n child.parent = this\n return child\n }\n}\n\nexport class TestKeymapEvent implements KeymapEvent {\n public readonly ctrl: boolean\n public readonly shift: boolean\n public readonly meta: boolean\n public readonly super: boolean\n public readonly hyper?: boolean\n public propagationStopped = false\n public defaultPrevented = false\n\n constructor(\n public readonly name: string,\n modifiers?: TestKeyModifierOptions,\n ) {\n this.ctrl = modifiers?.ctrl ?? false\n this.shift = modifiers?.shift ?? false\n this.meta = modifiers?.meta ?? false\n this.super = modifiers?.super ?? false\n this.hyper = modifiers?.hyper || undefined\n }\n\n public preventDefault(): void {\n this.defaultPrevented = true\n }\n\n public stopPropagation(): void {\n this.propagationStopped = true\n }\n}\n\nexport class TestKeymapHost implements KeymapHost<TestKeymapTarget, TestKeymapEvent> {\n public readonly metadata: HostMetadata\n public readonly rootTarget: TestKeymapTarget\n public isDestroyed = false\n\n private focusedTarget: TestKeymapTarget | null = null\n private readonly keyPressListeners = new Set<(event: TestKeymapEvent) => void>()\n private readonly keyReleaseListeners = new Set<(event: TestKeymapEvent) => void>()\n private readonly focusListeners = new Set<(target: TestKeymapTarget | null) => void>()\n private readonly destroyListeners = new Set<() => void>()\n private readonly rawListeners = new Set<(sequence: string) => boolean>()\n private readonly targetDestroyListeners = new WeakMap<TestKeymapTarget, Set<() => void>>()\n\n constructor(options?: CreateTestKeymapHostOptions) {\n this.metadata = normalizeTestHostMetadata(options?.metadata)\n this.rootTarget = new TestKeymapTarget(\"root\")\n }\n\n public createTarget(id: string): TestKeymapTarget {\n return new TestKeymapTarget(id)\n }\n\n public getFocusedTarget(): TestKeymapTarget | null {\n return this.focusedTarget && !this.focusedTarget.isDestroyed ? this.focusedTarget : null\n }\n\n public getParentTarget(target: TestKeymapTarget): TestKeymapTarget | null {\n return target.parent\n }\n\n public isTargetDestroyed(target: TestKeymapTarget): boolean {\n return target.isDestroyed\n }\n\n public onKeyPress(listener: (event: TestKeymapEvent) => void): () => void {\n this.keyPressListeners.add(listener)\n return () => {\n this.keyPressListeners.delete(listener)\n }\n }\n\n public onKeyRelease(listener: (event: TestKeymapEvent) => void): () => void {\n this.keyReleaseListeners.add(listener)\n return () => {\n this.keyReleaseListeners.delete(listener)\n }\n }\n\n public onFocusChange(listener: (target: TestKeymapTarget | null) => void): () => void {\n this.focusListeners.add(listener)\n return () => {\n this.focusListeners.delete(listener)\n }\n }\n\n public onDestroy(listener: () => void): () => void {\n this.destroyListeners.add(listener)\n return () => {\n this.destroyListeners.delete(listener)\n }\n }\n\n public onTargetDestroy(target: TestKeymapTarget, listener: () => void): () => void {\n let listeners = this.targetDestroyListeners.get(target)\n if (!listeners) {\n listeners = new Set()\n this.targetDestroyListeners.set(target, listeners)\n }\n\n listeners.add(listener)\n return () => {\n listeners?.delete(listener)\n if (listeners && listeners.size === 0) {\n this.targetDestroyListeners.delete(target)\n }\n }\n }\n\n public onRawInput(listener: (sequence: string) => boolean): () => void {\n this.rawListeners.add(listener)\n return () => {\n this.rawListeners.delete(listener)\n }\n }\n\n public createCommandEvent(): TestKeymapEvent {\n return new TestKeymapEvent(\"synthetic\")\n }\n\n public focus(target: TestKeymapTarget | null): void {\n this.focusedTarget = target\n for (const listener of this.focusListeners) {\n listener(target)\n }\n }\n\n public press(name: string, modifiers?: TestKeyModifierOptions): TestKeymapEvent {\n const event = new TestKeymapEvent(name, modifiers)\n for (const listener of this.keyPressListeners) {\n listener(event)\n }\n\n return event\n }\n\n public release(name: string, modifiers?: TestKeyModifierOptions): TestKeymapEvent {\n const event = new TestKeymapEvent(name, modifiers)\n for (const listener of this.keyReleaseListeners) {\n listener(event)\n }\n\n return event\n }\n\n public raw(sequence: string): boolean {\n let handled = false\n for (const listener of this.rawListeners) {\n handled = listener(sequence) || handled\n }\n\n return handled\n }\n\n public destroyTarget(target: TestKeymapTarget): void {\n target.isDestroyed = true\n const listeners = this.targetDestroyListeners.get(target)\n if (!listeners) {\n return\n }\n\n for (const listener of [...listeners]) {\n listener()\n }\n }\n\n public destroy(): void {\n if (this.isDestroyed) {\n return\n }\n\n this.isDestroyed = true\n for (const listener of [...this.destroyListeners]) {\n listener()\n }\n }\n}\n\nexport function createTestHostMetadata(options?: HostMetadata | TestHostMetadataOptions): HostMetadata {\n return normalizeTestHostMetadata(options)\n}\n\nexport function createTestKeymapHost(options?: CreateTestKeymapHostOptions): TestKeymapHost {\n return new TestKeymapHost(options)\n}\n\nexport function createTestKeymap(options?: CreateTestKeymapOptions): TestKeymapHarness {\n const host = createTestKeymapHost(options)\n const keymap = new Keymap(host)\n const diagnostics = captureKeymapDiagnostics(keymap)\n\n if (options?.defaultKeys === true) {\n registerDefaultKeys(keymap)\n }\n\n return {\n keymap,\n host,\n root: host.rootTarget,\n diagnostics,\n cleanup() {\n host.destroy()\n diagnostics.dispose()\n },\n }\n}\n\nexport function captureKeymapDiagnostics(keymap: Keymap<any, any>): TestDiagnosticCapture {\n const warnings: string[] = []\n const errors: string[] = []\n const warningEvents: WarningEvent[] = []\n const errorEvents: ErrorEvent[] = []\n\n const offWarning = keymap.on(\"warning\", (event) => {\n warnings.push(event.message)\n warningEvents.push(event)\n })\n const offError = keymap.on(\"error\", (event) => {\n errors.push(event.message)\n errorEvents.push(event)\n })\n\n return {\n warnings,\n errors,\n warningEvents,\n errorEvents,\n takeWarnings() {\n const snapshot = {\n warnings: [...warnings],\n warningEvents: [...warningEvents],\n }\n warnings.length = 0\n warningEvents.length = 0\n return snapshot\n },\n takeErrors() {\n const snapshot = {\n errors: [...errors],\n errorEvents: [...errorEvents],\n }\n errors.length = 0\n errorEvents.length = 0\n return snapshot\n },\n clear() {\n warnings.length = 0\n errors.length = 0\n warningEvents.length = 0\n errorEvents.length = 0\n },\n dispose() {\n offWarning()\n offError()\n },\n }\n}\n\nfunction normalizeTestHostMetadata(metadata?: HostMetadata | TestHostMetadataOptions): HostMetadata {\n if (isHostMetadata(metadata)) {\n return metadata\n }\n\n return {\n platform: metadata?.platform ?? DEFAULT_TEST_HOST_METADATA.platform,\n primaryModifier: metadata?.primaryModifier ?? DEFAULT_TEST_HOST_METADATA.primaryModifier,\n modifiers: {\n ...DEFAULT_TEST_HOST_METADATA.modifiers,\n ...metadata?.modifiers,\n },\n }\n}\n\nfunction isHostMetadata(value: HostMetadata | TestHostMetadataOptions | undefined): value is HostMetadata {\n return !!value && !!value.modifiers && \"ctrl\" in value.modifiers && \"shift\" in value.modifiers\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "AC56D442CF81C26564756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|