@crimsonsunset/jsg-logger 1.8.0 → 1.8.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/CHANGELOG.md +15 -0
- package/index.js +62 -12
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,21 @@ All notable changes to the JSG Logger project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.8.2] - 2026-03-27 🛡️ **Reinit Guard + configure() API**
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **`JSGLogger.configure(partialConfig)`** — new static method for post-init config updates. Merges partial config into the running instance without reinitializing or touching registered transports. Exposed on the default export as `logger.configure()` and on the class as `JSGLogger.configure()`. If called before any initialization has occurred, delegates to `getInstanceSync(partialConfig)`.
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
- **Reinit guard in `getInstanceSync()`** — calling `getInstanceSync(options)` on an already-initialized instance now returns the existing singleton instead of reinitializing. Previously this would wipe registered transports (e.g. PostHog transport) on every call. A `console.warn` is emitted to surface the misuse at call sites.
|
|
15
|
+
- **Reinit guard in `getInstance()`** — same protection applied to the async path.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- Removed stale comment "// If options are provided, we need to reinitialize even if global instance exists" — the behavior is now the opposite by design.
|
|
19
|
+
|
|
20
|
+
### Migration
|
|
21
|
+
No breaking changes. If you were relying on calling `getInstanceSync(options)` multiple times to update config post-init (which was always a footgun), switch to `logger.configure(partialConfig)` instead.
|
|
22
|
+
|
|
8
23
|
## [1.7.7] - 2025-11-07 🔧 **DevTools Import Path Fix**
|
|
9
24
|
|
|
10
25
|
### Fixed
|
package/index.js
CHANGED
|
@@ -81,14 +81,17 @@ class JSGLogger {
|
|
|
81
81
|
window.__JSG_Logger_Enhanced__ = JSGLogger._enhancedLoggers;
|
|
82
82
|
}
|
|
83
83
|
} else if (hasOptions) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
window
|
|
84
|
+
if (JSGLogger._instance.initialized) {
|
|
85
|
+
console.warn(
|
|
86
|
+
'[JSGLogger] getInstance() called with options on an already-initialized instance — ' +
|
|
87
|
+
'options were ignored to preserve registered transports. Use configure() to update settings post-init.'
|
|
88
|
+
);
|
|
89
|
+
} else {
|
|
90
|
+
JSGLogger._enhancedLoggers = await JSGLogger._instance.init(options);
|
|
91
|
+
if (isBrowser() && typeof window !== 'undefined' && JSGLogger._enhancedLoggers?.controls) {
|
|
92
|
+
window.JSG_Logger = JSGLogger._enhancedLoggers.controls;
|
|
93
|
+
window.__JSG_Logger_Enhanced__ = JSGLogger._enhancedLoggers;
|
|
94
|
+
}
|
|
92
95
|
}
|
|
93
96
|
}
|
|
94
97
|
|
|
@@ -104,21 +107,29 @@ class JSGLogger {
|
|
|
104
107
|
static getInstanceSync(options = {}) {
|
|
105
108
|
const hasOptions = options && Object.keys(options).length > 0;
|
|
106
109
|
|
|
107
|
-
// If options are provided, we need to reinitialize even if global instance exists
|
|
108
|
-
// This ensures config changes (like devtools.enabled) are applied
|
|
109
110
|
if (hasOptions) {
|
|
110
|
-
|
|
111
|
+
if (JSGLogger._instance?.initialized) {
|
|
112
|
+
console.warn(
|
|
113
|
+
'[JSGLogger] getInstanceSync() called with options on an already-initialized instance — ' +
|
|
114
|
+
'options were ignored to preserve registered transports. Use configure() to update settings post-init.'
|
|
115
|
+
);
|
|
116
|
+
return JSGLogger._enhancedLoggers;
|
|
117
|
+
}
|
|
118
|
+
|
|
111
119
|
if (!JSGLogger._instance) {
|
|
112
120
|
JSGLogger._instance = new JSGLogger();
|
|
113
121
|
}
|
|
114
122
|
JSGLogger._enhancedLoggers = JSGLogger._instance.initSync(options);
|
|
115
123
|
|
|
116
|
-
// Update global references after reinitialization
|
|
117
124
|
if (isBrowser() && typeof window !== 'undefined' && JSGLogger._enhancedLoggers?.controls) {
|
|
118
125
|
window.JSG_Logger = JSGLogger._enhancedLoggers.controls;
|
|
119
126
|
window.__JSG_Logger_Enhanced__ = JSGLogger._enhancedLoggers;
|
|
120
127
|
}
|
|
121
128
|
|
|
129
|
+
if (!isBrowser()) {
|
|
130
|
+
globalThis.__JSG_Logger_Enhanced__ = JSGLogger._enhancedLoggers;
|
|
131
|
+
}
|
|
132
|
+
|
|
122
133
|
return JSGLogger._enhancedLoggers;
|
|
123
134
|
}
|
|
124
135
|
|
|
@@ -143,6 +154,13 @@ class JSGLogger {
|
|
|
143
154
|
};
|
|
144
155
|
}
|
|
145
156
|
|
|
157
|
+
// Server equivalent: check globalThis for cross-module-instance singleton
|
|
158
|
+
// Same problem as browser cross-bundle, but for Node.js bundled server chunks
|
|
159
|
+
if (!isBrowser() && globalThis.__JSG_Logger_Enhanced__) {
|
|
160
|
+
JSGLogger._enhancedLoggers = globalThis.__JSG_Logger_Enhanced__;
|
|
161
|
+
return JSGLogger._enhancedLoggers;
|
|
162
|
+
}
|
|
163
|
+
|
|
146
164
|
// No options and no global instance - first time initialization
|
|
147
165
|
if (!JSGLogger._instance) {
|
|
148
166
|
JSGLogger._instance = new JSGLogger();
|
|
@@ -153,6 +171,11 @@ class JSGLogger {
|
|
|
153
171
|
window.JSG_Logger = JSGLogger._enhancedLoggers.controls;
|
|
154
172
|
window.__JSG_Logger_Enhanced__ = JSGLogger._enhancedLoggers;
|
|
155
173
|
}
|
|
174
|
+
|
|
175
|
+
// Server equivalent: persist to globalThis for cross-bundle access
|
|
176
|
+
if (!isBrowser()) {
|
|
177
|
+
globalThis.__JSG_Logger_Enhanced__ = JSGLogger._enhancedLoggers;
|
|
178
|
+
}
|
|
156
179
|
}
|
|
157
180
|
|
|
158
181
|
return JSGLogger._enhancedLoggers;
|
|
@@ -542,6 +565,9 @@ class JSGLogger {
|
|
|
542
565
|
// Expose config manager for runtime configuration
|
|
543
566
|
configManager: configManager,
|
|
544
567
|
|
|
568
|
+
// Post-init config updater — safe to call after transports are registered
|
|
569
|
+
configure: (partialConfig) => JSGLogger.configure(partialConfig),
|
|
570
|
+
|
|
545
571
|
// Log store for popup/debugging
|
|
546
572
|
logStore: this.logStore,
|
|
547
573
|
|
|
@@ -970,6 +996,29 @@ class JSGLogger {
|
|
|
970
996
|
}
|
|
971
997
|
}
|
|
972
998
|
|
|
999
|
+
/**
|
|
1000
|
+
* Update logger configuration post-initialization without reinitializing.
|
|
1001
|
+
* Merges partialConfig into the current config without touching registered transports.
|
|
1002
|
+
* Transports can only be registered at init time — this method cannot add or remove them.
|
|
1003
|
+
* If called before any initialization has occurred, delegates to getInstanceSync(partialConfig).
|
|
1004
|
+
* @param {Object} partialConfig - Partial config to merge into the current config
|
|
1005
|
+
* @returns {Object} Enhanced logger exports
|
|
1006
|
+
*/
|
|
1007
|
+
static configure(partialConfig = {}) {
|
|
1008
|
+
if (!JSGLogger._instance?.initialized) {
|
|
1009
|
+
return JSGLogger.getInstanceSync(partialConfig);
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
const currentTransports = JSGLogger._instance.transports;
|
|
1013
|
+
const normalized = configManager._normalizeConfigStructure(partialConfig);
|
|
1014
|
+
configManager.config = configManager.mergeConfigs(configManager.config, normalized);
|
|
1015
|
+
configManager.config.transports = currentTransports;
|
|
1016
|
+
JSGLogger._instance.transports = currentTransports;
|
|
1017
|
+
JSGLogger._instance.refreshLoggers();
|
|
1018
|
+
|
|
1019
|
+
return JSGLogger._enhancedLoggers;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
973
1022
|
/**
|
|
974
1023
|
* Get singleton controls without triggering initialization
|
|
975
1024
|
* Checks window.JSG_Logger first to ensure singleton works across separate bundles
|
|
@@ -1002,6 +1051,7 @@ if (isBrowser() && typeof window !== 'undefined') {
|
|
|
1002
1051
|
// Add static methods to the enhanced loggers for convenience
|
|
1003
1052
|
enhancedLoggers.getInstance = JSGLogger.getInstance;
|
|
1004
1053
|
enhancedLoggers.getInstanceSync = JSGLogger.getInstanceSync;
|
|
1054
|
+
enhancedLoggers.configure = JSGLogger.configure.bind(JSGLogger);
|
|
1005
1055
|
enhancedLoggers.logPerformance = JSGLogger.logPerformance;
|
|
1006
1056
|
enhancedLoggers.JSGLogger = JSGLogger;
|
|
1007
1057
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crimsonsunset/jsg-logger",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Multi-environment logger with smart detection, file-level overrides, and beautiful console formatting. Test it live: https://logger.joesangiorgio.com/",
|
|
6
6
|
"main": "index.js",
|