@rudderjs/core 0.0.8

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/di.js ADDED
@@ -0,0 +1,228 @@
1
+ import 'reflect-metadata';
2
+ let _AsyncLocalStorage;
3
+ if (typeof globalThis.process !== 'undefined') {
4
+ import(/* @vite-ignore */ 'node:async_hooks').then(m => { _AsyncLocalStorage = m.AsyncLocalStorage; }).catch(() => { });
5
+ }
6
+ // ─── Decorators ────────────────────────────────────────────
7
+ const INJECTABLE_METADATA = 'rudderjs:injectable';
8
+ const INJECT_METADATA = 'rudderjs:inject';
9
+ /** Mark a class as injectable (auto-resolved by the container) */
10
+ export function Injectable() {
11
+ return target => {
12
+ Reflect.defineMetadata(INJECTABLE_METADATA, true, target);
13
+ };
14
+ }
15
+ /** Inject a specific token into a constructor parameter */
16
+ export function Inject(token) {
17
+ return (target, _, index) => {
18
+ const existing = Reflect.getMetadata(INJECT_METADATA, target) ?? [];
19
+ Reflect.defineMetadata(INJECT_METADATA, [...existing, { index, token }], target);
20
+ };
21
+ }
22
+ // ─── Container ─────────────────────────────────────────────
23
+ export class Container {
24
+ bindings = new Map();
25
+ instances = new Map();
26
+ aliases = new Map();
27
+ // ── Scoped bindings (per-request via ALS) ─────────────────
28
+ // Lazy-initialized so the class can be loaded in the browser bundle without
29
+ // triggering a node:async_hooks import error.
30
+ _scopeAlsInstance = null;
31
+ get _scopeAls() {
32
+ if (!this._scopeAlsInstance) {
33
+ if (!_AsyncLocalStorage) {
34
+ throw new Error('[RudderJS] AsyncLocalStorage is not available — runScoped() and scoped bindings require Node.js (node:async_hooks).');
35
+ }
36
+ this._scopeAlsInstance = new _AsyncLocalStorage();
37
+ }
38
+ return this._scopeAlsInstance;
39
+ }
40
+ // ── Contextual bindings ───────────────────────────────────
41
+ _contextual = new Map();
42
+ // ── Missing handler (for deferred providers) ──────────────
43
+ _missingHandler = null;
44
+ reset() {
45
+ this.bindings.clear();
46
+ this.instances.clear();
47
+ this.aliases.clear();
48
+ this._contextual.clear();
49
+ this._missingHandler = null;
50
+ return this;
51
+ }
52
+ bind(token, factory) {
53
+ this.bindings.set(this.toToken(token), { factory, singleton: false });
54
+ return this;
55
+ }
56
+ singleton(token, factory) {
57
+ this.bindings.set(this.toToken(token), { factory, singleton: true });
58
+ return this;
59
+ }
60
+ /**
61
+ * Register a scoped binding — like singleton but per-request.
62
+ * The factory runs once per `runScoped()` call and is cached for that scope.
63
+ */
64
+ scoped(token, factory) {
65
+ this.bindings.set(this.toToken(token), { factory, singleton: false, scoped: true });
66
+ return this;
67
+ }
68
+ /**
69
+ * Execute `fn` inside a fresh scope. Scoped bindings resolved within
70
+ * this call are cached and automatically discarded when `fn` completes.
71
+ */
72
+ runScoped(fn) {
73
+ return this._scopeAls.run(new Map(), fn);
74
+ }
75
+ instance(token, value) {
76
+ const key = this.toToken(token);
77
+ this.instances.set(key, value);
78
+ return this;
79
+ }
80
+ alias(from, to) {
81
+ this.aliases.set(from, to);
82
+ return this;
83
+ }
84
+ make(token) {
85
+ const key = this.resolveAlias(this.toToken(token));
86
+ if (this.instances.has(key)) {
87
+ return this.instances.get(key);
88
+ }
89
+ const binding = this.bindings.get(key);
90
+ if (binding) {
91
+ // Scoped binding: cache per-request in ALS store
92
+ if (binding.scoped) {
93
+ const scope = this._scopeAls.getStore();
94
+ if (!scope) {
95
+ throw new Error(`[RudderJS] Cannot resolve scoped binding outside of a request scope.\n` +
96
+ ` Wrap the call in container.runScoped() or add ScopeMiddleware().`);
97
+ }
98
+ if (scope.has(key))
99
+ return scope.get(key);
100
+ const value = binding.factory(this);
101
+ scope.set(key, value);
102
+ return value;
103
+ }
104
+ const value = binding.factory(this);
105
+ if (binding.singleton)
106
+ this.instances.set(key, value);
107
+ return value;
108
+ }
109
+ if (typeof token === 'function') {
110
+ return this.autoResolve(token);
111
+ }
112
+ // Deferred provider hook — give the missing handler a chance to register the binding
113
+ if (this._missingHandler) {
114
+ this._missingHandler(key);
115
+ // Retry after handler may have registered the binding
116
+ if (this.instances.has(key))
117
+ return this.instances.get(key);
118
+ const retryBinding = this.bindings.get(key);
119
+ if (retryBinding) {
120
+ const value = retryBinding.factory(this);
121
+ if (retryBinding.singleton)
122
+ this.instances.set(key, value);
123
+ return value;
124
+ }
125
+ }
126
+ const label = typeof key === 'symbol' ? key.toString() : `"${String(key)}"`;
127
+ throw new Error(`[RudderJS] Cannot resolve ${label} from the DI container.\n` +
128
+ ` Did you forget to add @Injectable() to the class, or register it in a ServiceProvider?`);
129
+ }
130
+ has(token) {
131
+ const key = this.resolveAlias(this.toToken(token));
132
+ return this.bindings.has(key) || this.instances.has(key);
133
+ }
134
+ forget(token) {
135
+ const key = this.toToken(token);
136
+ this.bindings.delete(key);
137
+ this.instances.delete(key);
138
+ return this;
139
+ }
140
+ /**
141
+ * Set a handler called when `make()` cannot find a binding.
142
+ * Used by Application to lazily boot deferred providers.
143
+ */
144
+ setMissingHandler(fn) {
145
+ this._missingHandler = fn;
146
+ return this;
147
+ }
148
+ /**
149
+ * Contextual binding — when resolving `concrete`, override a dependency.
150
+ *
151
+ * @example
152
+ * container.when(PhotoController).needs('storage').give(() => new S3Storage())
153
+ */
154
+ when(concrete) {
155
+ return new ContextualBindingBuilder(this, concrete);
156
+ }
157
+ /** @internal — called by ContextualBindingBuilder */
158
+ _addContextualBinding(concrete, need, factory) {
159
+ const name = this.toToken(concrete);
160
+ let map = this._contextual.get(name);
161
+ if (!map) {
162
+ map = new Map();
163
+ this._contextual.set(name, map);
164
+ }
165
+ map.set(need, factory);
166
+ }
167
+ autoResolve(target) {
168
+ if (typeof Reflect === 'undefined' || typeof Reflect.getMetadata !== 'function') {
169
+ throw new Error(`[RudderJS] reflect-metadata is not loaded.\n` +
170
+ ` Add: import 'reflect-metadata' at the top of your bootstrap/app.ts`);
171
+ }
172
+ const isInjectable = Reflect.getMetadata(INJECTABLE_METADATA, target);
173
+ if (!isInjectable) {
174
+ throw new Error(`[RudderJS] "${target.name}" is not decorated with @Injectable().\n` +
175
+ ` Add @Injectable() above the class declaration to enable auto-resolution.`);
176
+ }
177
+ const paramTypes = Reflect.getMetadata('design:paramtypes', target) ?? [];
178
+ const tokenOverrides = Reflect.getMetadata(INJECT_METADATA, target) ?? [];
179
+ // Check contextual bindings for this target class
180
+ const ctxMap = this._contextual.get(target.name);
181
+ const args = paramTypes.map((type, i) => {
182
+ const override = tokenOverrides.find(o => o.index === i);
183
+ const needToken = override ? override.token : this.toToken(type);
184
+ // Contextual override takes priority
185
+ if (ctxMap) {
186
+ const ctxFactory = ctxMap.get(needToken);
187
+ if (ctxFactory)
188
+ return ctxFactory(this);
189
+ }
190
+ return override ? this.make(override.token) : this.make(type);
191
+ });
192
+ return new target(...args);
193
+ }
194
+ toToken(token) {
195
+ return typeof token === 'function' ? token.name : token;
196
+ }
197
+ resolveAlias(key) {
198
+ if (typeof key === 'string') {
199
+ return this.aliases.get(key) ?? key;
200
+ }
201
+ return key;
202
+ }
203
+ }
204
+ // ─── Contextual Binding Builder ───────────────────────────
205
+ export class ContextualBindingBuilder {
206
+ _container;
207
+ _concrete;
208
+ constructor(_container, _concrete) {
209
+ this._container = _container;
210
+ this._concrete = _concrete;
211
+ }
212
+ needs(token) {
213
+ return {
214
+ give: (factoryOrValue) => {
215
+ const factory = typeof factoryOrValue === 'function'
216
+ ? (c) => factoryOrValue(c)
217
+ : () => factoryOrValue;
218
+ this._container._addContextualBinding(this._concrete, resolveToken(token), factory);
219
+ },
220
+ };
221
+ }
222
+ }
223
+ function resolveToken(token) {
224
+ return typeof token === 'function' ? token.name : token;
225
+ }
226
+ // ─── Global container singleton ────────────────────────────
227
+ export const container = new Container();
228
+ //# sourceMappingURL=di.js.map
package/dist/di.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"di.js","sourceRoot":"","sources":["../src/di.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ export interface DispatchedEvent {
2
+ event: string;
3
+ payload: unknown;
4
+ }
5
+ /**
6
+ * Testing fake for @rudderjs/core events.
7
+ *
8
+ * Replaces the global EventDispatcher's dispatch method to record events
9
+ * without invoking real listeners.
10
+ *
11
+ * @example
12
+ * const fake = EventFake.fake()
13
+ *
14
+ * await dispatch(new UserRegistered(user))
15
+ *
16
+ * fake.assertDispatched('UserRegistered')
17
+ * fake.assertDispatchedTimes('UserRegistered', 1)
18
+ * fake.restore()
19
+ */
20
+ export declare class EventFake {
21
+ private readonly _dispatched;
22
+ private readonly _originalDispatch;
23
+ constructor();
24
+ /** Assert that an event was dispatched, optionally matching a predicate on the payload. */
25
+ assertDispatched(event: string, predicate?: (payload: unknown) => boolean): void;
26
+ /** Assert that an event was dispatched exactly N times. */
27
+ assertDispatchedTimes(event: string, count: number): void;
28
+ /** Assert that an event was NOT dispatched. */
29
+ assertNotDispatched(event: string): void;
30
+ /** Assert that nothing was dispatched. */
31
+ assertNothingDispatched(): void;
32
+ /** Get all dispatched events, optionally filtered by event name. */
33
+ dispatched(event?: string): DispatchedEvent[];
34
+ /** Restore the original EventDispatcher.dispatch() method. */
35
+ restore(): void;
36
+ /** Install the fake — replaces dispatcher.dispatch() to record instead of invoking listeners. */
37
+ static fake(): EventFake;
38
+ private _matching;
39
+ }
40
+ //# sourceMappingURL=events-fake.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events-fake.d.ts","sourceRoot":"","sources":["../src/events-fake.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;CACjB;AAID;;;;;;;;;;;;;;GAcG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAwB;IACpD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA6B;;IAQ/D,2FAA2F;IAC3F,gBAAgB,CACd,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,GACxC,IAAI;IAQP,2DAA2D;IAC3D,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IASzD,+CAA+C;IAC/C,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IASxC,0CAA0C;IAC1C,uBAAuB,IAAI,IAAI;IAU/B,oEAAoE;IACpE,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,EAAE;IAO7C,8DAA8D;IAC9D,OAAO,IAAI,IAAI;IAMf,iGAAiG;IACjG,MAAM,CAAC,IAAI,IAAI,SAAS;IAaxB,OAAO,CAAC,SAAS;CAUlB"}
@@ -0,0 +1,78 @@
1
+ import assert from 'node:assert/strict';
2
+ import { dispatcher } from './events.js';
3
+ // ─── Event Fake ────────────────────────────────────────────
4
+ /**
5
+ * Testing fake for @rudderjs/core events.
6
+ *
7
+ * Replaces the global EventDispatcher's dispatch method to record events
8
+ * without invoking real listeners.
9
+ *
10
+ * @example
11
+ * const fake = EventFake.fake()
12
+ *
13
+ * await dispatch(new UserRegistered(user))
14
+ *
15
+ * fake.assertDispatched('UserRegistered')
16
+ * fake.assertDispatchedTimes('UserRegistered', 1)
17
+ * fake.restore()
18
+ */
19
+ export class EventFake {
20
+ _dispatched = [];
21
+ _originalDispatch;
22
+ constructor() {
23
+ this._originalDispatch = dispatcher.dispatch.bind(dispatcher);
24
+ }
25
+ // ─── Assertions ──────────────────────────────────────────
26
+ /** Assert that an event was dispatched, optionally matching a predicate on the payload. */
27
+ assertDispatched(event, predicate) {
28
+ const matching = this._matching(event, predicate);
29
+ assert.ok(matching.length > 0, `[RudderJS Event] Expected event "${event}" to be dispatched, but it was not.`);
30
+ }
31
+ /** Assert that an event was dispatched exactly N times. */
32
+ assertDispatchedTimes(event, count) {
33
+ const matching = this._matching(event);
34
+ assert.strictEqual(matching.length, count, `[RudderJS Event] Expected event "${event}" to be dispatched ${count} time(s), but it was dispatched ${matching.length} time(s).`);
35
+ }
36
+ /** Assert that an event was NOT dispatched. */
37
+ assertNotDispatched(event) {
38
+ const matching = this._matching(event);
39
+ assert.strictEqual(matching.length, 0, `[RudderJS Event] Expected event "${event}" not to be dispatched, but it was dispatched ${matching.length} time(s).`);
40
+ }
41
+ /** Assert that nothing was dispatched. */
42
+ assertNothingDispatched() {
43
+ assert.strictEqual(this._dispatched.length, 0, `[RudderJS Event] Expected no events to be dispatched, but ${this._dispatched.length} were dispatched.`);
44
+ }
45
+ // ─── Access ──────────────────────────────────────────────
46
+ /** Get all dispatched events, optionally filtered by event name. */
47
+ dispatched(event) {
48
+ if (!event)
49
+ return [...this._dispatched];
50
+ return this._dispatched.filter((entry) => entry.event === event);
51
+ }
52
+ // ─── Cleanup ─────────────────────────────────────────────
53
+ /** Restore the original EventDispatcher.dispatch() method. */
54
+ restore() {
55
+ dispatcher.dispatch = this._originalDispatch;
56
+ }
57
+ // ─── Install ─────────────────────────────────────────────
58
+ /** Install the fake — replaces dispatcher.dispatch() to record instead of invoking listeners. */
59
+ static fake() {
60
+ const fake = new EventFake();
61
+ dispatcher.dispatch = async (event) => {
62
+ const name = event.constructor.name;
63
+ fake._dispatched.push({ event: name, payload: event });
64
+ };
65
+ return fake;
66
+ }
67
+ // ─── Internal ────────────────────────────────────────────
68
+ _matching(event, predicate) {
69
+ return this._dispatched.filter((entry) => {
70
+ if (entry.event !== event)
71
+ return false;
72
+ if (predicate && !predicate(entry.payload))
73
+ return false;
74
+ return true;
75
+ });
76
+ }
77
+ }
78
+ //# sourceMappingURL=events-fake.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events-fake.js","sourceRoot":"","sources":["../src/events-fake.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAUxC,8DAA8D;AAE9D;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,SAAS;IACH,WAAW,GAAsB,EAAE,CAAA;IACnC,iBAAiB,CAA6B;IAE/D;QACE,IAAI,CAAC,iBAAiB,GAAG,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAC/D,CAAC;IAED,4DAA4D;IAE5D,2FAA2F;IAC3F,gBAAgB,CACd,KAAa,EACb,SAAyC;QAEzC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;QACjD,MAAM,CAAC,EAAE,CACP,QAAQ,CAAC,MAAM,GAAG,CAAC,EACnB,oCAAoC,KAAK,qCAAqC,CAC/E,CAAA;IACH,CAAC;IAED,2DAA2D;IAC3D,qBAAqB,CAAC,KAAa,EAAE,KAAa;QAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;QACtC,MAAM,CAAC,WAAW,CAChB,QAAQ,CAAC,MAAM,EACf,KAAK,EACL,oCAAoC,KAAK,sBAAsB,KAAK,mCAAmC,QAAQ,CAAC,MAAM,WAAW,CAClI,CAAA;IACH,CAAC;IAED,+CAA+C;IAC/C,mBAAmB,CAAC,KAAa;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;QACtC,MAAM,CAAC,WAAW,CAChB,QAAQ,CAAC,MAAM,EACf,CAAC,EACD,oCAAoC,KAAK,iDAAiD,QAAQ,CAAC,MAAM,WAAW,CACrH,CAAA;IACH,CAAC;IAED,0CAA0C;IAC1C,uBAAuB;QACrB,MAAM,CAAC,WAAW,CAChB,IAAI,CAAC,WAAW,CAAC,MAAM,EACvB,CAAC,EACD,6DAA6D,IAAI,CAAC,WAAW,CAAC,MAAM,mBAAmB,CACxG,CAAA;IACH,CAAC;IAED,4DAA4D;IAE5D,oEAAoE;IACpE,UAAU,CAAC,KAAc;QACvB,IAAI,CAAC,KAAK;YAAE,OAAO,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAA;QACxC,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,CAAA;IAClE,CAAC;IAED,4DAA4D;IAE5D,8DAA8D;IAC9D,OAAO;QACL,UAAU,CAAC,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAA;IAC9C,CAAC;IAED,4DAA4D;IAE5D,iGAAiG;IACjG,MAAM,CAAC,IAAI;QACT,MAAM,IAAI,GAAG,IAAI,SAAS,EAAE,CAAA;QAE5B,UAAU,CAAC,QAAQ,GAAG,KAAK,EAAoB,KAAQ,EAAiB,EAAE;YACxE,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,CAAA;YACnC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;QACxD,CAAC,CAAA;QAED,OAAO,IAAI,CAAA;IACb,CAAC;IAED,4DAA4D;IAEpD,SAAS,CACf,KAAa,EACb,SAAyC;QAEzC,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACvC,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK;gBAAE,OAAO,KAAK,CAAA;YACvC,IAAI,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC;gBAAE,OAAO,KAAK,CAAA;YACxD,OAAO,IAAI,CAAA;QACb,CAAC,CAAC,CAAA;IACJ,CAAC;CACF"}
@@ -0,0 +1,40 @@
1
+ import type { Application } from './index.js';
2
+ import { ServiceProvider } from './service-provider.js';
3
+ export interface Listener<T = unknown> {
4
+ handle(event: T): void | Promise<void>;
5
+ }
6
+ export declare class EventDispatcher {
7
+ private readonly map;
8
+ /**
9
+ * Register one or more listeners for an event class name.
10
+ * Use `'*'` to listen to every dispatched event.
11
+ */
12
+ register(eventName: string, ...listeners: Listener<unknown>[]): void;
13
+ /**
14
+ * Dispatch an event to all matching listeners, then to wildcard (`'*'`) listeners.
15
+ * Listeners are awaited in registration order.
16
+ */
17
+ dispatch<T extends object>(event: T): Promise<void>;
18
+ /** Number of listeners registered for a given event name (or `'*'`). */
19
+ count(eventName: string): number;
20
+ /** Returns true if at least one listener is registered for the event name. */
21
+ hasListeners(eventName: string): boolean;
22
+ /**
23
+ * Returns a snapshot of all registered event names and their listener counts.
24
+ * Useful for `event:list` commands and introspection.
25
+ */
26
+ list(): Record<string, number>;
27
+ /** @internal — clears all listeners. Used for testing and hot-reload. */
28
+ reset(): void;
29
+ }
30
+ export declare const dispatcher: EventDispatcher;
31
+ /** Dispatch an event through the global dispatcher */
32
+ export declare function dispatch<T extends object>(event: T): Promise<void>;
33
+ /** Maps event class names to arrays of Listener classes */
34
+ export type ListenMap = Record<string, (new () => Listener<never>)[]>;
35
+ /**
36
+ * Returns an EventServiceProvider class that registers the given listener map
37
+ * into the global EventDispatcher on boot.
38
+ */
39
+ export declare function events(listen: ListenMap): new (app: Application) => ServiceProvider;
40
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAIvD,MAAM,WAAW,QAAQ,CAAC,CAAC,GAAG,OAAO;IACnC,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACvC;AAID,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAyC;IAE7D;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI;IAKpE;;;OAGG;IACG,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IASzD,wEAAwE;IACxE,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAIhC,8EAA8E;IAC9E,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIxC;;;OAGG;IACH,IAAI,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAQ9B,yEAAyE;IACzE,KAAK,IAAI,IAAI;CAGd;AAID,eAAO,MAAM,UAAU,iBAAwB,CAAA;AAE/C,sDAAsD;AACtD,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAElE;AAID,2DAA2D;AAC3D,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAA;AAIrE;;;GAGG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,KAAK,GAAG,EAAE,WAAW,KAAK,eAAe,CAanF"}
package/dist/events.js ADDED
@@ -0,0 +1,72 @@
1
+ import { ServiceProvider } from './service-provider.js';
2
+ // ─── Event Dispatcher ──────────────────────────────────────
3
+ export class EventDispatcher {
4
+ map = new Map();
5
+ /**
6
+ * Register one or more listeners for an event class name.
7
+ * Use `'*'` to listen to every dispatched event.
8
+ */
9
+ register(eventName, ...listeners) {
10
+ const existing = this.map.get(eventName) ?? [];
11
+ this.map.set(eventName, [...existing, ...listeners]);
12
+ }
13
+ /**
14
+ * Dispatch an event to all matching listeners, then to wildcard (`'*'`) listeners.
15
+ * Listeners are awaited in registration order.
16
+ */
17
+ async dispatch(event) {
18
+ const name = event.constructor.name;
19
+ const specific = this.map.get(name) ?? [];
20
+ const wildcards = this.map.get('*') ?? [];
21
+ for (const listener of [...specific, ...wildcards]) {
22
+ await listener.handle(event);
23
+ }
24
+ }
25
+ /** Number of listeners registered for a given event name (or `'*'`). */
26
+ count(eventName) {
27
+ return this.map.get(eventName)?.length ?? 0;
28
+ }
29
+ /** Returns true if at least one listener is registered for the event name. */
30
+ hasListeners(eventName) {
31
+ return this.count(eventName) > 0;
32
+ }
33
+ /**
34
+ * Returns a snapshot of all registered event names and their listener counts.
35
+ * Useful for `event:list` commands and introspection.
36
+ */
37
+ list() {
38
+ const result = {};
39
+ for (const [name, listeners] of this.map.entries()) {
40
+ result[name] = listeners.length;
41
+ }
42
+ return result;
43
+ }
44
+ /** @internal — clears all listeners. Used for testing and hot-reload. */
45
+ reset() {
46
+ this.map.clear();
47
+ }
48
+ }
49
+ // ─── Global Dispatcher Singleton ───────────────────────────
50
+ export const dispatcher = new EventDispatcher();
51
+ /** Dispatch an event through the global dispatcher */
52
+ export function dispatch(event) {
53
+ return dispatcher.dispatch(event);
54
+ }
55
+ // ─── Service Provider Factory ──────────────────────────────
56
+ /**
57
+ * Returns an EventServiceProvider class that registers the given listener map
58
+ * into the global EventDispatcher on boot.
59
+ */
60
+ export function events(listen) {
61
+ class EventServiceProvider extends ServiceProvider {
62
+ register() { }
63
+ boot() {
64
+ for (const [eventName, listenerClasses] of Object.entries(listen)) {
65
+ const instances = listenerClasses.map((LC) => new LC());
66
+ dispatcher.register(eventName, ...instances);
67
+ }
68
+ }
69
+ }
70
+ return EventServiceProvider;
71
+ }
72
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAQvD,8DAA8D;AAE9D,MAAM,OAAO,eAAe;IACT,GAAG,GAAG,IAAI,GAAG,EAA+B,CAAA;IAE7D;;;OAGG;IACH,QAAQ,CAAC,SAAiB,EAAE,GAAG,SAA8B;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAA;QAC9C,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,GAAG,QAAQ,EAAE,GAAG,SAAS,CAAC,CAAC,CAAA;IACtD,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,QAAQ,CAAmB,KAAQ;QACvC,MAAM,IAAI,GAAQ,KAAK,CAAC,WAAW,CAAC,IAAI,CAAA;QACxC,MAAM,QAAQ,GAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAA;QAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,IAAK,EAAE,CAAA;QAC1C,KAAK,MAAM,QAAQ,IAAI,CAAC,GAAG,QAAQ,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC;YACnD,MAAM,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAC9B,CAAC;IACH,CAAC;IAED,wEAAwE;IACxE,KAAK,CAAC,SAAiB;QACrB,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC,CAAA;IAC7C,CAAC;IAED,8EAA8E;IAC9E,YAAY,CAAC,SAAiB;QAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;IAClC,CAAC;IAED;;;OAGG;IACH,IAAI;QACF,MAAM,MAAM,GAA2B,EAAE,CAAA;QACzC,KAAK,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC;YACnD,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,MAAM,CAAA;QACjC,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC;IAED,yEAAyE;IACzE,KAAK;QACH,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAA;IAClB,CAAC;CACF;AAED,8DAA8D;AAE9D,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;AAE/C,sDAAsD;AACtD,MAAM,UAAU,QAAQ,CAAmB,KAAQ;IACjD,OAAO,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AACnC,CAAC;AAOD,8DAA8D;AAE9D;;;GAGG;AACH,MAAM,UAAU,MAAM,CAAC,MAAiB;IACtC,MAAM,oBAAqB,SAAQ,eAAe;QAChD,QAAQ,KAAU,CAAC;QAEnB,IAAI;YACF,KAAK,MAAM,CAAC,SAAS,EAAE,eAAe,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClE,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAwB,CAAA;gBAC9E,UAAU,CAAC,QAAQ,CAAC,SAAS,EAAE,GAAG,SAAS,CAAC,CAAA;YAC9C,CAAC;QACH,CAAC;KACF;IAED,OAAO,oBAAoB,CAAA;AAC7B,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { AppRequest } from '@rudderjs/contracts';
2
+ export declare class HttpException extends Error {
3
+ readonly statusCode: number;
4
+ readonly headers: Record<string, string>;
5
+ constructor(statusCode: number, message?: string, headers?: Record<string, string>);
6
+ }
7
+ export declare function abort(status: number, message?: string, headers?: Record<string, string>): never;
8
+ export declare function abort_if(condition: boolean, status: number, message?: string, headers?: Record<string, string>): void;
9
+ export declare function abort_unless(condition: boolean, status: number, message?: string, headers?: Record<string, string>): void;
10
+ type ReporterFn = (err: unknown) => void;
11
+ /**
12
+ * Override the global exception reporter.
13
+ *
14
+ * Called by `@rudderjs/log`'s service provider automatically when the log
15
+ * package is installed, routing all unhandled exceptions through the log
16
+ * channel. Can also be called in bootstrap/app.ts via `e.reportUsing(fn)`.
17
+ */
18
+ export declare function setExceptionReporter(fn: ReporterFn): void;
19
+ /** Report an exception to the configured reporter (default: console.error). */
20
+ export declare function report(err: unknown): void;
21
+ /** Conditionally report an exception. */
22
+ export declare function report_if(condition: boolean, err: unknown): void;
23
+ /** @internal — render an HttpException as a Response. */
24
+ export declare function renderHttpException(err: HttpException, req: AppRequest): Response;
25
+ /** @internal — render an unhandled error as a 500 Response. */
26
+ export declare function renderServerError(req: AppRequest, debug: boolean, err: unknown): Response;
27
+ export {};
28
+ //# sourceMappingURL=exceptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exceptions.d.ts","sourceRoot":"","sources":["../src/exceptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAmCrD,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;gBAGtC,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM;CAOvC;AAID,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,KAAK,CAE/F;AAED,wBAAgB,QAAQ,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAErH;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAEzH;AAID,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;AAMxC;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI,CAEzD;AAED,+EAA+E;AAC/E,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAEzC;AAED,yCAAyC;AACzC,wBAAgB,SAAS,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CAEhE;AA2CD,yDAAyD;AACzD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,aAAa,EAAE,GAAG,EAAE,UAAU,GAAG,QAAQ,CAYjF;AAED,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,GAAG,QAAQ,CAkBzF"}