@stonyx/events 0.1.1-beta.32 → 0.1.1-beta.34
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/dist/main.d.ts +31 -0
- package/dist/main.js +102 -0
- package/package.json +16 -7
- package/src/main.js +0 -179
package/dist/main.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Events - A lightweight pub/sub event system
|
|
3
|
+
*
|
|
4
|
+
* Provides event subscription and emission with support for:
|
|
5
|
+
* - One-time subscriptions (once)
|
|
6
|
+
* - Async event handlers
|
|
7
|
+
* - Error isolation per handler
|
|
8
|
+
* - Singleton pattern
|
|
9
|
+
*/
|
|
10
|
+
export type EventCallback = (...args: unknown[]) => void | Promise<void>;
|
|
11
|
+
declare class Events {
|
|
12
|
+
static instance: Events | null;
|
|
13
|
+
events: Map<string, Set<EventCallback>>;
|
|
14
|
+
registeredEvents: Set<string>;
|
|
15
|
+
constructor();
|
|
16
|
+
setup(eventNames: string[]): void;
|
|
17
|
+
subscribe(event: string, callback: EventCallback): () => void;
|
|
18
|
+
once(event: string, callback: EventCallback): () => void;
|
|
19
|
+
unsubscribe(event: string, callback: EventCallback): void;
|
|
20
|
+
emit(event: string, ...args: unknown[]): Promise<void>;
|
|
21
|
+
clear(event: string): void;
|
|
22
|
+
reset(): void;
|
|
23
|
+
}
|
|
24
|
+
export default Events;
|
|
25
|
+
export declare const setup: (eventNames: string[]) => void;
|
|
26
|
+
export declare const subscribe: (event: string, callback: EventCallback) => (() => void);
|
|
27
|
+
export declare const once: (event: string, callback: EventCallback) => (() => void);
|
|
28
|
+
export declare const unsubscribe: (event: string, callback: EventCallback) => void;
|
|
29
|
+
export declare const emit: (event: string, ...args: unknown[]) => Promise<void>;
|
|
30
|
+
export declare const clear: (event: string) => void;
|
|
31
|
+
export declare const reset: () => void;
|
package/dist/main.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Events - A lightweight pub/sub event system
|
|
3
|
+
*
|
|
4
|
+
* Provides event subscription and emission with support for:
|
|
5
|
+
* - One-time subscriptions (once)
|
|
6
|
+
* - Async event handlers
|
|
7
|
+
* - Error isolation per handler
|
|
8
|
+
* - Singleton pattern
|
|
9
|
+
*/
|
|
10
|
+
class Events {
|
|
11
|
+
static instance = null;
|
|
12
|
+
events = new Map();
|
|
13
|
+
registeredEvents = new Set();
|
|
14
|
+
constructor() {
|
|
15
|
+
if (Events.instance) {
|
|
16
|
+
return Events.instance;
|
|
17
|
+
}
|
|
18
|
+
Events.instance = this;
|
|
19
|
+
}
|
|
20
|
+
setup(eventNames) {
|
|
21
|
+
if (!Array.isArray(eventNames)) {
|
|
22
|
+
throw new Error('setup() requires an array of event names');
|
|
23
|
+
}
|
|
24
|
+
for (const eventName of eventNames) {
|
|
25
|
+
if (typeof eventName !== 'string') {
|
|
26
|
+
throw new Error('Event names must be strings');
|
|
27
|
+
}
|
|
28
|
+
this.registeredEvents.add(eventName);
|
|
29
|
+
if (!this.events.has(eventName)) {
|
|
30
|
+
this.events.set(eventName, new Set());
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
subscribe(event, callback) {
|
|
35
|
+
if (!this.registeredEvents.has(event)) {
|
|
36
|
+
throw new Error(`Event "${event}" is not registered. Call setup() first.`);
|
|
37
|
+
}
|
|
38
|
+
if (typeof callback !== 'function') {
|
|
39
|
+
throw new Error('Callback must be a function');
|
|
40
|
+
}
|
|
41
|
+
const subscribers = this.events.get(event);
|
|
42
|
+
subscribers.add(callback);
|
|
43
|
+
// Return unsubscribe function
|
|
44
|
+
return () => this.unsubscribe(event, callback);
|
|
45
|
+
}
|
|
46
|
+
once(event, callback) {
|
|
47
|
+
if (!this.registeredEvents.has(event)) {
|
|
48
|
+
throw new Error(`Event "${event}" is not registered. Call setup() first.`);
|
|
49
|
+
}
|
|
50
|
+
if (typeof callback !== 'function') {
|
|
51
|
+
throw new Error('Callback must be a function');
|
|
52
|
+
}
|
|
53
|
+
const wrapper = async (...args) => {
|
|
54
|
+
this.unsubscribe(event, wrapper);
|
|
55
|
+
await callback(...args);
|
|
56
|
+
};
|
|
57
|
+
return this.subscribe(event, wrapper);
|
|
58
|
+
}
|
|
59
|
+
unsubscribe(event, callback) {
|
|
60
|
+
if (!this.events.has(event)) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const subscribers = this.events.get(event);
|
|
64
|
+
subscribers.delete(callback);
|
|
65
|
+
}
|
|
66
|
+
async emit(event, ...args) {
|
|
67
|
+
if (!this.events.has(event)) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const subscribers = this.events.get(event);
|
|
71
|
+
// Execute all handlers with error isolation
|
|
72
|
+
const promises = Array.from(subscribers).map(async (callback) => {
|
|
73
|
+
try {
|
|
74
|
+
await callback(...args);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
console.error(`Error in event handler for "${event}":`, error);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
await Promise.all(promises);
|
|
81
|
+
}
|
|
82
|
+
clear(event) {
|
|
83
|
+
if (this.events.has(event)) {
|
|
84
|
+
this.events.get(event).clear();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
reset() {
|
|
88
|
+
this.events.clear();
|
|
89
|
+
this.registeredEvents.clear();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
export default Events;
|
|
93
|
+
// Create singleton instance
|
|
94
|
+
const events = new Events();
|
|
95
|
+
// Export convenience functions that use the singleton
|
|
96
|
+
export const setup = (eventNames) => events.setup(eventNames);
|
|
97
|
+
export const subscribe = (event, callback) => events.subscribe(event, callback);
|
|
98
|
+
export const once = (event, callback) => events.once(event, callback);
|
|
99
|
+
export const unsubscribe = (event, callback) => events.unsubscribe(event, callback);
|
|
100
|
+
export const emit = (event, ...args) => events.emit(event, ...args);
|
|
101
|
+
export const clear = (event) => events.clear(event);
|
|
102
|
+
export const reset = () => events.reset();
|
package/package.json
CHANGED
|
@@ -3,16 +3,20 @@
|
|
|
3
3
|
"keywords": [
|
|
4
4
|
"stonyx-module"
|
|
5
5
|
],
|
|
6
|
-
"version": "0.1.1-beta.
|
|
6
|
+
"version": "0.1.1-beta.34",
|
|
7
7
|
"description": "Lightweight pub/sub event system for the Stonyx framework",
|
|
8
|
-
"main": "
|
|
8
|
+
"main": "dist/main.js",
|
|
9
|
+
"types": "dist/main.d.ts",
|
|
9
10
|
"type": "module",
|
|
10
11
|
"files": [
|
|
11
|
-
"
|
|
12
|
+
"dist",
|
|
12
13
|
"README.md"
|
|
13
14
|
],
|
|
14
15
|
"exports": {
|
|
15
|
-
".":
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/main.d.ts",
|
|
18
|
+
"default": "./dist/main.js"
|
|
19
|
+
}
|
|
16
20
|
},
|
|
17
21
|
"publishConfig": {
|
|
18
22
|
"access": "public",
|
|
@@ -32,12 +36,17 @@
|
|
|
32
36
|
},
|
|
33
37
|
"homepage": "https://github.com/abofs/stonyx-events#readme",
|
|
34
38
|
"devDependencies": {
|
|
35
|
-
"@stonyx/utils": "0.2.3-beta.
|
|
39
|
+
"@stonyx/utils": "0.2.3-beta.18",
|
|
40
|
+
"@types/node": "^25.5.2",
|
|
41
|
+
"@types/qunit": "^2.19.13",
|
|
36
42
|
"qunit": "^2.24.1",
|
|
37
|
-
"sinon": "^21.0.0"
|
|
43
|
+
"sinon": "^21.0.0",
|
|
44
|
+
"typescript": "^5.8.3"
|
|
38
45
|
},
|
|
39
46
|
"dependencies": {},
|
|
40
47
|
"scripts": {
|
|
41
|
-
"
|
|
48
|
+
"build": "tsc",
|
|
49
|
+
"build:test": "tsc -p tsconfig.test.json",
|
|
50
|
+
"test": "pnpm build && pnpm build:test && qunit 'dist-test/test/**/*.js'"
|
|
42
51
|
}
|
|
43
52
|
}
|
package/src/main.js
DELETED
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Events - A lightweight pub/sub event system
|
|
3
|
-
*
|
|
4
|
-
* Provides event subscription and emission with support for:
|
|
5
|
-
* - One-time subscriptions (once)
|
|
6
|
-
* - Async event handlers
|
|
7
|
-
* - Error isolation per handler
|
|
8
|
-
* - Singleton pattern
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
class Events {
|
|
12
|
-
/**
|
|
13
|
-
* Singleton instance
|
|
14
|
-
* @type {Events}
|
|
15
|
-
*/
|
|
16
|
-
static instance = null;
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Create a new Events instance
|
|
20
|
-
*/
|
|
21
|
-
constructor() {
|
|
22
|
-
if (Events.instance) {
|
|
23
|
-
return Events.instance;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Map of event names to their subscribers
|
|
28
|
-
* @type {Map<string, Set<Function>>}
|
|
29
|
-
*/
|
|
30
|
-
this.events = new Map();
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Set of registered event names
|
|
34
|
-
* @type {Set<string>}
|
|
35
|
-
*/
|
|
36
|
-
this.registeredEvents = new Set();
|
|
37
|
-
|
|
38
|
-
Events.instance = this;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Register available event names
|
|
43
|
-
* @param {string[]} eventNames - Array of event names to register
|
|
44
|
-
*/
|
|
45
|
-
setup(eventNames) {
|
|
46
|
-
if (!Array.isArray(eventNames)) {
|
|
47
|
-
throw new Error('setup() requires an array of event names');
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
for (const eventName of eventNames) {
|
|
51
|
-
if (typeof eventName !== 'string') {
|
|
52
|
-
throw new Error('Event names must be strings');
|
|
53
|
-
}
|
|
54
|
-
this.registeredEvents.add(eventName);
|
|
55
|
-
if (!this.events.has(eventName)) {
|
|
56
|
-
this.events.set(eventName, new Set());
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Subscribe to an event
|
|
63
|
-
* @param {string} event - Event name to subscribe to
|
|
64
|
-
* @param {Function} callback - Handler function to call when event fires
|
|
65
|
-
* @returns {Function} Unsubscribe function
|
|
66
|
-
* @throws {Error} If event is not registered
|
|
67
|
-
*/
|
|
68
|
-
subscribe(event, callback) {
|
|
69
|
-
if (!this.registeredEvents.has(event)) {
|
|
70
|
-
throw new Error(`Event "${event}" is not registered. Call setup() first.`);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
if (typeof callback !== 'function') {
|
|
74
|
-
throw new Error('Callback must be a function');
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const subscribers = this.events.get(event);
|
|
78
|
-
subscribers.add(callback);
|
|
79
|
-
|
|
80
|
-
// Return unsubscribe function
|
|
81
|
-
return () => this.unsubscribe(event, callback);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Subscribe to an event once (auto-unsubscribe after first emit)
|
|
86
|
-
* @param {string} event - Event name to subscribe to
|
|
87
|
-
* @param {Function} callback - Handler function to call when event fires
|
|
88
|
-
* @returns {Function} Unsubscribe function
|
|
89
|
-
* @throws {Error} If event is not registered
|
|
90
|
-
*/
|
|
91
|
-
once(event, callback) {
|
|
92
|
-
if (!this.registeredEvents.has(event)) {
|
|
93
|
-
throw new Error(`Event "${event}" is not registered. Call setup() first.`);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (typeof callback !== 'function') {
|
|
97
|
-
throw new Error('Callback must be a function');
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const wrapper = async (...args) => {
|
|
101
|
-
this.unsubscribe(event, wrapper);
|
|
102
|
-
await callback(...args);
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
return this.subscribe(event, wrapper);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Unsubscribe from an event
|
|
110
|
-
* @param {string} event - Event name to unsubscribe from
|
|
111
|
-
* @param {Function} callback - Handler function to remove
|
|
112
|
-
*/
|
|
113
|
-
unsubscribe(event, callback) {
|
|
114
|
-
if (!this.events.has(event)) {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const subscribers = this.events.get(event);
|
|
119
|
-
subscribers.delete(callback);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Emit an event with arguments
|
|
124
|
-
* Executes all subscribed handlers asynchronously with error isolation
|
|
125
|
-
* @param {string} event - Event name to emit
|
|
126
|
-
* @param {...any} args - Arguments to pass to handlers
|
|
127
|
-
*/
|
|
128
|
-
async emit(event, ...args) {
|
|
129
|
-
if (!this.events.has(event)) {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const subscribers = this.events.get(event);
|
|
134
|
-
|
|
135
|
-
// Execute all handlers with error isolation
|
|
136
|
-
const promises = Array.from(subscribers).map(async (callback) => {
|
|
137
|
-
try {
|
|
138
|
-
await callback(...args);
|
|
139
|
-
} catch (error) {
|
|
140
|
-
console.error(`Error in event handler for "${event}":`, error);
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
await Promise.all(promises);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Clear all subscriptions for an event
|
|
149
|
-
* @param {string} event - Event name to clear
|
|
150
|
-
*/
|
|
151
|
-
clear(event) {
|
|
152
|
-
if (this.events.has(event)) {
|
|
153
|
-
this.events.get(event).clear();
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Reset the entire event system (clear all subscriptions)
|
|
159
|
-
* Useful for testing
|
|
160
|
-
*/
|
|
161
|
-
reset() {
|
|
162
|
-
this.events.clear();
|
|
163
|
-
this.registeredEvents.clear();
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
export default Events;
|
|
168
|
-
|
|
169
|
-
// Create singleton instance
|
|
170
|
-
const events = new Events();
|
|
171
|
-
|
|
172
|
-
// Export convenience functions that use the singleton
|
|
173
|
-
export const setup = (...args) => events.setup(...args);
|
|
174
|
-
export const subscribe = (...args) => events.subscribe(...args);
|
|
175
|
-
export const once = (...args) => events.once(...args);
|
|
176
|
-
export const unsubscribe = (...args) => events.unsubscribe(...args);
|
|
177
|
-
export const emit = (...args) => events.emit(...args);
|
|
178
|
-
export const clear = (...args) => events.clear(...args);
|
|
179
|
-
export const reset = (...args) => events.reset(...args);
|