@grest-ts/logger 0.0.5

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.
Files changed (64) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +38 -0
  3. package/dist/src/GGLog.d.ts +50 -0
  4. package/dist/src/GGLog.d.ts.map +1 -0
  5. package/dist/src/GGLog.js +150 -0
  6. package/dist/src/GGLog.js.map +1 -0
  7. package/dist/src/GGLogger.d.ts +9 -0
  8. package/dist/src/GGLogger.d.ts.map +1 -0
  9. package/dist/src/GGLogger.js +2 -0
  10. package/dist/src/GGLogger.js.map +1 -0
  11. package/dist/src/IAsyncLocalStorage.d.ts +8 -0
  12. package/dist/src/IAsyncLocalStorage.d.ts.map +1 -0
  13. package/dist/src/IAsyncLocalStorage.js +38 -0
  14. package/dist/src/IAsyncLocalStorage.js.map +1 -0
  15. package/dist/src/index-browser.d.ts +5 -0
  16. package/dist/src/index-browser.d.ts.map +1 -0
  17. package/dist/src/index-browser.js +5 -0
  18. package/dist/src/index-browser.js.map +1 -0
  19. package/dist/src/index-node.d.ts +5 -0
  20. package/dist/src/index-node.d.ts.map +1 -0
  21. package/dist/src/index-node.js +5 -0
  22. package/dist/src/index-node.js.map +1 -0
  23. package/dist/src/tsconfig.json +17 -0
  24. package/dist/src/types.d.ts +23 -0
  25. package/dist/src/types.d.ts.map +1 -0
  26. package/dist/src/types.js +12 -0
  27. package/dist/src/types.js.map +1 -0
  28. package/dist/testkit/GGLogCommands.d.ts +19 -0
  29. package/dist/testkit/GGLogCommands.d.ts.map +1 -0
  30. package/dist/testkit/GGLogCommands.js +31 -0
  31. package/dist/testkit/GGLogCommands.js.map +1 -0
  32. package/dist/testkit/GGLogCursor.d.ts +30 -0
  33. package/dist/testkit/GGLogCursor.d.ts.map +1 -0
  34. package/dist/testkit/GGLogCursor.js +62 -0
  35. package/dist/testkit/GGLogCursor.js.map +1 -0
  36. package/dist/testkit/GGLogInterceptor.d.ts +24 -0
  37. package/dist/testkit/GGLogInterceptor.d.ts.map +1 -0
  38. package/dist/testkit/GGLogInterceptor.js +109 -0
  39. package/dist/testkit/GGLogInterceptor.js.map +1 -0
  40. package/dist/testkit/GGLogSelector.d.ts +44 -0
  41. package/dist/testkit/GGLogSelector.d.ts.map +1 -0
  42. package/dist/testkit/GGLogSelector.js +55 -0
  43. package/dist/testkit/GGLogSelector.js.map +1 -0
  44. package/dist/testkit/GGLogWith.d.ts +13 -0
  45. package/dist/testkit/GGLogWith.d.ts.map +1 -0
  46. package/dist/testkit/GGLogWith.js +18 -0
  47. package/dist/testkit/GGLogWith.js.map +1 -0
  48. package/dist/testkit/GGTestLogger.d.ts +51 -0
  49. package/dist/testkit/GGTestLogger.d.ts.map +1 -0
  50. package/dist/testkit/GGTestLogger.js +102 -0
  51. package/dist/testkit/GGTestLogger.js.map +1 -0
  52. package/dist/testkit/index-testkit.d.ts +7 -0
  53. package/dist/testkit/index-testkit.d.ts.map +1 -0
  54. package/dist/testkit/index-testkit.js +18 -0
  55. package/dist/testkit/index-testkit.js.map +1 -0
  56. package/dist/tsconfig.publish.tsbuildinfo +1 -0
  57. package/package.json +62 -0
  58. package/src/GGLog.ts +197 -0
  59. package/src/GGLogger.ts +9 -0
  60. package/src/IAsyncLocalStorage.ts +53 -0
  61. package/src/index-browser.ts +5 -0
  62. package/src/index-node.ts +4 -0
  63. package/src/tsconfig.json +17 -0
  64. package/src/types.ts +23 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Grest Games OÜ
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # @grest-ts/logger
2
+
3
+ Async context-aware logging library for Grest Framework.
4
+
5
+ ## Features
6
+
7
+ - Multiple log levels (debug, info, warn, error, critical)
8
+ - Async context propagation (per-request logging)
9
+ - Pluggable loggers (console, custom)
10
+ - Structured data logging
11
+
12
+ ## Quick usage example
13
+
14
+ ```typescript
15
+
16
+ GGLog.debug(this, "Doing something cool!", {coolSomethingId: something.id})
17
+
18
+ GGLog.info(this, "Doing something cool!", {coolSomethingId: something.id})
19
+
20
+ GGLog.warn(this, "Doing something cool!", {coolSomethingId: something.id})
21
+
22
+ GGLog.error(this, "Something went wrong", {coolSomethingId: something.id})
23
+
24
+ const error = new Error("Something went wrong!")
25
+ GGLog.error(this, error)
26
+ GGLog.error(this, "User registration flow failed!", error)
27
+
28
+ // All levels provide multiple ways to log messages:
29
+ GGLog[LEVEL](this, "Doing something cool!", {coolSomethingId: something.id})
30
+ GGLog[LEVEL](this, new Error("some error"))
31
+ GGLog[LEVEL](this, "My flow failed", new Error("some error"))
32
+ ```
33
+
34
+ ## Documentation
35
+
36
+ - [Usage](./README-usage.md) - How to use logging in your application.
37
+ - [Testing](./README-testkit.md) - How to test log output with testkit.
38
+ - [Extending](./README-extending.md) - How to add custom loggers.
@@ -0,0 +1,50 @@
1
+ import { GGLocatorKey, GGLocatorScope } from "@grest-ts/locator";
2
+ import { GGLogger } from "./GGLogger";
3
+ import { LogLevel } from "./types";
4
+ export declare const GG_LOG: GGLocatorKey<GGLog>;
5
+ /**
6
+ * Logging system with async context awareness.
7
+ *
8
+ * GGLog uses GGAsyncContext for context propagation. It adds itself to
9
+ * whatever context exists, enabling per-runtime logger isolation.
10
+ *
11
+ * Usage:
12
+ * - Initialize: `GGLog.init()` (adds GGLog to current context)
13
+ * - Add loggers: `GGLog.add(new GGLoggerConsole())`
14
+ * - Log messages: `GGLog.info(this, "message", {data})`
15
+ */
16
+ export declare class GGLog {
17
+ private readonly loggers;
18
+ private globalMinLevel;
19
+ private constructor();
20
+ /**
21
+ * Initialize GGLog - creates a new instance and adds it to the current context.
22
+ */
23
+ static init(scope?: GGLocatorScope): GGLog;
24
+ addLogger(logger: GGLogger): this;
25
+ private clearLoggers;
26
+ private isLevelLoggedInternal;
27
+ private log;
28
+ static getLogger<T extends GGLogger>(type: new (...args: any[]) => T): T | undefined;
29
+ getLoggerInstance<T extends GGLogger>(type: new (...args: any[]) => T): T | undefined;
30
+ static add(logger: GGLogger): void;
31
+ static clear(): void;
32
+ static isLevelLogged(level: LogLevel): boolean;
33
+ private static log;
34
+ static debug(context: any, error: Error, data?: any): void;
35
+ static debug(context: any, message: string, data?: any): void;
36
+ static debug(context: any, message: string, error: Error, data?: any): void;
37
+ static info(context: any, error: Error, data?: any): void;
38
+ static info(context: any, message: string, data?: any): void;
39
+ static info(context: any, message: string, error: Error, data?: any): void;
40
+ static warn(context: any, error: Error, data?: any): void;
41
+ static warn(context: any, message: string, data?: any): void;
42
+ static warn(context: any, message: string, error: Error, data?: any): void;
43
+ static error(context: any, error: Error, data?: any): void;
44
+ static error(context: any, message: string, data?: any): void;
45
+ static error(context: any, message: string, error: Error, data?: any): void;
46
+ static critical(context: any, error: Error, data?: any): void;
47
+ static critical(context: any, message: string, data?: any): void;
48
+ static critical(context: any, message: string, error: Error, data?: any): void;
49
+ }
50
+ //# sourceMappingURL=GGLog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGLog.d.ts","sourceRoot":"","sources":["../../src/GGLog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,150 @@
1
+ import { GGLocator, GGLocatorKey } from "@grest-ts/locator";
2
+ import { LogLevel } from "./types.js";
3
+ export const GG_LOG = new GGLocatorKey("GGLog");
4
+ /**
5
+ * Logging system with async context awareness.
6
+ *
7
+ * GGLog uses GGAsyncContext for context propagation. It adds itself to
8
+ * whatever context exists, enabling per-runtime logger isolation.
9
+ *
10
+ * Usage:
11
+ * - Initialize: `GGLog.init()` (adds GGLog to current context)
12
+ * - Add loggers: `GGLog.add(new GGLoggerConsole())`
13
+ * - Log messages: `GGLog.info(this, "message", {data})`
14
+ */
15
+ export class GGLog {
16
+ loggers = [];
17
+ globalMinLevel = LogLevel.CRITICAL + 1; // No loggers = nothing logged
18
+ constructor() {
19
+ }
20
+ /**
21
+ * Initialize GGLog - creates a new instance and adds it to the current context.
22
+ */
23
+ static init(scope) {
24
+ const instance = new GGLog();
25
+ (scope ?? GGLocator.getScope()).set(GG_LOG, instance);
26
+ return instance;
27
+ }
28
+ // -----------------------------------------------
29
+ // Instance methods (operate on current context's loggers)
30
+ // -----------------------------------------------
31
+ addLogger(logger) {
32
+ this.loggers.push(logger);
33
+ if (this.loggers.length === 0) {
34
+ this.globalMinLevel = LogLevel.CRITICAL + 1;
35
+ }
36
+ else {
37
+ this.globalMinLevel = Math.min(...this.loggers.map(l => l.minLevel));
38
+ }
39
+ return this;
40
+ }
41
+ clearLoggers() {
42
+ this.loggers.length = 0;
43
+ this.globalMinLevel = LogLevel.CRITICAL + 1;
44
+ }
45
+ isLevelLoggedInternal(level) {
46
+ return level >= this.globalMinLevel;
47
+ }
48
+ log(entry) {
49
+ for (const logger of this.loggers) {
50
+ try {
51
+ logger.log(entry);
52
+ }
53
+ catch (error) {
54
+ // Prevent logger errors from breaking the application
55
+ console.error('Logger error:', error);
56
+ }
57
+ }
58
+ }
59
+ // -----------------------------------------------
60
+ // Static methods - main API
61
+ // -----------------------------------------------
62
+ static getLogger(type) {
63
+ return GG_LOG.get().loggers.find((l) => l instanceof type);
64
+ }
65
+ getLoggerInstance(type) {
66
+ return this.loggers.find((l) => l instanceof type);
67
+ }
68
+ static add(logger) {
69
+ GG_LOG.get().addLogger(logger);
70
+ }
71
+ static clear() {
72
+ GG_LOG.tryGet()?.clearLoggers();
73
+ }
74
+ static isLevelLogged(level) {
75
+ return GG_LOG.get().isLevelLoggedInternal(level);
76
+ }
77
+ static log(level, context, messageOrError, dataOrError, possiblyError) {
78
+ const ctx = GG_LOG.tryGet();
79
+ if (!ctx) {
80
+ console.warn("Log context not setup for message: ", messageOrError, dataOrError, possiblyError);
81
+ return;
82
+ }
83
+ // Fast path: skip all work if no logger cares about this level
84
+ if (!ctx.isLevelLoggedInternal(level)) {
85
+ return;
86
+ }
87
+ let message = undefined;
88
+ let data = undefined;
89
+ let error = undefined;
90
+ if (typeof messageOrError === "string") {
91
+ message = messageOrError;
92
+ }
93
+ else if (messageOrError instanceof Error) {
94
+ error = messageOrError;
95
+ }
96
+ else if (messageOrError) {
97
+ data = messageOrError;
98
+ }
99
+ if (dataOrError instanceof Error) {
100
+ error = dataOrError;
101
+ }
102
+ else if (dataOrError) {
103
+ data = dataOrError;
104
+ }
105
+ if (possiblyError instanceof Error) {
106
+ error = possiblyError;
107
+ }
108
+ // This is to support GGHttpError log levels
109
+ if (error && "logLevel" in error) {
110
+ if (error.logLevel === "error") {
111
+ level = LogLevel.ERROR;
112
+ }
113
+ else if (error.logLevel === "warn") {
114
+ level = LogLevel.WARN;
115
+ }
116
+ else if (error.logLevel === "info") {
117
+ level = LogLevel.INFO;
118
+ }
119
+ else if (error.logLevel === "debug") {
120
+ level = LogLevel.DEBUG;
121
+ }
122
+ }
123
+ const entry = {
124
+ timestamp: new Date(),
125
+ level,
126
+ contextName: typeof context === 'string' ? context : (context?.name ?? context?.constructor?.name),
127
+ message,
128
+ data,
129
+ error,
130
+ requestContext: undefined
131
+ };
132
+ ctx.log(entry);
133
+ }
134
+ static debug(context, a, b, c) {
135
+ this.log(LogLevel.DEBUG, context, a, b, c);
136
+ }
137
+ static info(context, a, b, c) {
138
+ this.log(LogLevel.INFO, context, a, b, c);
139
+ }
140
+ static warn(context, a, b, c) {
141
+ this.log(LogLevel.WARN, context, a, b, c);
142
+ }
143
+ static error(context, a, b, c) {
144
+ this.log(LogLevel.ERROR, context, a, b, c);
145
+ }
146
+ static critical(context, a, b, c) {
147
+ this.log(LogLevel.CRITICAL, context, a, b, c);
148
+ }
149
+ }
150
+ //# sourceMappingURL=GGLog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGLog.js","sourceRoot":"","sources":["../../src/GGLog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { LogEntry, LogLevel } from "./types";
2
+ /**
3
+ * Logger strategy interface
4
+ */
5
+ export interface GGLogger {
6
+ readonly minLevel: LogLevel;
7
+ log(entry: LogEntry): void;
8
+ }
9
+ //# sourceMappingURL=GGLogger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGLogger.d.ts","sourceRoot":"","sources":["../../src/GGLogger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,QAAQ,EAAC,MAAM,SAAS,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,QAAQ;IACrB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,GAAG,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;CAC9B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=GGLogger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGLogger.js","sourceRoot":"","sources":["../../src/GGLogger.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ export interface IAsyncLocalStorage<T> {
2
+ run<R>(store: T, callback: () => R): R;
3
+ getStore(): T | undefined;
4
+ exit<R>(callback: () => R): R;
5
+ enterWith(store: T): void;
6
+ }
7
+ export declare const AsyncLocalStorageImpl: new <T>() => IAsyncLocalStorage<T>;
8
+ //# sourceMappingURL=IAsyncLocalStorage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IAsyncLocalStorage.d.ts","sourceRoot":"","sources":["../../src/IAsyncLocalStorage.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACjC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAEvC,QAAQ,IAAI,CAAC,GAAG,SAAS,CAAC;IAE1B,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAE9B,SAAS,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;CAC7B;AAyCD,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC,CACA,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ class BrowserAsyncLocalStorage {
3
+ store = undefined;
4
+ run(store, callback) {
5
+ const previousStore = this.store;
6
+ this.store = store;
7
+ try {
8
+ return callback();
9
+ }
10
+ finally {
11
+ this.store = previousStore;
12
+ }
13
+ }
14
+ getStore() {
15
+ return this.store;
16
+ }
17
+ exit(callback) {
18
+ const previousStore = this.store;
19
+ this.store = undefined;
20
+ try {
21
+ return callback();
22
+ }
23
+ finally {
24
+ this.store = previousStore;
25
+ }
26
+ }
27
+ enterWith(store) {
28
+ this.store = store;
29
+ }
30
+ }
31
+ const isBrowser = typeof globalThis !== 'undefined' &&
32
+ typeof globalThis.window !== 'undefined' &&
33
+ typeof globalThis.window.document !== 'undefined';
34
+ // Export the appropriate implementation based on environment
35
+ // In browser: use BrowserAsyncLocalStorage
36
+ // In Node.js: use native AsyncLocalStorage from async_hooks
37
+ export const AsyncLocalStorageImpl = isBrowser ? BrowserAsyncLocalStorage : AsyncLocalStorage;
38
+ //# sourceMappingURL=IAsyncLocalStorage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IAsyncLocalStorage.js","sourceRoot":"","sources":["../../src/IAsyncLocalStorage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAC,MAAM,kBAAkB,CAAA;AAYlD,MAAM,wBAAwB;IAClB,KAAK,GAAkB,SAAS,CAAC;IAEzC,GAAG,CAAI,KAAQ,EAAE,QAAiB;QAC9B,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC;YACD,OAAO,QAAQ,EAAE,CAAC;QACtB,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,KAAK,GAAG,aAAa,CAAC;QAC/B,CAAC;IACL,CAAC;IAED,QAAQ;QACJ,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,IAAI,CAAI,QAAiB;QACrB,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACvB,IAAI,CAAC;YACD,OAAO,QAAQ,EAAE,CAAC;QACtB,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,KAAK,GAAG,aAAa,CAAC;QAC/B,CAAC;IACL,CAAC;IAED,SAAS,CAAC,KAAQ;QACd,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;CACJ;AAED,MAAM,SAAS,GAAG,OAAO,UAAU,KAAK,WAAW;IAC/C,OAAQ,UAAkB,CAAC,MAAM,KAAK,WAAW;IACjD,OAAQ,UAAkB,CAAC,MAAM,CAAC,QAAQ,KAAK,WAAW,CAAC;AAE/D,6DAA6D;AAC7D,2CAA2C;AAC3C,4DAA4D;AAC5D,MAAM,CAAC,MAAM,qBAAqB,GAC9B,SAAS,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAE,iBAAyB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './GGLog';
2
+ export * from './GGLogger';
3
+ export * from './types';
4
+ export type { IAsyncLocalStorage } from './IAsyncLocalStorage';
5
+ //# sourceMappingURL=index-browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-browser.d.ts","sourceRoot":"","sources":["../../src/index-browser.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,YAAY,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAA"}
@@ -0,0 +1,5 @@
1
+ export * from './GGLog.js';
2
+ export * from './GGLogger.js';
3
+ export * from './types.js';
4
+ // AsyncLocalStorageImpl excluded — uses Node.js async_hooks
5
+ //# sourceMappingURL=index-browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-browser.js","sourceRoot":"","sources":["../../src/index-browser.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AAExB,4DAA4D"}
@@ -0,0 +1,5 @@
1
+ export * from './GGLog';
2
+ export * from './GGLogger';
3
+ export * from './types';
4
+ export { type IAsyncLocalStorage, AsyncLocalStorageImpl } from './IAsyncLocalStorage';
5
+ //# sourceMappingURL=index-node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-node.d.ts","sourceRoot":"","sources":["../../src/index-node.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,OAAO,EAAC,KAAK,kBAAkB,EAAE,qBAAqB,EAAC,MAAM,sBAAsB,CAAA"}
@@ -0,0 +1,5 @@
1
+ export * from './GGLog.js';
2
+ export * from './GGLogger.js';
3
+ export * from './types.js';
4
+ export { AsyncLocalStorageImpl } from './IAsyncLocalStorage.js';
5
+ //# sourceMappingURL=index-node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-node.js","sourceRoot":"","sources":["../../src/index-node.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,OAAO,EAA0B,qBAAqB,EAAC,MAAM,sBAAsB,CAAA"}
@@ -0,0 +1,17 @@
1
+ {
2
+ "//": "THIS FILE IS GENERATED - DO NOT EDIT",
3
+ "extends": "../../../../tsconfig.base.json",
4
+ "compilerOptions": {
5
+ "rootDir": ".",
6
+ "lib": [
7
+ "ES2022",
8
+ "DOM"
9
+ ],
10
+ "types": [
11
+ "node"
12
+ ]
13
+ },
14
+ "include": [
15
+ "**/*"
16
+ ]
17
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Complete log entry structure
3
+ */
4
+ export interface LogEntry {
5
+ timestamp: Date;
6
+ level: LogLevel;
7
+ contextName?: string;
8
+ message: string;
9
+ data?: any;
10
+ error?: Error | string | unknown;
11
+ requestContext?: any;
12
+ }
13
+ /**
14
+ * Log levels
15
+ */
16
+ export declare enum LogLevel {
17
+ DEBUG = 1,
18
+ INFO = 2,
19
+ WARN = 3,
20
+ ERROR = 4,
21
+ CRITICAL = 5
22
+ }
23
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,QAAQ;IACrB,SAAS,EAAE,IAAI,CAAC;IAChB,KAAK,EAAE,QAAQ,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;IACjC,cAAc,CAAC,EAAE,GAAG,CAAC;CACxB;AAED;;GAEG;AACH,oBAAY,QAAQ;IAChB,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;IACT,QAAQ,IAAI;CACf"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Log levels
3
+ */
4
+ export var LogLevel;
5
+ (function (LogLevel) {
6
+ LogLevel[LogLevel["DEBUG"] = 1] = "DEBUG";
7
+ LogLevel[LogLevel["INFO"] = 2] = "INFO";
8
+ LogLevel[LogLevel["WARN"] = 3] = "WARN";
9
+ LogLevel[LogLevel["ERROR"] = 4] = "ERROR";
10
+ LogLevel[LogLevel["CRITICAL"] = 5] = "CRITICAL";
11
+ })(LogLevel || (LogLevel = {}));
12
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAaA;;GAEG;AACH,MAAM,CAAN,IAAY,QAMX;AAND,WAAY,QAAQ;IAChB,yCAAS,CAAA;IACT,uCAAQ,CAAA;IACR,uCAAQ,CAAA;IACR,yCAAS,CAAA;IACT,+CAAY,CAAA;AAChB,CAAC,EANW,QAAQ,KAAR,QAAQ,QAMnB"}
@@ -0,0 +1,19 @@
1
+ import { CapturedLogEntry, SerializableLogMatcher } from "./GGTestLogger";
2
+ import { LogLevel } from "@grest-ts/logger";
3
+ export interface FindFromPayload {
4
+ fromIndex: number;
5
+ matcher: SerializableLogMatcher;
6
+ minLevel?: LogLevel;
7
+ }
8
+ export interface RetrieveFromPayload {
9
+ fromIndex: number;
10
+ minLevel?: LogLevel;
11
+ }
12
+ export declare const GGLogIPC: {
13
+ worker: {
14
+ getCursor: import("@grest-ts/ipc").IPCClientRequest<void, number>;
15
+ findFrom: import("@grest-ts/ipc").IPCClientRequest<FindFromPayload, CapturedLogEntry>;
16
+ retrieveFrom: import("@grest-ts/ipc").IPCClientRequest<RetrieveFromPayload, CapturedLogEntry[]>;
17
+ };
18
+ };
19
+ //# sourceMappingURL=GGLogCommands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGLogCommands.d.ts","sourceRoot":"","sources":["../../testkit/GGLogCommands.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,gBAAgB,EAAgB,sBAAsB,EAAC,MAAM,gBAAgB,CAAC;AACtF,OAAO,EAAQ,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAEjD,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,sBAAsB,CAAC;IAChC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACvB;AAED,eAAO,MAAM,QAAQ;;;;;;CAMpB,CAAA"}
@@ -0,0 +1,31 @@
1
+ import { GG_TEST_RUNTIME_WORKER, GGTestRuntimeWorker } from "@grest-ts/testkit";
2
+ import { IPCClient } from "@grest-ts/ipc";
3
+ import { GGTestLogger } from "./GGTestLogger.js";
4
+ import { GGLog } from "@grest-ts/logger";
5
+ export const GGLogIPC = {
6
+ worker: {
7
+ getCursor: IPCClient.defineRequest("logs.getCursor"),
8
+ findFrom: IPCClient.defineRequest("logs.findFrom"),
9
+ retrieveFrom: IPCClient.defineRequest("logs.retrieveFrom"),
10
+ }
11
+ };
12
+ GGTestRuntimeWorker.onBeforeRuntimeStart(() => {
13
+ const worker = GG_TEST_RUNTIME_WORKER.get();
14
+ const getLogger = () => {
15
+ const logger = GGLog.getLogger(GGTestLogger);
16
+ if (!logger) {
17
+ throw new Error("GGTestLogger not found. Make sure @grest-ts/logger/testkit is loaded.");
18
+ }
19
+ return logger;
20
+ };
21
+ worker.onIpcRequest(GGLogIPC.worker.getCursor, () => {
22
+ return getLogger().getCursor();
23
+ });
24
+ worker.onIpcRequest(GGLogIPC.worker.findFrom, (payload) => {
25
+ return getLogger().findFrom(payload.fromIndex, payload.matcher, payload.minLevel);
26
+ });
27
+ worker.onIpcRequest(GGLogIPC.worker.retrieveFrom, (payload) => {
28
+ return getLogger().retrieveFrom(payload.fromIndex, payload.minLevel);
29
+ });
30
+ });
31
+ //# sourceMappingURL=GGLogCommands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGLogCommands.js","sourceRoot":"","sources":["../../testkit/GGLogCommands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,sBAAsB,EAAE,mBAAmB,EAAC,MAAM,mBAAmB,CAAC;AAC9E,OAAO,EAAC,SAAS,EAAC,MAAM,eAAe,CAAC;AACxC,OAAO,EAAmB,YAAY,EAAyB,MAAM,gBAAgB,CAAC;AACtF,OAAO,EAAC,KAAK,EAAW,MAAM,kBAAkB,CAAC;AAajD,MAAM,CAAC,MAAM,QAAQ,GAAG;IACpB,MAAM,EAAE;QACJ,SAAS,EAAE,SAAS,CAAC,aAAa,CAAe,gBAAgB,CAAC;QAClE,QAAQ,EAAE,SAAS,CAAC,aAAa,CAA2C,eAAe,CAAC;QAC5F,YAAY,EAAE,SAAS,CAAC,aAAa,CAA0C,mBAAmB,CAAC;KACtG;CACJ,CAAA;AAED,mBAAmB,CAAC,oBAAoB,CAAC,GAAG,EAAE;IAC1C,MAAM,MAAM,GAAG,sBAAsB,CAAC,GAAG,EAAE,CAAC;IAE5C,MAAM,SAAS,GAAG,GAAiB,EAAE;QACjC,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;QAC7F,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC,CAAC;IAEF,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE;QAChD,OAAO,SAAS,EAAE,CAAC,SAAS,EAAE,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,EAAE;QACtD,OAAO,SAAS,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,OAAO,EAAE,EAAE;QAC1D,OAAO,SAAS,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
@@ -0,0 +1,30 @@
1
+ import { LogLevel } from "@grest-ts/logger";
2
+ import { GGTestRuntime } from "@grest-ts/testkit";
3
+ import { CapturedLogEntry } from "./GGTestLogger";
4
+ export type LogMatcher = string | RegExp | Partial<CapturedLogEntry>;
5
+ export interface LogQueryOptions {
6
+ minLevel?: LogLevel;
7
+ }
8
+ /**
9
+ * Represents a cursor position in the log stream.
10
+ * Stores the starting index per runtime for querying logs from that point onwards.
11
+ */
12
+ export declare class GGLogCursor {
13
+ private readonly runtimes;
14
+ private readonly cursors;
15
+ constructor(runtimes: GGTestRuntime[], cursors: Map<GGTestRuntime, number>);
16
+ /**
17
+ * Find a log entry matching the given matcher across all runtimes.
18
+ * Returns the first match or null if not found.
19
+ */
20
+ find(matcher: LogMatcher, options?: LogQueryOptions): Promise<CapturedLogEntry | null>;
21
+ /**
22
+ * Retrieve all log entries from the cursor position onwards.
23
+ */
24
+ retrieve(options?: LogQueryOptions): Promise<CapturedLogEntry[]>;
25
+ /**
26
+ * Convert LogMatcher to SerializableLogMatcher for IPC.
27
+ */
28
+ private toSerializable;
29
+ }
30
+ //# sourceMappingURL=GGLogCursor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGLogCursor.d.ts","sourceRoot":"","sources":["../../testkit/GGLogCursor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAC,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAC,gBAAgB,EAAyB,MAAM,gBAAgB,CAAC;AAGxE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAErE,MAAM,WAAW,eAAe;IAC5B,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACvB;AAED;;;GAGG;AACH,qBAAa,WAAW;IAEpB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;gBAEzC,QAAQ,EAAE,aAAa,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC;IAK1E;;;OAGG;IACG,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAoB5F;;OAEG;IACG,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAkBtE;;OAEG;IACH,OAAO,CAAC,cAAc;CASzB"}
@@ -0,0 +1,62 @@
1
+ import { GGLogIPC } from "./GGLogCommands.js";
2
+ /**
3
+ * Represents a cursor position in the log stream.
4
+ * Stores the starting index per runtime for querying logs from that point onwards.
5
+ */
6
+ export class GGLogCursor {
7
+ runtimes;
8
+ cursors;
9
+ constructor(runtimes, cursors) {
10
+ this.runtimes = runtimes;
11
+ this.cursors = cursors;
12
+ }
13
+ /**
14
+ * Find a log entry matching the given matcher across all runtimes.
15
+ * Returns the first match or null if not found.
16
+ */
17
+ async find(matcher, options) {
18
+ const serializable = this.toSerializable(matcher);
19
+ const results = await Promise.all(this.runtimes.map(async (runtime) => {
20
+ const fromIndex = this.cursors.get(runtime) ?? 0;
21
+ return runtime.sendCommand(GGLogIPC.worker.findFrom, {
22
+ fromIndex,
23
+ matcher: serializable,
24
+ minLevel: options?.minLevel
25
+ });
26
+ }));
27
+ // Return first non-null match (sorted by index for determinism)
28
+ const matches = results.filter((r) => r !== null);
29
+ if (matches.length === 0)
30
+ return null;
31
+ return matches.sort((a, b) => a.index - b.index)[0];
32
+ }
33
+ /**
34
+ * Retrieve all log entries from the cursor position onwards.
35
+ */
36
+ async retrieve(options) {
37
+ const allLogs = [];
38
+ await Promise.all(this.runtimes.map(async (runtime) => {
39
+ const fromIndex = this.cursors.get(runtime) ?? 0;
40
+ const logs = await runtime.sendCommand(GGLogIPC.worker.retrieveFrom, {
41
+ fromIndex,
42
+ minLevel: options?.minLevel
43
+ });
44
+ allLogs.push(...logs);
45
+ }));
46
+ // Sort by timestamp for consistent ordering across runtimes
47
+ return allLogs.sort((a, b) => a.timestamp - b.timestamp);
48
+ }
49
+ /**
50
+ * Convert LogMatcher to SerializableLogMatcher for IPC.
51
+ */
52
+ toSerializable(matcher) {
53
+ if (typeof matcher === 'string') {
54
+ return { type: 'string', value: matcher };
55
+ }
56
+ if (matcher instanceof RegExp) {
57
+ return { type: 'regex', pattern: matcher.source, flags: matcher.flags };
58
+ }
59
+ return { type: 'object', value: matcher };
60
+ }
61
+ }
62
+ //# sourceMappingURL=GGLogCursor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GGLogCursor.js","sourceRoot":"","sources":["../../testkit/GGLogCursor.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,QAAQ,EAAC,MAAM,iBAAiB,CAAC;AAQzC;;;GAGG;AACH,MAAM,OAAO,WAAW;IAEH,QAAQ,CAAkB;IAC1B,OAAO,CAA6B;IAErD,YAAY,QAAyB,EAAE,OAAmC;QACtE,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI,CAAC,OAAmB,EAAE,OAAyB;QACrD,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAElD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC7B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YAChC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACjD,OAAO,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE;gBACjD,SAAS;gBACT,OAAO,EAAE,YAAY;gBACrB,QAAQ,EAAE,OAAO,EAAE,QAAQ;aAC9B,CAAC,CAAC;QACP,CAAC,CAAC,CACL,CAAC;QAEF,gEAAgE;QAChE,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAyB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QACzE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACtC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,OAAyB;QACpC,MAAM,OAAO,GAAuB,EAAE,CAAC;QAEvC,MAAM,OAAO,CAAC,GAAG,CACb,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YAChC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACjD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE;gBACjE,SAAS;gBACT,QAAQ,EAAE,OAAO,EAAE,QAAQ;aAC9B,CAAC,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;QAC1B,CAAC,CAAC,CACL,CAAC;QAEF,4DAA4D;QAC5D,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;IAC7D,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,OAAmB;QACtC,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QAC9C,CAAC;QACD,IAAI,OAAO,YAAY,MAAM,EAAE,CAAC;YAC5B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;QAC5E,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAkC,EAAE,CAAC;IACzE,CAAC;CACJ"}