rx-hotkeys 1.0.0 → 2.0.0

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 CHANGED
@@ -26,18 +26,18 @@ npm install rxjs rx-hotkeys
26
26
  First, ensure you have the `rx-hotkeys` library and its helper Keys imported:
27
27
 
28
28
  ```typescript
29
- import { HotKeys, Keys, KeyCombinationConfig, KeySequenceConfig } from 'rx-hotkeys';
29
+ import { Hotkeys, Keys, KeyCombinationConfig, KeySequenceConfig } from 'rx-hotkeys';
30
30
  ```
31
31
 
32
- 1. Initialize HotKeys
32
+ 1. Initialize Hotkeys
33
33
 
34
34
  Create an instance of the `Hotkeys` class. You can optionally provide an initial context and enable debug mode.
35
35
 
36
36
  ```typescript
37
- const keyManager = new HotKeys(); // No initial context, debug mode off
37
+ const keyManager = new Hotkeys(); // No initial context, debug mode off
38
38
 
39
39
  // With an initial context and debug mode enabled:
40
- // const keyManager = new HotKeys('editor', true);
40
+ // const keyManager = new Hotkeys('editor', true);
41
41
  ```
42
42
 
43
43
  2. Add a Key Combination
@@ -93,7 +93,7 @@ keyManager.setContext(null);
93
93
 
94
94
  5. Clean Up
95
95
 
96
- When the HotKeys instance is no longer needed (e.g., component unmount), call `destroy()` to clean up subscriptions and prevent memory leaks.
96
+ When the Hotkeys instance is no longer needed (e.g., component unmount), call `destroy()` to clean up subscriptions and prevent memory leaks.
97
97
 
98
98
  ```typescript
99
99
  // In a component lifecycle cleanup method or similar:
@@ -108,11 +108,11 @@ keyManager.destroy();
108
108
  * `Keys`: An exported constant object containing standard KeyboardEvent.key string values (e.g., Keys.Enter, Keys.ArrowUp, Keys.A). It's highly recommended to use these when defining key in `KeyCombinationConfig` or keys in the sequence array of `KeySequenceConfig`.
109
109
  * `StandardKey`: A TypeScript type representing any valid key string from the Keys object.
110
110
 
111
- ### `HotKeys` Class
111
+ ### `Hotkeys` Class
112
112
 
113
113
  `constructor(initialContext?: string | null, debugMode?: boolean)`
114
114
 
115
- Creates a new HotKeys instance.
115
+ Creates a new Hotkeys instance.
116
116
 
117
117
  `addCombination(config: KeyCombinationConfig): string | undefined`
118
118
 
package/dist/hotkeys.d.ts CHANGED
@@ -48,7 +48,7 @@ export interface KeySequenceConfig extends ShortcutConfigBase {
48
48
  * Allows registration of single key combinations (e.g., Ctrl+S) and key sequences (e.g., g -> i).
49
49
  * Supports contexts to enable/disable shortcuts based on application state.
50
50
  */
51
- export declare class HotKeys {
51
+ export declare class Hotkeys {
52
52
  private static readonly KEYDOWN_EVENT;
53
53
  private static readonly LOG_PREFIX;
54
54
  private keydown$;
package/dist/hotkeys.js CHANGED
@@ -20,7 +20,7 @@ function compareKey(eventKey, configuredKey) {
20
20
  * Allows registration of single key combinations (e.g., Ctrl+S) and key sequences (e.g., g -> i).
21
21
  * Supports contexts to enable/disable shortcuts based on application state.
22
22
  */
23
- export class HotKeys {
23
+ export class Hotkeys {
24
24
  static KEYDOWN_EVENT = "keydown";
25
25
  static LOG_PREFIX = "Hotkeys:";
26
26
  keydown$;
@@ -36,13 +36,13 @@ export class HotKeys {
36
36
  constructor(initialContext = null, debugMode = false) {
37
37
  this.debugMode = debugMode;
38
38
  if (typeof document === "undefined" || typeof performance === "undefined") {
39
- throw new Error(`${HotKeys.LOG_PREFIX} Hotkeys can only be used in a browser environment with global 'document' and 'performance' objects.`);
39
+ throw new Error(`${Hotkeys.LOG_PREFIX} Hotkeys can only be used in a browser environment with global 'document' and 'performance' objects.`);
40
40
  }
41
- this.keydown$ = fromEvent(document, HotKeys.KEYDOWN_EVENT);
41
+ this.keydown$ = fromEvent(document, Hotkeys.KEYDOWN_EVENT);
42
42
  this.activeContext$ = new BehaviorSubject(initialContext);
43
43
  this.activeShortcuts = new Map();
44
44
  if (this.debugMode) {
45
- console.log(`${HotKeys.LOG_PREFIX} Library initialized. Initial context: "${initialContext}". Debug mode: ${debugMode}.`);
45
+ console.log(`${Hotkeys.LOG_PREFIX} Library initialized. Initial context: "${initialContext}". Debug mode: ${debugMode}.`);
46
46
  }
47
47
  }
48
48
  /**
@@ -54,7 +54,7 @@ export class HotKeys {
54
54
  */
55
55
  setContext(contextName) {
56
56
  if (this.debugMode) {
57
- console.log(`${HotKeys.LOG_PREFIX} Context changed to "${contextName}"`);
57
+ console.log(`${Hotkeys.LOG_PREFIX} Context changed to "${contextName}"`);
58
58
  }
59
59
  this.activeContext$.next(contextName);
60
60
  }
@@ -73,7 +73,7 @@ export class HotKeys {
73
73
  setDebugMode(enable) {
74
74
  this.debugMode = enable;
75
75
  if (this.debugMode) {
76
- console.log(`${HotKeys.LOG_PREFIX} Debug mode ${enable ? 'enabled' : 'disabled'}.`);
76
+ console.log(`${Hotkeys.LOG_PREFIX} Debug mode ${enable ? 'enabled' : 'disabled'}.`);
77
77
  }
78
78
  }
79
79
  /**
@@ -90,12 +90,12 @@ export class HotKeys {
90
90
  _registerShortcut(config, subscription, type, detailsForLog) {
91
91
  const existingShortcut = this.activeShortcuts.get(config.id);
92
92
  if (existingShortcut) {
93
- console.warn(`${HotKeys.LOG_PREFIX} Shortcut with ID "${config.id}" already exists. It will be overwritten.`);
93
+ console.warn(`${Hotkeys.LOG_PREFIX} Shortcut with ID "${config.id}" already exists. It will be overwritten.`);
94
94
  existingShortcut.subscription.unsubscribe();
95
95
  }
96
96
  this.activeShortcuts.set(config.id, { id: config.id, config, subscription });
97
97
  if (this.debugMode) {
98
- console.log(`${HotKeys.LOG_PREFIX} ${type} shortcut "${config.id}" added. ${detailsForLog}, Context: ${config.context ?? "any"}`);
98
+ console.log(`${Hotkeys.LOG_PREFIX} ${type} shortcut "${config.id}" added. ${detailsForLog}, Context: ${config.context ?? "any"}`);
99
99
  }
100
100
  return config.id;
101
101
  }
@@ -121,7 +121,7 @@ export class HotKeys {
121
121
  addCombination(config) {
122
122
  const { keys, callback, context, preventDefault = false, id } = config;
123
123
  if (!keys || !keys.key || typeof keys.key !== 'string' || keys.key.trim() === '') {
124
- console.warn(`${HotKeys.LOG_PREFIX} Invalid 'keys.key' for combination shortcut "${id}". Key must be a non-empty value from Keys. Shortcut not added.`);
124
+ console.warn(`${Hotkeys.LOG_PREFIX} Invalid 'keys.key' for combination shortcut "${id}". Key must be a non-empty value from Keys. Shortcut not added.`);
125
125
  return undefined;
126
126
  }
127
127
  const configuredMainKey = keys.key;
@@ -131,12 +131,12 @@ export class HotKeys {
131
131
  (keys.metaKey === undefined || event.metaKey === keys.metaKey)), filter(event => compareKey(event.key, configuredMainKey)), tap(event => {
132
132
  if (this.debugMode) {
133
133
  const preventAction = preventDefault ? ", preventing default" : "";
134
- console.log(`${HotKeys.LOG_PREFIX} Combination "${id}" triggered${preventAction}.`);
134
+ console.log(`${Hotkeys.LOG_PREFIX} Combination "${id}" triggered${preventAction}.`);
135
135
  }
136
136
  if (preventDefault)
137
137
  event.preventDefault();
138
138
  }), catchError(err => {
139
- console.error(`${HotKeys.LOG_PREFIX} Error in combination stream for shortcut "${id}":`, err);
139
+ console.error(`${Hotkeys.LOG_PREFIX} Error in combination stream for shortcut "${id}":`, err);
140
140
  return EMPTY;
141
141
  }));
142
142
  const subscription = shortcut$.subscribe(event => {
@@ -144,7 +144,7 @@ export class HotKeys {
144
144
  callback(event);
145
145
  }
146
146
  catch (e) {
147
- console.error(`${HotKeys.LOG_PREFIX} Error in user callback for combination shortcut "${id}":`, e);
147
+ console.error(`${Hotkeys.LOG_PREFIX} Error in user callback for combination shortcut "${id}":`, e);
148
148
  }
149
149
  });
150
150
  const keyDetails = `key: "${keys.key}"` +
@@ -177,11 +177,11 @@ export class HotKeys {
177
177
  addSequence(config) {
178
178
  const { sequence, callback, context, preventDefault = false, id, sequenceTimeoutMs } = config;
179
179
  if (!Array.isArray(sequence) || sequence.length === 0) {
180
- console.warn(`${HotKeys.LOG_PREFIX} Sequence for shortcut "${id}" is empty or invalid. Shortcut not added.`);
180
+ console.warn(`${Hotkeys.LOG_PREFIX} Sequence for shortcut "${id}" is empty or invalid. Shortcut not added.`);
181
181
  return undefined;
182
182
  }
183
183
  if (sequence.some(key => typeof key !== 'string' || key.trim() === '')) {
184
- console.warn(`${HotKeys.LOG_PREFIX} Invalid key in sequence for shortcut "${id}". All keys must be non-empty strings from Keys. Shortcut not added.`);
184
+ console.warn(`${Hotkeys.LOG_PREFIX} Invalid key in sequence for shortcut "${id}". All keys must be non-empty strings from Keys. Shortcut not added.`);
185
185
  return undefined;
186
186
  }
187
187
  const configuredSequence = sequence;
@@ -198,7 +198,7 @@ export class HotKeys {
198
198
  }
199
199
  if (matchedEvents.length > 0 && (currentTime - lastEventTime > sequenceTimeoutMs)) {
200
200
  if (this.debugMode) {
201
- console.log(`${HotKeys.LOG_PREFIX} Sequence "${id}" (timeout: ${sequenceTimeoutMs}ms) attempt timed out. Matched: ${matchedEvents.map(e => e.key).join(',')}. Resetting.`);
201
+ console.log(`${Hotkeys.LOG_PREFIX} Sequence "${id}" (timeout: ${sequenceTimeoutMs}ms) attempt timed out. Matched: ${matchedEvents.map(e => e.key).join(',')}. Resetting.`);
202
202
  }
203
203
  matchedEvents = [];
204
204
  }
@@ -213,7 +213,7 @@ export class HotKeys {
213
213
  const newMatchedEvents = [...matchedEvents, event];
214
214
  if (newMatchedEvents.length === sequenceLength) {
215
215
  if (this.debugMode)
216
- console.log(`${HotKeys.LOG_PREFIX} Sequence "${id}" (timeout: ${sequenceTimeoutMs}ms) matched.`);
216
+ console.log(`${Hotkeys.LOG_PREFIX} Sequence "${id}" (timeout: ${sequenceTimeoutMs}ms) matched.`);
217
217
  return { matchedEvents: newMatchedEvents, lastEventTime: currentTime, emitState: 'emit' };
218
218
  }
219
219
  else {
@@ -222,7 +222,7 @@ export class HotKeys {
222
222
  }
223
223
  else {
224
224
  if (matchedEvents.length > 0 && this.debugMode) {
225
- console.log(`${HotKeys.LOG_PREFIX} Sequence "${id}" (timeout: ${sequenceTimeoutMs}ms) broken by key "${event.key}". Matched: ${matchedEvents.map(e => e.key).join(',')}. Resetting.`);
225
+ console.log(`${Hotkeys.LOG_PREFIX} Sequence "${id}" (timeout: ${sequenceTimeoutMs}ms) broken by key "${event.key}". Matched: ${matchedEvents.map(e => e.key).join(',')}. Resetting.`);
226
226
  }
227
227
  if (sequenceLength > 0 && compareKey(event.key, configuredSequence[0])) {
228
228
  return { matchedEvents: [event], lastEventTime: currentTime, emitState: 'in-progress' };
@@ -244,13 +244,13 @@ export class HotKeys {
244
244
  if (this.debugMode) {
245
245
  const timeoutInfo = (sequenceTimeoutMs && sequenceTimeoutMs > 0) ? ` (with timeout logic)` : ` (no timeout logic)`;
246
246
  const preventAction = preventDefault ? ", preventing default for last event" : "";
247
- console.log(`${HotKeys.LOG_PREFIX} Sequence "${id}" triggered${timeoutInfo}${preventAction}.`);
247
+ console.log(`${Hotkeys.LOG_PREFIX} Sequence "${id}" triggered${timeoutInfo}${preventAction}.`);
248
248
  }
249
249
  if (preventDefault && events.length > 0) {
250
250
  events[events.length - 1].preventDefault();
251
251
  }
252
252
  }), catchError(err => {
253
- console.error(`${HotKeys.LOG_PREFIX} Error in sequence stream for shortcut "${id}":`, err);
253
+ console.error(`${Hotkeys.LOG_PREFIX} Error in sequence stream for shortcut "${id}":`, err);
254
254
  return EMPTY;
255
255
  }));
256
256
  const subscription = finalShortcut$.subscribe((events) => {
@@ -259,7 +259,7 @@ export class HotKeys {
259
259
  callback(events[events.length - 1]);
260
260
  }
261
261
  catch (e) {
262
- console.error(`${HotKeys.LOG_PREFIX} Error in user callback for sequence shortcut "${id}":`, e);
262
+ console.error(`${Hotkeys.LOG_PREFIX} Error in user callback for sequence shortcut "${id}":`, e);
263
263
  }
264
264
  });
265
265
  const logDetails = `Sequence: ${sequence.join(" -> ")}${sequenceTimeoutMs && sequenceTimeoutMs > 0 ? ` (timeout: ${sequenceTimeoutMs}ms)` : ''}`;
@@ -278,10 +278,10 @@ export class HotKeys {
278
278
  shortcut.subscription.unsubscribe();
279
279
  this.activeShortcuts.delete(id);
280
280
  if (this.debugMode)
281
- console.log(`${HotKeys.LOG_PREFIX} Shortcut "${id}" removed.`);
281
+ console.log(`${Hotkeys.LOG_PREFIX} Shortcut "${id}" removed.`);
282
282
  return true;
283
283
  }
284
- console.warn(`${HotKeys.LOG_PREFIX} Shortcut with ID "${id}" not found for removal.`);
284
+ console.warn(`${Hotkeys.LOG_PREFIX} Shortcut with ID "${id}" not found for removal.`);
285
285
  return false;
286
286
  }
287
287
  /**
@@ -311,11 +311,11 @@ export class HotKeys {
311
311
  */
312
312
  destroy() {
313
313
  if (this.debugMode)
314
- console.log(`${HotKeys.LOG_PREFIX} Destroying library instance and unsubscribing all shortcuts.`);
314
+ console.log(`${Hotkeys.LOG_PREFIX} Destroying library instance and unsubscribing all shortcuts.`);
315
315
  this.activeShortcuts.forEach(shortcut => shortcut.subscription.unsubscribe());
316
316
  this.activeShortcuts.clear();
317
317
  this.activeContext$.complete(); // Complete the BehaviorSubject to release its resources
318
318
  if (this.debugMode)
319
- console.log(`${HotKeys.LOG_PREFIX} Library destroyed.`);
319
+ console.log(`${Hotkeys.LOG_PREFIX} Library destroyed.`);
320
320
  }
321
321
  }
@@ -1,7 +1,7 @@
1
1
  import { describe, it, before, beforeEach, afterEach, mock } from "node:test";
2
2
  import assert from "node:assert";
3
3
  // Importing main library components
4
- import { HotKeys } from "./hotkeys.js";
4
+ import { Hotkeys } from "./hotkeys.js";
5
5
  // Importing Keys and StandardKey from the separate keys.js file
6
6
  import { Keys } from "./keys.js";
7
7
  import { fromEvent, BehaviorSubject } from "rxjs";
@@ -49,7 +49,7 @@ describe("Hotkeys Library (Node.js Test Runner)", () => {
49
49
  let consoleErrorMock;
50
50
  let performanceNowMock; // To mock global.performance.now specifically for sequence tests
51
51
  beforeEach(() => {
52
- keyManager = new HotKeys(null, false);
52
+ keyManager = new Hotkeys(null, false);
53
53
  mockCallback = createMockFn();
54
54
  consoleWarnMock = mock.method(console, "warn");
55
55
  consoleErrorMock = mock.method(console, "error");
@@ -72,13 +72,13 @@ describe("Hotkeys Library (Node.js Test Runner)", () => {
72
72
  });
73
73
  describe("Initialization and Basic Context", () => {
74
74
  it("should initialize without errors", () => {
75
- assert(keyManager instanceof HotKeys);
75
+ assert(keyManager instanceof Hotkeys);
76
76
  });
77
77
  it("should initialize with a null context by default", () => {
78
78
  assert.strictEqual(keyManager.getContext(), null);
79
79
  });
80
80
  it("should initialize with a given initial context", () => {
81
- const manager = new HotKeys("editor");
81
+ const manager = new Hotkeys("editor");
82
82
  assert.strictEqual(manager.getContext(), "editor");
83
83
  manager.destroy();
84
84
  });
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { type StandardKey, Keys, } from "./keys.js";
2
- export { type KeyCombinationConfig, type KeySequenceConfig, HotKeys, } from "./hotkeys.js";
2
+ export { type KeyCombinationConfig, type KeySequenceConfig, Hotkeys, } from "./hotkeys.js";
3
3
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  export { Keys, } from "./keys.js";
2
- export { HotKeys, } from "./hotkeys.js";
2
+ export { Hotkeys, } from "./hotkeys.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rx-hotkeys",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": "tsc",
@@ -14,7 +14,12 @@
14
14
  "types": "./dist/index.d.ts"
15
15
  }
16
16
  },
17
- "keywords": ["rxjs", "hotkeys", "hotkey", "key"],
17
+ "keywords": [
18
+ "rxjs",
19
+ "hotkeys",
20
+ "hotkey",
21
+ "key"
22
+ ],
18
23
  "author": "Colin Cheng <zbinlin@outlook.com>",
19
24
  "repository": {
20
25
  "type": "git",