extension-develop 3.9.0-next.3 → 3.9.0-next.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.
package/dist/323.cjs CHANGED
@@ -268,20 +268,7 @@ exports.modules = {
268
268
  class CDPExtensionController {
269
269
  async connect() {
270
270
  if (this.cdp) return;
271
- this.cdp = await connectToChromeCdp(this.cdpPort);
272
- try {
273
- await this.cdp.sendCommand('Target.setDiscoverTargets', {
274
- discover: true
275
- });
276
- await this.cdp.sendCommand('Target.setAutoAttach', {
277
- autoAttach: true,
278
- waitForDebuggerOnStart: false,
279
- flatten: true
280
- });
281
- } catch (error) {
282
- if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.warn(messages.wXK(String(error?.message || error)));
283
- }
284
- registerAutoEnableLogging(this.cdp, ()=>this.extensionId);
271
+ await this.connectFreshClient();
285
272
  }
286
273
  async ensureLoaded() {
287
274
  if (!this.cdp) throw new Error('CDP not connected');
@@ -414,13 +401,45 @@ exports.modules = {
414
401
  return 'unknown';
415
402
  }
416
403
  async hardReload() {
417
- if (!this.cdp || !this.extensionId) return false;
404
+ if (!this.extensionId) return false;
418
405
  try {
419
- return await this.cdp.forceReloadExtension(this.extensionId);
406
+ if (!this.cdp) await this.connectFreshClient();
407
+ if (this.cdp && await this.cdp.forceReloadExtension(this.extensionId)) return true;
408
+ } catch {}
409
+ try {
410
+ await this.reconnectForReload();
411
+ return Boolean(this.cdp && this.extensionId && await this.cdp.forceReloadExtension(this.extensionId));
420
412
  } catch {
421
413
  return false;
422
414
  }
423
415
  }
416
+ async connectFreshClient() {
417
+ this.cdp = await connectToChromeCdp(this.cdpPort);
418
+ try {
419
+ await this.cdp.sendCommand('Target.setDiscoverTargets', {
420
+ discover: true
421
+ });
422
+ await this.cdp.sendCommand('Target.setAutoAttach', {
423
+ autoAttach: true,
424
+ waitForDebuggerOnStart: false,
425
+ flatten: true
426
+ });
427
+ } catch (error) {
428
+ if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.warn(messages.wXK(String(error?.message || error)));
429
+ }
430
+ registerAutoEnableLogging(this.cdp, ()=>this.extensionId);
431
+ }
432
+ async reconnectForReload() {
433
+ try {
434
+ this.cdp?.disconnect?.();
435
+ } catch {}
436
+ this.cdp = null;
437
+ await this.connectFreshClient();
438
+ try {
439
+ const derivedExtensionId = await this.deriveExtensionIdFromTargets(10, 150);
440
+ if (derivedExtensionId) this.extensionId = derivedExtensionId;
441
+ } catch {}
442
+ }
424
443
  onProtocolEvent(cb) {
425
444
  if (!this.cdp) throw new Error('CDP not connected');
426
445
  this.cdp.onProtocolEvent((raw)=>{
package/dist/324.cjs CHANGED
@@ -7,7 +7,10 @@ exports.modules = {
7
7
  __webpack_require__.d(__webpack_exports__, {
8
8
  devServer: ()=>dev_server_devServer
9
9
  });
10
+ var external_fs_ = __webpack_require__("fs");
11
+ var external_fs_default = /*#__PURE__*/ __webpack_require__.n(external_fs_);
10
12
  var external_path_ = __webpack_require__("path");
13
+ var external_stream_ = __webpack_require__("stream");
11
14
  var core_ = __webpack_require__("@rspack/core");
12
15
  var dev_server_ = __webpack_require__("@rspack/dev-server");
13
16
  var external_webpack_merge_ = __webpack_require__("webpack-merge");
@@ -88,7 +91,6 @@ exports.modules = {
88
91
  this.basePort = basePort;
89
92
  }
90
93
  }
91
- var external_fs_ = __webpack_require__("fs");
92
94
  function hasDependency(projectPath, dependency) {
93
95
  const findNearestPackageJsonDirectory = (startPath)=>{
94
96
  let currentDirectory = startPath;
@@ -213,6 +215,139 @@ exports.modules = {
213
215
  function shouldWriteAssetToDisk(filePath) {
214
216
  return !/(?:^|[/\\])manifest\.json$/i.test(filePath);
215
217
  }
218
+ function isSamePath(left, right) {
219
+ return external_path_.resolve(left) === external_path_.resolve(right);
220
+ }
221
+ function isManifestTempPath(filePath) {
222
+ const base = external_path_.basename(filePath);
223
+ return base.startsWith('.manifest.') && base.endsWith('.tmp');
224
+ }
225
+ function createDiscardWriteStream() {
226
+ const stream = new external_stream_.Writable({
227
+ write (_chunk, _encoding, callback) {
228
+ callback();
229
+ }
230
+ });
231
+ stream.on('finish', ()=>{
232
+ stream.emit('close');
233
+ });
234
+ process.nextTick(()=>{
235
+ stream.emit('open', 0);
236
+ });
237
+ return stream;
238
+ }
239
+ const guardedManifestDiskWritePaths = new Set();
240
+ let isManifestDiskWriteGuardInstalled = false;
241
+ function hasGuardedManifestDiskPath(filePath) {
242
+ if ('string' != typeof filePath) return false;
243
+ const resolvedPath = external_path_.resolve(filePath);
244
+ for (const guardedPath of guardedManifestDiskWritePaths)if (isSamePath(guardedPath, resolvedPath)) return true;
245
+ return false;
246
+ }
247
+ function suppressManifestOutputWrites(compiler, manifestOutputPath) {
248
+ const outputFileSystem = compiler?.outputFileSystem;
249
+ if (!outputFileSystem || outputFileSystem.__extensionjsManifestWriteGuard) return;
250
+ const isManifestPath = (filePath)=>'string' == typeof filePath && isSamePath(filePath, manifestOutputPath);
251
+ if ('function' == typeof outputFileSystem.writeFile) {
252
+ const originalWriteFile = outputFileSystem.writeFile.bind(outputFileSystem);
253
+ outputFileSystem.writeFile = (filePath, ...args)=>{
254
+ if (isManifestPath(filePath)) {
255
+ const callback = args[args.length - 1];
256
+ if ('function' == typeof callback) callback(null);
257
+ return;
258
+ }
259
+ return originalWriteFile(filePath, ...args);
260
+ };
261
+ }
262
+ if ('function' == typeof outputFileSystem.writeFileSync) {
263
+ const originalWriteFileSync = outputFileSystem.writeFileSync.bind(outputFileSystem);
264
+ outputFileSystem.writeFileSync = (filePath, ...args)=>{
265
+ if (isManifestPath(filePath)) return;
266
+ return originalWriteFileSync(filePath, ...args);
267
+ };
268
+ }
269
+ if ('function' == typeof outputFileSystem.createWriteStream) {
270
+ const originalCreateWriteStream = outputFileSystem.createWriteStream.bind(outputFileSystem);
271
+ outputFileSystem.createWriteStream = (filePath, ...args)=>{
272
+ if (isManifestPath(filePath)) {
273
+ const stream = createDiscardWriteStream();
274
+ stream.path = filePath;
275
+ return stream;
276
+ }
277
+ return originalCreateWriteStream(filePath, ...args);
278
+ };
279
+ }
280
+ if ('function' == typeof outputFileSystem?.promises?.writeFile) {
281
+ const originalPromiseWriteFile = outputFileSystem.promises.writeFile.bind(outputFileSystem.promises);
282
+ outputFileSystem.promises.writeFile = async (filePath, ...args)=>{
283
+ if (isManifestPath(filePath)) return;
284
+ return originalPromiseWriteFile(filePath, ...args);
285
+ };
286
+ }
287
+ outputFileSystem.__extensionjsManifestWriteGuard = true;
288
+ }
289
+ function installManifestDiskWriteGuard(manifestOutputPath) {
290
+ const guardKey = external_path_.resolve(manifestOutputPath);
291
+ guardedManifestDiskWritePaths.add(guardKey);
292
+ if (isManifestDiskWriteGuardInstalled) return;
293
+ const guardedFs = external_fs_default();
294
+ const isManifestPath = (filePath)=>hasGuardedManifestDiskPath(filePath);
295
+ const allowManifestRename = (fromPath, toPath)=>'string' == typeof fromPath && 'string' == typeof toPath && isManifestPath(toPath) && isManifestTempPath(fromPath);
296
+ const originalWriteFile = guardedFs.writeFile.bind(guardedFs);
297
+ guardedFs.writeFile = (filePath, ...args)=>{
298
+ if (isManifestPath(filePath)) {
299
+ const callback = args[args.length - 1];
300
+ if ('function' == typeof callback) callback(null);
301
+ return;
302
+ }
303
+ return originalWriteFile(filePath, ...args);
304
+ };
305
+ const originalWriteFileSync = guardedFs.writeFileSync.bind(guardedFs);
306
+ guardedFs.writeFileSync = (filePath, ...args)=>{
307
+ if (isManifestPath(filePath)) return;
308
+ return originalWriteFileSync(filePath, ...args);
309
+ };
310
+ const originalCreateWriteStream = guardedFs.createWriteStream.bind(guardedFs);
311
+ guardedFs.createWriteStream = (filePath, ...args)=>{
312
+ if (isManifestPath(filePath)) {
313
+ const stream = createDiscardWriteStream();
314
+ stream.path = String(filePath);
315
+ return stream;
316
+ }
317
+ return originalCreateWriteStream(filePath, ...args);
318
+ };
319
+ const originalOpen = guardedFs.open.bind(guardedFs);
320
+ guardedFs.open = (pathLike, flags, ...args)=>{
321
+ const nextPath = isManifestPath(pathLike) ? '/dev/null' : pathLike;
322
+ return originalOpen(nextPath, flags, ...args);
323
+ };
324
+ const originalOpenSync = guardedFs.openSync.bind(guardedFs);
325
+ guardedFs.openSync = (pathLike, flags, ...args)=>{
326
+ const nextPath = isManifestPath(pathLike) ? '/dev/null' : pathLike;
327
+ return originalOpenSync(nextPath, flags, ...args);
328
+ };
329
+ const originalRename = guardedFs.rename.bind(guardedFs);
330
+ guardedFs.rename = (oldPath, newPath, callback)=>{
331
+ if (isManifestPath(newPath) && !allowManifestRename(oldPath, newPath)) {
332
+ if ('function' == typeof callback) callback(null);
333
+ return;
334
+ }
335
+ return originalRename(oldPath, newPath, callback);
336
+ };
337
+ const originalRenameSync = guardedFs.renameSync.bind(guardedFs);
338
+ guardedFs.renameSync = (oldPath, newPath)=>{
339
+ if (isManifestPath(newPath) && !allowManifestRename(oldPath, newPath)) return;
340
+ return originalRenameSync(oldPath, newPath);
341
+ };
342
+ if (guardedFs.promises?.writeFile) {
343
+ const originalPromiseWriteFile = guardedFs.promises.writeFile.bind(guardedFs.promises);
344
+ guardedFs.promises.writeFile = async (filePath, ...args)=>{
345
+ if (isManifestPath(filePath)) return;
346
+ return originalPromiseWriteFile(filePath, ...args);
347
+ };
348
+ }
349
+ isManifestDiskWriteGuardInstalled = true;
350
+ }
216
351
  async function dev_server_devServer(projectStructure, devOptions) {
217
352
  process.env.EXTENSION_BROWSER_LAUNCH_ENABLED = devOptions.noBrowser ? '0' : '1';
218
353
  const { manifestPath, packageJsonPath } = projectStructure;
@@ -272,6 +407,9 @@ exports.modules = {
272
407
  }
273
408
  };
274
409
  const compiler = (0, core_.rspack)(compilerConfig);
410
+ const manifestOutputPath = external_path_.join(packageJsonDir, 'dist', devOptions.browser, 'manifest.json');
411
+ installManifestDiskWriteGuard(manifestOutputPath);
412
+ suppressManifestOutputWrites(compiler, manifestOutputPath);
275
413
  const metadata = (0, plugin_playwright.Ih)({
276
414
  packageJsonDir,
277
415
  browser: String(devOptions.browser || 'chromium'),
@@ -280,7 +418,13 @@ exports.modules = {
280
418
  manifestPath,
281
419
  port
282
420
  });
283
- (0, compiler_hooks.N)(compiler);
421
+ (0, compiler_hooks.NP)(compiler);
422
+ if (devOptions.noBrowser) (0, compiler_hooks.y1)({
423
+ compiler,
424
+ browser: String(devOptions.browser || 'chromium'),
425
+ manifestPath,
426
+ readyPath: metadata.readyPath
427
+ });
284
428
  if (void 0 !== devOptions.port && devOptions.port !== port) console.log(messages.aO(devOptions.port, port));
285
429
  const serverConfig = {
286
430
  host: devServerHost,
@@ -332,16 +476,6 @@ exports.modules = {
332
476
  }, START_TIMEOUT_MS);
333
477
  await devServer.start();
334
478
  if (startTimeout) clearTimeout(startTimeout);
335
- if (devOptions.noBrowser) {
336
- console.log(messages.Gc('development', devOptions.browser));
337
- console.log(messages.tl());
338
- console.log(messages.bL({
339
- browser: String(devOptions.browser || 'chromium'),
340
- manifestPath,
341
- readyPath: metadata.readyPath
342
- }));
343
- }
344
- console.log(messages.tl());
345
479
  } catch (error) {
346
480
  if (startTimeout) clearTimeout(startTimeout);
347
481
  metadata.writeError('dev_server_start_failed', error instanceof Error ? error.message : String(error));
package/dist/552.cjs CHANGED
@@ -11,7 +11,7 @@ exports.modules = {
11
11
  function scrubBrand(txt, brand = 'Extension.js') {
12
12
  if (!txt) return txt;
13
13
  const safeBrand = brand.replace(/\$/g, '$$$$');
14
- return txt.replace(RegExp("(?<!@)\\bRspack\\b", "gi"), safeBrand).replace(RegExp("(?<!@)\\bWebpack\\b", "gi"), safeBrand).replace(RegExp("(?<!@)\\bwebpack-dev-server\\b", "gi"), `${safeBrand} dev server`).replace(RegExp("(?<!@)\\bRspackDevServer\\b", "gi"), `${safeBrand} dev server`).replace(/ModuleBuildError:\s*/g, '').replace(/ModuleParseError:\s*/g, '').replace(/Error:\s*Module\s+build\s+failed.*?\n/gi, '').replace(/\n{3,}/g, '\n\n');
14
+ return txt.replace(RegExp("(?<!@)\\bRspack\\b", "gi"), safeBrand).replace(RegExp("(?<!@)\\bWebpack\\b", "gi"), safeBrand).replace(RegExp("(?<!@)\\bwebpack-dev-server\\b", "gi"), `${safeBrand} dev server`).replace(RegExp("(?<!@)\\bRspackDevServer\\b", "gi"), `${safeBrand} dev server`).replace(/ModuleBuildError:\s*/g, '').replace(/ModuleParseError:\s*/g, '').replace(/Error:\s*Module\s+build\s+failed.*?\n/gi, '').replace(/\n{3,}/g, '\n\n').replace(/\n{2}(?=WARNING in )/g, '\n');
15
15
  }
16
16
  function makeSanitizedConsole(brand = 'Extension.js') {
17
17
  const sanitize = (a)=>'string' == typeof a ? scrubBrand(a, brand) : a;
package/dist/module.cjs CHANGED
@@ -129186,7 +129186,6 @@ var __webpack_modules__ = {
129186
129186
  async function maybePrintDevBanner(args) {
129187
129187
  const mode = args.compilation?.options?.mode || 'development';
129188
129188
  if ('development' !== mode) return;
129189
- if (args.enableCdp) return;
129190
129189
  const loadExtensionFlag = args.chromiumConfig.find((flag)=>flag.startsWith('--load-extension='));
129191
129190
  const extensionOutputPath = (0, extension_output_path.W)(args.compilation, loadExtensionFlag);
129192
129191
  if (!extensionOutputPath) return;
@@ -129194,6 +129193,7 @@ var __webpack_modules__ = {
129194
129193
  timeoutMs: 10000
129195
129194
  });
129196
129195
  if (!ready) return;
129196
+ if (args.enableCdp) return;
129197
129197
  await (0, banner.a)({
129198
129198
  browser: args.browser,
129199
129199
  outPath: extensionOutputPath,
@@ -129226,7 +129226,7 @@ var __webpack_modules__ = {
129226
129226
  if (this.didLaunch) return;
129227
129227
  await this.launchChromium(stats.compilation);
129228
129228
  this.didLaunch = true;
129229
- if (!this.didReportReady) this.logger.info(dev_server_messages.Gc(stats.compilation.options.mode, this.options.browser));
129229
+ if (!this.didReportReady) console.log(dev_server_messages.Gc(stats.compilation.options.mode, this.options.browser));
129230
129230
  } catch (error) {
129231
129231
  try {
129232
129232
  this.logger.error(messages._D4(this.options.browser, error));
@@ -129280,9 +129280,10 @@ var __webpack_modules__ = {
129280
129280
  return 'npx extension install chrome';
129281
129281
  }
129282
129282
  };
129283
+ const isAuthorMode = 'true' === process.env.EXTENSION_AUTHOR_MODE;
129283
129284
  switch(browser){
129284
129285
  case 'chrome':
129285
- console.log(messages.GqE(browser));
129286
+ if (isAuthorMode) console.log(messages.GqE(browser));
129286
129287
  if (!skipDetection) try {
129287
129288
  try {
129288
129289
  const located = (0, external_chrome_location2_.locateChromeOrExplain)({
@@ -129319,7 +129320,7 @@ var __webpack_modules__ = {
129319
129320
  }
129320
129321
  break;
129321
129322
  case 'chromium':
129322
- console.log(messages.GqE(browser));
129323
+ if (isAuthorMode) console.log(messages.GqE(browser));
129323
129324
  browserBinaryLocation = this.options?.chromiumBinary || null;
129324
129325
  if (this.options?.chromiumBinary) {
129325
129326
  const normalized = normalizePath(String(this.options.chromiumBinary));
@@ -129339,7 +129340,7 @@ var __webpack_modules__ = {
129339
129340
  if (!browserBinaryLocation) browserBinaryLocation = resolveWslWindowsBinary(browser);
129340
129341
  break;
129341
129342
  case 'edge':
129342
- console.log(messages.GqE(browser));
129343
+ if (isAuthorMode) console.log(messages.GqE(browser));
129343
129344
  try {
129344
129345
  const override = String(process.env.EDGE_BINARY || '').trim();
129345
129346
  if (override) {
@@ -129515,7 +129516,7 @@ var __webpack_modules__ = {
129515
129516
  if (this.options.dryRun) return void logChromiumDryRun(browserBinaryLocation, chromiumConfig);
129516
129517
  await this.launchWithDirectSpawn(browserBinaryLocation, chromiumConfig);
129517
129518
  if ('development' === compilation.options.mode && !this.didReportReady) {
129518
- this.logger.info(dev_server_messages.Gc(compilation.options.mode, this.options.browser));
129519
+ console.log(dev_server_messages.Gc(compilation.options.mode, this.options.browser));
129519
129520
  this.didReportReady = true;
129520
129521
  }
129521
129522
  try {
@@ -129656,6 +129657,42 @@ var __webpack_modules__ = {
129656
129657
  return;
129657
129658
  }
129658
129659
  }
129660
+ function normalizeManifestFile(filePath) {
129661
+ if ('string' != typeof filePath) return;
129662
+ const normalized = filePath.trim().replace(/^\/+/, '');
129663
+ if (!normalized) return;
129664
+ if (/^(https?:)?\/\//i.test(filePath)) return;
129665
+ if (/[*?[\]{}]/.test(normalized)) return;
129666
+ return normalized;
129667
+ }
129668
+ function getManifestRequiredFiles(content) {
129669
+ try {
129670
+ const manifest = JSON.parse(content);
129671
+ const requiredFiles = new Set();
129672
+ const addFile = (filePath)=>{
129673
+ const normalized = normalizeManifestFile(filePath);
129674
+ if (normalized) requiredFiles.add(normalized);
129675
+ };
129676
+ addFile(manifest.background?.service_worker);
129677
+ addFile(manifest.background?.page);
129678
+ if (Array.isArray(manifest.background?.scripts)) for (const script of manifest.background?.scripts || [])addFile(script);
129679
+ addFile(manifest.side_panel?.default_path);
129680
+ if (Array.isArray(manifest.content_scripts)) for (const contentScript of manifest.content_scripts){
129681
+ if (Array.isArray(contentScript?.js)) for (const jsFile of contentScript.js)addFile(jsFile);
129682
+ if (Array.isArray(contentScript?.css)) for (const cssFile of contentScript.css)addFile(cssFile);
129683
+ }
129684
+ return [
129685
+ ...requiredFiles
129686
+ ];
129687
+ } catch {
129688
+ return [];
129689
+ }
129690
+ }
129691
+ function hasRequiredManifestFiles(outPath, content) {
129692
+ const requiredFiles = getManifestRequiredFiles(content);
129693
+ for (const relativeFile of requiredFiles)if (!fs__rspack_import_0.existsSync(path__rspack_import_1.join(outPath, relativeFile))) return false;
129694
+ return true;
129695
+ }
129659
129696
  async function waitForStableManifest(outPath, options) {
129660
129697
  const timeoutMs = options?.timeoutMs ?? 8000;
129661
129698
  const pollIntervalMs = options?.pollIntervalMs ?? 150;
@@ -129666,7 +129703,7 @@ var __webpack_modules__ = {
129666
129703
  let stableReads = 0;
129667
129704
  while(Date.now() - start < timeoutMs){
129668
129705
  const currentContent = readValidManifest(manifestPath);
129669
- if (currentContent) {
129706
+ if (currentContent && hasRequiredManifestFiles(outPath, currentContent)) {
129670
129707
  if (currentContent === lastValidContent) stableReads += 1;
129671
129708
  else {
129672
129709
  lastValidContent = currentContent;
@@ -135379,7 +135416,7 @@ var __webpack_modules__ = {
135379
135416
  },
135380
135417
  "./package.json" (module) {
135381
135418
  "use strict";
135382
- module.exports = JSON.parse('{"rE":"3.9.0-next.3","El":{"@rspack/core":"^1.7.5","@rspack/dev-server":"^1.1.5","@swc/core":"^1.15.8","@swc/helpers":"^0.5.18","adm-zip":"^0.5.16","browser-extension-manifest-fields":"^2.2.1","case-sensitive-paths-webpack-plugin":"^2.4.0","chrome-location2":"4.0.0","chromium-location":"2.0.0","content-security-policy-parser":"^0.6.0","cross-spawn":"^7.0.6","dotenv":"^17.2.3","edge-location":"2.2.0","extension-from-store":"^0.1.1","firefox-location2":"3.0.0","go-git-it":"^5.1.1","ignore":"^7.0.5","loader-utils":"^3.3.1","magic-string":"^0.30.21","parse5":"^8.0.0","parse5-utilities":"^1.0.0","pintor":"0.3.0","schema-utils":"^4.3.3","tiny-glob":"^0.2.9","unique-names-generator":"^4.7.1","webextension-polyfill":"^0.12.0","webpack-merge":"^6.0.1","webpack-target-webextension":"^2.1.3","ws":"^8.19.0"}}');
135419
+ module.exports = JSON.parse('{"rE":"3.9.0-next.5","El":{"@rspack/core":"^1.7.5","@rspack/dev-server":"^1.1.5","@swc/core":"^1.15.8","@swc/helpers":"^0.5.18","adm-zip":"^0.5.16","browser-extension-manifest-fields":"^2.2.1","case-sensitive-paths-webpack-plugin":"^2.4.0","chrome-location2":"4.0.0","chromium-location":"2.0.0","content-security-policy-parser":"^0.6.0","cross-spawn":"^7.0.6","dotenv":"^17.2.3","edge-location":"2.2.0","extension-from-store":"^0.1.1","firefox-location2":"3.0.0","go-git-it":"^5.1.1","ignore":"^7.0.5","loader-utils":"^3.3.1","magic-string":"^0.30.21","parse5":"^8.0.0","parse5-utilities":"^1.0.0","pintor":"0.3.0","schema-utils":"^4.3.3","tiny-glob":"^0.2.9","unique-names-generator":"^4.7.1","webextension-polyfill":"^0.12.0","webpack-merge":"^6.0.1","webpack-target-webextension":"^2.1.3","ws":"^8.19.0"}}');
135383
135420
  }
135384
135421
  };
135385
135422
  var __webpack_module_cache__ = {};
@@ -136259,7 +136296,7 @@ var __webpack_exports__ = {};
136259
136296
  __webpack_require__.e("552").then(__webpack_require__.bind(__webpack_require__, "./webpack/webpack-lib/stats-handler.ts")),
136260
136297
  Promise.all([
136261
136298
  __webpack_require__.e("215"),
136262
- __webpack_require__.e("946")
136299
+ __webpack_require__.e("270")
136263
136300
  ]).then(__webpack_require__.bind(__webpack_require__, "./webpack/webpack-config.ts"))
136264
136301
  ]);
136265
136302
  const debug = isAuthor;
@@ -136403,7 +136440,7 @@ var __webpack_exports__ = {};
136403
136440
  if ('true' === process.env.EXTENSION_DEV_DRY_RUN) return;
136404
136441
  const { devServer } = await Promise.all([
136405
136442
  __webpack_require__.e("215"),
136406
- __webpack_require__.e("946"),
136443
+ __webpack_require__.e("270"),
136407
136444
  __webpack_require__.e("324")
136408
136445
  ]).then(__webpack_require__.bind(__webpack_require__, "./webpack/dev-server/index.ts"));
136409
136446
  await devServer(projectStructure, {
@@ -1,4 +1,7 @@
1
1
  "use strict";
2
+ const __rslib_import_meta_url__ = /*#__PURE__*/ function() {
3
+ return "u" < typeof document ? new (require('url'.replace('', ''))).URL('file:' + __filename).href : document.currentScript && document.currentScript.src || new URL('main.js', document.baseURI).href;
4
+ }();
2
5
  var __webpack_require__ = {};
3
6
  (()=>{
4
7
  __webpack_require__.n = (module)=>{
@@ -64,6 +67,38 @@ function findNearestPackageJsonSync(manifestPath) {
64
67
  return null;
65
68
  }
66
69
  }
70
+ require("os");
71
+ require("pintor");
72
+ const external_module_namespaceObject = require("module");
73
+ (0, external_module_namespaceObject.createRequire)(__rslib_import_meta_url__);
74
+ require("crypto");
75
+ require("child_process");
76
+ (0, external_module_namespaceObject.createRequire)(__rslib_import_meta_url__);
77
+ function parseJsonSafe(text) {
78
+ const s = text && 0xfeff === text.charCodeAt(0) ? text.slice(1) : text;
79
+ return JSON.parse(s || '{}');
80
+ }
81
+ function hasDependency(projectPath, dependency) {
82
+ const findNearestPackageJsonDirectory = (startPath)=>{
83
+ let currentDirectory = startPath;
84
+ const maxDepth = 4;
85
+ for(let i = 0; i < maxDepth; i++){
86
+ const candidate = external_path_namespaceObject.join(currentDirectory, 'package.json');
87
+ if (external_fs_namespaceObject.existsSync(candidate)) return currentDirectory;
88
+ const parentDirectory = external_path_namespaceObject.dirname(currentDirectory);
89
+ if (parentDirectory === currentDirectory) break;
90
+ currentDirectory = parentDirectory;
91
+ }
92
+ };
93
+ const packageJsonDirectory = findNearestPackageJsonDirectory(projectPath);
94
+ if (!packageJsonDirectory) return false;
95
+ const packageJsonPath = external_path_namespaceObject.join(packageJsonDirectory, 'package.json');
96
+ if (!external_fs_namespaceObject.existsSync(packageJsonPath)) return false;
97
+ const packageJson = parseJsonSafe(external_fs_namespaceObject.readFileSync(packageJsonPath, 'utf8'));
98
+ const dependencies = packageJson.dependencies || {};
99
+ const devDependencies = packageJson.devDependencies || {};
100
+ return !!dependencies[dependency] || !!devDependencies[dependency];
101
+ }
67
102
  const core_namespaceObject = require("@swc/core");
68
103
  const external_schema_utils_namespaceObject = require("schema-utils");
69
104
  const schema = {
@@ -80,6 +115,34 @@ const schema = {
80
115
  }
81
116
  }
82
117
  };
118
+ const EXAMPLES_BASE = 'https://github.com/extension-js/examples/blob/main';
119
+ function getContentScriptSampleInfo(packageJsonDir, resourcePath) {
120
+ if (hasDependency(packageJsonDir, 'react')) return {
121
+ phrase: 'See React sample',
122
+ url: `${EXAMPLES_BASE}/react/src/content/scripts.tsx`
123
+ };
124
+ if (hasDependency(packageJsonDir, 'preact')) return {
125
+ phrase: 'See Preact sample',
126
+ url: `${EXAMPLES_BASE}/preact/src/content/scripts.tsx`
127
+ };
128
+ if (hasDependency(packageJsonDir, 'vue')) return {
129
+ phrase: 'See Vue sample',
130
+ url: `${EXAMPLES_BASE}/vue/src/content/scripts.ts`
131
+ };
132
+ if (hasDependency(packageJsonDir, 'svelte')) return {
133
+ phrase: 'See Svelte sample',
134
+ url: `${EXAMPLES_BASE}/svelte/src/content/scripts.ts`
135
+ };
136
+ const ext = external_path_default().extname(resourcePath).toLowerCase();
137
+ if ('.ts' === ext || '.tsx' === ext || '.mts' === ext || '.mtsx' === ext) return {
138
+ phrase: 'See TypeScript sample',
139
+ url: `${EXAMPLES_BASE}/typescript/src/content/scripts.ts`
140
+ };
141
+ return {
142
+ phrase: 'See vanilla JS sample',
143
+ url: `${EXAMPLES_BASE}/content/src/content/scripts.js`
144
+ };
145
+ }
83
146
  function getSourceSignature(source) {
84
147
  const head = source.slice(0, 64);
85
148
  const tail = source.slice(-64);
@@ -253,47 +316,28 @@ function warn_no_default_export(source) {
253
316
  }
254
317
  const relativeFile = external_path_default().relative(packageJsonDir, resourceAbsPath);
255
318
  const found = 'class' === analysis.kind ? 'class' : 'non-callable value';
319
+ const sample = getContentScriptSampleInfo(packageJsonDir, this.resourcePath);
256
320
  const message = [
257
321
  "Content script default export must be a function.",
258
- `File: ${relativeFile}`,
259
- "",
260
- `Found: ${found}`,
261
- "",
262
- "Fix:",
263
- " - Export a default function that sets up your script and returns optional cleanup.",
264
- " - If you want to use a class, instantiate it inside the default function and call its methods.",
265
- "",
266
- "Example:",
267
- " class App { start(){} stop(){} }",
268
- " export default function main(){",
269
- " const app = new App(); app.start();",
270
- " return () => app.stop();",
271
- " }"
322
+ `File: ${relativeFile}`,
323
+ "",
324
+ `Found: ${found}. Export a default function that sets up your script and returns optional cleanup.`,
325
+ " │ Without it: duplicate UI mounts, memory leaks, and inconsistent state during HMR.",
326
+ ` │ ${sample.phrase} ${sample.url}`
272
327
  ].join('\n');
273
328
  compilation?.warnings.push(message);
274
329
  compilation?.__extjsWarnedDefaultExportKinds?.add(dedupeKindKey);
275
330
  }
276
331
  } else {
277
332
  const relativeFile = external_path_default().relative(packageJsonDir, resourceAbsPath);
333
+ const sample = getContentScriptSampleInfo(packageJsonDir, this.resourcePath);
278
334
  const message = [
279
335
  "Content script requires a default export.",
280
- `File: ${relativeFile}`,
281
- "",
282
- "Why:",
283
- " - During development, Extension.js uses your default export to start and stop your content script safely.",
284
- " - Without it, automatic reloads and cleanup might not work reliably.",
285
- "",
286
- "Required:",
287
- " - Export a default function (it can optionally return a cleanup callback).",
288
- "",
289
- "Example:",
290
- " export default function main() {",
291
- " // setup...",
292
- " return () => { /* cleanup */ }",
293
- " }",
336
+ ` File: ${relativeFile}`,
294
337
  "",
295
- "Side effects if omitted:",
296
- " - Duplicate UI mounts, memory leaks, and inconsistent state during development."
338
+ " Export a default function so Extension.js can mount and cleanup safely.",
339
+ " Without it: duplicate UI mounts and inconsistent state during HMR.",
340
+ ` ${sample.phrase}: ${sample.url}`
297
341
  ].join('\n');
298
342
  compilation?.warnings.push(message);
299
343
  compilation?.__extjsWarnedDefaultExport?.add(dedupeKey);
package/package.json CHANGED
@@ -25,7 +25,7 @@
25
25
  "webpack/webpack-lib/optional-dependencies.json"
26
26
  ],
27
27
  "name": "extension-develop",
28
- "version": "3.9.0-next.3",
28
+ "version": "3.9.0-next.5",
29
29
  "description": "Develop, build, preview, and package Extension.js projects.",
30
30
  "author": {
31
31
  "name": "Cezar Augusto",