quantum-forge 2.0.2
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/LICENSE-BINARY.md +57 -0
- package/LICENSE.md +21 -0
- package/LICENSING.md +33 -0
- package/dist/lib/logging.d.ts +76 -0
- package/dist/lib/logging.js +198 -0
- package/dist/lib/logging.js.map +1 -0
- package/dist/lib/quantum.d.ts +370 -0
- package/dist/lib/quantum.js +535 -0
- package/dist/lib/quantum.js.map +1 -0
- package/dist/lib/vite-plugin.d.ts +32 -0
- package/dist/lib/vite-plugin.js +93 -0
- package/dist/lib/vite-plugin.js.map +1 -0
- package/dist/quantum-forge-web-0.3.0.tgz +0 -0
- package/dist/quantum-forge-web-api.d.mts +61 -0
- package/dist/quantum-forge-web-api.mjs +202 -0
- package/dist/quantum-forge-web-esm.mjs +14 -0
- package/dist/quantum-forge-web-esm.wasm +0 -0
- package/package.json +70 -0
- package/scripts/build-quantum-forge-variant.mjs +177 -0
- package/scripts/copy-quantum-forge.mjs +61 -0
- package/scripts/prepare.mjs +296 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Quantum Forge Binary License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2026 Quantum Realm Games, LLC. All rights reserved.
|
|
4
|
+
|
|
5
|
+
This license applies to the compiled binary components of Quantum Forge,
|
|
6
|
+
including WebAssembly (.wasm) files, native shared libraries (.bundle, .dll,
|
|
7
|
+
.so, .a), and any other compiled artifacts distributed alongside the
|
|
8
|
+
MIT-licensed source code.
|
|
9
|
+
|
|
10
|
+
## Grant of License
|
|
11
|
+
|
|
12
|
+
Quantum Realm Games, LLC. ("Licensor") grants you a worldwide,
|
|
13
|
+
non-exclusive, non-transferable license to use the binary components
|
|
14
|
+
("Binaries") as part of applications you build, subject to the terms below.
|
|
15
|
+
|
|
16
|
+
## Free Use
|
|
17
|
+
|
|
18
|
+
You may use the Binaries free of charge in any application, provided:
|
|
19
|
+
|
|
20
|
+
1. **Attribution.** Your application must include visible "Powered by
|
|
21
|
+
Quantum Forge" attribution (e.g., splash screen, credits, or about page)
|
|
22
|
+
with a link to quantumnative.io where practical.
|
|
23
|
+
|
|
24
|
+
2. **Revenue threshold.** If your application generates more than $100,000
|
|
25
|
+
USD in annual gross revenue, you must purchase a commercial license from
|
|
26
|
+
Quantum Realm Games, LLC.
|
|
27
|
+
|
|
28
|
+
## Restrictions
|
|
29
|
+
|
|
30
|
+
You may not:
|
|
31
|
+
|
|
32
|
+
1. Reverse engineer, decompile, or disassemble the Binaries.
|
|
33
|
+
2. Distribute the Binaries separately from an application you built.
|
|
34
|
+
3. Use the Binaries to create a product or service that competes with
|
|
35
|
+
Quantum Forge.
|
|
36
|
+
4. Remove or alter any copyright notices, license files, or attribution
|
|
37
|
+
requirements included with the Binaries.
|
|
38
|
+
|
|
39
|
+
## Commercial Licensing
|
|
40
|
+
|
|
41
|
+
For use above the revenue threshold, volume licensing, or to remove the
|
|
42
|
+
attribution requirement, contact: hello@quantum.dev
|
|
43
|
+
|
|
44
|
+
## Termination
|
|
45
|
+
|
|
46
|
+
This license terminates automatically if you fail to comply with its terms.
|
|
47
|
+
Upon termination, you must stop using and delete all copies of the Binaries.
|
|
48
|
+
|
|
49
|
+
## Disclaimer
|
|
50
|
+
|
|
51
|
+
THE BINARIES ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
52
|
+
IMPLIED. IN NO EVENT SHALL QUANTUM REALM GAMES, LLC BE LIABLE FOR ANY CLAIM,
|
|
53
|
+
DAMAGES, OR OTHER LIABILITY ARISING FROM THE USE OF THE BINARIES.
|
|
54
|
+
|
|
55
|
+
## Governing Law
|
|
56
|
+
|
|
57
|
+
This license is governed by the laws of the State of California.
|
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2026 Quantum Realm Games, LLC.
|
|
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/LICENSING.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Licensing
|
|
2
|
+
|
|
3
|
+
Quantum Forge uses a split licensing model:
|
|
4
|
+
|
|
5
|
+
## Source Code (MIT)
|
|
6
|
+
|
|
7
|
+
All TypeScript and JavaScript source code in this repository is licensed under
|
|
8
|
+
the [MIT License](LICENSE.md). You can read it, modify it, use it in your
|
|
9
|
+
games, contribute to it, and redistribute it freely.
|
|
10
|
+
|
|
11
|
+
## Compiled Binaries (Proprietary)
|
|
12
|
+
|
|
13
|
+
The WebAssembly (.wasm) files and related compiled artifacts are proprietary.
|
|
14
|
+
See [LICENSE-BINARY.md](LICENSE-BINARY.md) for the full terms. The short
|
|
15
|
+
version:
|
|
16
|
+
|
|
17
|
+
- **Free** for applications generating under $100K/year in revenue
|
|
18
|
+
- **Attribution** required: "Powered by Quantum Forge"
|
|
19
|
+
- **No reverse engineering** of the compiled binaries
|
|
20
|
+
- Above $100K, contact hello@quantum.dev for a commercial license
|
|
21
|
+
|
|
22
|
+
## Why This Split?
|
|
23
|
+
|
|
24
|
+
The source code is the API surface you build with. We want it open so you can
|
|
25
|
+
read, debug, learn from, and contribute to it. The compiled quantum simulator
|
|
26
|
+
is years of specialized work and is how we sustain the project. This model lets
|
|
27
|
+
us keep Quantum Forge free for indie developers and students while building a
|
|
28
|
+
sustainable business.
|
|
29
|
+
|
|
30
|
+
## Trademarks
|
|
31
|
+
|
|
32
|
+
"Quantum Forge" and the Quantum Native logo are trademarks of Quantum Realm
|
|
33
|
+
Games, LLC. The MIT license grants rights to the code, not to the trademarks.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger - Centralized logging with configurable levels
|
|
3
|
+
*
|
|
4
|
+
* IMPORTANT: Never use console.* directly in game code (except in Logger implementation,
|
|
5
|
+
* crash fallback, or dev utilities). Always use Logger methods with optional chaining.
|
|
6
|
+
*/
|
|
7
|
+
type LogLevel = "debug" | "info" | "warn" | "error";
|
|
8
|
+
interface LoggerConfig {
|
|
9
|
+
isDebugEnabled: () => boolean;
|
|
10
|
+
getLogLevel: () => LogLevel;
|
|
11
|
+
}
|
|
12
|
+
interface LoggerInterface {
|
|
13
|
+
debug(message: string, context?: string): void;
|
|
14
|
+
info(message: string, context?: string): void;
|
|
15
|
+
warn(message: string, context?: string): void;
|
|
16
|
+
error(message: string, error?: Error, context?: string): void;
|
|
17
|
+
group<T>(title: string, callback: () => T): T;
|
|
18
|
+
time<T>(label: string, callback: () => T): T;
|
|
19
|
+
createChildLogger?: (context: string) => LoggerInterface;
|
|
20
|
+
}
|
|
21
|
+
declare class Logger implements LoggerInterface {
|
|
22
|
+
private readonly config;
|
|
23
|
+
private readonly levels;
|
|
24
|
+
private filtersCached;
|
|
25
|
+
private cachedIncludes;
|
|
26
|
+
private cachedExcludes;
|
|
27
|
+
constructor(config?: LoggerConfig | null);
|
|
28
|
+
/**
|
|
29
|
+
* Cache filter configuration on first use.
|
|
30
|
+
* Filters only change on page reload, so no need to re-read every call.
|
|
31
|
+
*/
|
|
32
|
+
private ensureFiltersCached;
|
|
33
|
+
/**
|
|
34
|
+
* Check if logging is enabled for the given level
|
|
35
|
+
*/
|
|
36
|
+
private shouldLog;
|
|
37
|
+
/**
|
|
38
|
+
* Format log message with timestamp and context
|
|
39
|
+
*/
|
|
40
|
+
private formatMessage;
|
|
41
|
+
/**
|
|
42
|
+
* Determine if this log line should pass include/exclude filters.
|
|
43
|
+
* Uses cached filter configuration for performance.
|
|
44
|
+
*/
|
|
45
|
+
private passesFilters;
|
|
46
|
+
/**
|
|
47
|
+
* Debug level logging
|
|
48
|
+
*/
|
|
49
|
+
debug(message: string, context?: string): void;
|
|
50
|
+
/**
|
|
51
|
+
* Info level logging
|
|
52
|
+
*/
|
|
53
|
+
info(message: string, context?: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* Warning level logging
|
|
56
|
+
*/
|
|
57
|
+
warn(message: string, context?: string): void;
|
|
58
|
+
/**
|
|
59
|
+
* Error level logging
|
|
60
|
+
*/
|
|
61
|
+
error(message: string, error?: Error, context?: string): void;
|
|
62
|
+
/**
|
|
63
|
+
* Group logging operations
|
|
64
|
+
*/
|
|
65
|
+
group<T>(title: string, callback: () => T): T;
|
|
66
|
+
/**
|
|
67
|
+
* Time a logging operation
|
|
68
|
+
*/
|
|
69
|
+
time<T>(label: string, callback: () => T): T;
|
|
70
|
+
/**
|
|
71
|
+
* Create a child logger with a specific context
|
|
72
|
+
*/
|
|
73
|
+
createChildLogger(context: string): LoggerInterface;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { type LogLevel, Logger, type LoggerConfig, type LoggerInterface };
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
// src/logging/Logger.ts
|
|
2
|
+
var Logger = class {
|
|
3
|
+
config;
|
|
4
|
+
levels = {
|
|
5
|
+
debug: 0,
|
|
6
|
+
info: 1,
|
|
7
|
+
warn: 2,
|
|
8
|
+
error: 3
|
|
9
|
+
};
|
|
10
|
+
// Cached filter configuration - computed once on first use
|
|
11
|
+
filtersCached = false;
|
|
12
|
+
cachedIncludes = [];
|
|
13
|
+
cachedExcludes = [];
|
|
14
|
+
constructor(config = null) {
|
|
15
|
+
this.config = config;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Cache filter configuration on first use.
|
|
19
|
+
* Filters only change on page reload, so no need to re-read every call.
|
|
20
|
+
*/
|
|
21
|
+
ensureFiltersCached() {
|
|
22
|
+
if (this.filtersCached) return;
|
|
23
|
+
this.filtersCached = true;
|
|
24
|
+
try {
|
|
25
|
+
const params = (() => {
|
|
26
|
+
try {
|
|
27
|
+
return new URLSearchParams(globalThis?.location?.search || "");
|
|
28
|
+
} catch {
|
|
29
|
+
return new URLSearchParams("");
|
|
30
|
+
}
|
|
31
|
+
})();
|
|
32
|
+
const urlInclude = params.get("logInclude") || params.get("log") || "";
|
|
33
|
+
const urlExclude = params.get("logExclude") || "";
|
|
34
|
+
const lsInclude = (() => {
|
|
35
|
+
try {
|
|
36
|
+
return globalThis?.localStorage?.getItem("game.log.include") || "";
|
|
37
|
+
} catch {
|
|
38
|
+
return "";
|
|
39
|
+
}
|
|
40
|
+
})();
|
|
41
|
+
const lsExclude = (() => {
|
|
42
|
+
try {
|
|
43
|
+
return globalThis?.localStorage?.getItem("game.log.exclude") || "";
|
|
44
|
+
} catch {
|
|
45
|
+
return "";
|
|
46
|
+
}
|
|
47
|
+
})();
|
|
48
|
+
const includeRaw = (urlInclude || lsInclude || "").trim();
|
|
49
|
+
const excludeRaw = (urlExclude || lsExclude || "").trim();
|
|
50
|
+
this.cachedIncludes = includeRaw ? includeRaw.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean) : [];
|
|
51
|
+
this.cachedExcludes = excludeRaw ? excludeRaw.split(",").map((s) => s.trim().toLowerCase()).filter(Boolean) : [];
|
|
52
|
+
} catch {
|
|
53
|
+
this.cachedIncludes = [];
|
|
54
|
+
this.cachedExcludes = [];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Check if logging is enabled for the given level
|
|
59
|
+
*/
|
|
60
|
+
shouldLog(level) {
|
|
61
|
+
if (!this.config?.isDebugEnabled()) return false;
|
|
62
|
+
const configLogLevel = this.config.getLogLevel();
|
|
63
|
+
const currentLevel = this.levels[configLogLevel] ?? 1;
|
|
64
|
+
const messageLevel = this.levels[level] ?? 1;
|
|
65
|
+
return messageLevel >= currentLevel;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Format log message with timestamp and context
|
|
69
|
+
*/
|
|
70
|
+
formatMessage(level, message, context) {
|
|
71
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
72
|
+
const prefix = `[${timestamp}] [${level.toUpperCase()}]`;
|
|
73
|
+
if (context) {
|
|
74
|
+
return `${prefix} [${context}] ${message}`;
|
|
75
|
+
}
|
|
76
|
+
return `${prefix} ${message}`;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Determine if this log line should pass include/exclude filters.
|
|
80
|
+
* Uses cached filter configuration for performance.
|
|
81
|
+
*/
|
|
82
|
+
passesFilters(message, context) {
|
|
83
|
+
this.ensureFiltersCached();
|
|
84
|
+
if (this.cachedIncludes.length > 0) {
|
|
85
|
+
const hay = `${context || ""} ${message}`.toLowerCase();
|
|
86
|
+
const match = this.cachedIncludes.some((tok) => hay.includes(tok));
|
|
87
|
+
if (!match) return false;
|
|
88
|
+
}
|
|
89
|
+
if (this.cachedExcludes.length > 0) {
|
|
90
|
+
const hay = `${context || ""} ${message}`.toLowerCase();
|
|
91
|
+
const match = this.cachedExcludes.some((tok) => hay.includes(tok));
|
|
92
|
+
if (match) return false;
|
|
93
|
+
}
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Debug level logging
|
|
98
|
+
*/
|
|
99
|
+
debug(message, context) {
|
|
100
|
+
if (this.shouldLog("debug") && this.passesFilters(message, context)) {
|
|
101
|
+
console.debug(this.formatMessage("debug", message, context));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Info level logging
|
|
106
|
+
*/
|
|
107
|
+
info(message, context) {
|
|
108
|
+
if (this.shouldLog("info") && this.passesFilters(message, context)) {
|
|
109
|
+
console.info(this.formatMessage("info", message, context));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Warning level logging
|
|
114
|
+
*/
|
|
115
|
+
warn(message, context) {
|
|
116
|
+
if (this.shouldLog("warn") && this.passesFilters(message, context)) {
|
|
117
|
+
console.warn(this.formatMessage("warn", message, context));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Error level logging
|
|
122
|
+
*/
|
|
123
|
+
error(message, error, context) {
|
|
124
|
+
if (this.shouldLog("error") && this.passesFilters(message, context)) {
|
|
125
|
+
let errorMessage = message;
|
|
126
|
+
if (error) {
|
|
127
|
+
errorMessage += `: ${error.message}`;
|
|
128
|
+
if (error.stack && this.config?.isDebugEnabled()) {
|
|
129
|
+
errorMessage += `
|
|
130
|
+
Stack trace: ${error.stack}`;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
console.error(this.formatMessage("error", errorMessage, context));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Group logging operations
|
|
138
|
+
*/
|
|
139
|
+
group(title, callback) {
|
|
140
|
+
if (this.shouldLog("debug")) {
|
|
141
|
+
console.group(this.formatMessage("debug", `Group: ${title}`));
|
|
142
|
+
try {
|
|
143
|
+
return callback();
|
|
144
|
+
} finally {
|
|
145
|
+
console.groupEnd();
|
|
146
|
+
}
|
|
147
|
+
} else {
|
|
148
|
+
return callback();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Time a logging operation
|
|
153
|
+
*/
|
|
154
|
+
time(label, callback) {
|
|
155
|
+
if (this.shouldLog("debug")) {
|
|
156
|
+
const startTime = performance.now();
|
|
157
|
+
try {
|
|
158
|
+
return callback();
|
|
159
|
+
} finally {
|
|
160
|
+
const endTime = performance.now();
|
|
161
|
+
const duration = endTime - startTime;
|
|
162
|
+
this.debug(`${label} completed in ${duration.toFixed(2)}ms`);
|
|
163
|
+
}
|
|
164
|
+
} else {
|
|
165
|
+
return callback();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Create a child logger with a specific context
|
|
170
|
+
*/
|
|
171
|
+
createChildLogger(context) {
|
|
172
|
+
return {
|
|
173
|
+
debug: (message, childContext) => this.debug(
|
|
174
|
+
message,
|
|
175
|
+
childContext ? `${context}:${childContext}` : context
|
|
176
|
+
),
|
|
177
|
+
info: (message, childContext) => this.info(
|
|
178
|
+
message,
|
|
179
|
+
childContext ? `${context}:${childContext}` : context
|
|
180
|
+
),
|
|
181
|
+
warn: (message, childContext) => this.warn(
|
|
182
|
+
message,
|
|
183
|
+
childContext ? `${context}:${childContext}` : context
|
|
184
|
+
),
|
|
185
|
+
error: (message, error, childContext) => this.error(
|
|
186
|
+
message,
|
|
187
|
+
error,
|
|
188
|
+
childContext ? `${context}:${childContext}` : context
|
|
189
|
+
),
|
|
190
|
+
group: (title, callback) => this.group(`${context}: ${title}`, callback),
|
|
191
|
+
time: (label, callback) => this.time(`${context}: ${label}`, callback)
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
export {
|
|
196
|
+
Logger
|
|
197
|
+
};
|
|
198
|
+
//# sourceMappingURL=logging.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/logging/Logger.ts"],"sourcesContent":["/**\n * Logger - Centralized logging with configurable levels\n * \n * IMPORTANT: Never use console.* directly in game code (except in Logger implementation,\n * crash fallback, or dev utilities). Always use Logger methods with optional chaining.\n */\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\ninterface LogLevels {\n readonly debug: 0;\n readonly info: 1;\n readonly warn: 2;\n readonly error: 3;\n}\n\nexport interface LoggerConfig {\n isDebugEnabled: () => boolean;\n getLogLevel: () => LogLevel;\n}\n\nexport interface LoggerInterface {\n debug(message: string, context?: string): void;\n info(message: string, context?: string): void;\n warn(message: string, context?: string): void;\n error(message: string, error?: Error, context?: string): void;\n group<T>(title: string, callback: () => T): T;\n time<T>(label: string, callback: () => T): T;\n createChildLogger?: (context: string) => LoggerInterface;\n}\n\nexport class Logger implements LoggerInterface {\n private readonly config: LoggerConfig | null;\n private readonly levels: LogLevels = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n } as const;\n\n // Cached filter configuration - computed once on first use\n private filtersCached = false;\n private cachedIncludes: string[] = [];\n private cachedExcludes: string[] = [];\n\n constructor(config: LoggerConfig | null = null) {\n this.config = config;\n }\n\n /**\n * Cache filter configuration on first use.\n * Filters only change on page reload, so no need to re-read every call.\n */\n private ensureFiltersCached(): void {\n if (this.filtersCached) return;\n this.filtersCached = true;\n\n try {\n const params = (() => {\n try {\n return new URLSearchParams(globalThis?.location?.search || \"\");\n } catch {\n return new URLSearchParams(\"\");\n }\n })();\n\n const urlInclude = params.get(\"logInclude\") || params.get(\"log\") || \"\";\n const urlExclude = params.get(\"logExclude\") || \"\";\n const lsInclude = (() => {\n try {\n return globalThis?.localStorage?.getItem(\"game.log.include\") || \"\";\n } catch {\n return \"\";\n }\n })();\n const lsExclude = (() => {\n try {\n return globalThis?.localStorage?.getItem(\"game.log.exclude\") || \"\";\n } catch {\n return \"\";\n }\n })();\n\n const includeRaw = (urlInclude || lsInclude || \"\").trim();\n const excludeRaw = (urlExclude || lsExclude || \"\").trim();\n\n this.cachedIncludes = includeRaw\n ? includeRaw\n .split(\",\")\n .map((s) => s.trim().toLowerCase())\n .filter(Boolean)\n : [];\n this.cachedExcludes = excludeRaw\n ? excludeRaw\n .split(\",\")\n .map((s) => s.trim().toLowerCase())\n .filter(Boolean)\n : [];\n } catch {\n // If filters cannot be evaluated, use empty arrays\n this.cachedIncludes = [];\n this.cachedExcludes = [];\n }\n }\n\n /**\n * Check if logging is enabled for the given level\n */\n private shouldLog(level: LogLevel): boolean {\n if (!this.config?.isDebugEnabled()) return false;\n\n const configLogLevel = this.config.getLogLevel();\n const currentLevel = this.levels[configLogLevel] ?? 1;\n const messageLevel = this.levels[level] ?? 1;\n\n return messageLevel >= currentLevel;\n }\n\n /**\n * Format log message with timestamp and context\n */\n private formatMessage(\n level: LogLevel,\n message: string,\n context?: string,\n ): string {\n const timestamp = new Date().toISOString();\n const prefix = `[${timestamp}] [${level.toUpperCase()}]`;\n\n if (context) {\n return `${prefix} [${context}] ${message}`;\n }\n return `${prefix} ${message}`;\n }\n\n /**\n * Determine if this log line should pass include/exclude filters.\n * Uses cached filter configuration for performance.\n */\n private passesFilters(message: string, context?: string): boolean {\n this.ensureFiltersCached();\n\n // If includes are specified, require at least one to match\n if (this.cachedIncludes.length > 0) {\n const hay = `${context || \"\"} ${message}`.toLowerCase();\n const match = this.cachedIncludes.some((tok) => hay.includes(tok));\n if (!match) return false;\n }\n // If any exclude matches, drop the line\n if (this.cachedExcludes.length > 0) {\n const hay = `${context || \"\"} ${message}`.toLowerCase();\n const match = this.cachedExcludes.some((tok) => hay.includes(tok));\n if (match) return false;\n }\n return true;\n }\n\n /**\n * Debug level logging\n */\n debug(message: string, context?: string): void {\n if (this.shouldLog(\"debug\") && this.passesFilters(message, context)) {\n console.debug(this.formatMessage(\"debug\", message, context));\n }\n }\n\n /**\n * Info level logging\n */\n info(message: string, context?: string): void {\n if (this.shouldLog(\"info\") && this.passesFilters(message, context)) {\n console.info(this.formatMessage(\"info\", message, context));\n }\n }\n\n /**\n * Warning level logging\n */\n warn(message: string, context?: string): void {\n if (this.shouldLog(\"warn\") && this.passesFilters(message, context)) {\n console.warn(this.formatMessage(\"warn\", message, context));\n }\n }\n\n /**\n * Error level logging\n */\n error(message: string, error?: Error, context?: string): void {\n if (this.shouldLog(\"error\") && this.passesFilters(message, context)) {\n let errorMessage = message;\n if (error) {\n errorMessage += `: ${error.message}`;\n if (error.stack && this.config?.isDebugEnabled()) {\n errorMessage += `\\nStack trace: ${error.stack}`;\n }\n }\n console.error(this.formatMessage(\"error\", errorMessage, context));\n }\n }\n\n /**\n * Group logging operations\n */\n group<T>(title: string, callback: () => T): T {\n if (this.shouldLog(\"debug\")) {\n console.group(this.formatMessage(\"debug\", `Group: ${title}`));\n try {\n return callback();\n } finally {\n console.groupEnd();\n }\n } else {\n return callback();\n }\n }\n\n /**\n * Time a logging operation\n */\n time<T>(label: string, callback: () => T): T {\n if (this.shouldLog(\"debug\")) {\n const startTime = performance.now();\n try {\n return callback();\n } finally {\n const endTime = performance.now();\n const duration = endTime - startTime;\n this.debug(`${label} completed in ${duration.toFixed(2)}ms`);\n }\n } else {\n return callback();\n }\n }\n\n /**\n * Create a child logger with a specific context\n */\n createChildLogger(context: string): LoggerInterface {\n return {\n debug: (message: string, childContext?: string) =>\n this.debug(\n message,\n childContext ? `${context}:${childContext}` : context,\n ),\n info: (message: string, childContext?: string) =>\n this.info(\n message,\n childContext ? `${context}:${childContext}` : context,\n ),\n warn: (message: string, childContext?: string) =>\n this.warn(\n message,\n childContext ? `${context}:${childContext}` : context,\n ),\n error: (message: string, error?: Error, childContext?: string) =>\n this.error(\n message,\n error,\n childContext ? `${context}:${childContext}` : context,\n ),\n group: <T>(title: string, callback: () => T) =>\n this.group(`${context}: ${title}`, callback),\n time: <T>(label: string, callback: () => T) =>\n this.time(`${context}: ${label}`, callback),\n };\n }\n}\n"],"mappings":"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","names":[]}
|