najm-event 0.1.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.
- package/README.md +48 -0
- package/dist/index.d.ts +68 -0
- package/dist/index.mjs +315 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# najm-events
|
|
2
|
+
|
|
3
|
+
Optional events (event bus) plugin for Najm framework with decorator-based event handling and async event emission.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun install najm-events
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { On, Events } from 'najm-events';
|
|
15
|
+
|
|
16
|
+
// Listen to events with the @On decorator
|
|
17
|
+
@Service()
|
|
18
|
+
class UserService {
|
|
19
|
+
@On('user.created')
|
|
20
|
+
async handleUserCreated(data: any) {
|
|
21
|
+
console.log('User created:', data);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Inject event methods using @Events decorator
|
|
26
|
+
@Controller('/api/users')
|
|
27
|
+
class UserController {
|
|
28
|
+
@Events() private events!: any;
|
|
29
|
+
|
|
30
|
+
@Post('/create')
|
|
31
|
+
async createUser(@Body() userData: any) {
|
|
32
|
+
// Create user logic here
|
|
33
|
+
const user = await this.userService.create(userData);
|
|
34
|
+
|
|
35
|
+
// Emit event
|
|
36
|
+
this.events.emit('user.created', user);
|
|
37
|
+
|
|
38
|
+
return user;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Features
|
|
44
|
+
|
|
45
|
+
- Decorator-based event handling with `@On()` and `@Events()`
|
|
46
|
+
- Async event emission with error handling
|
|
47
|
+
- Integration with Najm's DI system
|
|
48
|
+
- Event statistics and management
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { InjectionDefinition, Constructor } from 'diject';
|
|
2
|
+
import * as najm_core from 'najm-core';
|
|
3
|
+
import { Constructor as Constructor$1 } from 'najm-core';
|
|
4
|
+
import * as mitt from 'mitt';
|
|
5
|
+
import { Handler } from 'mitt';
|
|
6
|
+
|
|
7
|
+
interface EventEmitter {
|
|
8
|
+
emit<T = any>(event: string, data?: T): void;
|
|
9
|
+
emitAsync<T = any>(event: string, data?: T): Promise<void>;
|
|
10
|
+
on<T = any>(event: string, handler: (data: T) => void): void;
|
|
11
|
+
off<T = any>(event: string, handler?: (data: T) => void): void;
|
|
12
|
+
once<T = any>(event: string, handler: (data: T) => void): void;
|
|
13
|
+
hasListeners(event: string): boolean;
|
|
14
|
+
listenerCount(event: string): number;
|
|
15
|
+
eventNames(): string[];
|
|
16
|
+
all(): any;
|
|
17
|
+
}
|
|
18
|
+
interface EventRegistration extends InjectionDefinition {
|
|
19
|
+
type: 'event';
|
|
20
|
+
target: Constructor;
|
|
21
|
+
eventName: string;
|
|
22
|
+
methodName: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
declare const EVENTS_META: unique symbol;
|
|
26
|
+
declare const EVENT_CONFIG: unique symbol;
|
|
27
|
+
|
|
28
|
+
declare function Events(): any;
|
|
29
|
+
declare function On(eventName: string): MethodDecorator;
|
|
30
|
+
declare const getEventListeners: (t: any) => any;
|
|
31
|
+
|
|
32
|
+
declare const events: () => najm_core.NajmPlugin;
|
|
33
|
+
|
|
34
|
+
declare class EventService {
|
|
35
|
+
private container;
|
|
36
|
+
private scanner;
|
|
37
|
+
private log;
|
|
38
|
+
private emitter;
|
|
39
|
+
private eventHandlers;
|
|
40
|
+
scan(): Promise<void>;
|
|
41
|
+
private setupEventsGetter;
|
|
42
|
+
configure(): Promise<void>;
|
|
43
|
+
private registerInjectors;
|
|
44
|
+
activate(): Promise<void>;
|
|
45
|
+
private registerEventHandler;
|
|
46
|
+
onReady(): Promise<void>;
|
|
47
|
+
emit<T = any>(event: string, data?: T): void;
|
|
48
|
+
emitAsync<T = any>(event: string, data?: T): Promise<void>;
|
|
49
|
+
on<T = any>(event: string, handler: Handler<T>): void;
|
|
50
|
+
off<T = any>(event: string, handler?: Handler<T>): void;
|
|
51
|
+
once<T = any>(event: string, handler: Handler<T>): void;
|
|
52
|
+
hasListeners(event: string): boolean;
|
|
53
|
+
listenerCount(event: string): number;
|
|
54
|
+
eventNames(): string[];
|
|
55
|
+
all(): mitt.EventHandlerMap<any>;
|
|
56
|
+
registerProviderEvents(provider: Constructor$1): Promise<void>;
|
|
57
|
+
unregisterProviderEvents(provider: Constructor$1): void;
|
|
58
|
+
clear(): void;
|
|
59
|
+
getStats(): {
|
|
60
|
+
totalProviders: number;
|
|
61
|
+
totalHandlers: number;
|
|
62
|
+
providers: string[];
|
|
63
|
+
events: string[];
|
|
64
|
+
eventCounts: Record<string, number>;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export { EVENTS_META, EVENT_CONFIG, type EventEmitter, type EventRegistration, EventService, Events, On, events, getEventListeners };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
|
|
4
|
+
// src/tokens.ts
|
|
5
|
+
var EVENTS_META = /* @__PURE__ */ Symbol("events");
|
|
6
|
+
var EVENT_CONFIG = /* @__PURE__ */ Symbol("event:config");
|
|
7
|
+
|
|
8
|
+
// src/decorator.ts
|
|
9
|
+
import { INJECT_PROPS, MetaHelper } from "najm-core";
|
|
10
|
+
function Events() {
|
|
11
|
+
return (target, propertyKey) => {
|
|
12
|
+
MetaHelper.append(INJECT_PROPS, {
|
|
13
|
+
propertyKey,
|
|
14
|
+
token: "EventsMethods"
|
|
15
|
+
}, target.constructor);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
__name(Events, "Events");
|
|
19
|
+
function On(eventName) {
|
|
20
|
+
return (target, method) => {
|
|
21
|
+
MetaHelper.append(EVENTS_META, { eventName, methodName: method }, target.constructor);
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
__name(On, "On");
|
|
25
|
+
var getEventListeners = /* @__PURE__ */ __name((t) => MetaHelper.get(EVENTS_META, t) ?? [], "getEventListeners");
|
|
26
|
+
|
|
27
|
+
// src/EventPlugin.ts
|
|
28
|
+
import { plugin } from "najm-core";
|
|
29
|
+
|
|
30
|
+
// src/EventService.ts
|
|
31
|
+
import mitt from "mitt";
|
|
32
|
+
import { LoggerService, Scan, ScannerService, ScanType, INJECTION_TYPES } from "najm-core";
|
|
33
|
+
import { Meta, Container, Inject, getPropertyInjections, DI, Service } from "najm-core";
|
|
34
|
+
var __decorate = function(decorators, target, key, desc) {
|
|
35
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
36
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
37
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
38
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
39
|
+
};
|
|
40
|
+
var __metadata = function(k, v) {
|
|
41
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
42
|
+
};
|
|
43
|
+
var _a;
|
|
44
|
+
var _b;
|
|
45
|
+
var _c;
|
|
46
|
+
var EventService = class EventService2 {
|
|
47
|
+
static {
|
|
48
|
+
__name(this, "EventService");
|
|
49
|
+
}
|
|
50
|
+
container;
|
|
51
|
+
scanner;
|
|
52
|
+
log;
|
|
53
|
+
emitter;
|
|
54
|
+
eventHandlers = /* @__PURE__ */ new Map();
|
|
55
|
+
// ============================================================================
|
|
56
|
+
// LIFECYCLE: SCAN
|
|
57
|
+
// ============================================================================
|
|
58
|
+
async scan() {
|
|
59
|
+
this.emitter = mitt();
|
|
60
|
+
this.scanner.scan(ScanType.APP, {
|
|
61
|
+
onClass: /* @__PURE__ */ __name((provider) => {
|
|
62
|
+
const listeners = getEventListeners(provider);
|
|
63
|
+
for (const { eventName, methodName } of listeners) {
|
|
64
|
+
this.container.setInjection({
|
|
65
|
+
type: INJECTION_TYPES.EVENT,
|
|
66
|
+
target: provider,
|
|
67
|
+
eventName,
|
|
68
|
+
methodName
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
const propInjections = getPropertyInjections(provider);
|
|
72
|
+
const eventsInjections = propInjections.filter((inj) => inj.token === "EventsMethods");
|
|
73
|
+
for (const injection of eventsInjections) {
|
|
74
|
+
this.setupEventsGetter(provider, injection.propertyKey);
|
|
75
|
+
}
|
|
76
|
+
}, "onClass")
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
setupEventsGetter(provider, propertyKey) {
|
|
80
|
+
const eventService = this;
|
|
81
|
+
const createEventsMethods = /* @__PURE__ */ __name(() => ({
|
|
82
|
+
emit: eventService.emit.bind(eventService),
|
|
83
|
+
emitAsync: eventService.emitAsync.bind(eventService),
|
|
84
|
+
on: eventService.on.bind(eventService),
|
|
85
|
+
off: eventService.off.bind(eventService),
|
|
86
|
+
once: eventService.once.bind(eventService),
|
|
87
|
+
hasListeners: eventService.hasListeners.bind(eventService),
|
|
88
|
+
listenerCount: eventService.listenerCount.bind(eventService),
|
|
89
|
+
eventNames: eventService.eventNames.bind(eventService),
|
|
90
|
+
all: eventService.all.bind(eventService)
|
|
91
|
+
}), "createEventsMethods");
|
|
92
|
+
const instanceCache = /* @__PURE__ */ new WeakMap();
|
|
93
|
+
Object.defineProperty(provider.prototype, propertyKey, {
|
|
94
|
+
configurable: true,
|
|
95
|
+
enumerable: true,
|
|
96
|
+
get() {
|
|
97
|
+
let methods = instanceCache.get(this);
|
|
98
|
+
if (!methods) {
|
|
99
|
+
methods = createEventsMethods();
|
|
100
|
+
instanceCache.set(this, methods);
|
|
101
|
+
}
|
|
102
|
+
return methods;
|
|
103
|
+
},
|
|
104
|
+
set(value) {
|
|
105
|
+
Object.defineProperty(this, propertyKey, {
|
|
106
|
+
configurable: true,
|
|
107
|
+
enumerable: true,
|
|
108
|
+
writable: true,
|
|
109
|
+
value
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
// ============================================================================
|
|
115
|
+
// LIFECYCLE: CONFIGURE
|
|
116
|
+
// ============================================================================
|
|
117
|
+
async configure() {
|
|
118
|
+
this.registerInjectors();
|
|
119
|
+
}
|
|
120
|
+
registerInjectors() {
|
|
121
|
+
this.container.use({
|
|
122
|
+
name: "Events",
|
|
123
|
+
global: true,
|
|
124
|
+
inject: /* @__PURE__ */ __name((instance) => {
|
|
125
|
+
instance.events = this;
|
|
126
|
+
}, "inject")
|
|
127
|
+
});
|
|
128
|
+
this.container.use({
|
|
129
|
+
name: "EventsMethods",
|
|
130
|
+
global: true,
|
|
131
|
+
inject: /* @__PURE__ */ __name((instance, _ctor, _registry, injections) => {
|
|
132
|
+
if (!injections)
|
|
133
|
+
return;
|
|
134
|
+
const eventsInjections = injections.filter((inj) => inj.token === "EventsMethods");
|
|
135
|
+
for (const injection of eventsInjections) {
|
|
136
|
+
const { propertyKey } = injection;
|
|
137
|
+
instance[propertyKey] = {
|
|
138
|
+
emit: this.emit.bind(this),
|
|
139
|
+
emitAsync: this.emitAsync.bind(this),
|
|
140
|
+
on: this.on.bind(this),
|
|
141
|
+
off: this.off.bind(this),
|
|
142
|
+
once: this.once.bind(this),
|
|
143
|
+
hasListeners: this.hasListeners.bind(this),
|
|
144
|
+
listenerCount: this.listenerCount.bind(this),
|
|
145
|
+
eventNames: this.eventNames.bind(this),
|
|
146
|
+
all: this.all.bind(this)
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
}, "inject")
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
// ============================================================================
|
|
153
|
+
// LIFECYCLE: ACTIVATE
|
|
154
|
+
// ============================================================================
|
|
155
|
+
async activate() {
|
|
156
|
+
const registrations = this.container.getInjections(INJECTION_TYPES.EVENT);
|
|
157
|
+
const providersWithHandlers = new Set(registrations.map((r) => r.target));
|
|
158
|
+
for (const provider of providersWithHandlers) {
|
|
159
|
+
await this.container.resolve(provider);
|
|
160
|
+
}
|
|
161
|
+
for (const registration of registrations) {
|
|
162
|
+
await this.registerEventHandler(registration);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async registerEventHandler(registration) {
|
|
166
|
+
const { target, eventName, methodName } = registration;
|
|
167
|
+
if (!this.eventHandlers.has(target)) {
|
|
168
|
+
this.eventHandlers.set(target, []);
|
|
169
|
+
}
|
|
170
|
+
const instance = await this.container.resolve(target);
|
|
171
|
+
const handler = /* @__PURE__ */ __name(async (data) => {
|
|
172
|
+
return instance[methodName]?.(data);
|
|
173
|
+
}, "handler");
|
|
174
|
+
this.on(eventName, handler);
|
|
175
|
+
this.eventHandlers.get(target).push({ eventName, handler });
|
|
176
|
+
}
|
|
177
|
+
// ============================================================================
|
|
178
|
+
// LIFECYCLE: READY
|
|
179
|
+
// ============================================================================
|
|
180
|
+
async onReady() {
|
|
181
|
+
const count = this.container.getInjections(INJECTION_TYPES.EVENT).length;
|
|
182
|
+
this.log.info(`Event plugin ready: ${count} handler(s) registered`);
|
|
183
|
+
}
|
|
184
|
+
// ============================================================================
|
|
185
|
+
// EVENT EMITTER API
|
|
186
|
+
// ============================================================================
|
|
187
|
+
emit(event, data) {
|
|
188
|
+
this.emitter.emit(event, data);
|
|
189
|
+
}
|
|
190
|
+
async emitAsync(event, data) {
|
|
191
|
+
const handlers = this.emitter.all.get(event);
|
|
192
|
+
if (!handlers || handlers.size === 0)
|
|
193
|
+
return;
|
|
194
|
+
const results = await Promise.allSettled([...handlers].map((h) => Promise.resolve(h(data))));
|
|
195
|
+
const errors = results.filter((r) => r.status === "rejected").map((r) => r.reason);
|
|
196
|
+
if (errors.length > 0) {
|
|
197
|
+
const errorMessage = `${errors.length} handler(s) failed for event "${event}"`;
|
|
198
|
+
this.log.error(errorMessage, errors[0], { event, failedHandlers: errors.length });
|
|
199
|
+
throw new AggregateError(errors, errorMessage);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
on(event, handler) {
|
|
203
|
+
this.emitter.on(event, handler);
|
|
204
|
+
}
|
|
205
|
+
off(event, handler) {
|
|
206
|
+
if (handler) {
|
|
207
|
+
this.emitter.off(event, handler);
|
|
208
|
+
} else {
|
|
209
|
+
this.emitter.all.delete(event);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
once(event, handler) {
|
|
213
|
+
const onceHandler = /* @__PURE__ */ __name((data) => {
|
|
214
|
+
this.off(event, onceHandler);
|
|
215
|
+
handler(data);
|
|
216
|
+
}, "onceHandler");
|
|
217
|
+
this.on(event, onceHandler);
|
|
218
|
+
}
|
|
219
|
+
hasListeners(event) {
|
|
220
|
+
const handlers = this.emitter.all.get(event);
|
|
221
|
+
return handlers ? handlers.length > 0 : false;
|
|
222
|
+
}
|
|
223
|
+
listenerCount(event) {
|
|
224
|
+
const handlers = this.emitter.all.get(event);
|
|
225
|
+
return handlers ? handlers.length : 0;
|
|
226
|
+
}
|
|
227
|
+
eventNames() {
|
|
228
|
+
return Array.from(this.emitter.all.keys());
|
|
229
|
+
}
|
|
230
|
+
all() {
|
|
231
|
+
return this.emitter.all;
|
|
232
|
+
}
|
|
233
|
+
// ============================================================================
|
|
234
|
+
// DYNAMIC REGISTRATION
|
|
235
|
+
// ============================================================================
|
|
236
|
+
async registerProviderEvents(provider) {
|
|
237
|
+
if (this.eventHandlers.has(provider))
|
|
238
|
+
return;
|
|
239
|
+
const listeners = getEventListeners(provider);
|
|
240
|
+
if (listeners.length === 0)
|
|
241
|
+
return;
|
|
242
|
+
const instance = await this.container.resolve(provider);
|
|
243
|
+
const handlers = [];
|
|
244
|
+
for (const { eventName, methodName } of listeners) {
|
|
245
|
+
const handler = /* @__PURE__ */ __name(async (data) => {
|
|
246
|
+
return instance[methodName]?.(data);
|
|
247
|
+
}, "handler");
|
|
248
|
+
this.on(eventName, handler);
|
|
249
|
+
handlers.push({ eventName, handler });
|
|
250
|
+
}
|
|
251
|
+
this.eventHandlers.set(provider, handlers);
|
|
252
|
+
}
|
|
253
|
+
unregisterProviderEvents(provider) {
|
|
254
|
+
const handlers = this.eventHandlers.get(provider);
|
|
255
|
+
if (!handlers)
|
|
256
|
+
return;
|
|
257
|
+
for (const { eventName, handler } of handlers) {
|
|
258
|
+
this.emitter.off(eventName, handler);
|
|
259
|
+
}
|
|
260
|
+
this.eventHandlers.delete(provider);
|
|
261
|
+
}
|
|
262
|
+
// ============================================================================
|
|
263
|
+
// UTILITIES
|
|
264
|
+
// ============================================================================
|
|
265
|
+
clear() {
|
|
266
|
+
this.eventHandlers.clear();
|
|
267
|
+
this.emitter.all.clear();
|
|
268
|
+
}
|
|
269
|
+
getStats() {
|
|
270
|
+
const events2 = this.eventNames();
|
|
271
|
+
const eventCounts = {};
|
|
272
|
+
for (const event of events2) {
|
|
273
|
+
const count = this.listenerCount(event);
|
|
274
|
+
if (count > 0) {
|
|
275
|
+
eventCounts[event] = count;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
const totalHandlers = Array.from(this.eventHandlers.values()).reduce((sum, handlers) => sum + handlers.length, 0);
|
|
279
|
+
return {
|
|
280
|
+
totalProviders: this.eventHandlers.size,
|
|
281
|
+
totalHandlers,
|
|
282
|
+
providers: Array.from(this.eventHandlers.keys()).map((p) => p.name),
|
|
283
|
+
events: events2,
|
|
284
|
+
eventCounts
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
__decorate([
|
|
289
|
+
DI(),
|
|
290
|
+
__metadata("design:type", typeof (_a = typeof Container !== "undefined" && Container) === "function" ? _a : Object)
|
|
291
|
+
], EventService.prototype, "container", void 0);
|
|
292
|
+
__decorate([
|
|
293
|
+
Scan(),
|
|
294
|
+
__metadata("design:type", typeof (_b = typeof ScannerService !== "undefined" && ScannerService) === "function" ? _b : Object)
|
|
295
|
+
], EventService.prototype, "scanner", void 0);
|
|
296
|
+
__decorate([
|
|
297
|
+
Inject(LoggerService),
|
|
298
|
+
__metadata("design:type", typeof (_c = typeof LoggerService !== "undefined" && LoggerService) === "function" ? _c : Object)
|
|
299
|
+
], EventService.prototype, "log", void 0);
|
|
300
|
+
EventService = __decorate([
|
|
301
|
+
Service(),
|
|
302
|
+
Meta({ layer: "plugin" })
|
|
303
|
+
], EventService);
|
|
304
|
+
|
|
305
|
+
// src/EventPlugin.ts
|
|
306
|
+
var events = /* @__PURE__ */ __name(() => plugin("events").services(EventService).build(), "events");
|
|
307
|
+
export {
|
|
308
|
+
EVENTS_META,
|
|
309
|
+
EVENT_CONFIG,
|
|
310
|
+
EventService,
|
|
311
|
+
Events,
|
|
312
|
+
On,
|
|
313
|
+
events,
|
|
314
|
+
getEventListeners
|
|
315
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "najm-event",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Event .",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"main": "./dist/index.mjs",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"bun": "./src/index.ts",
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.mjs",
|
|
16
|
+
"default": "./dist/index.mjs"
|
|
17
|
+
},
|
|
18
|
+
"./*": {
|
|
19
|
+
"bun": "./src/*.ts",
|
|
20
|
+
"types": "./src/*.ts",
|
|
21
|
+
"import": "./src/*.ts",
|
|
22
|
+
"default": "./src/*.ts"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsup",
|
|
27
|
+
"test": "bun test",
|
|
28
|
+
"test:watch": "bun test --watch",
|
|
29
|
+
"start": "bun --watch src/main.ts",
|
|
30
|
+
"clean": "rimraf dist tsconfig.tsbuildinfo"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"typescript": "^5.7.3",
|
|
34
|
+
"rimraf": "^6.0.1"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"mitt": "^3.0.1"
|
|
38
|
+
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"najm-core": "^0.1.1",
|
|
41
|
+
"reflect-metadata": "^0.2.0"
|
|
42
|
+
}
|
|
43
|
+
}
|