simen-keyboard-listener 1.0.0 → 1.0.1

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.
@@ -0,0 +1,27 @@
1
+ type IGlobalKeyState = 'DOWN' | 'UP';
2
+ interface IGlobalKeyEvent {
3
+ readonly name: string;
4
+ readonly state: IGlobalKeyState;
5
+ }
6
+ type IGlobalKeyDownMap = Record<string, boolean>;
7
+ type IGlobalKeyListener = (event: IGlobalKeyEvent, isDown: IGlobalKeyDownMap) => void;
8
+ interface IGlobalKeyboardListener {
9
+ addListener(listener: IGlobalKeyListener): void;
10
+ removeListener(listener: IGlobalKeyListener): void;
11
+ kill(): void;
12
+ }
13
+ /**
14
+ * Get the global keyboard listener singleton.
15
+ * The listener is shared across all consumers - use addListener/removeListener
16
+ * to subscribe to key events.
17
+ *
18
+ * @throws Error if platform is not supported (only macOS and Windows are supported)
19
+ */
20
+ declare function getGlobalKeyboardListener(): IGlobalKeyboardListener;
21
+ /**
22
+ * @deprecated Use getGlobalKeyboardListener() instead for singleton access.
23
+ * This function is kept for backward compatibility but now returns the singleton.
24
+ */
25
+ declare function createGlobalKeyboardListener(): IGlobalKeyboardListener;
26
+
27
+ export { type IGlobalKeyDownMap, type IGlobalKeyEvent, type IGlobalKeyListener, type IGlobalKeyState, type IGlobalKeyboardListener, createGlobalKeyboardListener, getGlobalKeyboardListener };
@@ -0,0 +1,27 @@
1
+ type IGlobalKeyState = 'DOWN' | 'UP';
2
+ interface IGlobalKeyEvent {
3
+ readonly name: string;
4
+ readonly state: IGlobalKeyState;
5
+ }
6
+ type IGlobalKeyDownMap = Record<string, boolean>;
7
+ type IGlobalKeyListener = (event: IGlobalKeyEvent, isDown: IGlobalKeyDownMap) => void;
8
+ interface IGlobalKeyboardListener {
9
+ addListener(listener: IGlobalKeyListener): void;
10
+ removeListener(listener: IGlobalKeyListener): void;
11
+ kill(): void;
12
+ }
13
+ /**
14
+ * Get the global keyboard listener singleton.
15
+ * The listener is shared across all consumers - use addListener/removeListener
16
+ * to subscribe to key events.
17
+ *
18
+ * @throws Error if platform is not supported (only macOS and Windows are supported)
19
+ */
20
+ declare function getGlobalKeyboardListener(): IGlobalKeyboardListener;
21
+ /**
22
+ * @deprecated Use getGlobalKeyboardListener() instead for singleton access.
23
+ * This function is kept for backward compatibility but now returns the singleton.
24
+ */
25
+ declare function createGlobalKeyboardListener(): IGlobalKeyboardListener;
26
+
27
+ export { type IGlobalKeyDownMap, type IGlobalKeyEvent, type IGlobalKeyListener, type IGlobalKeyState, type IGlobalKeyboardListener, createGlobalKeyboardListener, getGlobalKeyboardListener };
package/dist/index.js ADDED
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ createGlobalKeyboardListener: () => createGlobalKeyboardListener,
34
+ getGlobalKeyboardListener: () => getGlobalKeyboardListener
35
+ });
36
+ module.exports = __toCommonJS(index_exports);
37
+ var path = __toESM(require("path"));
38
+ var fs = __toESM(require("fs"));
39
+ var import_node_module = require("module");
40
+ var import_url = require("url");
41
+ var import_meta = {};
42
+ function getModulePaths() {
43
+ if (typeof import_meta !== "undefined" && import_meta.url) {
44
+ const filename = (0, import_url.fileURLToPath)(import_meta.url);
45
+ const dirname2 = path.dirname(filename);
46
+ const require2 = (0, import_node_module.createRequire)(import_meta.url);
47
+ return { dirname: dirname2, require: require2 };
48
+ }
49
+ return {
50
+ dirname: __dirname,
51
+ require
52
+ };
53
+ }
54
+ var modulePaths = getModulePaths();
55
+ function getNativeAddonPath() {
56
+ const platformArch = `${process.platform}-${process.arch}`;
57
+ const baseDir = modulePaths.dirname;
58
+ const possiblePaths = [
59
+ // Prebuilt binaries (preferred)
60
+ path.join(baseDir, "..", "prebuilds", platformArch, "simen_keyboard_listener.node"),
61
+ // Build output from node-gyp
62
+ path.join(baseDir, "native", "build", "Release", "simen_keyboard_listener.node"),
63
+ path.join(baseDir, "native", "build", "Debug", "simen_keyboard_listener.node"),
64
+ // Source native directory (for development)
65
+ path.join(baseDir, "..", "src", "native", "build", "Release", "simen_keyboard_listener.node"),
66
+ path.join(baseDir, "..", "src", "native", "build", "Debug", "simen_keyboard_listener.node")
67
+ ];
68
+ for (const addonPath of possiblePaths) {
69
+ if (fs.existsSync(addonPath)) {
70
+ return addonPath;
71
+ }
72
+ }
73
+ throw new Error(
74
+ `simen-keyboard-listener: Native addon not found for ${platformArch}. Searched paths: ${possiblePaths.join(", ")}`
75
+ );
76
+ }
77
+ var nativeAddon = null;
78
+ function getNativeAddon() {
79
+ if (nativeAddon) {
80
+ return nativeAddon;
81
+ }
82
+ const addonPath = getNativeAddonPath();
83
+ nativeAddon = modulePaths.require(addonPath);
84
+ return nativeAddon;
85
+ }
86
+ var NativeKeyboardListener = class _NativeKeyboardListener {
87
+ constructor(addon) {
88
+ this.addon = addon;
89
+ }
90
+ static _instance = null;
91
+ started = false;
92
+ listeners = /* @__PURE__ */ new Set();
93
+ static getInstance() {
94
+ if (!_NativeKeyboardListener._instance) {
95
+ const addon = getNativeAddon();
96
+ _NativeKeyboardListener._instance = new _NativeKeyboardListener(addon);
97
+ }
98
+ return _NativeKeyboardListener._instance;
99
+ }
100
+ addListener(listener) {
101
+ this.listeners.add(listener);
102
+ if (!this.started) {
103
+ const ok = this.addon.start((event) => {
104
+ const listenersCopy = Array.from(this.listeners);
105
+ for (const cb of listenersCopy) {
106
+ try {
107
+ cb(event, {});
108
+ } catch {
109
+ }
110
+ }
111
+ });
112
+ if (!ok) {
113
+ throw new Error("Failed to start native keyboard listener (permission denied or unsupported platform)");
114
+ }
115
+ this.started = true;
116
+ }
117
+ }
118
+ removeListener(listener) {
119
+ this.listeners.delete(listener);
120
+ if (this.listeners.size === 0 && this.started) {
121
+ this.kill();
122
+ }
123
+ }
124
+ kill() {
125
+ if (this.listeners.size > 0) {
126
+ return;
127
+ }
128
+ try {
129
+ if (this.started && this.addon.isRunning()) {
130
+ this.addon.stop();
131
+ }
132
+ } catch {
133
+ } finally {
134
+ this.started = false;
135
+ }
136
+ }
137
+ /**
138
+ * Force stop the listener regardless of remaining listeners.
139
+ * Use with caution - this will affect all consumers.
140
+ */
141
+ forceKill() {
142
+ try {
143
+ if (this.started && this.addon.isRunning()) {
144
+ this.addon.stop();
145
+ }
146
+ } catch {
147
+ } finally {
148
+ this.started = false;
149
+ this.listeners.clear();
150
+ _NativeKeyboardListener._instance = null;
151
+ }
152
+ }
153
+ };
154
+ function getGlobalKeyboardListener() {
155
+ if (process.platform !== "darwin" && process.platform !== "win32") {
156
+ throw new Error(`Unsupported platform for global keyboard listener: ${process.platform}`);
157
+ }
158
+ return NativeKeyboardListener.getInstance();
159
+ }
160
+ function createGlobalKeyboardListener() {
161
+ return getGlobalKeyboardListener();
162
+ }
163
+ // Annotate the CommonJS export names for ESM import in node:
164
+ 0 && (module.exports = {
165
+ createGlobalKeyboardListener,
166
+ getGlobalKeyboardListener
167
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,137 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/index.ts
9
+ import * as path from "path";
10
+ import * as fs from "fs";
11
+ import { createRequire } from "module";
12
+ import { fileURLToPath } from "url";
13
+ function getModulePaths() {
14
+ if (typeof import.meta !== "undefined" && import.meta.url) {
15
+ const filename = fileURLToPath(import.meta.url);
16
+ const dirname2 = path.dirname(filename);
17
+ const require2 = createRequire(import.meta.url);
18
+ return { dirname: dirname2, require: require2 };
19
+ }
20
+ return {
21
+ dirname: __dirname,
22
+ require: __require
23
+ };
24
+ }
25
+ var modulePaths = getModulePaths();
26
+ function getNativeAddonPath() {
27
+ const platformArch = `${process.platform}-${process.arch}`;
28
+ const baseDir = modulePaths.dirname;
29
+ const possiblePaths = [
30
+ // Prebuilt binaries (preferred)
31
+ path.join(baseDir, "..", "prebuilds", platformArch, "simen_keyboard_listener.node"),
32
+ // Build output from node-gyp
33
+ path.join(baseDir, "native", "build", "Release", "simen_keyboard_listener.node"),
34
+ path.join(baseDir, "native", "build", "Debug", "simen_keyboard_listener.node"),
35
+ // Source native directory (for development)
36
+ path.join(baseDir, "..", "src", "native", "build", "Release", "simen_keyboard_listener.node"),
37
+ path.join(baseDir, "..", "src", "native", "build", "Debug", "simen_keyboard_listener.node")
38
+ ];
39
+ for (const addonPath of possiblePaths) {
40
+ if (fs.existsSync(addonPath)) {
41
+ return addonPath;
42
+ }
43
+ }
44
+ throw new Error(
45
+ `simen-keyboard-listener: Native addon not found for ${platformArch}. Searched paths: ${possiblePaths.join(", ")}`
46
+ );
47
+ }
48
+ var nativeAddon = null;
49
+ function getNativeAddon() {
50
+ if (nativeAddon) {
51
+ return nativeAddon;
52
+ }
53
+ const addonPath = getNativeAddonPath();
54
+ nativeAddon = modulePaths.require(addonPath);
55
+ return nativeAddon;
56
+ }
57
+ var NativeKeyboardListener = class _NativeKeyboardListener {
58
+ constructor(addon) {
59
+ this.addon = addon;
60
+ }
61
+ static _instance = null;
62
+ started = false;
63
+ listeners = /* @__PURE__ */ new Set();
64
+ static getInstance() {
65
+ if (!_NativeKeyboardListener._instance) {
66
+ const addon = getNativeAddon();
67
+ _NativeKeyboardListener._instance = new _NativeKeyboardListener(addon);
68
+ }
69
+ return _NativeKeyboardListener._instance;
70
+ }
71
+ addListener(listener) {
72
+ this.listeners.add(listener);
73
+ if (!this.started) {
74
+ const ok = this.addon.start((event) => {
75
+ const listenersCopy = Array.from(this.listeners);
76
+ for (const cb of listenersCopy) {
77
+ try {
78
+ cb(event, {});
79
+ } catch {
80
+ }
81
+ }
82
+ });
83
+ if (!ok) {
84
+ throw new Error("Failed to start native keyboard listener (permission denied or unsupported platform)");
85
+ }
86
+ this.started = true;
87
+ }
88
+ }
89
+ removeListener(listener) {
90
+ this.listeners.delete(listener);
91
+ if (this.listeners.size === 0 && this.started) {
92
+ this.kill();
93
+ }
94
+ }
95
+ kill() {
96
+ if (this.listeners.size > 0) {
97
+ return;
98
+ }
99
+ try {
100
+ if (this.started && this.addon.isRunning()) {
101
+ this.addon.stop();
102
+ }
103
+ } catch {
104
+ } finally {
105
+ this.started = false;
106
+ }
107
+ }
108
+ /**
109
+ * Force stop the listener regardless of remaining listeners.
110
+ * Use with caution - this will affect all consumers.
111
+ */
112
+ forceKill() {
113
+ try {
114
+ if (this.started && this.addon.isRunning()) {
115
+ this.addon.stop();
116
+ }
117
+ } catch {
118
+ } finally {
119
+ this.started = false;
120
+ this.listeners.clear();
121
+ _NativeKeyboardListener._instance = null;
122
+ }
123
+ }
124
+ };
125
+ function getGlobalKeyboardListener() {
126
+ if (process.platform !== "darwin" && process.platform !== "win32") {
127
+ throw new Error(`Unsupported platform for global keyboard listener: ${process.platform}`);
128
+ }
129
+ return NativeKeyboardListener.getInstance();
130
+ }
131
+ function createGlobalKeyboardListener() {
132
+ return getGlobalKeyboardListener();
133
+ }
134
+ export {
135
+ createGlobalKeyboardListener,
136
+ getGlobalKeyboardListener
137
+ };
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "simen-keyboard-listener",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Native global keyboard listener for macOS and Windows",
5
- "main": "./lib/index.js",
6
- "module": "./lib/index.mjs",
7
- "types": "./lib/index.d.ts",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
8
  "exports": {
9
9
  ".": {
10
- "types": "./lib/index.d.ts",
11
- "import": "./lib/index.mjs",
12
- "require": "./lib/index.js"
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
13
  }
14
14
  },
15
15
  "files": [
16
- "lib",
16
+ "dist",
17
17
  "prebuilds",
18
18
  "src/native"
19
19
  ],