@chromahq/core 1.0.57 → 1.0.61

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.
@@ -537,11 +537,11 @@ function setupEarlyListener(portName = DEFAULT_PORT_NAME$1) {
537
537
  if (portsClaimed && onPortConnectCallback) {
538
538
  onPortConnectCallback(port);
539
539
  } else {
540
- console.log(`[EarlyListener] Captured early port connection: ${port.name}`);
540
+ console.debug(`[EarlyListener] Captured early port connection: ${port.name}`);
541
541
  earlyPorts.push(port);
542
542
  }
543
543
  });
544
- console.log(`[EarlyListener] Early connection listener registered for port: ${portName}`);
544
+ console.debug(`[EarlyListener] Early connection listener registered for port: ${portName}`);
545
545
  }
546
546
  function claimEarlyPorts(onConnect) {
547
547
  if (portsClaimed) {
@@ -553,7 +553,7 @@ function claimEarlyPorts(onConnect) {
553
553
  const captured = [...earlyPorts];
554
554
  earlyPorts.length = 0;
555
555
  if (captured.length > 0) {
556
- console.log(`[EarlyListener] Claimed ${captured.length} early port(s)`);
556
+ console.debug(`[EarlyListener] Claimed ${captured.length} early port(s)`);
557
557
  }
558
558
  return captured;
559
559
  }
@@ -669,7 +669,7 @@ const _BridgeRuntimeManager = class _BridgeRuntimeManager {
669
669
  if (!this.isValidPort(port)) {
670
670
  return;
671
671
  }
672
- this.logger.info(`\u{1F4E1} Port connected: ${port.name}`);
672
+ this.logger.debug(`\u{1F4E1} Port connected: ${port.name}`);
673
673
  this.setupMessageHandler(port);
674
674
  if (chrome.runtime.lastError) {
675
675
  this.logger.warn(`Runtime error during port setup: ${chrome.runtime.lastError.message}`);
@@ -686,7 +686,7 @@ const _BridgeRuntimeManager = class _BridgeRuntimeManager {
686
686
  if (isEarlyListenerSetup()) {
687
687
  const earlyPorts = claimEarlyPorts(handlePort);
688
688
  if (earlyPorts.length > 0) {
689
- this.logger.info(
689
+ this.logger.debug(
690
690
  `\u{1F4E1} Processing ${earlyPorts.length} early port(s) captured during bootstrap`
691
691
  );
692
692
  earlyPorts.forEach(handlePort);
@@ -740,7 +740,7 @@ const _BridgeRuntimeManager = class _BridgeRuntimeManager {
740
740
  });
741
741
  chrome.alarms.onAlarm.addListener(this.handleKeepAliveAlarm);
742
742
  this.keepAliveAlarmRegistered = true;
743
- this.logger.info("Registered keep-alive alarm for background wakeups");
743
+ this.logger.debug("Registered keep-alive alarm for background wakeups");
744
744
  }
745
745
  recordKeepAlivePing(source) {
746
746
  const timestamp = Date.now();
@@ -817,7 +817,7 @@ const _BridgeRuntimeManager = class _BridgeRuntimeManager {
817
817
  void chrome.runtime.lastError;
818
818
  this.diagnostics.lastPortDisconnectError = runtimeErrorMessage;
819
819
  } else {
820
- this.logger.info(`\u{1F4F4} Port disconnected: ${port.name}`);
820
+ this.logger.debug(`\u{1F4F4} Port disconnected: ${port.name}`);
821
821
  }
822
822
  this.diagnostics.portDisconnects++;
823
823
  this.diagnostics.lastPortDisconnectAt = Date.now();
@@ -1075,7 +1075,7 @@ const _BridgeRuntimeManager = class _BridgeRuntimeManager {
1075
1075
  */
1076
1076
  startKeepAlive() {
1077
1077
  if (this.keepAliveTimer) return;
1078
- this.logger.info("Starting keep-alive timer to keep service worker alive");
1078
+ this.logger.debug("Starting keep-alive timer to keep service worker alive");
1079
1079
  this.keepAliveTimer = setInterval(() => {
1080
1080
  chrome.runtime.getPlatformInfo(() => {
1081
1081
  this.recordKeepAlivePing("interval");
@@ -1095,7 +1095,7 @@ const _BridgeRuntimeManager = class _BridgeRuntimeManager {
1095
1095
  if (this.keepAliveTimer) {
1096
1096
  clearInterval(this.keepAliveTimer);
1097
1097
  this.keepAliveTimer = null;
1098
- this.logger.info("Stopped keep-alive timer");
1098
+ this.logger.debug("Stopped keep-alive timer");
1099
1099
  }
1100
1100
  }
1101
1101
  };
@@ -1145,10 +1145,10 @@ const _AlarmAdapter = class _AlarmAdapter {
1145
1145
  /**
1146
1146
  * Initialize the Chrome Alarms listener (once)
1147
1147
  */
1148
- this.initializeAlarmListener = () => {
1148
+ this.initializeAlarmListener = async () => {
1149
1149
  if (this.listenerRegistered) return;
1150
1150
  if (this.isChromeAlarmsAvailable()) {
1151
- this.clearStaleAlarms();
1151
+ await this.clearStaleAlarms();
1152
1152
  chrome.alarms.onAlarm.addListener(this.handleAlarm);
1153
1153
  this.listenerRegistered = true;
1154
1154
  console.log("[AlarmAdapter] \u2705 Chrome Alarms API available and listener registered");
@@ -1159,20 +1159,31 @@ const _AlarmAdapter = class _AlarmAdapter {
1159
1159
  }
1160
1160
  };
1161
1161
  /**
1162
- * Clear any stale chroma alarms from previous SW instances
1162
+ * Clear any stale chroma alarms from previous SW instances.
1163
+ * Returns a promise that resolves once all stale alarms are cleared.
1163
1164
  */
1164
1165
  this.clearStaleAlarms = () => {
1165
- if (!this.isChromeAlarmsAvailable()) return;
1166
- chrome.alarms.getAll((alarms) => {
1167
- const staleAlarms = alarms.filter((a) => a.name.startsWith(_AlarmAdapter.ALARM_PREFIX));
1168
- if (staleAlarms.length > 0) {
1169
- console.log(
1170
- `[AlarmAdapter] \u{1F9F9} Clearing ${staleAlarms.length} stale alarms from previous session`
1171
- );
1172
- staleAlarms.forEach((alarm) => {
1173
- chrome.alarms.clear(alarm.name);
1174
- });
1175
- }
1166
+ if (!this.isChromeAlarmsAvailable()) return Promise.resolve();
1167
+ return new Promise((resolve) => {
1168
+ chrome.alarms.getAll((alarms) => {
1169
+ const staleAlarms = alarms.filter((a) => a.name.startsWith(_AlarmAdapter.ALARM_PREFIX));
1170
+ if (staleAlarms.length > 0) {
1171
+ console.log(
1172
+ `[AlarmAdapter] \u{1F9F9} Clearing ${staleAlarms.length} stale alarms from previous session`
1173
+ );
1174
+ let cleared = 0;
1175
+ staleAlarms.forEach((alarm) => {
1176
+ chrome.alarms.clear(alarm.name, () => {
1177
+ cleared++;
1178
+ if (cleared === staleAlarms.length) {
1179
+ resolve();
1180
+ }
1181
+ });
1182
+ });
1183
+ } else {
1184
+ resolve();
1185
+ }
1186
+ });
1176
1187
  });
1177
1188
  };
1178
1189
  /**
@@ -1277,7 +1288,7 @@ const _AlarmAdapter = class _AlarmAdapter {
1277
1288
  usingChromeApi: this.isChromeAlarmsAvailable()
1278
1289
  };
1279
1290
  };
1280
- this.initializeAlarmListener();
1291
+ this.ready = this.initializeAlarmListener();
1281
1292
  }
1282
1293
  };
1283
1294
  _AlarmAdapter.ALARM_PREFIX = "chroma_job_";
@@ -2086,11 +2097,32 @@ class Scheduler {
2086
2097
  error: console.error,
2087
2098
  debug: console.debug
2088
2099
  };
2089
- this.logger.info("Scheduler initialized");
2100
+ this.logger.debug("Scheduler initialized");
2090
2101
  this.alarm.onTrigger(this.execute.bind(this));
2091
2102
  this.timeout.onTrigger(this.execute.bind(this));
2092
2103
  this.setupPopupVisibilityListener();
2093
2104
  }
2105
+ /**
2106
+ * When `options.schedulerDebug` is true, log at info so diagnostics show without
2107
+ * enabling global debug. Otherwise logs at debug.
2108
+ */
2109
+ logJobDiagnostics(options, message, context) {
2110
+ const ctx = context;
2111
+ if (options?.schedulerDebug) {
2112
+ this.logger.info(message, ctx);
2113
+ } else {
2114
+ this.logger.debug(message, ctx);
2115
+ }
2116
+ }
2117
+ /** Batch summary visible at info if any involved job has `schedulerDebug`. */
2118
+ logBatchIfAnyJobDebug(jobIds, message) {
2119
+ const anyDebug = jobIds.some((jid) => this.registry.meta(jid)?.schedulerDebug);
2120
+ if (anyDebug) {
2121
+ this.logger.info(message);
2122
+ } else {
2123
+ this.logger.debug(message);
2124
+ }
2125
+ }
2094
2126
  /**
2095
2127
  * Setup listener for popup visibility changes.
2096
2128
  * When popup closes, pause all jobs with requiresPopup.
@@ -2098,9 +2130,9 @@ class Scheduler {
2098
2130
  */
2099
2131
  setupPopupVisibilityListener() {
2100
2132
  const visibilityService = PopupVisibilityService.instance;
2101
- this.logger.info("[Scheduler] Setting up popup visibility listener");
2133
+ this.logger.debug("[Scheduler] Setting up popup visibility listener");
2102
2134
  this.popupVisibilityUnsubscribe = visibilityService.onVisibilityChange((isVisible) => {
2103
- this.logger.info(`[Scheduler] Visibility changed: ${isVisible ? "visible" : "hidden"}`);
2135
+ this.logger.debug(`[Scheduler] Visibility changed: ${isVisible ? "visible" : "hidden"}`);
2104
2136
  if (isVisible) {
2105
2137
  this.resumePopupDependentJobs();
2106
2138
  } else {
@@ -2113,13 +2145,14 @@ class Scheduler {
2113
2145
  */
2114
2146
  pausePopupDependentJobs() {
2115
2147
  const jobs = this.registry.listAll();
2116
- this.logger.info(`[Scheduler] pausePopupDependentJobs called, total jobs: ${jobs.length}`);
2148
+ this.logger.debug(`[Scheduler] pausePopupDependentJobs called, total jobs: ${jobs.length}`);
2117
2149
  let pausedCount = 0;
2118
2150
  const pausedJobIds = [];
2119
2151
  for (const job of jobs) {
2120
2152
  const hasRequiresPopup = job.options?.requiresPopup;
2121
2153
  const isPaused = this.registry.getContext(job.id)?.isPaused();
2122
- this.logger.debug(
2154
+ this.logJobDiagnostics(
2155
+ job.options,
2123
2156
  `[Scheduler] Job ${job.id}: requiresPopup=${hasRequiresPopup}, isPaused=${isPaused}`
2124
2157
  );
2125
2158
  if (hasRequiresPopup && !isPaused) {
@@ -2131,11 +2164,12 @@ class Scheduler {
2131
2164
  }
2132
2165
  }
2133
2166
  if (pausedCount > 0) {
2134
- this.logger.info(
2167
+ this.logBatchIfAnyJobDebug(
2168
+ pausedJobIds,
2135
2169
  `[Scheduler] Paused ${pausedCount} popup-dependent jobs (popup closed): ${pausedJobIds.join(", ")}`
2136
2170
  );
2137
2171
  } else {
2138
- this.logger.info(`[Scheduler] No popup-dependent jobs to pause`);
2172
+ this.logger.debug(`[Scheduler] No popup-dependent jobs to pause`);
2139
2173
  }
2140
2174
  }
2141
2175
  /**
@@ -2143,13 +2177,14 @@ class Scheduler {
2143
2177
  */
2144
2178
  resumePopupDependentJobs() {
2145
2179
  const jobs = this.registry.listAll();
2146
- this.logger.info(`[Scheduler] resumePopupDependentJobs called, total jobs: ${jobs.length}`);
2180
+ this.logger.debug(`[Scheduler] resumePopupDependentJobs called, total jobs: ${jobs.length}`);
2147
2181
  let resumedCount = 0;
2148
2182
  const resumedJobIds = [];
2149
2183
  for (const job of jobs) {
2150
2184
  const hasRequiresPopup = job.options?.requiresPopup;
2151
2185
  const isPaused = this.registry.getContext(job.id)?.isPaused();
2152
- this.logger.debug(
2186
+ this.logJobDiagnostics(
2187
+ job.options,
2153
2188
  `[Scheduler] Job ${job.id}: requiresPopup=${hasRequiresPopup}, isPaused=${isPaused}`
2154
2189
  );
2155
2190
  if (hasRequiresPopup && isPaused) {
@@ -2160,11 +2195,12 @@ class Scheduler {
2160
2195
  }
2161
2196
  }
2162
2197
  if (resumedCount > 0) {
2163
- this.logger.info(
2198
+ this.logBatchIfAnyJobDebug(
2199
+ resumedJobIds,
2164
2200
  `[Scheduler] Resumed ${resumedCount} popup-dependent jobs (popup opened): ${resumedJobIds.join(", ")}`
2165
2201
  );
2166
2202
  } else {
2167
- this.logger.info(`[Scheduler] No popup-dependent jobs to resume`);
2203
+ this.logger.debug(`[Scheduler] No popup-dependent jobs to resume`);
2168
2204
  }
2169
2205
  }
2170
2206
  schedule(id, options) {
@@ -2175,7 +2211,8 @@ class Scheduler {
2175
2211
  if (options?.requiresPopup) {
2176
2212
  const isPopupVisible = PopupVisibilityService.instance.isPopupVisible();
2177
2213
  if (!isPopupVisible) {
2178
- this.logger.debug(
2214
+ this.logJobDiagnostics(
2215
+ options,
2179
2216
  `Job ${id} requires popup but popup is not visible, pausing instead of scheduling`
2180
2217
  );
2181
2218
  if (!context.isPaused()) {
@@ -2184,6 +2221,13 @@ class Scheduler {
2184
2221
  return;
2185
2222
  }
2186
2223
  }
2224
+ this.alarm.ready.then(() => this.scheduleInternal(id, options));
2225
+ }
2226
+ scheduleInternal(id, options) {
2227
+ const context = this.registry.getContext(id);
2228
+ if (!context || context.isStopped() || context.isPaused()) {
2229
+ return;
2230
+ }
2187
2231
  const when = this.getScheduleTime(options);
2188
2232
  const now = Date.now();
2189
2233
  if (when <= now) {
@@ -2207,26 +2251,27 @@ class Scheduler {
2207
2251
  if (adapter === this.timeout && timerId) {
2208
2252
  this.registry.setTimeoutId(id, timerId);
2209
2253
  }
2210
- this.logger.info(
2254
+ this.logJobDiagnostics(
2255
+ options,
2211
2256
  `[Scheduler] Job "${id}" scheduled for ${new Date(when).toISOString()} (in ${Math.round(delayMs / 1e3)}s) \u2192 ${adapter === this.alarm ? "\u23F0 AlarmAdapter" : "\u23F1\uFE0F TimeoutAdapter"}`
2212
2257
  );
2213
2258
  }
2214
2259
  pause(id) {
2215
- this.logger.info(`Pausing job ${id}`);
2260
+ this.logJobDiagnostics(this.registry.meta(id), `Pausing job ${id}`);
2216
2261
  this.alarm.cancel(id);
2217
2262
  this.timeout.cancel(id);
2218
2263
  this.registry.pause(id);
2219
2264
  }
2220
2265
  resume(id) {
2221
- this.logger.info(`Resuming job ${id}`);
2222
- this.registry.resume(id);
2223
2266
  const options = this.registry.meta(id);
2267
+ this.logJobDiagnostics(options, `Resuming job ${id}`);
2268
+ this.registry.resume(id);
2224
2269
  if (options) {
2225
2270
  this.schedule(id, options);
2226
2271
  }
2227
2272
  }
2228
2273
  stop(id) {
2229
- this.logger.info(`Stopping job ${id}`);
2274
+ this.logJobDiagnostics(this.registry.meta(id), `Stopping job ${id}`);
2230
2275
  this.alarm.cancel(id);
2231
2276
  this.timeout.cancel(id);
2232
2277
  this.registry.stop(id);
@@ -2236,26 +2281,25 @@ class Scheduler {
2236
2281
  const context = this.registry.getContext(id);
2237
2282
  const options = this.registry.meta(id);
2238
2283
  if (!job || !context) {
2239
- this.logger.debug(`Job ${id} not found or no context`);
2284
+ this.logJobDiagnostics(options, `Job ${id} not found or no context`);
2240
2285
  return;
2241
2286
  }
2242
2287
  if (context.isPaused() || context.isStopped()) {
2243
- this.logger.debug(`Job ${id} is paused or stopped, skipping execution`);
2288
+ this.logJobDiagnostics(options, `Job ${id} is paused or stopped, skipping execution`);
2244
2289
  return;
2245
2290
  }
2246
2291
  if (options?.requiresPopup) {
2247
2292
  const isPopupVisible = PopupVisibilityService.instance.isPopupVisible();
2248
2293
  if (!isPopupVisible) {
2249
- this.logger.debug(`Job ${id} requires popup but popup closed, pausing job`);
2294
+ this.logJobDiagnostics(options, `Job ${id} requires popup but popup closed, pausing job`);
2250
2295
  this.registry.pause(id);
2251
2296
  return;
2252
2297
  }
2253
2298
  }
2254
2299
  try {
2255
2300
  this.registry.updateState(id, JobState.RUNNING);
2256
- this.logger.info(`Executing job ${id}`);
2301
+ this.logJobDiagnostics(options, `Executing job ${id}`);
2257
2302
  const jobInstance = container.get(id);
2258
- this.logger.debug("Job instance:", { jobInstance });
2259
2303
  await jobInstance.handle.bind(jobInstance).call(jobInstance, context);
2260
2304
  if (!context.isStopped() && !context.isPaused()) {
2261
2305
  this.registry.updateState(id, JobState.COMPLETED);
@@ -2268,7 +2312,7 @@ class Scheduler {
2268
2312
  this.logger.error(`Job ${id} execution failed:`, error);
2269
2313
  context.fail(error);
2270
2314
  if (options?.cron || options?.recurring) {
2271
- this.logger.info(`Rescheduling failed recurring job ${id}`);
2315
+ this.logJobDiagnostics(options, `Rescheduling failed recurring job ${id}`);
2272
2316
  this.registry.updateState(id, JobState.SCHEDULED);
2273
2317
  this.schedule(id, options);
2274
2318
  }
@@ -2296,7 +2340,7 @@ class Scheduler {
2296
2340
  * Gracefully shutdown the scheduler, clearing all timers
2297
2341
  */
2298
2342
  shutdown() {
2299
- this.logger.info("Shutting down scheduler...");
2343
+ this.logger.debug("Shutting down scheduler...");
2300
2344
  if (this.popupVisibilityUnsubscribe) {
2301
2345
  this.popupVisibilityUnsubscribe();
2302
2346
  this.popupVisibilityUnsubscribe = void 0;
@@ -2304,7 +2348,7 @@ class Scheduler {
2304
2348
  this.alarm.clear();
2305
2349
  this.timeout.clear();
2306
2350
  this.registry.clear();
2307
- this.logger.info("Scheduler shutdown complete");
2351
+ this.logger.debug("Scheduler shutdown complete");
2308
2352
  }
2309
2353
  /**
2310
2354
  * Get scheduler stats for monitoring
@@ -2799,7 +2843,7 @@ class ApplicationBootstrap {
2799
2843
  if (!container.isBound(JobClass)) {
2800
2844
  container.bind(JobClass).toSelf().inSingletonScope();
2801
2845
  }
2802
- const id = `${jobName.toLowerCase()}:${JobClass.name.toLowerCase()} ${Math.random().toString(36).substring(2, 15)}`;
2846
+ const id = `${jobName.toLowerCase()}:${JobClass.name.toLowerCase()}`;
2803
2847
  container.bind(id).to(JobClass).inSingletonScope();
2804
2848
  const options = Reflect.getMetadata("job:options", JobClass) || {};
2805
2849
  jobEntries.push({ JobClass, jobName, id, options });
@@ -2942,4 +2986,4 @@ exports.getPopupVisibilityService = getPopupVisibilityService;
2942
2986
  exports.getSubscribeMetadata = getSubscribeMetadata;
2943
2987
  exports.isEarlyListenerSetup = isEarlyListenerSetup;
2944
2988
  exports.setupEarlyListener = setupEarlyListener;
2945
- //# sourceMappingURL=boot-DIMyFZvd.js.map
2989
+ //# sourceMappingURL=boot-CYBjSPxy.js.map