@crimsonsunset/jsg-logger 1.7.11 → 1.7.12

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 (2) hide show
  1. package/index.js +66 -2
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -49,6 +49,7 @@ class JSGLogger {
49
49
  static _instance = null;
50
50
  static _enhancedLoggers = null;
51
51
  static _hasLoggedInitialization = false;
52
+ static _initLock = false; // Lock to prevent concurrent initializations
52
53
 
53
54
  constructor() {
54
55
  this.loggers = {};
@@ -103,6 +104,8 @@ class JSGLogger {
103
104
  JSGLogger._enhancedLoggers = JSGLogger._instance.initSync(options);
104
105
  } else if (hasOptions) {
105
106
  // Instance exists but new options provided - reinitialize
107
+ // Only reinit if flag is not set (first init hasn't completed yet)
108
+ // or if we need to apply new config
106
109
  JSGLogger._enhancedLoggers = JSGLogger._instance.initSync(options);
107
110
  }
108
111
 
@@ -116,6 +119,17 @@ class JSGLogger {
116
119
  */
117
120
  async init(options = {}) {
118
121
  try {
122
+ // Track if this is a reinitialization (already initialized)
123
+ const isReinit = this.initialized;
124
+
125
+ // CRITICAL: Use global window flag to coordinate across bundled instances
126
+ const globalInitFlag = typeof window !== 'undefined'
127
+ ? (window.__JSG_LOGGER_INITIALIZED__ = window.__JSG_LOGGER_INITIALIZED__ || false)
128
+ : false;
129
+
130
+ // Check both static flag and global flag
131
+ const shouldLogInit = !JSGLogger._hasLoggedInitialization && !globalInitFlag && !isReinit;
132
+
119
133
  metaLog('[JSG-LOGGER] Initializing logger...', options.configPath ? `configPath: ${options.configPath}` : options.config ? 'inline config provided' : 'using defaults');
120
134
 
121
135
  // Load configuration FIRST (before environment detection)
@@ -155,7 +169,13 @@ class JSGLogger {
155
169
  this.initialized = true;
156
170
 
157
171
  // Log initialization success (only on first initialization)
158
- if (!JSGLogger._hasLoggedInitialization && this.loggers.core) {
172
+ // Double-check both flags here in case another call set it while we were initializing
173
+ const finalCheck = shouldLogInit &&
174
+ !JSGLogger._hasLoggedInitialization &&
175
+ !(typeof window !== 'undefined' && window.__JSG_LOGGER_INITIALIZED__) &&
176
+ this.loggers.core;
177
+
178
+ if (finalCheck) {
159
179
  this.loggers.core.info('JSG Logger initialized', {
160
180
  version: packageJson.version,
161
181
  environment: this.environment,
@@ -164,7 +184,11 @@ class JSGLogger {
164
184
  configPaths: configManager.loadedPaths,
165
185
  fileOverrides: Object.keys(configManager.config.fileOverrides || {}).length
166
186
  });
187
+ // Set both static flag and global flag immediately after logging
167
188
  JSGLogger._hasLoggedInitialization = true;
189
+ if (typeof window !== 'undefined') {
190
+ window.__JSG_LOGGER_INITIALIZED__ = true;
191
+ }
168
192
  }
169
193
 
170
194
  return this.getLoggerExports();
@@ -190,6 +214,31 @@ class JSGLogger {
190
214
  // Track if this is a reinitialization (already initialized)
191
215
  const isReinit = this.initialized;
192
216
 
217
+ // CRITICAL: Use global window flag to coordinate across bundled instances
218
+ // This handles cases where jsg-stylizer bundles its own copy of the logger
219
+ const globalInitFlag = typeof window !== 'undefined'
220
+ ? (window.__JSG_LOGGER_INITIALIZED__ = window.__JSG_LOGGER_INITIALIZED__ || false)
221
+ : false;
222
+
223
+ // CRITICAL: Use lock + flag to prevent race conditions
224
+ // If another call is already initializing, wait for it to complete
225
+ // This ensures only the first call logs, even if multiple calls happen simultaneously
226
+ if (!isReinit && JSGLogger._initLock) {
227
+ // Another initialization is in progress, skip this one
228
+ // Return existing instance if available, otherwise wait briefly
229
+ if (JSGLogger._enhancedLoggers) {
230
+ return JSGLogger._enhancedLoggers;
231
+ }
232
+ }
233
+
234
+ // Set lock if this is first initialization
235
+ if (!isReinit && !JSGLogger._hasLoggedInitialization && !globalInitFlag) {
236
+ JSGLogger._initLock = true;
237
+ }
238
+
239
+ // Check both static flag and global flag
240
+ const shouldLogInit = !JSGLogger._hasLoggedInitialization && !globalInitFlag && !isReinit;
241
+
193
242
  // Load inline config if provided (sync loading for objects)
194
243
  if (options && Object.keys(options).length > 0) {
195
244
  // Reset to default config for clean reinitialization
@@ -238,7 +287,13 @@ class JSGLogger {
238
287
 
239
288
  // Log initialization success (only on first initialization, not on reinit)
240
289
  // This prevents duplicate logs when multiple libraries call getInstanceSync
241
- if (!JSGLogger._hasLoggedInitialization && !isReinit && this.loggers.core) {
290
+ // Double-check both flags here in case another call set it while we were initializing
291
+ const finalCheck = shouldLogInit &&
292
+ !JSGLogger._hasLoggedInitialization &&
293
+ !(typeof window !== 'undefined' && window.__JSG_LOGGER_INITIALIZED__) &&
294
+ this.loggers.core;
295
+
296
+ if (finalCheck) {
242
297
  this.loggers.core.info('JSG Logger initialized (sync)', {
243
298
  version: packageJson.version,
244
299
  environment: this.environment,
@@ -247,7 +302,16 @@ class JSGLogger {
247
302
  fileOverrides: Object.keys(configManager.config.fileOverrides || {}).length,
248
303
  timestampMode: configManager.getTimestampMode()
249
304
  });
305
+ // Set both static flag and global flag immediately after logging
250
306
  JSGLogger._hasLoggedInitialization = true;
307
+ if (typeof window !== 'undefined') {
308
+ window.__JSG_LOGGER_INITIALIZED__ = true;
309
+ }
310
+ }
311
+
312
+ // Release lock after initialization completes
313
+ if (JSGLogger._initLock) {
314
+ JSGLogger._initLock = false;
251
315
  }
252
316
 
253
317
  return this.getLoggerExports();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crimsonsunset/jsg-logger",
3
- "version": "1.7.11",
3
+ "version": "1.7.12",
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",