@gobing-ai/ts-infra 0.3.7 → 0.3.10

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.
@@ -1,4 +1,5 @@
1
1
  import type { JobQueue } from '../job-queue/types';
2
+ import { type Logger } from '../logger';
2
3
  import type { BusLifecycleEvents, EventMap, SubscribeOptions } from './types';
3
4
  /**
4
5
  * Type-safe event bus supporting both synchronous (in-process) and
@@ -10,10 +11,12 @@ export declare class EventBus<TEvents extends EventMap> {
10
11
  private readonly asyncHandlerIds;
11
12
  private readonly jobQueue;
12
13
  private readonly lifecycleBus;
14
+ private readonly logger;
13
15
  private nextAsyncHandlerId;
14
16
  constructor(opts?: {
15
17
  jobQueue?: JobQueue;
16
18
  lifecycleBus?: EventBus<BusLifecycleEvents>;
19
+ logger?: Logger;
17
20
  });
18
21
  on<K extends keyof TEvents>(event: K, handler: TEvents[K], opts?: SubscribeOptions): void;
19
22
  once<K extends keyof TEvents>(event: K, handler: TEvents[K], opts?: SubscribeOptions): void;
@@ -1 +1 @@
1
- {"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../../src/event-bus/event-bus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,KAAK,EAER,kBAAkB,EAElB,QAAQ,EAER,gBAAgB,EACnB,MAAM,SAAS,CAAC;AAQjB;;;GAGG;AACH,qBAAa,QAAQ,CAAC,OAAO,SAAS,QAAQ;IAC1C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyD;IACtF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyD;IACvF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiD;IACjF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsC;IACnE,OAAO,CAAC,kBAAkB,CAAK;gBAEnB,IAAI,CAAC,EAAE;QACf,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,YAAY,CAAC,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC;KAC/C;IAKD,EAAE,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,IAAI;IAQzF,IAAI,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,IAAI;IAS3F,GAAG,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI;IAkBjE,kBAAkB,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI;IAUtD,IAAI,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA4E7F,aAAa,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM;IAMjF,UAAU,IAAI,MAAM,EAAE;IAOtB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,oBAAoB;CAU/B"}
1
+ {"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../../src/event-bus/event-bus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAa,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnD,OAAO,KAAK,EAER,kBAAkB,EAElB,QAAQ,EAER,gBAAgB,EACnB,MAAM,SAAS,CAAC;AAQjB;;;GAGG;AACH,qBAAa,QAAQ,CAAC,OAAO,SAAS,QAAQ;IAC1C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyD;IACtF,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyD;IACvF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiD;IACjF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsC;IACnE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,kBAAkB,CAAK;gBACnB,IAAI,CAAC,EAAE;QACf,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,YAAY,CAAC,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC;QAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;KACnB;IAMD,EAAE,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,IAAI;IAQzF,IAAI,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,gBAAgB,GAAG,IAAI;IAS3F,GAAG,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI;IAkBjE,kBAAkB,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,IAAI;IAUtD,IAAI,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAkF7F,aAAa,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM;IAMjF,UAAU,IAAI,MAAM,EAAE;IAOtB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,mBAAmB;IAW3B,OAAO,CAAC,oBAAoB;CAU/B"}
@@ -16,10 +16,12 @@ export class EventBus {
16
16
  asyncHandlerIds = new WeakMap();
17
17
  jobQueue;
18
18
  lifecycleBus;
19
+ logger;
19
20
  nextAsyncHandlerId = 0;
20
21
  constructor(opts) {
21
22
  this.jobQueue = opts?.jobQueue ?? null;
22
23
  this.lifecycleBus = opts?.lifecycleBus ?? null;
24
+ this.logger = opts?.logger;
23
25
  }
24
26
  on(event, handler, opts) {
25
27
  if (opts?.async) {
@@ -68,6 +70,11 @@ export class EventBus {
68
70
  let syncCount = 0;
69
71
  let asyncCount = 0;
70
72
  let errors = 0;
73
+ this.logger?.debug('event.emit', {
74
+ event: eventName,
75
+ syncHandlers: this.syncHandlers.get(event)?.size ?? 0,
76
+ asyncHandlers: this.asyncHandlers.get(event)?.size ?? 0,
77
+ });
71
78
  const syncSet = this.syncHandlers.get(event);
72
79
  if (syncSet) {
73
80
  syncCount = syncSet.size;
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAeH,2FAA2F;AAC3F,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAU/E;;;;GAIG;AACH,MAAM,WAAW,MAAM;IACnB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzD,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC;CACnD;AAKD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAEnD;AA8BD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,4CAA4C;AAC5C,MAAM,WAAW,iBAAiB;IAC9B,6CAA6C;IAC7C,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,8FAA8F;IAC9F,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BrF"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAeH,2FAA2F;AAC3F,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAU/E;;;;GAIG;AACH,MAAM,WAAW,MAAM;IACnB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzD,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC;CACnD;AAKD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAEnD;AA8BD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,4CAA4C;AAC5C,MAAM,WAAW,iBAAiB;IAC9B,6CAA6C;IAC7C,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,8FAA8F;IAC9F,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkCrF"}
package/dist/logger.js CHANGED
@@ -76,11 +76,18 @@ export async function initializeLogger(options = {}) {
76
76
  const { level = 'info', console: enableConsole = true, fileSink, json = true } = options;
77
77
  const lowestLevel = toLogTapeLevel(level);
78
78
  const formatter = json ? getJsonLinesFormatter() : getTextFormatter();
79
+ // When muted, install no sinks regardless of `console`/`fileSink`. The
80
+ // adapter flag (`setLoggerMuted`) is the single source of truth for "silence
81
+ // everything": without this, a reconfigure after muting would reinstall a
82
+ // console sink and resurface output the caller explicitly silenced. Keeping
83
+ // both mute paths consistent makes `setLoggerMuted(true)` survive any later
84
+ // `initializeLogger` (e.g. an application bootstrap running under a muted
85
+ // test harness).
79
86
  const sinks = {};
80
- if (enableConsole) {
87
+ if (!muted && enableConsole) {
81
88
  sinks.console = getConsoleSink({ formatter });
82
89
  }
83
- if (fileSink) {
90
+ if (!muted && fileSink) {
84
91
  sinks.file = (record) => {
85
92
  fileSink(formatter(record));
86
93
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobing-ai/ts-infra",
3
- "version": "0.3.7",
3
+ "version": "0.3.10",
4
4
  "description": "@gobing-ai/ts-infra — Infrastructure backbone: event bus, job queue, scheduler, telemetry, API client, and logging.",
5
5
  "keywords": [
6
6
  "typescript",
@@ -77,8 +77,8 @@
77
77
  "@logtape/logtape": "^2.0.0"
78
78
  },
79
79
  "peerDependencies": {
80
- "@gobing-ai/ts-db": "^0.3.7",
81
- "@gobing-ai/ts-runtime": "^0.3.7",
80
+ "@gobing-ai/ts-db": "^0.3.10",
81
+ "@gobing-ai/ts-runtime": "^0.3.10",
82
82
  "@opentelemetry/api": "^1.9.0",
83
83
  "@opentelemetry/sdk-trace-node": "^2.0.0",
84
84
  "@opentelemetry/sdk-metrics": "^2.0.0",
@@ -111,8 +111,8 @@
111
111
  }
112
112
  },
113
113
  "devDependencies": {
114
- "@gobing-ai/ts-db": "^0.3.7",
115
- "@gobing-ai/ts-runtime": "^0.3.7",
114
+ "@gobing-ai/ts-db": "^0.3.10",
115
+ "@gobing-ai/ts-runtime": "^0.3.10",
116
116
  "@types/bun": "1.3.14",
117
117
  "@opentelemetry/api": "^1.9.0",
118
118
  "@opentelemetry/sdk-trace-node": "^2.0.0",
@@ -26,14 +26,16 @@ export class EventBus<TEvents extends EventMap> {
26
26
  private readonly asyncHandlerIds = new WeakMap<TEvents[keyof TEvents], string>();
27
27
  private readonly jobQueue: JobQueue | null;
28
28
  private readonly lifecycleBus: EventBus<BusLifecycleEvents> | null;
29
+ private readonly logger: Logger | undefined;
29
30
  private nextAsyncHandlerId = 0;
30
-
31
31
  constructor(opts?: {
32
32
  jobQueue?: JobQueue;
33
33
  lifecycleBus?: EventBus<BusLifecycleEvents>;
34
+ logger?: Logger;
34
35
  }) {
35
36
  this.jobQueue = opts?.jobQueue ?? null;
36
37
  this.lifecycleBus = opts?.lifecycleBus ?? null;
38
+ this.logger = opts?.logger;
37
39
  }
38
40
 
39
41
  on<K extends keyof TEvents>(event: K, handler: TEvents[K], opts?: SubscribeOptions): void {
@@ -88,6 +90,12 @@ export class EventBus<TEvents extends EventMap> {
88
90
  let asyncCount = 0;
89
91
  let errors = 0;
90
92
 
93
+ this.logger?.debug('event.emit', {
94
+ event: eventName,
95
+ syncHandlers: this.syncHandlers.get(event)?.size ?? 0,
96
+ asyncHandlers: this.asyncHandlers.get(event)?.size ?? 0,
97
+ });
98
+
91
99
  const syncSet = this.syncHandlers.get(event);
92
100
  if (syncSet) {
93
101
  syncCount = syncSet.size;
package/src/logger.ts CHANGED
@@ -123,11 +123,18 @@ export async function initializeLogger(options: InitLoggerOptions = {}): Promise
123
123
  const lowestLevel = toLogTapeLevel(level);
124
124
  const formatter = json ? getJsonLinesFormatter() : getTextFormatter();
125
125
 
126
+ // When muted, install no sinks regardless of `console`/`fileSink`. The
127
+ // adapter flag (`setLoggerMuted`) is the single source of truth for "silence
128
+ // everything": without this, a reconfigure after muting would reinstall a
129
+ // console sink and resurface output the caller explicitly silenced. Keeping
130
+ // both mute paths consistent makes `setLoggerMuted(true)` survive any later
131
+ // `initializeLogger` (e.g. an application bootstrap running under a muted
132
+ // test harness).
126
133
  const sinks: Record<string, Sink> = {};
127
- if (enableConsole) {
134
+ if (!muted && enableConsole) {
128
135
  sinks.console = getConsoleSink({ formatter });
129
136
  }
130
- if (fileSink) {
137
+ if (!muted && fileSink) {
131
138
  sinks.file = (record: LogRecord) => {
132
139
  fileSink(formatter(record));
133
140
  };