@opentui/keymap 0.2.2 → 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.
Files changed (78) hide show
  1. package/README.md +56 -32
  2. package/chunks/index-frk6sdcd.js +409 -0
  3. package/chunks/index-frk6sdcd.js.map +14 -0
  4. package/package.json +17 -7
  5. package/src/addons/index.js +511 -4870
  6. package/src/addons/index.js.map +25 -0
  7. package/src/addons/opentui/edit-buffer-bindings.d.ts +6 -2
  8. package/src/addons/opentui/index.d.ts +2 -2
  9. package/src/addons/opentui/index.js +101 -5515
  10. package/src/addons/opentui/index.js.map +12 -0
  11. package/src/addons/universal/dead-bindings.d.ts +1 -1
  12. package/src/addons/universal/default-parser.d.ts +2 -2
  13. package/src/addons/universal/ex-commands.d.ts +11 -8
  14. package/src/addons/universal/index.d.ts +2 -1
  15. package/src/addons/universal/leader.d.ts +1 -1
  16. package/src/addons/universal/metadata.d.ts +2 -2
  17. package/src/addons/universal/mod-bindings.d.ts +6 -0
  18. package/src/addons/universal/unresolved-commands.d.ts +1 -1
  19. package/src/extras/binding-sections.d.ts +4 -4
  20. package/src/extras/command-bindings.d.ts +2 -2
  21. package/src/extras/formatting.d.ts +3 -0
  22. package/src/extras/graph.d.ts +9 -0
  23. package/src/extras/graph.js +373 -0
  24. package/src/extras/graph.js.map +11 -0
  25. package/src/extras/index.js +13 -0
  26. package/src/extras/index.js.map +12 -0
  27. package/src/extras/lib/graph-snapshot.d.ts +14 -0
  28. package/src/extras/lib/graph-types.d.ts +83 -0
  29. package/src/html.d.ts +3 -3
  30. package/src/html.js +47 -4992
  31. package/src/html.js.map +10 -0
  32. package/src/index.d.ts +3 -1
  33. package/src/index.js +2688 -2807
  34. package/src/index.js.map +34 -0
  35. package/src/keymap.d.ts +17 -33
  36. package/src/lib/emitter.d.ts +1 -2
  37. package/src/lib/registry.d.ts +2 -2
  38. package/src/lib/runtime-utils.d.ts +34 -0
  39. package/src/opentui.d.ts +1 -3
  40. package/src/opentui.js +40 -4994
  41. package/src/opentui.js.map +10 -0
  42. package/src/react/index.d.ts +5 -19
  43. package/src/react/index.js +3 -0
  44. package/src/react/index.js.map +10 -0
  45. package/src/runtime-modules.d.ts +2 -0
  46. package/src/runtime-modules.js +5 -0
  47. package/src/runtime-modules.js.map +10 -0
  48. package/src/services/activation.d.ts +7 -33
  49. package/src/services/active-key-cache.d.ts +29 -0
  50. package/src/services/command-catalog.d.ts +27 -52
  51. package/src/services/command-executor.d.ts +6 -12
  52. package/src/services/compiler.d.ts +4 -12
  53. package/src/services/conditions.d.ts +4 -16
  54. package/src/services/dispatch-decisions.d.ts +21 -0
  55. package/src/services/dispatch-patterns.d.ts +5 -0
  56. package/src/services/dispatch.d.ts +6 -42
  57. package/src/services/environment.d.ts +6 -24
  58. package/src/services/extension-context.d.ts +16 -0
  59. package/src/services/layer-diagnostics.d.ts +10 -0
  60. package/src/services/layers.d.ts +15 -24
  61. package/src/services/notify.d.ts +6 -8
  62. package/src/services/pending-sequence.d.ts +4 -0
  63. package/src/services/primitives/active-layers.d.ts +2 -3
  64. package/src/services/primitives/bindings.d.ts +4 -0
  65. package/src/services/primitives/field-invariants.d.ts +16 -1
  66. package/src/services/primitives/pending-captures.d.ts +5 -0
  67. package/src/services/runtime-view.d.ts +5 -0
  68. package/src/services/runtime.d.ts +2 -7
  69. package/src/services/sequence-index.d.ts +24 -0
  70. package/src/services/state.d.ts +46 -92
  71. package/src/solid/index.d.ts +5 -19
  72. package/src/solid/index.js +3 -0
  73. package/src/solid/index.js.map +10 -0
  74. package/src/testing/index.d.ts +90 -0
  75. package/src/testing/index.js +276 -0
  76. package/src/testing/index.js.map +10 -0
  77. package/src/types.d.ts +180 -128
  78. package/src/services/primitives/binding-inputs.d.ts +0 -4
package/src/types.d.ts CHANGED
@@ -10,7 +10,16 @@ export interface KeymapEvent {
10
10
  stopPropagation(): void;
11
11
  readonly propagationStopped: boolean;
12
12
  }
13
+ export type HostPlatform = "macos" | "windows" | "linux" | "unknown";
14
+ export type HostModifier = "ctrl" | "shift" | "meta" | "super" | "hyper";
15
+ export type HostCapability = "supported" | "unsupported" | "unknown";
16
+ export interface HostMetadata {
17
+ platform: HostPlatform;
18
+ primaryModifier: "ctrl" | "super" | "unknown";
19
+ modifiers: Record<HostModifier, HostCapability>;
20
+ }
13
21
  export interface KeymapHost<TTarget extends object, TEvent extends KeymapEvent = KeymapEvent> {
22
+ readonly metadata: HostMetadata;
14
23
  readonly rootTarget: TTarget;
15
24
  readonly isDestroyed: boolean;
16
25
  getFocusedTarget(): TTarget | null;
@@ -88,6 +97,8 @@ export interface KeySequencePart {
88
97
  display: string;
89
98
  match: KeyMatch;
90
99
  tokenName?: string;
100
+ patternName?: string;
101
+ payloadKey?: string;
91
102
  }
92
103
  export interface StringifyOptions {
93
104
  preferDisplay?: boolean;
@@ -99,23 +110,25 @@ export type KeyStringifyInput = KeyStrokeInput | NormalizedKeyStroke | KeySequen
99
110
  };
100
111
  export type KeyLike = string | KeyStrokeInput;
101
112
  /**
102
- * Read-only view of a registered command. `fields` is raw registration
103
- * metadata; `attrs` is compiled command-field metadata.
113
+ * Public command shape used for layer registration, command queries, command
114
+ * contexts, and command resolver results. Custom command fields are top-level
115
+ * properties so registration stays as simple as `{ name, run, desc }`.
104
116
  */
105
- export interface CommandRecord {
117
+ export interface Command<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent, TPayload = unknown> {
106
118
  name: string;
107
- fields: Readonly<Record<string, unknown>>;
108
- attrs?: Readonly<Attributes>;
119
+ run(ctx: CommandContext<TTarget, TEvent, TPayload>): CommandResult<TTarget, TEvent>;
120
+ [key: string]: unknown;
109
121
  }
110
- export type CommandQueryValue = unknown | readonly unknown[] | ((value: unknown, command: CommandRecord) => boolean);
111
- export type CommandFilter = Readonly<Record<string, CommandQueryValue>> | ((command: CommandRecord) => boolean);
112
- export interface CommandQuery<TTarget extends object = object> {
122
+ export type CommandQueryValue<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = unknown | readonly unknown[] | ((value: unknown, command: Command<TTarget, TEvent>) => boolean);
123
+ export type CommandFilter<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = Readonly<Record<string, CommandQueryValue<TTarget, TEvent>>> | ((command: Command<TTarget, TEvent>) => boolean);
124
+ export interface CommandQuery<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
113
125
  visibility?: "reachable" | "active" | "registered";
114
126
  focused?: TTarget | null;
115
127
  namespace?: string | readonly string[];
116
128
  search?: string;
117
129
  searchIn?: readonly string[];
118
- filter?: CommandFilter;
130
+ filter?: CommandFilter<TTarget, TEvent>;
131
+ limit?: number;
119
132
  }
120
133
  export interface CommandBindingsQuery<TTarget extends object = object> {
121
134
  visibility?: "reachable" | "active" | "registered";
@@ -127,32 +140,35 @@ export interface RunCommandOptions<TTarget extends object = object, TEvent exten
127
140
  focused?: TTarget | null;
128
141
  target?: TTarget | null;
129
142
  includeCommand?: boolean;
143
+ payload?: unknown;
130
144
  }
131
- export type RunCommandResult = {
145
+ export type RunCommandResult<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = {
132
146
  ok: true;
133
- command?: CommandRecord;
147
+ command?: Command<TTarget, TEvent>;
134
148
  } | {
135
149
  ok: false;
136
150
  reason: "not-found";
137
151
  } | {
138
152
  ok: false;
139
153
  reason: "inactive" | "disabled" | "invalid-args" | "rejected" | "error";
140
- command?: CommandRecord;
154
+ command?: Command<TTarget, TEvent>;
141
155
  };
142
- export interface CommandContext<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
156
+ export interface CommandContext<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent, TPayload = unknown> {
143
157
  keymap: Keymap<TTarget, TEvent>;
144
158
  event: TEvent;
145
159
  focused: TTarget | null;
146
160
  target: TTarget | null;
147
161
  data: Readonly<EventData>;
148
- command?: CommandRecord;
162
+ command?: Command<TTarget, TEvent, TPayload>;
163
+ input: string;
164
+ payload: TPayload;
149
165
  }
150
- export type CommandResult = boolean | void | Promise<boolean | void>;
166
+ export type CommandResult<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = boolean | void | RunCommandResult<TTarget, TEvent> | Promise<boolean | void | RunCommandResult<TTarget, TEvent>>;
151
167
  export type CommandResolutionStatus = "resolved" | "unresolved" | "error";
152
- export type CommandHandler<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = (ctx: CommandContext<TTarget, TEvent>) => CommandResult;
168
+ export type CommandHandler<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent, TPayload = unknown> = (ctx: CommandContext<TTarget, TEvent, TPayload>) => CommandResult<TTarget, TEvent>;
153
169
  export type BindingCommand<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = string | CommandHandler<TTarget, TEvent>;
154
170
  export type BindingEvent = "press" | "release";
155
- export interface BindingInput<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
171
+ export interface Binding<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
156
172
  key: KeyLike;
157
173
  cmd?: BindingCommand<TTarget, TEvent>;
158
174
  event?: BindingEvent;
@@ -173,12 +189,13 @@ export interface BindingInput<TTarget extends object = object, TEvent extends Ke
173
189
  fallthrough?: boolean;
174
190
  [key: string]: unknown;
175
191
  }
176
- export type Bindings<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = readonly BindingInput<TTarget, TEvent>[];
192
+ export type Bindings<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = readonly Binding<TTarget, TEvent>[];
177
193
  export type TargetMode = "focus" | "focus-within";
178
- export interface LayerFields<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
194
+ export interface Layer<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
195
+ target?: TTarget;
179
196
  priority?: number;
180
197
  bindings?: Bindings<TTarget, TEvent>;
181
- commands?: readonly CommandDefinition<TTarget, TEvent>[];
198
+ commands?: readonly Command<TTarget, TEvent, any>[];
182
199
  targetMode?: TargetMode;
183
200
  /**
184
201
  * Extra layer fields feed layer-field compilers and binding compilation via
@@ -187,55 +204,45 @@ export interface LayerFields<TTarget extends object = object, TEvent extends Key
187
204
  */
188
205
  [key: string]: unknown;
189
206
  }
190
- export interface Layer<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> extends LayerFields<TTarget, TEvent> {
191
- target?: TTarget;
192
- }
193
- export interface GlobalLayer<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> extends LayerFields<TTarget, TEvent> {
194
- target?: undefined;
195
- }
196
- export interface FocusWithinLayer<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> extends LayerFields<TTarget, TEvent> {
197
- target: TTarget;
198
- targetMode?: TargetMode;
199
- }
200
- export interface FocusLayer<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> extends LayerFields<TTarget, TEvent> {
201
- target: TTarget;
202
- targetMode?: TargetMode;
203
- }
204
- export type TargetLayer<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = FocusWithinLayer<TTarget, TEvent> | FocusLayer<TTarget, TEvent>;
205
207
  export interface ParsedCommand {
206
208
  input: string;
207
209
  name: string;
208
210
  args: string[];
209
211
  }
210
- export interface CommandResolverContext {
211
- getCommandAttrs(name: string): Readonly<Attributes> | undefined;
212
- getCommandRecord(name: string): CommandRecord | undefined;
212
+ export interface CommandResolverContext<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
213
+ readonly input: string;
214
+ readonly payload: unknown;
215
+ setInput(input: string): void;
216
+ setPayload(payload: unknown): void;
217
+ getCommand(name: string): Command<TTarget, TEvent> | undefined;
213
218
  }
214
- /**
215
- * Resolver output. `run` executes the command, `attrs` / `record` expose
216
- * metadata, and `rejectedResult` overrides the default rejected result.
217
- */
218
- export interface ResolvedBindingCommand<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
219
- run: CommandHandler<TTarget, TEvent>;
220
- attrs?: Readonly<Attributes>;
221
- record?: CommandRecord;
222
- rejectedResult?: Extract<RunCommandResult, {
223
- ok: false;
224
- }>;
219
+ export type CommandResolver<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = (command: string, ctx: CommandResolverContext<TTarget, TEvent>) => Command<TTarget, TEvent> | undefined;
220
+ export interface KeyToken {
221
+ name: string;
222
+ key: KeyLike;
225
223
  }
226
- export type CommandResolver<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = (command: string, ctx: CommandResolverContext) => ResolvedBindingCommand<TTarget, TEvent> | undefined;
227
- /**
228
- * Layer command registration input. Extra fields stay on `fields` and can be
229
- * compiled into `attrs` by command-field addons.
230
- */
231
- export interface CommandDefinition<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
224
+ export interface SequencePatternMatch {
225
+ value?: unknown;
226
+ display?: string;
227
+ }
228
+ export interface SequencePattern<TEvent extends KeymapEvent = KeymapEvent> {
232
229
  name: string;
233
- run: CommandHandler<TTarget, TEvent>;
234
- [key: string]: unknown;
230
+ display?: string;
231
+ payloadKey?: string;
232
+ min?: number;
233
+ max?: number;
234
+ match(event: TEvent): SequencePatternMatch | undefined;
235
+ finalize?(values: readonly unknown[]): unknown;
235
236
  }
236
- export interface KeyToken {
237
+ export interface ResolvedSequencePattern<TEvent extends KeymapEvent = KeymapEvent> {
237
238
  name: string;
238
- key: KeyLike;
239
+ display?: string;
240
+ payloadKey: string;
241
+ match: KeyMatch;
242
+ min: number;
243
+ max: number;
244
+ matcher(event: TEvent): SequencePatternMatch | undefined;
245
+ finalize?: (values: readonly unknown[]) => unknown;
239
246
  }
240
247
  export interface ActiveBinding<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
241
248
  sequence: KeySequencePart[];
@@ -246,12 +253,48 @@ export interface ActiveBinding<TTarget extends object = object, TEvent extends K
246
253
  preventDefault: boolean;
247
254
  fallthrough: boolean;
248
255
  }
256
+ export interface DispatchLayer<TTarget extends object = object> {
257
+ order: number;
258
+ priority: number;
259
+ target?: TTarget;
260
+ targetMode?: TargetMode;
261
+ }
262
+ export interface DispatchBinding<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> extends ActiveBinding<TTarget, TEvent> {
263
+ sourceLayerOrder: number;
264
+ bindingIndex: number;
265
+ }
266
+ export type DispatchPhase = "sequence-start" | "sequence-advance" | "sequence-clear" | "binding-execute" | "binding-reject";
267
+ export interface DispatchEvent<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
268
+ phase: DispatchPhase;
269
+ event: BindingEvent;
270
+ focused: TTarget | null;
271
+ layer?: DispatchLayer<TTarget>;
272
+ binding?: DispatchBinding<TTarget, TEvent>;
273
+ sequence: readonly KeySequencePart[];
274
+ command?: BindingCommand<TTarget, TEvent>;
275
+ }
276
+ export type KeyAfterReason = "intercept-consumed" | "binding-handled" | "binding-rejected" | "no-match" | "sequence-pending" | "sequence-miss" | "sequence-cleared";
277
+ export interface KeyAfterInputContext<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
278
+ event: TEvent;
279
+ eventType: BindingEvent;
280
+ focused: TTarget | null;
281
+ handled: boolean;
282
+ reason: KeyAfterReason;
283
+ sequence: readonly KeySequencePart[];
284
+ pendingSequence: readonly KeySequencePart[];
285
+ setData: (name: string, value: unknown) => void;
286
+ getData: (name: string) => unknown;
287
+ consume: (options?: {
288
+ preventDefault?: boolean;
289
+ stopPropagation?: boolean;
290
+ }) => void;
291
+ }
249
292
  /**
250
293
  * Command metadata together with the bindings that invoke it in a given query
251
294
  * projection.
252
295
  */
253
296
  export interface CommandEntry<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
254
- command: CommandRecord;
297
+ command: Command<TTarget, TEvent>;
255
298
  bindings: readonly ActiveBinding<TTarget, TEvent>[];
256
299
  }
257
300
  export interface ActiveKeyOptions {
@@ -281,21 +324,20 @@ export interface BindingFieldContext {
281
324
  require(name: string, value: unknown): void;
282
325
  attr(name: string, value: unknown): void;
283
326
  /**
284
- * Registers a runtime matcher. Raw callbacks re-run on every read;
285
- * reactive matchers stay cached until they notify.
327
+ * Registers a runtime matcher. Matchers are evaluated when the owning
328
+ * record is queried or dispatched; reactive matchers also notify state
329
+ * subscribers when their external source changes.
286
330
  */
287
331
  activeWhen(matcher: (() => boolean) | ReactiveMatcher): void;
288
332
  }
289
333
  export type BindingFieldCompiler = (value: unknown, ctx: BindingFieldContext) => void;
290
334
  export interface LayerFieldContext {
291
335
  require(name: string, value: unknown): void;
336
+ attr(name: string, value: unknown): void;
292
337
  /**
293
- * Layer fields only influence activation and binding compilation. They do
294
- * not expose `attr(...)` because the current model has no layer-level attrs
295
- * surface on `ActiveKey`, `ActiveBinding`, or `CommandRecord`.
296
- *
297
- * Registers a runtime matcher. Raw callbacks re-run on every read;
298
- * reactive matchers stay cached until they notify.
338
+ * Registers a runtime matcher. Matchers are evaluated when the owning
339
+ * record is queried or dispatched; reactive matchers also notify state
340
+ * subscribers when their external source changes.
299
341
  */
300
342
  activeWhen(matcher: (() => boolean) | ReactiveMatcher): void;
301
343
  }
@@ -303,7 +345,7 @@ export type LayerFieldCompiler = (value: unknown, ctx: LayerFieldContext) => voi
303
345
  export interface LayerAnalysisContext<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
304
346
  target?: TTarget;
305
347
  order: number;
306
- bindingInputs: readonly BindingInput<TTarget, TEvent>[];
348
+ sourceBindings: readonly Binding<TTarget, TEvent>[];
307
349
  bindings: readonly LayerBindingAnalysis<TTarget, TEvent>[];
308
350
  hasTokenBindings: boolean;
309
351
  checkCommandResolution(command: string): CommandResolutionStatus;
@@ -318,10 +360,10 @@ export interface LayerBindingAnalysis<TTarget extends object = object, TEvent ex
318
360
  event: BindingEvent;
319
361
  preventDefault: boolean;
320
362
  fallthrough: boolean;
321
- sourceBinding: ParsedBindingInput<TTarget, TEvent>;
363
+ parsedBinding: ParsedBinding<TTarget, TEvent>;
322
364
  sourceTarget?: TTarget;
323
365
  sourceLayerOrder: number;
324
- sourceBindingIndex: number;
366
+ bindingIndex: number;
325
367
  hasCommandAtSequence: boolean;
326
368
  hasContinuations: boolean;
327
369
  }
@@ -331,6 +373,7 @@ export interface BindingParserContext {
331
373
  index: number;
332
374
  layer: Readonly<Record<string, unknown>>;
333
375
  tokens: ReadonlyMap<string, ResolvedKeyToken>;
376
+ patterns: ReadonlyMap<string, ResolvedSequencePattern>;
334
377
  normalizeTokenName(token: string): string;
335
378
  createMatch(id: string): KeyMatch;
336
379
  parseObjectKey(key: KeyStrokeInput, options?: {
@@ -341,8 +384,13 @@ export interface BindingParserContext {
341
384
  }
342
385
  export interface BindingExpanderContext {
343
386
  input: string;
387
+ displays?: readonly string[];
344
388
  layer: Readonly<Record<string, unknown>>;
345
389
  }
390
+ export interface BindingExpansion {
391
+ key: string;
392
+ displays?: readonly string[];
393
+ }
346
394
  export interface BindingParserResult {
347
395
  parts: KeySequencePart[];
348
396
  nextIndex: number;
@@ -350,8 +398,8 @@ export interface BindingParserResult {
350
398
  unknownTokens?: readonly string[];
351
399
  }
352
400
  export type BindingParser = (ctx: BindingParserContext) => BindingParserResult | undefined;
353
- export type BindingExpander = (ctx: BindingExpanderContext) => readonly string[] | undefined;
354
- export interface ParsedBindingInput<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
401
+ export type BindingExpander = (ctx: BindingExpanderContext) => readonly BindingExpansion[] | undefined;
402
+ export interface ParsedBinding<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
355
403
  key: KeyLike;
356
404
  sequence: KeySequencePart[];
357
405
  cmd?: BindingCommand<TTarget, TEvent>;
@@ -363,11 +411,11 @@ export interface ParsedBindingInput<TTarget extends object = object, TEvent exte
363
411
  export interface BindingTransformerContext<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
364
412
  layer: Readonly<Record<string, unknown>>;
365
413
  parseKey(key: KeyLike): KeySequencePart;
366
- add(binding: ParsedBindingInput<TTarget, TEvent>): void;
414
+ add(binding: ParsedBinding<TTarget, TEvent>): void;
367
415
  skipOriginal(): void;
368
416
  }
369
- export type BindingTransformer<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = (binding: ParsedBindingInput<TTarget, TEvent>, ctx: BindingTransformerContext<TTarget, TEvent>) => void;
370
- export type BindingInputsValidationResult = {
417
+ export type BindingTransformer<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = (binding: ParsedBinding<TTarget, TEvent>, ctx: BindingTransformerContext<TTarget, TEvent>) => void;
418
+ export type BindingsValidationResult = {
371
419
  ok: true;
372
420
  } | {
373
421
  ok: false;
@@ -375,15 +423,22 @@ export type BindingInputsValidationResult = {
375
423
  };
376
424
  export interface LayerBindingsTransformerContext<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
377
425
  layer: Readonly<Layer<TTarget, TEvent>>;
378
- validateBindings(bindings: unknown): BindingInputsValidationResult;
426
+ validateBindings(bindings: unknown): BindingsValidationResult;
379
427
  }
380
- export type LayerBindingsTransformer<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = (bindings: readonly BindingInput<TTarget, TEvent>[], ctx: LayerBindingsTransformerContext<TTarget, TEvent>) => readonly BindingInput<TTarget, TEvent>[] | void;
428
+ export type LayerBindingsTransformer<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = (bindings: readonly Binding<TTarget, TEvent>[], ctx: LayerBindingsTransformerContext<TTarget, TEvent>) => readonly Binding<TTarget, TEvent>[] | void;
429
+ export interface CommandTransformerContext<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
430
+ layer: Readonly<Layer<TTarget, TEvent>>;
431
+ add(command: Command<TTarget, TEvent>): void;
432
+ skipOriginal(): void;
433
+ }
434
+ export type CommandTransformer<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = (command: Command<TTarget, TEvent>, ctx: CommandTransformerContext<TTarget, TEvent>) => void;
381
435
  export interface CommandFieldContext {
382
436
  require(name: string, value: unknown): void;
383
437
  attr(name: string, value: unknown): void;
384
438
  /**
385
- * Registers a runtime matcher. Raw callbacks re-run on every read;
386
- * reactive matchers stay cached until they notify.
439
+ * Registers a runtime matcher. Matchers are evaluated when the owning
440
+ * record is queried or dispatched; reactive matchers also notify state
441
+ * subscribers when their external source changes.
387
442
  */
388
443
  activeWhen(matcher: (() => boolean) | ReactiveMatcher): void;
389
444
  }
@@ -412,6 +467,8 @@ export type Hooks<TTarget extends object = object, TEvent extends KeymapEvent =
412
467
  * current sequence.
413
468
  */
414
469
  pendingSequence: readonly KeySequencePart[];
470
+ /** Dispatch trace events for sequence continuation and binding execution. */
471
+ dispatch: DispatchEvent<TTarget, TEvent>;
415
472
  };
416
473
  export type HookName = keyof Hooks;
417
474
  export type Listener<TValue> = [TValue] extends [void] ? () => void : (value: TValue) => void;
@@ -431,8 +488,9 @@ export type Events<TTarget extends object = object, TEvent extends KeymapEvent =
431
488
  error: ErrorEvent;
432
489
  };
433
490
  export type EventName = keyof Events;
434
- export type Intercepts<TEvent extends KeymapEvent = KeymapEvent> = {
491
+ export type Intercepts<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = {
435
492
  key: KeyInputContext<TEvent>;
493
+ "key:after": KeyAfterInputContext<TTarget, TEvent>;
436
494
  raw: RawInputContext;
437
495
  };
438
496
  export type InterceptName = keyof Intercepts;
@@ -447,11 +505,6 @@ export type { Keymap };
447
505
  export interface RuntimeMatcher {
448
506
  source: string;
449
507
  match: () => boolean;
450
- /**
451
- * False for raw callbacks with no subscription or data dependency, so the
452
- * owner must re-evaluate on every read.
453
- */
454
- cacheable: boolean;
455
508
  /**
456
509
  * Present for reactive matchers; wired during registration and torn down via
457
510
  * `dispose`.
@@ -462,27 +515,22 @@ export interface RuntimeMatcher {
462
515
  export interface RuntimeMatchable {
463
516
  requires: readonly [name: string, value: unknown][];
464
517
  matchers: readonly RuntimeMatcher[];
465
- /** Data keys referenced via `require(...)`; used for `setData` invalidation. */
466
- conditionKeys: readonly string[];
467
- /** True when any matcher is a raw callback and therefore cannot be cached. */
468
- hasUnkeyedMatchers: boolean;
469
- matchCacheDirty?: boolean;
470
- matchCache?: boolean;
471
- }
472
- export interface CompiledBinding<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> extends ActiveBinding<TTarget, TEvent>, RuntimeMatchable {
518
+ }
519
+ export interface BindingState<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> extends ActiveBinding<TTarget, TEvent>, RuntimeMatchable {
520
+ binding: Binding<TTarget, TEvent>;
473
521
  run?: CommandHandler<TTarget, TEvent>;
474
- sourceBinding: ParsedBindingInput<TTarget, TEvent>;
522
+ parsedBinding: ParsedBinding<TTarget, TEvent>;
475
523
  sourceTarget?: TTarget;
476
524
  sourceLayerOrder: number;
477
- sourceBindingIndex: number;
525
+ bindingIndex: number;
478
526
  }
479
527
  export interface ActiveKeySelection<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
480
528
  display: string;
481
529
  tokenName?: string;
482
530
  continues: boolean;
483
- firstBinding?: CompiledBinding<TTarget, TEvent>;
484
- commandBinding?: CompiledBinding<TTarget, TEvent>;
485
- bindings?: readonly CompiledBinding<TTarget, TEvent>[];
531
+ firstBinding?: BindingState<TTarget, TEvent>;
532
+ commandBinding?: BindingState<TTarget, TEvent>;
533
+ bindings?: readonly BindingState<TTarget, TEvent>[];
486
534
  stop: boolean;
487
535
  }
488
536
  export interface ActiveKeyState<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
@@ -490,20 +538,17 @@ export interface ActiveKeyState<TTarget extends object = object, TEvent extends
490
538
  display: string;
491
539
  tokenName?: string;
492
540
  continues: boolean;
493
- firstBinding?: CompiledBinding<TTarget, TEvent>;
494
- commandBinding?: CompiledBinding<TTarget, TEvent>;
495
- bindings?: CompiledBinding<TTarget, TEvent>[];
496
- }
497
- export interface RegisteredCommand<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> extends CommandRecord, RuntimeMatchable {
498
- run: (ctx: CommandContext<TTarget, TEvent>) => CommandResult;
499
- runner?: CommandHandler<TTarget, TEvent>;
500
- resolved?: ResolvedBindingCommand<TTarget, TEvent>;
501
- resolvedWithRecord?: ResolvedBindingCommand<TTarget, TEvent>;
502
- record?: CommandRecord;
503
- }
504
- export interface CompiledBindingsResult<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
505
- root: SequenceNode<TTarget, TEvent>;
506
- bindings: readonly CompiledBinding<TTarget, TEvent>[];
541
+ firstBinding?: BindingState<TTarget, TEvent>;
542
+ commandBinding?: BindingState<TTarget, TEvent>;
543
+ bindings?: BindingState<TTarget, TEvent>[];
544
+ }
545
+ export interface CommandState<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> extends RuntimeMatchable {
546
+ command: Command<TTarget, TEvent, any>;
547
+ fields: Readonly<Record<string, unknown>>;
548
+ attrs?: Readonly<Attributes>;
549
+ }
550
+ export interface BindingCompilationResult<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
551
+ bindings: readonly BindingState<TTarget, TEvent>[];
507
552
  hasTokenBindings: boolean;
508
553
  }
509
554
  export interface SequenceNode<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
@@ -511,9 +556,11 @@ export interface SequenceNode<TTarget extends object = object, TEvent extends Ke
511
556
  depth: number;
512
557
  stroke: NormalizedKeyStroke | null;
513
558
  match: KeyMatch | null;
559
+ pattern?: ResolvedSequencePattern<TEvent>;
514
560
  children: Map<KeyMatch, SequenceNode<TTarget, TEvent>>;
515
- bindings: CompiledBinding<TTarget, TEvent>[];
516
- reachableBindings: CompiledBinding<TTarget, TEvent>[];
561
+ patternChildren: SequenceNode<TTarget, TEvent>[];
562
+ bindings: BindingState<TTarget, TEvent>[];
563
+ reachableBindings: BindingState<TTarget, TEvent>[];
517
564
  }
518
565
  export interface RegisteredLayer<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
519
566
  order: number;
@@ -522,24 +569,29 @@ export interface RegisteredLayer<TTarget extends object = object, TEvent extends
522
569
  priority: number;
523
570
  requires: readonly [name: string, value: unknown][];
524
571
  matchers: readonly RuntimeMatcher[];
525
- conditionKeys: readonly string[];
526
- hasUnkeyedMatchers: boolean;
527
- matchCacheDirty?: boolean;
528
- matchCache?: boolean;
529
- compileFields?: Readonly<Record<string, unknown>>;
530
- commands: readonly RegisteredCommand<TTarget, TEvent>[];
531
- commandLookup?: ReadonlyMap<string, RegisteredCommand<TTarget, TEvent>>;
532
- bindingInputs: readonly BindingInput<TTarget, TEvent>[];
533
- compiledBindings: readonly CompiledBinding<TTarget, TEvent>[];
534
- hasUnkeyedCommands: boolean;
535
- hasUnkeyedBindings: boolean;
536
- hasTokenBindings: boolean;
572
+ fields?: Readonly<Record<string, unknown>>;
573
+ attrs?: Readonly<Attributes>;
574
+ commands: readonly CommandState<TTarget, TEvent>[];
575
+ sourceBindings: readonly Binding<TTarget, TEvent>[];
576
+ bindings: readonly BindingState<TTarget, TEvent>[];
537
577
  root: SequenceNode<TTarget, TEvent>;
578
+ hasTokenBindings: boolean;
579
+ activeKeyCacheBlocked: boolean;
580
+ activeCommandViewCacheBlocked: boolean;
538
581
  offTargetDestroy?: () => void;
539
582
  }
540
583
  export interface PendingSequenceCapture<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
541
584
  layer: RegisteredLayer<TTarget, TEvent>;
542
- node: SequenceNode<TTarget, TEvent>;
585
+ binding: BindingState<TTarget, TEvent>;
586
+ index: number;
587
+ parts: readonly KeySequencePart[];
588
+ patterns?: readonly PendingSequencePatternCapture[];
589
+ }
590
+ export interface PendingSequencePatternCapture {
591
+ name: string;
592
+ payloadKey: string;
593
+ values: readonly unknown[];
594
+ parts: readonly KeySequencePart[];
543
595
  }
544
596
  export interface PendingSequenceState<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
545
597
  captures: readonly PendingSequenceCapture<TTarget, TEvent>[];
@@ -1,4 +0,0 @@
1
- import type { BindingInput, BindingInputsValidationResult, Bindings, KeymapEvent, ParsedBindingInput } from "../../types.js";
2
- export declare function validateBindingInputs(bindings: unknown): BindingInputsValidationResult;
3
- export declare function snapshotBindingInputs<TTarget extends object, TEvent extends KeymapEvent>(bindings: Bindings<TTarget, TEvent>): BindingInput<TTarget, TEvent>[];
4
- export declare function snapshotParsedBindingInput<TTarget extends object, TEvent extends KeymapEvent>(binding: ParsedBindingInput<TTarget, TEvent>): ParsedBindingInput<TTarget, TEvent>;