vbstyle-event-models 1.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.
@@ -0,0 +1,41 @@
1
+ /**
2
+ * A type for event arguments that can be any array of values.
3
+ */
4
+ export type EventArgs = any[];
5
+
6
+ /**
7
+ * A delegate type for event handlers that take any sender and event arguments.
8
+ */
9
+ export type EventHandler = (sender: any, e: EventArgs) => void;
10
+
11
+ /**
12
+ * A basic event model that allows registration and invocation of event handlers.
13
+ */
14
+ export class BasicEventModel {
15
+ private eventHandlers: EventHandler[] = [];
16
+
17
+ /**
18
+ * Add an event handler to the event model.
19
+ * @param {EventHandler} handler - The event handler to add.
20
+ */
21
+ public addHandler(handler: EventHandler): void {
22
+ this.eventHandlers.push(handler);
23
+ }
24
+
25
+ /**
26
+ * Remove an event handler from the event model.
27
+ * @param {EventHandler} handler - The event handler to remove.
28
+ */
29
+ public removeHandler(handler: EventHandler): void {
30
+ this.eventHandlers = this.eventHandlers.filter(h => h !== handler);
31
+ }
32
+
33
+ /**
34
+ * Raise the event from the event model, invoking all registered event handlers.
35
+ * @param {any} sender - The event sender.
36
+ * @param {EventArgs} e - The event arguments.
37
+ */
38
+ public raiseEvent(sender: any, e: EventArgs): void {
39
+ this.eventHandlers.forEach(handler => handler(sender, e));
40
+ }
41
+ }
package/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, pac-dessert1436
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,136 @@
1
+ import { Spinlock } from "./Spinlock";
2
+
3
+ /**
4
+ * A singleton class for message routing, using a spinlock for thread safety.
5
+ */
6
+ export class MessageRouter {
7
+ /**
8
+ * Get the singleton instance of the MessageRouter.
9
+ * @returns {MessageRouter} The singleton instance.
10
+ */
11
+ private static _instance: MessageRouter;
12
+
13
+ private _subscribers: Map<string, ((content: any) => void)[]> = new Map();
14
+ private _lock: Spinlock = new Spinlock();
15
+
16
+ constructor() {
17
+ if (MessageRouter._instance) {
18
+ throw new Error("Use MessageRouter.instance to get the singleton instance.");
19
+ }
20
+ }
21
+
22
+ /**
23
+ * Get the singleton instance of the MessageRouter.
24
+ * @returns {MessageRouter} The singleton instance.
25
+ */
26
+ public static get instance(): MessageRouter {
27
+ if (!MessageRouter._instance) {
28
+ MessageRouter._instance = new MessageRouter();
29
+ }
30
+ return MessageRouter._instance;
31
+ }
32
+
33
+ /**
34
+ * Subscribe to a message type.
35
+ * @param {string} messageType - The type of message to subscribe to.
36
+ * @param {function} handler - The handler function to call when a message of the specified type is sent.
37
+ */
38
+ public async subscribe(messageType: string, handler: (content: any) => void): Promise<void> {
39
+ if (!messageType) throw new Error("messageType is required");
40
+ if (typeof handler !== "function") throw new Error("handler must be a function");
41
+
42
+ await this._lock.acquireLock();
43
+ try {
44
+ if (!this._subscribers.has(messageType)) {
45
+ this._subscribers.set(messageType, []);
46
+ }
47
+ this._subscribers.get(messageType)!.push(handler);
48
+ } finally {
49
+ this._lock.releaseLock();
50
+ }
51
+ }
52
+
53
+ /**
54
+ * Send a message of a specific type.
55
+ * @param {string} messageType - The type of message to send.
56
+ * @param {*} content - The content of the message to send.
57
+ */
58
+ public async send(messageType: string, content: any): Promise<void> {
59
+ if (!messageType) throw new Error("messageType is required");
60
+
61
+ let handlers = null;
62
+
63
+ await this._lock.acquireLock();
64
+ try {
65
+ if (this._subscribers.has(messageType)) {
66
+ // Copy handlers to avoid issues if subscribers change during iteration
67
+ handlers = [...this._subscribers.get(messageType)!];
68
+ }
69
+ } finally {
70
+ this._lock.releaseLock();
71
+ }
72
+
73
+ if (handlers) {
74
+ for (const handler of handlers) {
75
+ try {
76
+ handler(content);
77
+ } catch (ex) {
78
+ // Log but don't crash the message pump
79
+ console.debug(`Handler error: ${(ex as Error).message}`);
80
+ }
81
+ }
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Unsubscribe from a message type.
87
+ * @param {string} messageType - The type of message to unsubscribe from.
88
+ * @param {function} handler - The handler function to remove from the subscribers list.
89
+ */
90
+ public async unsubscribe(messageType: string, handler: (content: any) => void): Promise<void> {
91
+ await this._lock.acquireLock();
92
+ try {
93
+ if (this._subscribers.has(messageType)) {
94
+ const handlers = this._subscribers.get(messageType);
95
+ const index = handlers!.indexOf(handler);
96
+ if (index !== -1) {
97
+ handlers!.splice(index, 1);
98
+ }
99
+ }
100
+ } finally {
101
+ this._lock.releaseLock();
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Clear all subscribers for a specific message type.
107
+ * @param {string} messageType - The type of message to clear subscribers for.
108
+ */
109
+ public async clearSubscribers(messageType: string): Promise<void> {
110
+ await this._lock.acquireLock();
111
+ try {
112
+ if (this._subscribers.has(messageType)) {
113
+ this._subscribers.get(messageType)!.length = 0;
114
+ }
115
+ } finally {
116
+ this._lock.releaseLock();
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Get the total number of subscribers across all message types.
122
+ * @returns {number} The total number of subscribers.
123
+ */
124
+ public async getSubscriberCount(): Promise<number> {
125
+ await this._lock.acquireLock();
126
+ try {
127
+ let count = 0;
128
+ for (const handlers of this._subscribers.values()) {
129
+ count += handlers.length;
130
+ }
131
+ return count;
132
+ } finally {
133
+ this._lock.releaseLock();
134
+ }
135
+ }
136
+ }
@@ -0,0 +1,54 @@
1
+ import { Spinlock } from "./Spinlock";
2
+
3
+ /**
4
+ * A simple event scheduler that uses a queue and a spinlock.
5
+ */
6
+ export class QueueEventScheduler {
7
+ private _eventQueue: (() => void)[] = [];
8
+ private _spinlock: Spinlock = new Spinlock();
9
+
10
+ /**
11
+ * Schedule an event action to be processed.
12
+ * @param {() => void} eventAction - The event action to be processed.
13
+ */
14
+ public async scheduleEventAction(eventAction: () => void): Promise<void> {
15
+ await this._spinlock.acquireLock();
16
+ this._eventQueue.push(eventAction);
17
+ this._spinlock.releaseLock();
18
+ }
19
+
20
+ /**
21
+ * Process all events in the queue.
22
+ */
23
+ public async processEvents(): Promise<void> {
24
+ if (this._eventQueue.length === 0) {
25
+ return;
26
+ }
27
+ await this._spinlock.acquireLock();
28
+ while (this._eventQueue.length > 0) {
29
+ const event = this._eventQueue.shift()!;
30
+ event();
31
+ }
32
+ this._spinlock.releaseLock();
33
+ }
34
+
35
+ /**
36
+ * Clear all pending events.
37
+ */
38
+ public async clearEvents(): Promise<void> {
39
+ await this._spinlock.acquireLock();
40
+ this._eventQueue = [];
41
+ this._spinlock.releaseLock();
42
+ }
43
+
44
+ /**
45
+ * Get the number of pending events.
46
+ * @returns {number} The number of pending events.
47
+ */
48
+ public get pendingEventCount(): number {
49
+ this._spinlock.acquireLock();
50
+ const count = this._eventQueue.length;
51
+ this._spinlock.releaseLock();
52
+ return count;
53
+ }
54
+ }
package/README.md ADDED
@@ -0,0 +1,125 @@
1
+ # VB.NET-Style Event Models
2
+
3
+ A TypeScript library providing event models, message routing, and event scheduling utilities with thread safety.
4
+
5
+ ## Features
6
+
7
+ - **BasicEventModel**: A simple event model for registering and invoking event handlers
8
+ - **MessageRouter**: A singleton message router for publish-subscribe pattern
9
+ - **QueueEventScheduler**: A queue-based event scheduler with thread safety
10
+ - **Spinlock**: A simple mutex/lock implementation for thread safety
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ npm install vbstyle-event-models
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ ### BasicEventModel
21
+
22
+ ```typescript
23
+ import { BasicEventModel, EventHandler, EventArgs } from 'vbstyle-event-models';
24
+
25
+ // Create an event model
26
+ const eventModel = new BasicEventModel();
27
+
28
+ // Define an event handler
29
+ const handler: EventHandler = (sender, e) => {
30
+ console.log('Event triggered:', { sender, args: e });
31
+ };
32
+
33
+ // Add the handler
34
+ eventModel.addHandler(handler);
35
+
36
+ // Raise the event
37
+ eventModel.raiseEvent('sender', ['arg1', 'arg2']);
38
+
39
+ // Remove the handler
40
+ eventModel.removeHandler(handler);
41
+ ```
42
+
43
+ ### MessageRouter
44
+
45
+ ```typescript
46
+ import { MessageRouter } from 'vbstyle-event-models';
47
+
48
+ // Get the singleton instance
49
+ const router = MessageRouter.instance;
50
+
51
+ // Subscribe to a message type
52
+ await router.subscribe('userCreated', (user) => {
53
+ console.log('User created:', user);
54
+ });
55
+
56
+ // Send a message
57
+ await router.send('userCreated', { id: 1, name: 'John' });
58
+
59
+ // Unsubscribe from a message type
60
+ await router.unsubscribe('userCreated', handler);
61
+
62
+ // Clear all subscribers for a message type
63
+ await router.clearSubscribers('userCreated');
64
+
65
+ // Get total subscriber count
66
+ const count = await router.getSubscriberCount();
67
+ console.log('Total subscribers:', count);
68
+ ```
69
+
70
+ ### QueueEventScheduler
71
+
72
+ ```typescript
73
+ import { QueueEventScheduler } from 'vbstyle-event-models';
74
+
75
+ // Create an event scheduler
76
+ const scheduler = new QueueEventScheduler();
77
+
78
+ // Schedule events
79
+ await scheduler.scheduleEvent(() => {
80
+ console.log('Event 1 executed');
81
+ });
82
+
83
+ await scheduler.scheduleEvent(() => {
84
+ console.log('Event 2 executed');
85
+ });
86
+
87
+ // Process all events
88
+ await scheduler.processEvents();
89
+
90
+ // Clear pending events
91
+ await scheduler.clearEvents();
92
+
93
+ // Get pending event count
94
+ console.log('Pending events:', scheduler.pendingEventCount);
95
+ ```
96
+
97
+ ### Spinlock
98
+
99
+ ```typescript
100
+ import { Spinlock } from 'vbstyle-event-models';
101
+
102
+ // Create a spinlock
103
+ const lock = new Spinlock();
104
+
105
+ // Acquire the lock
106
+ await lock.acquireLock();
107
+ try {
108
+ // Critical section
109
+ console.log('Lock acquired');
110
+ } finally {
111
+ // Release the lock
112
+ lock.releaseLock();
113
+ console.log('Lock released');
114
+ }
115
+
116
+ // Check if locked
117
+ console.log('Is locked:', lock.isLocked);
118
+
119
+ // Get waiter count
120
+ console.log('Waiters:', lock.waiterCount);
121
+ ```
122
+
123
+ ## License
124
+
125
+ BSD 3-Clause
package/Spinlock.ts ADDED
@@ -0,0 +1,57 @@
1
+ /**
2
+ * A simple mutex/lock implementation using a queue.
3
+ */
4
+ export class Spinlock {
5
+ private locked: boolean = false;
6
+ private waitingQueue: Array<() => void> = [];
7
+
8
+ /**
9
+ * Acquire the lock. If the lock is already held, queue the request.
10
+ */
11
+ public async acquireLock(): Promise<void> {
12
+ // If lock is free, acquire it immediately
13
+ if (!this.locked) {
14
+ this.locked = true;
15
+ return Promise.resolve();
16
+ }
17
+
18
+ // Otherwise, queue this request
19
+ return new Promise(resolve => {
20
+ this.waitingQueue.push(resolve);
21
+ });
22
+ }
23
+
24
+ /**
25
+ * Release the lock. If there are waiting acquisitions, pass the lock to the next in line.
26
+ */
27
+ public releaseLock(): void {
28
+ if (!this.locked && this.waitingQueue.length === 0) {
29
+ throw new Error("Lock is not held.");
30
+ }
31
+
32
+ // If there are waiting acquisitions, pass the lock to the next one
33
+ if (this.waitingQueue.length > 0) {
34
+ const nextResolve = this.waitingQueue.shift()!;
35
+ // The lock remains locked, but now the next waiter has it
36
+ // We don't set locked = false because it's immediately re-acquired
37
+ nextResolve();
38
+ } else {
39
+ // No waiters, release the lock
40
+ this.locked = false;
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Check if the lock is currently held.
46
+ */
47
+ public get isLocked(): boolean {
48
+ return this.locked;
49
+ }
50
+
51
+ /**
52
+ * Get the number of waiters.
53
+ */
54
+ public get waiterCount(): number {
55
+ return this.waitingQueue.length;
56
+ }
57
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * A type for event arguments that can be any array of values.
3
+ */
4
+ export type EventArgs = any[];
5
+ /**
6
+ * A delegate type for event handlers that take any sender and event arguments.
7
+ */
8
+ export type EventHandler = (sender: any, e: EventArgs) => void;
9
+ /**
10
+ * A basic event model that allows registration and invocation of event handlers.
11
+ */
12
+ export declare class BasicEventModel {
13
+ private eventHandlers;
14
+ /**
15
+ * Add an event handler to the event model.
16
+ * @param {EventHandler} handler - The event handler to add.
17
+ */
18
+ addHandler(handler: EventHandler): void;
19
+ /**
20
+ * Remove an event handler from the event model.
21
+ * @param {EventHandler} handler - The event handler to remove.
22
+ */
23
+ removeHandler(handler: EventHandler): void;
24
+ /**
25
+ * Raise the event from the event model, invoking all registered event handlers.
26
+ * @param {any} sender - The event sender.
27
+ * @param {EventArgs} e - The event arguments.
28
+ */
29
+ raiseEvent(sender: any, e: EventArgs): void;
30
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BasicEventModel.d.ts","sourceRoot":"","sources":["../BasicEventModel.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;AAE9B;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,SAAS,KAAK,IAAI,CAAC;AAE/D;;GAEG;AACH,qBAAa,eAAe;IACxB,OAAO,CAAC,aAAa,CAAsB;IAE3C;;;OAGG;IACI,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAI9C;;;OAGG;IACI,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAIjD;;;;OAIG;IACI,UAAU,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,SAAS,GAAG,IAAI;CAGrD"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BasicEventModel = void 0;
4
+ /**
5
+ * A basic event model that allows registration and invocation of event handlers.
6
+ */
7
+ class BasicEventModel {
8
+ constructor() {
9
+ this.eventHandlers = [];
10
+ }
11
+ /**
12
+ * Add an event handler to the event model.
13
+ * @param {EventHandler} handler - The event handler to add.
14
+ */
15
+ addHandler(handler) {
16
+ this.eventHandlers.push(handler);
17
+ }
18
+ /**
19
+ * Remove an event handler from the event model.
20
+ * @param {EventHandler} handler - The event handler to remove.
21
+ */
22
+ removeHandler(handler) {
23
+ this.eventHandlers = this.eventHandlers.filter(h => h !== handler);
24
+ }
25
+ /**
26
+ * Raise the event from the event model, invoking all registered event handlers.
27
+ * @param {any} sender - The event sender.
28
+ * @param {EventArgs} e - The event arguments.
29
+ */
30
+ raiseEvent(sender, e) {
31
+ this.eventHandlers.forEach(handler => handler(sender, e));
32
+ }
33
+ }
34
+ exports.BasicEventModel = BasicEventModel;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BasicEventModel.js","sourceRoot":"","sources":["../BasicEventModel.ts"],"names":[],"mappings":";;;AAUA;;GAEG;AACH,MAAa,eAAe;IAA5B;QACY,kBAAa,GAAmB,EAAE,CAAC;IA0B/C,CAAC;IAxBG;;;OAGG;IACI,UAAU,CAAC,OAAqB;QACnC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED;;;OAGG;IACI,aAAa,CAAC,OAAqB;QACtC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC;IACvE,CAAC;IAED;;;;OAIG;IACI,UAAU,CAAC,MAAW,EAAE,CAAY;QACvC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC;CACJ;AA3BD,0CA2BC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * A singleton class for message routing, using a spinlock for thread safety.
3
+ */
4
+ export declare class MessageRouter {
5
+ /**
6
+ * Get the singleton instance of the MessageRouter.
7
+ * @returns {MessageRouter} The singleton instance.
8
+ */
9
+ private static _instance;
10
+ private _subscribers;
11
+ private _lock;
12
+ constructor();
13
+ /**
14
+ * Get the singleton instance of the MessageRouter.
15
+ * @returns {MessageRouter} The singleton instance.
16
+ */
17
+ static get instance(): MessageRouter;
18
+ /**
19
+ * Subscribe to a message type.
20
+ * @param {string} messageType - The type of message to subscribe to.
21
+ * @param {function} handler - The handler function to call when a message of the specified type is sent.
22
+ */
23
+ subscribe(messageType: string, handler: (content: any) => void): Promise<void>;
24
+ /**
25
+ * Send a message of a specific type.
26
+ * @param {string} messageType - The type of message to send.
27
+ * @param {*} content - The content of the message to send.
28
+ */
29
+ send(messageType: string, content: any): Promise<void>;
30
+ /**
31
+ * Unsubscribe from a message type.
32
+ * @param {string} messageType - The type of message to unsubscribe from.
33
+ * @param {function} handler - The handler function to remove from the subscribers list.
34
+ */
35
+ unsubscribe(messageType: string, handler: (content: any) => void): Promise<void>;
36
+ /**
37
+ * Clear all subscribers for a specific message type.
38
+ * @param {string} messageType - The type of message to clear subscribers for.
39
+ */
40
+ clearSubscribers(messageType: string): Promise<void>;
41
+ /**
42
+ * Get the total number of subscribers across all message types.
43
+ * @returns {number} The total number of subscribers.
44
+ */
45
+ getSubscriberCount(): Promise<number>;
46
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageRouter.d.ts","sourceRoot":"","sources":["../MessageRouter.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,qBAAa,aAAa;IACtB;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,SAAS,CAAgB;IAExC,OAAO,CAAC,YAAY,CAAsD;IAC1E,OAAO,CAAC,KAAK,CAA4B;;IAQzC;;;OAGG;IACH,WAAkB,QAAQ,IAAI,aAAa,CAK1C;IAED;;;;OAIG;IACU,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAe3F;;;;OAIG;IACU,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BnE;;;;OAIG;IACU,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAe7F;;;OAGG;IACU,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWjE;;;OAGG;IACU,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC;CAYrD"}
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.MessageRouter = void 0;
13
+ const Spinlock_1 = require("./Spinlock");
14
+ /**
15
+ * A singleton class for message routing, using a spinlock for thread safety.
16
+ */
17
+ class MessageRouter {
18
+ constructor() {
19
+ this._subscribers = new Map();
20
+ this._lock = new Spinlock_1.Spinlock();
21
+ if (MessageRouter._instance) {
22
+ throw new Error("Use MessageRouter.instance to get the singleton instance.");
23
+ }
24
+ }
25
+ /**
26
+ * Get the singleton instance of the MessageRouter.
27
+ * @returns {MessageRouter} The singleton instance.
28
+ */
29
+ static get instance() {
30
+ if (!MessageRouter._instance) {
31
+ MessageRouter._instance = new MessageRouter();
32
+ }
33
+ return MessageRouter._instance;
34
+ }
35
+ /**
36
+ * Subscribe to a message type.
37
+ * @param {string} messageType - The type of message to subscribe to.
38
+ * @param {function} handler - The handler function to call when a message of the specified type is sent.
39
+ */
40
+ subscribe(messageType, handler) {
41
+ return __awaiter(this, void 0, void 0, function* () {
42
+ if (!messageType)
43
+ throw new Error("messageType is required");
44
+ if (typeof handler !== "function")
45
+ throw new Error("handler must be a function");
46
+ yield this._lock.acquireLock();
47
+ try {
48
+ if (!this._subscribers.has(messageType)) {
49
+ this._subscribers.set(messageType, []);
50
+ }
51
+ this._subscribers.get(messageType).push(handler);
52
+ }
53
+ finally {
54
+ this._lock.releaseLock();
55
+ }
56
+ });
57
+ }
58
+ /**
59
+ * Send a message of a specific type.
60
+ * @param {string} messageType - The type of message to send.
61
+ * @param {*} content - The content of the message to send.
62
+ */
63
+ send(messageType, content) {
64
+ return __awaiter(this, void 0, void 0, function* () {
65
+ if (!messageType)
66
+ throw new Error("messageType is required");
67
+ let handlers = null;
68
+ yield this._lock.acquireLock();
69
+ try {
70
+ if (this._subscribers.has(messageType)) {
71
+ // Copy handlers to avoid issues if subscribers change during iteration
72
+ handlers = [...this._subscribers.get(messageType)];
73
+ }
74
+ }
75
+ finally {
76
+ this._lock.releaseLock();
77
+ }
78
+ if (handlers) {
79
+ for (const handler of handlers) {
80
+ try {
81
+ handler(content);
82
+ }
83
+ catch (ex) {
84
+ // Log but don't crash the message pump
85
+ console.debug(`Handler error: ${ex.message}`);
86
+ }
87
+ }
88
+ }
89
+ });
90
+ }
91
+ /**
92
+ * Unsubscribe from a message type.
93
+ * @param {string} messageType - The type of message to unsubscribe from.
94
+ * @param {function} handler - The handler function to remove from the subscribers list.
95
+ */
96
+ unsubscribe(messageType, handler) {
97
+ return __awaiter(this, void 0, void 0, function* () {
98
+ yield this._lock.acquireLock();
99
+ try {
100
+ if (this._subscribers.has(messageType)) {
101
+ const handlers = this._subscribers.get(messageType);
102
+ const index = handlers.indexOf(handler);
103
+ if (index !== -1) {
104
+ handlers.splice(index, 1);
105
+ }
106
+ }
107
+ }
108
+ finally {
109
+ this._lock.releaseLock();
110
+ }
111
+ });
112
+ }
113
+ /**
114
+ * Clear all subscribers for a specific message type.
115
+ * @param {string} messageType - The type of message to clear subscribers for.
116
+ */
117
+ clearSubscribers(messageType) {
118
+ return __awaiter(this, void 0, void 0, function* () {
119
+ yield this._lock.acquireLock();
120
+ try {
121
+ if (this._subscribers.has(messageType)) {
122
+ this._subscribers.get(messageType).length = 0;
123
+ }
124
+ }
125
+ finally {
126
+ this._lock.releaseLock();
127
+ }
128
+ });
129
+ }
130
+ /**
131
+ * Get the total number of subscribers across all message types.
132
+ * @returns {number} The total number of subscribers.
133
+ */
134
+ getSubscriberCount() {
135
+ return __awaiter(this, void 0, void 0, function* () {
136
+ yield this._lock.acquireLock();
137
+ try {
138
+ let count = 0;
139
+ for (const handlers of this._subscribers.values()) {
140
+ count += handlers.length;
141
+ }
142
+ return count;
143
+ }
144
+ finally {
145
+ this._lock.releaseLock();
146
+ }
147
+ });
148
+ }
149
+ }
150
+ exports.MessageRouter = MessageRouter;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageRouter.js","sourceRoot":"","sources":["../MessageRouter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * A simple event scheduler that uses a queue and a spinlock.
3
+ */
4
+ export declare class QueueEventScheduler {
5
+ private _eventQueue;
6
+ private _spinlock;
7
+ /**
8
+ * Schedule an event action to be processed.
9
+ * @param {() => void} eventAction - The event action to be processed.
10
+ */
11
+ scheduleEventAction(eventAction: () => void): Promise<void>;
12
+ /**
13
+ * Process all events in the queue.
14
+ */
15
+ processEvents(): Promise<void>;
16
+ /**
17
+ * Clear all pending events.
18
+ */
19
+ clearEvents(): Promise<void>;
20
+ /**
21
+ * Get the number of pending events.
22
+ * @returns {number} The number of pending events.
23
+ */
24
+ get pendingEventCount(): number;
25
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueueEventScheduler.d.ts","sourceRoot":"","sources":["../QueueEventScheduler.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,qBAAa,mBAAmB;IAC5B,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,SAAS,CAA4B;IAE7C;;;OAGG;IACU,mBAAmB,CAAC,WAAW,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxE;;OAEG;IACU,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAY3C;;OAEG;IACU,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAMzC;;;OAGG;IACH,IAAW,iBAAiB,IAAI,MAAM,CAKrC;CACJ"}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.QueueEventScheduler = void 0;
13
+ const Spinlock_1 = require("./Spinlock");
14
+ /**
15
+ * A simple event scheduler that uses a queue and a spinlock.
16
+ */
17
+ class QueueEventScheduler {
18
+ constructor() {
19
+ this._eventQueue = [];
20
+ this._spinlock = new Spinlock_1.Spinlock();
21
+ }
22
+ /**
23
+ * Schedule an event action to be processed.
24
+ * @param {() => void} eventAction - The event action to be processed.
25
+ */
26
+ scheduleEventAction(eventAction) {
27
+ return __awaiter(this, void 0, void 0, function* () {
28
+ yield this._spinlock.acquireLock();
29
+ this._eventQueue.push(eventAction);
30
+ this._spinlock.releaseLock();
31
+ });
32
+ }
33
+ /**
34
+ * Process all events in the queue.
35
+ */
36
+ processEvents() {
37
+ return __awaiter(this, void 0, void 0, function* () {
38
+ if (this._eventQueue.length === 0) {
39
+ return;
40
+ }
41
+ yield this._spinlock.acquireLock();
42
+ while (this._eventQueue.length > 0) {
43
+ const event = this._eventQueue.shift();
44
+ event();
45
+ }
46
+ this._spinlock.releaseLock();
47
+ });
48
+ }
49
+ /**
50
+ * Clear all pending events.
51
+ */
52
+ clearEvents() {
53
+ return __awaiter(this, void 0, void 0, function* () {
54
+ yield this._spinlock.acquireLock();
55
+ this._eventQueue = [];
56
+ this._spinlock.releaseLock();
57
+ });
58
+ }
59
+ /**
60
+ * Get the number of pending events.
61
+ * @returns {number} The number of pending events.
62
+ */
63
+ get pendingEventCount() {
64
+ this._spinlock.acquireLock();
65
+ const count = this._eventQueue.length;
66
+ this._spinlock.releaseLock();
67
+ return count;
68
+ }
69
+ }
70
+ exports.QueueEventScheduler = QueueEventScheduler;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QueueEventScheduler.js","sourceRoot":"","sources":["../QueueEventScheduler.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,yCAAsC;AAEtC;;GAEG;AACH,MAAa,mBAAmB;IAAhC;QACY,gBAAW,GAAmB,EAAE,CAAC;QACjC,cAAS,GAAa,IAAI,mBAAQ,EAAE,CAAC;IA8CjD,CAAC;IA5CG;;;OAGG;IACU,mBAAmB,CAAC,WAAuB;;YACpD,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;YACnC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACnC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;QACjC,CAAC;KAAA;IAED;;OAEG;IACU,aAAa;;YACtB,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAChC,OAAO;YACX,CAAC;YACD,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;YACnC,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACjC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,EAAG,CAAC;gBACxC,KAAK,EAAE,CAAC;YACZ,CAAC;YACD,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;QACjC,CAAC;KAAA;IAED;;OAEG;IACU,WAAW;;YACpB,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;YACnC,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC;YACtB,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;QACjC,CAAC;KAAA;IAED;;;OAGG;IACH,IAAW,iBAAiB;QACxB,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC;QACtC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC;IACjB,CAAC;CACJ;AAhDD,kDAgDC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * A simple mutex/lock implementation using a queue.
3
+ */
4
+ export declare class Spinlock {
5
+ private locked;
6
+ private waitingQueue;
7
+ /**
8
+ * Acquire the lock. If the lock is already held, queue the request.
9
+ */
10
+ acquireLock(): Promise<void>;
11
+ /**
12
+ * Release the lock. If there are waiting acquisitions, pass the lock to the next in line.
13
+ */
14
+ releaseLock(): void;
15
+ /**
16
+ * Check if the lock is currently held.
17
+ */
18
+ get isLocked(): boolean;
19
+ /**
20
+ * Get the number of waiters.
21
+ */
22
+ get waiterCount(): number;
23
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Spinlock.d.ts","sourceRoot":"","sources":["../Spinlock.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,QAAQ;IACjB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,YAAY,CAAyB;IAE7C;;OAEG;IACU,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAazC;;OAEG;IACI,WAAW,IAAI,IAAI;IAiB1B;;OAEG;IACH,IAAW,QAAQ,IAAI,OAAO,CAE7B;IAED;;OAEG;IACH,IAAW,WAAW,IAAI,MAAM,CAE/B;CACJ"}
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.Spinlock = void 0;
13
+ /**
14
+ * A simple mutex/lock implementation using a queue.
15
+ */
16
+ class Spinlock {
17
+ constructor() {
18
+ this.locked = false;
19
+ this.waitingQueue = [];
20
+ }
21
+ /**
22
+ * Acquire the lock. If the lock is already held, queue the request.
23
+ */
24
+ acquireLock() {
25
+ return __awaiter(this, void 0, void 0, function* () {
26
+ // If lock is free, acquire it immediately
27
+ if (!this.locked) {
28
+ this.locked = true;
29
+ return Promise.resolve();
30
+ }
31
+ // Otherwise, queue this request
32
+ return new Promise(resolve => {
33
+ this.waitingQueue.push(resolve);
34
+ });
35
+ });
36
+ }
37
+ /**
38
+ * Release the lock. If there are waiting acquisitions, pass the lock to the next in line.
39
+ */
40
+ releaseLock() {
41
+ if (!this.locked && this.waitingQueue.length === 0) {
42
+ throw new Error("Lock is not held.");
43
+ }
44
+ // If there are waiting acquisitions, pass the lock to the next one
45
+ if (this.waitingQueue.length > 0) {
46
+ const nextResolve = this.waitingQueue.shift();
47
+ // The lock remains locked, but now the next waiter has it
48
+ // We don't set locked = false because it's immediately re-acquired
49
+ nextResolve();
50
+ }
51
+ else {
52
+ // No waiters, release the lock
53
+ this.locked = false;
54
+ }
55
+ }
56
+ /**
57
+ * Check if the lock is currently held.
58
+ */
59
+ get isLocked() {
60
+ return this.locked;
61
+ }
62
+ /**
63
+ * Get the number of waiters.
64
+ */
65
+ get waiterCount() {
66
+ return this.waitingQueue.length;
67
+ }
68
+ }
69
+ exports.Spinlock = Spinlock;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Spinlock.js","sourceRoot":"","sources":["../Spinlock.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA;;GAEG;AACH,MAAa,QAAQ;IAArB;QACY,WAAM,GAAY,KAAK,CAAC;QACxB,iBAAY,GAAsB,EAAE,CAAC;IAmDjD,CAAC;IAjDG;;OAEG;IACU,WAAW;;YACpB,0CAA0C;YAC1C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACf,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;gBACnB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;YAC7B,CAAC;YAED,gCAAgC;YAChC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;gBACzB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACpC,CAAC,CAAC,CAAC;QACP,CAAC;KAAA;IAED;;OAEG;IACI,WAAW;QACd,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjD,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACzC,CAAC;QAED,mEAAmE;QACnE,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,EAAG,CAAC;YAC/C,0DAA0D;YAC1D,mEAAmE;YACnE,WAAW,EAAE,CAAC;QAClB,CAAC;aAAM,CAAC;YACJ,+BAA+B;YAC/B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACxB,CAAC;IACL,CAAC;IAED;;OAEG;IACH,IAAW,QAAQ;QACf,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,IAAW,WAAW;QAClB,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC;IACpC,CAAC;CACJ;AArDD,4BAqDC"}
@@ -0,0 +1,4 @@
1
+ export * from './BasicEventModel';
2
+ export * from './MessageRouter';
3
+ export * from './QueueEventScheduler';
4
+ export * from './Spinlock';
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./BasicEventModel"), exports);
18
+ __exportStar(require("./MessageRouter"), exports);
19
+ __exportStar(require("./QueueEventScheduler"), exports);
20
+ __exportStar(require("./Spinlock"), exports);
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oDAAkC;AAClC,kDAAgC;AAChC,wDAAsC;AACtC,6CAA2B"}
package/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * from './BasicEventModel';
2
+ export * from './MessageRouter';
3
+ export * from './QueueEventScheduler';
4
+ export * from './Spinlock';
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "vbstyle-event-models",
3
+ "version": "1.0.0",
4
+ "description": "A TypeScript library providing event models, message routing, and event scheduling utilities with thread safety",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc"
9
+ },
10
+ "keywords": [
11
+ "events",
12
+ "event-model",
13
+ "message-router",
14
+ "event-scheduler",
15
+ "spinlock",
16
+ "typescript"
17
+ ],
18
+ "author": "pac-dessert1436",
19
+ "license": "BSD-3-Clause",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/yourusername/vbstyle-event-models.git"
23
+ },
24
+ "homepage": "https://github.com/yourusername/vbstyle-event-models#readme",
25
+ "dependencies": {
26
+ "typescript": "^5.9.3"
27
+ }
28
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2016",
4
+ "module": "CommonJS",
5
+ "outDir": "./dist",
6
+ "rootDir": "./",
7
+ "declaration": true,
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true
12
+ },
13
+ "include": [
14
+ "*.ts"
15
+ ],
16
+ "exclude": [
17
+ "node_modules",
18
+ "dist"
19
+ ]
20
+ }