@opentui/keymap 0.2.2 → 0.2.4

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 +16 -7
  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 +57 -4
  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
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/extras/lib/graph-snapshot.ts", "../src/extras/graph.ts"],
4
+ "sourcesContent": [
5
+ "import type { ActivationService } from \"../../services/activation.js\"\nimport type { CommandCatalogService } from \"../../services/command-catalog.js\"\nimport type { ConditionService } from \"../../services/conditions.js\"\nimport type { State } from \"../../services/state.js\"\nimport type {\n BindingState,\n CommandState,\n KeymapEvent,\n KeymapHost,\n KeySequencePart,\n RegisteredLayer,\n SequenceNode,\n} from \"../../types.js\"\nimport type {\n GraphBinding,\n GraphCommand,\n GraphInactiveReason,\n GraphLayer,\n GraphSequenceNode,\n GraphSnapshot,\n GraphSnapshotOptions,\n} from \"./graph-types.js\"\nimport { cloneKeySequence, cloneKeyStroke } from \"../../services/keys.js\"\nimport {\n getActivationPath,\n getFocusedTargetIfAvailable,\n getSortedLayers,\n isLayerActiveForFocused,\n} from \"../../services/primitives/active-layers.js\"\nimport { childNodes, getCaptureNode, getNodePresentation, getNodeSequence } from \"../../services/sequence-index.js\"\n\ninterface LayerGraphState<TTarget extends object, TEvent extends KeymapEvent> {\n layer: RegisteredLayer<TTarget, TEvent>\n id: string\n focusActive: boolean\n enabled: boolean\n active: boolean\n inactiveReasons: GraphInactiveReason[]\n}\n\ninterface BindingGraphState<TTarget extends object, TEvent extends KeymapEvent> {\n binding: BindingState<TTarget, TEvent>\n id: string\n layerState: LayerGraphState<TTarget, TEvent>\n commandIds: string[]\n enabled: boolean\n commandResolved: boolean\n active: boolean\n reachable: boolean\n shadowed: boolean\n inactiveReasons: GraphInactiveReason[]\n}\n\ninterface CommandGraphState<TTarget extends object, TEvent extends KeymapEvent> {\n command: CommandState<TTarget, TEvent>\n id: string\n layerState: LayerGraphState<TTarget, TEvent>\n active: boolean\n reachable: boolean\n enabled: boolean\n inactiveReasons: GraphInactiveReason[]\n}\n\ninterface SequenceStop {\n event: string\n matches: readonly string[]\n}\n\nfunction hasOwnFocused<TTarget extends object>(\n options: GraphSnapshotOptions<TTarget> | undefined,\n): options is GraphSnapshotOptions<TTarget> & { focused: TTarget | null | undefined } {\n return !!options && Object.prototype.hasOwnProperty.call(options, \"focused\")\n}\n\nfunction layerId<TTarget extends object, TEvent extends KeymapEvent>(layer: RegisteredLayer<TTarget, TEvent>): string {\n return `layer:${layer.order}`\n}\n\nfunction bindingId<TTarget extends object, TEvent extends KeymapEvent>(\n layer: RegisteredLayer<TTarget, TEvent>,\n index: number,\n): string {\n return `binding:${layer.order}:${index}`\n}\n\nfunction commandId<TTarget extends object, TEvent extends KeymapEvent>(\n layer: RegisteredLayer<TTarget, TEvent>,\n index: number,\n): string {\n return `command:${layer.order}:${index}`\n}\n\nfunction nodeId<TTarget extends object, TEvent extends KeymapEvent>(\n layer: RegisteredLayer<TTarget, TEvent>,\n index: number,\n): string {\n return `node:${layer.order}:${index}`\n}\n\nfunction getSequenceMatches(sequence: readonly KeySequencePart[]): string[] {\n return sequence.map((part) => part.match)\n}\n\nfunction isPrefix(left: readonly string[], right: readonly string[]): boolean {\n if (left.length > right.length) {\n return false\n }\n\n for (let index = 0; index < left.length; index += 1) {\n if (left[index] !== right[index]) {\n return false\n }\n }\n\n return true\n}\n\nfunction collectPendingNodes<TTarget extends object, TEvent extends KeymapEvent>(\n pending: State<TTarget, TEvent>[\"pending\"],\n layerIds: ReadonlyMap<RegisteredLayer<TTarget, TEvent>, string>,\n nodeIds: ReadonlyMap<SequenceNode<TTarget, TEvent>, string>,\n roots: ReadonlyMap<RegisteredLayer<TTarget, TEvent>, SequenceNode<TTarget, TEvent>>,\n): { pending: Set<string>; pendingPath: Set<string> } {\n const pendingIds = new Set<string>()\n const pendingPathIds = new Set<string>()\n\n if (!pending) {\n return { pending: pendingIds, pendingPath: pendingPathIds }\n }\n\n for (const capture of pending.captures) {\n const layerGraphId = layerIds.get(capture.layer)\n if (!layerGraphId) {\n continue\n }\n\n const root = roots.get(capture.layer)\n if (!root) {\n continue\n }\n\n let current: SequenceNode<TTarget, TEvent> | null = getCaptureNode(root, capture) ?? null\n const capturedNodeId = current ? nodeIds.get(current) : undefined\n if (capturedNodeId) {\n pendingIds.add(capturedNodeId)\n }\n\n while (current) {\n const currentNodeId = nodeIds.get(current)\n if (currentNodeId) {\n pendingPathIds.add(currentNodeId)\n }\n current = current.parent\n }\n }\n\n return { pending: pendingIds, pendingPath: pendingPathIds }\n}\n\nexport function createGraphSnapshot<TTarget extends object, TEvent extends KeymapEvent>(options: {\n state: State<TTarget, TEvent>\n host: KeymapHost<TTarget, TEvent>\n conditions: ConditionService<TTarget, TEvent>\n catalog: CommandCatalogService<TTarget, TEvent>\n activation: ActivationService<TTarget, TEvent>\n snapshotOptions?: GraphSnapshotOptions<TTarget>\n}): GraphSnapshot<TTarget, TEvent> {\n const { state, host, conditions, catalog, activation, snapshotOptions } = options\n const includeTargets = snapshotOptions?.includeTargets !== false\n const currentFocused = getFocusedTargetIfAvailable(host)\n const focused = hasOwnFocused(snapshotOptions) ? (snapshotOptions.focused ?? null) : currentFocused\n const activeView = catalog.getActiveCommandView(focused)\n const activeCommandStates = new Set(activeView.entries.map((entry) => entry.commandState))\n const reachableCommandStates = new Set(activeView.reachable.map((entry) => entry.commandState))\n const activationPath = getActivationPath(host, focused)\n const sortedLayers = getSortedLayers(state.layers)\n const layerStates = new Map<RegisteredLayer<TTarget, TEvent>, LayerGraphState<TTarget, TEvent>>()\n const commandStates = new Map<CommandState<TTarget, TEvent>, CommandGraphState<TTarget, TEvent>>()\n const bindingStates = new Map<BindingState<TTarget, TEvent>, BindingGraphState<TTarget, TEvent>>()\n const commandIdsByCommand = new Map<CommandState<TTarget, TEvent>[\"command\"], string[]>()\n const commandIdsByName = new Map<string, string[]>()\n const nodeIds = new Map<SequenceNode<TTarget, TEvent>, string>()\n const layerIds = new Map<RegisteredLayer<TTarget, TEvent>, string>()\n const layerRoots = new Map<RegisteredLayer<TTarget, TEvent>, SequenceNode<TTarget, TEvent>>()\n const bindingNodeIds = new Map<BindingState<TTarget, TEvent>, string>()\n const sequenceNodes: GraphSequenceNode[] = []\n\n for (const layer of sortedLayers) {\n layerRoots.set(layer, layer.root)\n }\n\n for (const layer of sortedLayers) {\n const currentLayerId = layerId(layer)\n const targetDestroyed = layer.target ? host.isTargetDestroyed(layer.target) : false\n const focusActive = isLayerActiveForFocused(host, layer, focused, activationPath)\n const enabled = conditions.matchesConditions(layer)\n const inactiveReasons: GraphInactiveReason[] = []\n if (targetDestroyed) inactiveReasons.push(\"target-destroyed\")\n if (!focusActive) inactiveReasons.push(\"focus\")\n if (!enabled) inactiveReasons.push(\"layer-disabled\")\n\n layerIds.set(layer, currentLayerId)\n layerStates.set(layer, {\n layer,\n id: currentLayerId,\n focusActive,\n enabled,\n active: !targetDestroyed && focusActive && enabled,\n inactiveReasons,\n })\n }\n\n for (const layer of sortedLayers) {\n const currentLayerId = layerIds.get(layer)!\n for (const [index, command] of layer.commands.entries()) {\n const currentCommandId = commandId(layer, index)\n const idsByCommand = commandIdsByCommand.get(command.command)\n if (idsByCommand) {\n idsByCommand.push(currentCommandId)\n } else {\n commandIdsByCommand.set(command.command, [currentCommandId])\n }\n\n const idsByName = commandIdsByName.get(command.command.name)\n if (idsByName) {\n idsByName.push(currentCommandId)\n } else {\n commandIdsByName.set(command.command.name, [currentCommandId])\n }\n\n const layerState = layerStates.get(layer)!\n const enabled = conditions.matchesConditions(command)\n const active = activeCommandStates.has(command)\n const reachable = reachableCommandStates.has(command)\n const inactiveReasons = [...layerState.inactiveReasons]\n if (!enabled) {\n inactiveReasons.push(\"command-disabled\")\n }\n if (active && !reachable) {\n inactiveReasons.push(\"shadowed\")\n }\n commandStates.set(command, {\n command,\n id: currentCommandId,\n layerState,\n active,\n reachable,\n enabled,\n inactiveReasons,\n })\n }\n\n let nextNodeIndex = 0\n const visitNode = (node: SequenceNode<TTarget, TEvent>, parentId: string | null): void => {\n const currentNodeId = nodeId(layer, nextNodeIndex)\n nextNodeIndex += 1\n nodeIds.set(node, currentNodeId)\n\n for (const binding of node.bindings) {\n bindingNodeIds.set(binding, currentNodeId)\n }\n\n for (const child of childNodes(node)) {\n visitNode(child, currentNodeId)\n }\n }\n\n const root = layerRoots.get(layer)!\n visitNode(root, null)\n if (!nodeIds.has(root)) {\n nodeIds.set(root, `${currentLayerId}:root`)\n }\n }\n\n const stoppedSequences: SequenceStop[] = []\n for (const layer of sortedLayers) {\n const layerState = layerStates.get(layer)!\n for (const [index, binding] of layer.bindings.entries()) {\n const enabled = conditions.matchesConditions(binding)\n const commandResolved = catalog.isBindingVisible(binding, focused, activeView)\n const active = layerState.active && enabled && commandResolved\n const matches = getSequenceMatches(binding.sequence)\n const shadowed =\n active && stoppedSequences.some((stop) => stop.event === binding.event && isPrefix(stop.matches, matches))\n const inactiveReasons = [...layerState.inactiveReasons]\n if (!enabled) {\n inactiveReasons.push(\"binding-disabled\")\n }\n if (!commandResolved) {\n const unavailable =\n typeof binding.command === \"string\"\n ? catalog.getDispatchUnavailableCommandState(binding.command, focused, false)\n : undefined\n if (unavailable?.reason === \"disabled\") {\n inactiveReasons.push(\"command-disabled\")\n } else if (unavailable?.reason === \"inactive\") {\n inactiveReasons.push(\"command-inactive\")\n } else {\n inactiveReasons.push(\"command-unresolved\")\n }\n }\n if (shadowed) {\n inactiveReasons.push(\"shadowed\")\n }\n\n const currentBindingState: BindingGraphState<TTarget, TEvent> = {\n binding,\n id: bindingId(layer, index),\n layerState,\n commandIds: [],\n enabled,\n commandResolved,\n active,\n reachable: active && !shadowed,\n shadowed,\n inactiveReasons,\n }\n bindingStates.set(binding, currentBindingState)\n\n if (active && binding.command !== undefined && !binding.fallthrough) {\n stoppedSequences.push({ event: binding.event, matches })\n }\n }\n }\n\n for (const state of bindingStates.values()) {\n if (typeof state.binding.command !== \"string\") {\n continue\n }\n\n const ids = new Set(commandIdsByName.get(state.binding.command) ?? [])\n const chain = catalog.getResolvedCommandChain(state.binding.command, focused).entries\n for (const entry of chain ?? []) {\n for (const id of commandIdsByCommand.get(entry.command) ?? []) {\n ids.add(id)\n }\n }\n state.commandIds = [...ids]\n }\n\n const pending = focused === currentFocused ? activation.ensureValidPendingSequence() : undefined\n const pendingNodes = collectPendingNodes(pending ?? null, layerIds, nodeIds, layerRoots)\n\n for (const layer of sortedLayers) {\n const currentLayerId = layerIds.get(layer)!\n const visitNode = (node: SequenceNode<TTarget, TEvent>, parentId: string | null): void => {\n const currentNodeId = nodeIds.get(node)!\n const childIds = childNodes(node)\n .map((child) => nodeIds.get(child)!)\n .filter(Boolean)\n const bindingIds = node.bindings\n .map((binding) => bindingStates.get(binding)?.id)\n .filter((id): id is string => !!id)\n const reachableBindingIds = node.reachableBindings\n .map((binding) => bindingStates.get(binding)?.id)\n .filter((id): id is string => !!id)\n const sequence = getNodeSequence(node)\n const presentation = getNodePresentation(node)\n const active = node.reachableBindings.some((binding) => bindingStates.get(binding)?.active === true)\n const reachable = node.reachableBindings.some((binding) => bindingStates.get(binding)?.reachable === true)\n\n for (let index = 0; index < sequence.length; index += 1) {\n const sourcePart = node.reachableBindings[0]?.sequence[index]\n if (sourcePart) {\n sequence[index] = { ...sourcePart, stroke: cloneKeyStroke(sourcePart.stroke) }\n }\n }\n\n sequenceNodes.push({\n id: currentNodeId,\n layerId: currentLayerId,\n parentId,\n childIds,\n bindingIds,\n reachableBindingIds,\n depth: node.depth,\n sequence,\n stroke: node.stroke ? cloneKeyStroke(node.stroke) : null,\n match: node.match,\n display: presentation.display,\n tokenName: presentation.tokenName,\n active,\n reachable,\n pending: pendingNodes.pending.has(currentNodeId),\n pendingPath: pendingNodes.pendingPath.has(currentNodeId),\n })\n\n for (const child of childNodes(node)) {\n visitNode(child, currentNodeId)\n }\n }\n\n visitNode(layerRoots.get(layer)!, null)\n }\n\n const layers: GraphLayer<TTarget>[] = sortedLayers.map((layer) => {\n const state = layerStates.get(layer)!\n return {\n id: state.id,\n order: layer.order,\n priority: layer.priority,\n target: includeTargets ? layer.target : undefined,\n targetMode: layer.targetMode,\n fields: layer.fields ?? {},\n attrs: layer.attrs,\n active: state.active,\n focusActive: state.focusActive,\n enabled: state.enabled,\n inactiveReasons: state.inactiveReasons,\n rootNodeId: nodeIds.get(layerRoots.get(layer)!)!,\n bindingIds: layer.bindings.map((binding) => bindingStates.get(binding)!.id),\n commandIds: layer.commands.map((command) => commandStates.get(command)!.id),\n }\n })\n\n const commands: GraphCommand<TTarget, TEvent>[] = []\n for (const state of commandStates.values()) {\n commands.push({\n id: state.id,\n layerId: state.layerState.id,\n name: state.command.command.name,\n command: state.command.command,\n fields: state.command.fields,\n attrs: state.command.attrs,\n target: includeTargets ? state.layerState.layer.target : undefined,\n active: state.active,\n reachable: state.reachable,\n enabled: state.enabled,\n inactiveReasons: state.inactiveReasons,\n })\n }\n\n const bindings: GraphBinding<TTarget, TEvent>[] = []\n for (const state of bindingStates.values()) {\n const binding = state.binding\n bindings.push({\n id: state.id,\n layerId: state.layerState.id,\n sourceLayerOrder: binding.sourceLayerOrder,\n bindingIndex: binding.bindingIndex,\n nodeId: bindingNodeIds.get(binding),\n commandIds: state.commandIds,\n sequence: cloneKeySequence(binding.sequence),\n command: binding.command,\n commandAttrs: catalog.getBindingCommandAttrs(binding, focused, activeView),\n attrs: binding.attrs,\n event: binding.event,\n preventDefault: binding.preventDefault,\n fallthrough: binding.fallthrough,\n active: state.active,\n reachable: state.reachable,\n enabled: state.enabled,\n commandResolved: state.commandResolved,\n shadowed: state.shadowed,\n inactiveReasons: state.inactiveReasons,\n })\n }\n\n const activeKeys = activation.getActiveKeysForFocused(focused, { includeBindings: true, includeMetadata: true })\n\n return {\n focused: includeTargets ? focused : undefined,\n pendingSequence: focused === currentFocused ? activation.getPendingSequence() : [],\n activeKeys,\n layers,\n commands,\n bindings,\n sequenceNodes,\n }\n}\n",
6
+ "import { KEYMAP_EXTENSION_CONTEXT, type KeymapExtensionProvider } from \"../services/extension-context.js\"\nimport { createGraphSnapshot } from \"./lib/graph-snapshot.js\"\nimport type { KeymapEvent } from \"../types.js\"\nimport type { GraphSnapshot, GraphSnapshotOptions } from \"./lib/graph-types.js\"\n\nexport type {\n GraphBinding,\n GraphCommand,\n GraphInactiveReason,\n GraphLayer,\n GraphSequenceNode,\n GraphSnapshot,\n GraphSnapshotOptions,\n} from \"./lib/graph-types.js\"\n\nexport interface KeymapGraphExtra<TTarget extends object, TEvent extends KeymapEvent> {\n getGraphSnapshot(options?: GraphSnapshotOptions<TTarget>): GraphSnapshot<TTarget, TEvent>\n}\n\nexport function getGraphSnapshot<TTarget extends object, TEvent extends KeymapEvent>(\n keymap: KeymapExtensionProvider<TTarget, TEvent>,\n options?: GraphSnapshotOptions<TTarget>,\n): GraphSnapshot<TTarget, TEvent> {\n const context = keymap[KEYMAP_EXTENSION_CONTEXT]()\n return createGraphSnapshot({\n state: context.state,\n host: context.host,\n conditions: context.conditions,\n catalog: context.catalog,\n activation: context.activation,\n snapshotOptions: options,\n })\n}\n\nexport function createGraphExtra<TTarget extends object, TEvent extends KeymapEvent>(\n keymap: KeymapExtensionProvider<TTarget, TEvent>,\n): KeymapGraphExtra<TTarget, TEvent> {\n return {\n getGraphSnapshot(options) {\n return getGraphSnapshot(keymap, options)\n },\n }\n}\n"
7
+ ],
8
+ "mappings": "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",
9
+ "debugId": "68A22ECA1358D66B64756E2164756E21",
10
+ "names": []
11
+ }
@@ -37,7 +37,7 @@ function resolveBindingItem(section, command, item, index) {
37
37
  cmd: command
38
38
  };
39
39
  }
40
- function resolveBindingValue(section, command, value) {
40
+ function resolveBindingValue(section, command, value, bindingDefaults) {
41
41
  if (value === false || value === "none") {
42
42
  return;
43
43
  }
@@ -48,15 +48,24 @@ function resolveBindingValue(section, command, value) {
48
48
  const items = value;
49
49
  const bindings = new Array(items.length);
50
50
  for (let index = 0;index < items.length; index += 1) {
51
- bindings[index] = resolveBindingItem(section, command, items[index], index);
51
+ const binding2 = resolveBindingItem(section, command, items[index], index);
52
+ bindings[index] = bindingDefaults ? withBindingDefaults(section, command, binding2, bindingDefaults) : binding2;
52
53
  }
53
54
  return bindings;
54
55
  }
55
- return [resolveBindingItem(section, command, value)];
56
+ const binding = resolveBindingItem(section, command, value);
57
+ return [bindingDefaults ? withBindingDefaults(section, command, binding, bindingDefaults) : binding];
58
+ }
59
+ function withBindingDefaults(section, command, binding, bindingDefaults) {
60
+ const defaults = bindingDefaults?.({ section, command, binding });
61
+ if (!defaults)
62
+ return binding;
63
+ return { ...defaults, ...binding };
56
64
  }
57
65
  function resolveBindingSections(config, options) {
58
66
  const sections = {};
59
67
  const lookups = new Map;
68
+ const bindingDefaults = options?.bindingDefaults;
60
69
  for (const section of options?.sections ?? []) {
61
70
  sections[section] = [];
62
71
  lookups.set(section, new Map);
@@ -75,7 +84,7 @@ function resolveBindingSections(config, options) {
75
84
  continue;
76
85
  }
77
86
  const command = rawCommand.trim();
78
- const bindings = resolveBindingValue(section, command, sectionConfig[rawCommand]);
87
+ const bindings = resolveBindingValue(section, command, sectionConfig[rawCommand], bindingDefaults);
79
88
  if (!bindings) {
80
89
  sectionLookup.delete(command);
81
90
  continue;
@@ -101,6 +110,37 @@ function resolveBindingSections(config, options) {
101
110
  sections,
102
111
  get(section, cmd) {
103
112
  return lookups.get(section)?.get(cmd.trim());
113
+ },
114
+ pick(section, commands) {
115
+ const lookup = lookups.get(section);
116
+ if (!lookup)
117
+ return [];
118
+ const result = [];
119
+ for (const command of commands) {
120
+ const bindings = lookup.get(command);
121
+ if (!bindings)
122
+ continue;
123
+ for (let index = 0;index < bindings.length; index += 1) {
124
+ result.push(bindings[index]);
125
+ }
126
+ }
127
+ return result;
128
+ },
129
+ omit(section, commands) {
130
+ const sectionBindings = sections[section];
131
+ if (!sectionBindings)
132
+ return [];
133
+ if (commands.length === 0)
134
+ return sectionBindings.slice();
135
+ const omitted = new Set(commands);
136
+ const result = [];
137
+ for (let index = 0;index < sectionBindings.length; index += 1) {
138
+ const binding = sectionBindings[index];
139
+ if (typeof binding.cmd === "string" && omitted.has(binding.cmd))
140
+ continue;
141
+ result.push(binding);
142
+ }
143
+ return result;
104
144
  }
105
145
  };
106
146
  }
@@ -154,6 +194,16 @@ function formatStroke(part, options) {
154
194
  return tokenDisplay(part.tokenName, part) ?? part.display;
155
195
  return tokenDisplay[part.tokenName] ?? part.display;
156
196
  }
197
+ if (part.patternName) {
198
+ const patternDisplay = options.patternDisplay;
199
+ if (!patternDisplay)
200
+ return part.display;
201
+ if (typeof patternDisplay === "function")
202
+ return patternDisplay(part.patternName, part) ?? part.display;
203
+ return patternDisplay[part.patternName] ?? part.display;
204
+ }
205
+ if (!options.keyNameAliases && !options.modifierAliases)
206
+ return part.display;
157
207
  const stroke = part.stroke;
158
208
  const modifierAliases = options.modifierAliases;
159
209
  let formatted = "";
@@ -224,3 +274,6 @@ export {
224
274
  formatCommandBindings,
225
275
  commandBindings
226
276
  };
277
+
278
+ //# debugId=12505B3C78ECCBFB64756E2164756E21
279
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,12 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/extras/binding-sections.ts", "../src/extras/command-bindings.ts", "../src/extras/formatting.ts"],
4
+ "sourcesContent": [
5
+ "// Opinionated config-to-keymap transformation helper. Treat this as one\n// practical shape you can copy and adjust for application-specific needs.\nimport type { Binding, KeyLike, KeymapEvent } from \"../types.js\"\n\nexport type BindingSectionItem<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> =\n | KeyLike\n | Binding<TTarget, TEvent>\n\nexport type BindingValue<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> =\n | false\n | \"none\"\n | BindingSectionItem<TTarget, TEvent>\n | readonly BindingSectionItem<TTarget, TEvent>[]\n\nexport type BindingSectionConfig<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = Readonly<\n Record<string, BindingValue<TTarget, TEvent>>\n>\n\nexport type BindingSectionsConfig<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = Readonly<\n Record<string, BindingSectionConfig<TTarget, TEvent>>\n>\n\ntype LiteralStringKeys<T> = string extends Extract<keyof T, string> ? never : Extract<keyof T, string>\n\nconst hasOwn = Object.prototype.hasOwnProperty\n\nexport interface BindingDefaultsContext<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {\n section: string\n command: string\n binding: Readonly<Binding<TTarget, TEvent>>\n}\n\nexport type BindingDefaults<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> = (\n ctx: BindingDefaultsContext<TTarget, TEvent>,\n) => Readonly<Record<string, unknown>> | void\n\nexport interface ResolvedBindingSections<\n TTarget extends object = object,\n TEvent extends KeymapEvent = KeymapEvent,\n TSection extends string = string,\n> {\n sections: Record<TSection, Binding<TTarget, TEvent>[]>\n get(section: string, cmd: string): readonly Binding<TTarget, TEvent>[] | undefined\n pick(section: string, commands: readonly string[]): Binding<TTarget, TEvent>[]\n omit(section: string, commands: readonly string[]): Binding<TTarget, TEvent>[]\n}\n\nexport interface ResolveBindingSectionsOptions<\n TSection extends string = string,\n TTarget extends object = object,\n TEvent extends KeymapEvent = KeymapEvent,\n> {\n sections?: readonly TSection[]\n bindingDefaults?: BindingDefaults<TTarget, TEvent>\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === \"object\" && !Array.isArray(value)\n}\n\nfunction isKeyLike(value: unknown): value is KeyLike {\n return typeof value === \"string\" || isObject(value)\n}\n\nfunction cloneKeyLike(key: KeyLike): KeyLike {\n if (typeof key === \"string\") {\n return key\n }\n\n return { ...key }\n}\n\nfunction invalidBindingValue(section: string, command: string, index?: number): Error {\n const location = index === undefined ? `\"${section}.${command}\"` : `\"${section}.${command}\" at index ${index}`\n return new Error(\n `Invalid binding value for ${location}: expected false, a key, a binding object, or an array of keys/binding objects`,\n )\n}\n\nfunction resolveBindingItem<TTarget extends object, TEvent extends KeymapEvent>(\n section: string,\n command: string,\n item: BindingSectionItem<TTarget, TEvent>,\n index?: number,\n): Binding<TTarget, TEvent> {\n if (!isKeyLike(item)) {\n throw invalidBindingValue(section, command, index)\n }\n\n if (typeof item === \"string\" || !(\"key\" in item)) {\n return {\n key: cloneKeyLike(item),\n cmd: command,\n }\n }\n\n const key = item.key\n if (!isKeyLike(key)) {\n throw invalidBindingValue(section, command, index)\n }\n\n return {\n ...item,\n key: cloneKeyLike(key),\n cmd: command,\n }\n}\n\nfunction resolveBindingValue<TTarget extends object, TEvent extends KeymapEvent>(\n section: string,\n command: string,\n value: BindingValue<TTarget, TEvent>,\n bindingDefaults: BindingDefaults<TTarget, TEvent> | undefined,\n): Binding<TTarget, TEvent>[] | undefined {\n if (value === false || value === \"none\") {\n return undefined\n }\n\n if (Array.isArray(value)) {\n if (value.length === 0) {\n return undefined\n }\n\n const items = value as readonly BindingSectionItem<TTarget, TEvent>[]\n const bindings = new Array<Binding<TTarget, TEvent>>(items.length)\n for (let index = 0; index < items.length; index += 1) {\n const binding = resolveBindingItem(section, command, items[index]!, index)\n bindings[index] = bindingDefaults ? withBindingDefaults(section, command, binding, bindingDefaults) : binding\n }\n\n return bindings\n }\n\n const binding = resolveBindingItem(section, command, value as BindingSectionItem<TTarget, TEvent>)\n return [bindingDefaults ? withBindingDefaults(section, command, binding, bindingDefaults) : binding]\n}\n\nfunction withBindingDefaults<TTarget extends object, TEvent extends KeymapEvent>(\n section: string,\n command: string,\n binding: Binding<TTarget, TEvent>,\n bindingDefaults: BindingDefaults<TTarget, TEvent> | undefined,\n): Binding<TTarget, TEvent> {\n const defaults = bindingDefaults?.({ section, command, binding })\n if (!defaults) return binding\n return { ...defaults, ...binding }\n}\n\nexport function resolveBindingSections<\n TTarget extends object = object,\n TEvent extends KeymapEvent = KeymapEvent,\n const TConfig extends BindingSectionsConfig<TTarget, TEvent> = BindingSectionsConfig<TTarget, TEvent>,\n const TSection extends string = string,\n>(\n config: TConfig,\n options: ResolveBindingSectionsOptions<TSection, TTarget, TEvent> & { sections: readonly TSection[] },\n): ResolvedBindingSections<TTarget, TEvent, TSection | LiteralStringKeys<TConfig>>\nexport function resolveBindingSections<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent>(\n config: BindingSectionsConfig<TTarget, TEvent>,\n options?: ResolveBindingSectionsOptions<string, TTarget, TEvent>,\n): ResolvedBindingSections<TTarget, TEvent>\nexport function resolveBindingSections<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent>(\n config: BindingSectionsConfig<TTarget, TEvent>,\n options?: ResolveBindingSectionsOptions<string, TTarget, TEvent>,\n): ResolvedBindingSections<TTarget, TEvent> {\n const sections: Record<string, Binding<TTarget, TEvent>[]> = {}\n const lookups = new Map<string, Map<string, Binding<TTarget, TEvent>[]>>()\n const bindingDefaults = options?.bindingDefaults\n\n for (const section of options?.sections ?? []) {\n sections[section] = []\n lookups.set(section, new Map())\n }\n\n // Own-property loops avoid Object.entries allocations while still ignoring inherited config.\n for (const section in config) {\n if (!hasOwn.call(config, section)) {\n continue\n }\n\n const sectionConfig = config[section]\n if (!isObject(sectionConfig)) {\n throw new Error(`Invalid binding section \"${section}\": expected an object`)\n }\n\n const sectionLookup = new Map<string, Binding<TTarget, TEvent>[]>()\n\n for (const rawCommand in sectionConfig) {\n if (!hasOwn.call(sectionConfig, rawCommand)) {\n continue\n }\n\n const command = rawCommand.trim()\n const bindings = resolveBindingValue(section, command, sectionConfig[rawCommand]!, bindingDefaults)\n\n if (!bindings) {\n sectionLookup.delete(command)\n continue\n }\n\n sectionLookup.set(command, bindings)\n }\n\n // Manual flattening avoids Array.flat allocations on large generated configs.\n let sectionBindingCount = 0\n for (const bindings of sectionLookup.values()) {\n sectionBindingCount += bindings.length\n }\n\n const sectionBindings = new Array<Binding<TTarget, TEvent>>(sectionBindingCount)\n let bindingIndex = 0\n for (const bindings of sectionLookup.values()) {\n for (let index = 0; index < bindings.length; index += 1) {\n sectionBindings[bindingIndex] = bindings[index]!\n bindingIndex += 1\n }\n }\n\n sections[section] = sectionBindings\n lookups.set(section, sectionLookup)\n }\n\n return {\n sections,\n get(section, cmd) {\n return lookups.get(section)?.get(cmd.trim())\n },\n pick(section, commands) {\n const lookup = lookups.get(section)\n if (!lookup) return []\n\n const result: Binding<TTarget, TEvent>[] = []\n for (const command of commands) {\n const bindings = lookup.get(command)\n if (!bindings) continue\n for (let index = 0; index < bindings.length; index += 1) {\n result.push(bindings[index]!)\n }\n }\n\n return result\n },\n omit(section, commands) {\n const sectionBindings = sections[section]\n if (!sectionBindings) return []\n if (commands.length === 0) return sectionBindings.slice()\n\n const omitted = new Set(commands)\n const result: Binding<TTarget, TEvent>[] = []\n for (let index = 0; index < sectionBindings.length; index += 1) {\n const binding = sectionBindings[index]!\n if (typeof binding.cmd === \"string\" && omitted.has(binding.cmd)) continue\n result.push(binding)\n }\n\n return result\n },\n }\n}\n",
6
+ "import type { Binding, KeyLike, KeymapEvent } from \"../types.js\"\n\nexport type CommandBindingMap = Record<string, KeyLike>\n\nexport interface CommandBindingsOverrideWarning {\n code: \"command-binding-override\"\n command: string\n previousKey: KeyLike\n nextKey: KeyLike\n}\n\nexport interface CommandBindingsError {\n code: \"invalid-command-binding\"\n command: string\n value: unknown\n reason: Error\n}\n\nexport interface CommandBindingsOptions {\n onWarning?: (warning: CommandBindingsOverrideWarning) => void\n onError?: (error: CommandBindingsError) => void\n}\n\nfunction isCommandBindingKey(value: unknown): value is KeyLike {\n return typeof value === \"string\" || (!!value && typeof value === \"object\" && !Array.isArray(value))\n}\n\nexport function commandBindings<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent>(\n bindings: Readonly<CommandBindingMap>,\n options?: CommandBindingsOptions,\n): Binding<TTarget, TEvent>[] {\n const normalized: Binding<TTarget, TEvent>[] = []\n const indexesByCommand = new Map<string, number>()\n\n for (const [command, key] of Object.entries(bindings)) {\n if (!isCommandBindingKey(key)) {\n const error = new Error(\n `Invalid command binding for \"${command}\": command bindings must map command strings to key strings or keystroke objects`,\n )\n\n options?.onError?.({\n code: \"invalid-command-binding\",\n command,\n value: key,\n reason: error,\n })\n continue\n }\n\n const normalizedCommand = command.trim()\n\n const nextBinding = {\n key: typeof key === \"string\" ? key : { ...key },\n cmd: normalizedCommand,\n } satisfies Binding<TTarget, TEvent>\n\n const existingIndex = indexesByCommand.get(normalizedCommand)\n if (existingIndex !== undefined) {\n const previousBinding = normalized[existingIndex]!\n options?.onWarning?.({\n code: \"command-binding-override\",\n command: normalizedCommand,\n previousKey: previousBinding.key,\n nextKey: nextBinding.key,\n })\n normalized[existingIndex] = nextBinding\n continue\n }\n\n indexesByCommand.set(normalizedCommand, normalized.length)\n normalized.push(nextBinding)\n }\n\n return normalized\n}\n",
7
+ "import type { KeySequencePart } from \"../types.js\"\n\nexport type KeyModifierName = \"ctrl\" | \"shift\" | \"meta\" | \"super\" | \"hyper\"\n\nexport interface KeySequenceFormatPart {\n stroke: KeySequencePart[\"stroke\"]\n display: string\n match?: KeySequencePart[\"match\"]\n tokenName?: string\n patternName?: string\n}\n\nexport type TokenDisplayResolver =\n | Readonly<Record<string, string>>\n | ((tokenName: string, part: KeySequenceFormatPart) => string | undefined)\n\nexport type PatternDisplayResolver =\n | Readonly<Record<string, string>>\n | ((patternName: string, part: KeySequenceFormatPart) => string | undefined)\n\nexport interface FormatKeySequenceOptions {\n tokenDisplay?: TokenDisplayResolver\n patternDisplay?: PatternDisplayResolver\n keyNameAliases?: Readonly<Record<string, string>>\n modifierAliases?: Partial<Record<KeyModifierName, string>>\n separator?: string\n}\n\nexport interface FormatCommandBindingsOptions extends FormatKeySequenceOptions {\n bindingSeparator?: string\n dedupe?: boolean\n}\n\nexport interface SequenceBindingLike {\n sequence: readonly KeySequenceFormatPart[]\n}\n\nfunction formatStroke(part: KeySequenceFormatPart, options: FormatKeySequenceOptions): string {\n if (part.tokenName) {\n const tokenDisplay = options.tokenDisplay\n if (!tokenDisplay) return part.display\n if (typeof tokenDisplay === \"function\") return tokenDisplay(part.tokenName, part) ?? part.display\n return tokenDisplay[part.tokenName] ?? part.display\n }\n\n if (part.patternName) {\n const patternDisplay = options.patternDisplay\n if (!patternDisplay) return part.display\n if (typeof patternDisplay === \"function\") return patternDisplay(part.patternName, part) ?? part.display\n return patternDisplay[part.patternName] ?? part.display\n }\n\n if (!options.keyNameAliases && !options.modifierAliases) return part.display\n\n // This is on the command-palette hot path; build directly to avoid per-stroke arrays.\n const stroke = part.stroke\n const modifierAliases = options.modifierAliases\n let formatted = \"\"\n let pieceCount = 0\n\n if (stroke.ctrl) {\n formatted = modifierAliases?.ctrl ?? \"ctrl\"\n pieceCount = 1\n }\n\n if (stroke.shift) {\n const alias = modifierAliases?.shift ?? \"shift\"\n formatted = pieceCount === 0 ? alias : `${formatted}+${alias}`\n pieceCount += 1\n }\n\n if (stroke.meta) {\n const alias = modifierAliases?.meta ?? \"meta\"\n formatted = pieceCount === 0 ? alias : `${formatted}+${alias}`\n pieceCount += 1\n }\n\n if (stroke.super) {\n const alias = modifierAliases?.super ?? \"super\"\n formatted = pieceCount === 0 ? alias : `${formatted}+${alias}`\n pieceCount += 1\n }\n\n if (stroke.hyper) {\n const alias = modifierAliases?.hyper ?? \"hyper\"\n formatted = pieceCount === 0 ? alias : `${formatted}+${alias}`\n pieceCount += 1\n }\n\n const name = stroke.name === \"return\" ? \"enter\" : stroke.name\n const keyName = options.keyNameAliases?.[name] ?? name\n return pieceCount === 0 ? keyName : `${formatted}+${keyName}`\n}\n\nexport function formatKeySequence(\n parts: readonly KeySequenceFormatPart[] | undefined,\n options: FormatKeySequenceOptions = {},\n): string {\n if (!parts || parts.length === 0) return \"\"\n\n // Avoid map/join allocation here; binding-list formatting calls this repeatedly.\n const separator = options.separator ?? \" \"\n let formatted = formatStroke(parts[0]!, options)\n for (let index = 1; index < parts.length; index += 1) {\n formatted += separator + formatStroke(parts[index]!, options)\n }\n\n return formatted\n}\n\nexport function formatCommandBindings(\n bindings: readonly SequenceBindingLike[] | undefined,\n options: FormatCommandBindingsOptions = {},\n): string | undefined {\n if (!bindings?.length) return\n\n const bindingSeparator = options.bindingSeparator ?? \", \"\n const dedupe = options.dedupe !== false\n const seen = dedupe ? new Set<string>() : undefined\n let formatted = \"\"\n let itemCount = 0\n\n // One pass keeps dedupe, filtering, and joining allocation-light for large binding lists.\n for (const binding of bindings) {\n const item = formatKeySequence(binding.sequence, options)\n if (!item) continue\n\n if (seen) {\n if (seen.has(item)) continue\n seen.add(item)\n }\n\n formatted = itemCount === 0 ? item : `${formatted}${bindingSeparator}${item}`\n itemCount += 1\n }\n\n return formatted\n}\n"
8
+ ],
9
+ "mappings": "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",
10
+ "debugId": "12505B3C78ECCBFB64756E2164756E21",
11
+ "names": []
12
+ }
@@ -0,0 +1,14 @@
1
+ import type { ActivationService } from "../../services/activation.js";
2
+ import type { CommandCatalogService } from "../../services/command-catalog.js";
3
+ import type { ConditionService } from "../../services/conditions.js";
4
+ import type { State } from "../../services/state.js";
5
+ import type { KeymapEvent, KeymapHost } from "../../types.js";
6
+ import type { GraphSnapshot, GraphSnapshotOptions } from "./graph-types.js";
7
+ export declare function createGraphSnapshot<TTarget extends object, TEvent extends KeymapEvent>(options: {
8
+ state: State<TTarget, TEvent>;
9
+ host: KeymapHost<TTarget, TEvent>;
10
+ conditions: ConditionService<TTarget, TEvent>;
11
+ catalog: CommandCatalogService<TTarget, TEvent>;
12
+ activation: ActivationService<TTarget, TEvent>;
13
+ snapshotOptions?: GraphSnapshotOptions<TTarget>;
14
+ }): GraphSnapshot<TTarget, TEvent>;
@@ -0,0 +1,83 @@
1
+ import type { ActiveKey, Attributes, BindingCommand, BindingEvent, Command, KeymapEvent, KeyMatch, KeySequencePart, NormalizedKeyStroke, TargetMode } from "../../types.js";
2
+ export interface GraphSnapshotOptions<TTarget extends object = object> {
3
+ focused?: TTarget | null;
4
+ includeTargets?: boolean;
5
+ }
6
+ export type GraphInactiveReason = "focus" | "target-destroyed" | "layer-disabled" | "binding-disabled" | "command-disabled" | "command-inactive" | "command-unresolved" | "shadowed";
7
+ export interface GraphLayer<TTarget extends object = object> {
8
+ id: string;
9
+ order: number;
10
+ priority: number;
11
+ target?: TTarget;
12
+ targetMode?: TargetMode;
13
+ fields: Readonly<Record<string, unknown>>;
14
+ attrs?: Readonly<Attributes>;
15
+ active: boolean;
16
+ focusActive: boolean;
17
+ enabled: boolean;
18
+ inactiveReasons: readonly GraphInactiveReason[];
19
+ rootNodeId: string;
20
+ bindingIds: readonly string[];
21
+ commandIds: readonly string[];
22
+ }
23
+ export interface GraphCommand<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
24
+ id: string;
25
+ layerId: string;
26
+ name: string;
27
+ command: Command<TTarget, TEvent>;
28
+ fields: Readonly<Record<string, unknown>>;
29
+ attrs?: Readonly<Attributes>;
30
+ target?: TTarget;
31
+ active: boolean;
32
+ reachable: boolean;
33
+ enabled: boolean;
34
+ inactiveReasons: readonly GraphInactiveReason[];
35
+ }
36
+ export interface GraphBinding<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
37
+ id: string;
38
+ layerId: string;
39
+ sourceLayerOrder: number;
40
+ bindingIndex: number;
41
+ nodeId?: string;
42
+ commandIds: readonly string[];
43
+ sequence: readonly KeySequencePart[];
44
+ command?: BindingCommand<TTarget, TEvent>;
45
+ commandAttrs?: Readonly<Attributes>;
46
+ attrs?: Readonly<Attributes>;
47
+ event: BindingEvent;
48
+ preventDefault: boolean;
49
+ fallthrough: boolean;
50
+ active: boolean;
51
+ reachable: boolean;
52
+ enabled: boolean;
53
+ commandResolved: boolean;
54
+ shadowed: boolean;
55
+ inactiveReasons: readonly GraphInactiveReason[];
56
+ }
57
+ export interface GraphSequenceNode {
58
+ id: string;
59
+ layerId: string;
60
+ parentId: string | null;
61
+ childIds: readonly string[];
62
+ bindingIds: readonly string[];
63
+ reachableBindingIds: readonly string[];
64
+ depth: number;
65
+ sequence: readonly KeySequencePart[];
66
+ stroke: NormalizedKeyStroke | null;
67
+ match: KeyMatch | null;
68
+ display: string;
69
+ tokenName?: string;
70
+ active: boolean;
71
+ reachable: boolean;
72
+ pending: boolean;
73
+ pendingPath: boolean;
74
+ }
75
+ export interface GraphSnapshot<TTarget extends object = object, TEvent extends KeymapEvent = KeymapEvent> {
76
+ focused?: TTarget | null;
77
+ pendingSequence: readonly KeySequencePart[];
78
+ activeKeys: readonly ActiveKey<TTarget, TEvent>[];
79
+ layers: readonly GraphLayer<TTarget>[];
80
+ commands: readonly GraphCommand<TTarget, TEvent>[];
81
+ bindings: readonly GraphBinding<TTarget, TEvent>[];
82
+ sequenceNodes: readonly GraphSequenceNode[];
83
+ }
package/src/html.d.ts CHANGED
@@ -1,6 +1,5 @@
1
- import { Keymap } from "./keymap.js";
2
- import type { EventMatchResolver, KeymapEvent, KeymapHost } from "./types.js";
3
- export * from "./index.js";
1
+ import { Keymap } from "@opentui/keymap";
2
+ import type { EventMatchResolver, KeymapEvent, KeymapHost } from "@opentui/keymap";
4
3
  export interface HtmlKeymapEvent extends KeymapEvent {
5
4
  readonly originalEvent?: KeyboardEvent;
6
5
  }
@@ -19,3 +18,4 @@ export declare function createHtmlKeymapHost(root: HTMLElement): KeymapHost<HTML
19
18
  export declare const htmlEventMatchResolver: EventMatchResolver<HtmlKeymapEvent>;
20
19
  export declare function createHtmlKeymap(root: HTMLElement): Keymap<HTMLElement, HtmlKeymapEvent>;
21
20
  export declare function createDefaultHtmlKeymap(root: HTMLElement): Keymap<HTMLElement, HtmlKeymapEvent>;
21
+ export {};