@crxjs/vite-plugin 1.0.0 → 1.0.3

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 ADDED
@@ -0,0 +1,20 @@
1
+ # @crxjs/vite-plugin
2
+
3
+ ## 1.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 8b2e587: check service worker on interval from extension page
8
+
9
+ ## 1.0.2
10
+
11
+ ### Patch Changes
12
+
13
+ - be8a1de: Remove unused code that throws when web accessible resources contains
14
+ an HTML file.
15
+
16
+ ## 1.0.1
17
+
18
+ ### Patch Changes
19
+
20
+ - d2b4f9e: feat: allow hash in manifest html urls
package/dist/index.cjs CHANGED
@@ -42,6 +42,7 @@ function _interopNamespace(e) {
42
42
  var debug__default = /*#__PURE__*/_interopDefaultLegacy(debug$5);
43
43
  var fg__default = /*#__PURE__*/_interopDefaultLegacy(fg);
44
44
  var v8__default = /*#__PURE__*/_interopDefaultLegacy(v8);
45
+ var fsExtra__default = /*#__PURE__*/_interopDefaultLegacy(fsExtra);
45
46
  var MagicString__default = /*#__PURE__*/_interopDefaultLegacy(MagicString);
46
47
  var colors__default = /*#__PURE__*/_interopDefaultLegacy(colors);
47
48
  var jsesc__default = /*#__PURE__*/_interopDefaultLegacy(jsesc);
@@ -101,7 +102,7 @@ function htmlFiles(manifest) {
101
102
  manifest.options_page,
102
103
  manifest.options_ui?.page,
103
104
  manifest.sandbox?.pages
104
- ].flat().filter(isString).sort();
105
+ ].flat().filter(isString).map((s) => s.split("#")[0]).sort();
105
106
  return [...new Set(files)];
106
107
  }
107
108
  function decodeManifest(code) {
@@ -1981,6 +1982,7 @@ function withLatestFrom() {
1981
1982
  });
1982
1983
  }
1983
1984
 
1985
+ const { pathExistsSync, outputFile, statSync } = fsExtra__default["default"];
1984
1986
  const debug$3 = _debug("file-writer").extend("events");
1985
1987
  const writerEvent$ = new BehaviorSubject({
1986
1988
  type: "init"
@@ -2002,7 +2004,7 @@ const filesReady$ = writerEvent$.pipe(filter((x) => {
2002
2004
  return x.type === "writeBundle";
2003
2005
  }), switchMap((event) => interval(100).pipe(mapTo(event), first(({ bundle, options, timestamp }) => {
2004
2006
  const result = Object.keys(bundle).every((p) => {
2005
- const stats = fsExtra.statSync(join(options.dir, p));
2007
+ const stats = statSync(join(options.dir, p));
2006
2008
  return stats.mtimeMs > timestamp;
2007
2009
  });
2008
2010
  return result;
@@ -2014,7 +2016,7 @@ const rebuildFiles = async () => {
2014
2016
  debug$3("rebuildFiles start");
2015
2017
  await filesReady();
2016
2018
  await Promise.all([
2017
- fsExtra.outputFile(await triggerName, Date.now().toString()),
2019
+ outputFile(await triggerName, Date.now().toString()),
2018
2020
  filesStart()
2019
2021
  ]);
2020
2022
  await filesReady();
@@ -2063,8 +2065,8 @@ const pluginFileWriterEvents = () => {
2063
2065
  async buildStart(options) {
2064
2066
  start = perf_hooks.performance.now();
2065
2067
  const filename = await triggerName;
2066
- if (!fsExtra.existsSync(filename)) {
2067
- await fsExtra.outputFile(filename, Date.now().toString());
2068
+ if (!pathExistsSync(filename)) {
2069
+ await outputFile(filename, Date.now().toString());
2068
2070
  }
2069
2071
  this.addWatchFile(filename);
2070
2072
  writerEvent$.next({ type: "buildStart", options });
@@ -2091,7 +2093,7 @@ const pluginFileWriterEvents = () => {
2091
2093
  };
2092
2094
  };
2093
2095
 
2094
- var preControllerScript = "setTimeout(() => location.reload(), 100);\n";
2096
+ var preControllerScript = "const id = setInterval(() => location.reload(), 100);\nsetTimeout(() => clearInterval(id), 5e3);\n";
2095
2097
 
2096
2098
  var preControllerHtml = "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <title>Waiting for the extension service worker...</title>\n <script src=\"%PATH%\"></script>\n </head>\n <body>\n <h1>Waiting for service worker</h1>\n\n <p>\n If you see this message, it means the service worker has not loaded fully.\n </p>\n\n <p>\n During development, the service worker reroutes HTML requests to the dev\n server, so this file isn't used unless the extension service worker opens\n a page immediately after a full extension reload, and before the service\n worker takes control of fetch (e.g., in the onInstalled event). In that\n case, this page will continuously reload until the service worker is\n ready, always less than 100 ms.\n </p>\n\n <p>This page is never added in production.</p>\n </body>\n</html>\n";
2097
2099
 
@@ -2543,6 +2545,216 @@ const pluginHtmlAuditor = () => {
2543
2545
  };
2544
2546
  };
2545
2547
 
2548
+ const pluginManifest = (_manifest) => () => {
2549
+ let manifest;
2550
+ let plugins;
2551
+ let refId;
2552
+ let config;
2553
+ return [
2554
+ {
2555
+ name: "crx:manifest-init",
2556
+ enforce: "pre",
2557
+ async config(config2, env) {
2558
+ manifest = await (typeof _manifest === "function" ? _manifest(env) : _manifest);
2559
+ if (manifest.manifest_version !== 3)
2560
+ throw new Error(`Manifest v${manifest.manifest_version} is currently unsupported, please use manifest v3`);
2561
+ if (env.command === "serve") {
2562
+ const {
2563
+ contentScripts: js,
2564
+ background: sw,
2565
+ html
2566
+ } = await manifestFiles(manifest);
2567
+ let { entries = [] } = config2.optimizeDeps ?? {};
2568
+ entries = [entries].flat();
2569
+ const set = new Set(entries);
2570
+ for (const x of [...js, ...sw, ...html])
2571
+ set.add(x);
2572
+ return {
2573
+ ...config2,
2574
+ optimizeDeps: {
2575
+ ...config2.optimizeDeps,
2576
+ entries: [...set]
2577
+ }
2578
+ };
2579
+ }
2580
+ },
2581
+ buildStart(options) {
2582
+ if (options.plugins)
2583
+ plugins = options.plugins;
2584
+ }
2585
+ },
2586
+ {
2587
+ name: "crx:manifest-loader",
2588
+ apply: "build",
2589
+ enforce: "pre",
2590
+ buildStart() {
2591
+ refId = this.emitFile({
2592
+ type: "chunk",
2593
+ id: manifestId,
2594
+ name: "crx-manifest.js",
2595
+ preserveSignature: "strict"
2596
+ });
2597
+ },
2598
+ resolveId(source) {
2599
+ if (source === manifestId)
2600
+ return manifestId;
2601
+ return null;
2602
+ },
2603
+ load(id) {
2604
+ if (id === manifestId)
2605
+ return encodeManifest(manifest);
2606
+ return null;
2607
+ }
2608
+ },
2609
+ {
2610
+ name: "crx:stub-input",
2611
+ apply: "build",
2612
+ enforce: "pre",
2613
+ options({ input, ...options }) {
2614
+ return {
2615
+ input: isString(input) && input.endsWith("index.html") ? stubId : input,
2616
+ ...options
2617
+ };
2618
+ },
2619
+ resolveId(source) {
2620
+ if (source === stubId)
2621
+ return stubId;
2622
+ return null;
2623
+ },
2624
+ load(id) {
2625
+ if (id === stubId)
2626
+ return `console.log('stub')`;
2627
+ return null;
2628
+ },
2629
+ generateBundle(options, bundle) {
2630
+ for (const [key, chunk] of Object.entries(bundle)) {
2631
+ if (chunk.type === "chunk" && chunk.facadeModuleId === stubId) {
2632
+ delete bundle[key];
2633
+ break;
2634
+ }
2635
+ }
2636
+ }
2637
+ },
2638
+ {
2639
+ name: "crx:manifest-post",
2640
+ apply: "build",
2641
+ enforce: "post",
2642
+ configResolved(_config) {
2643
+ config = _config;
2644
+ const plugins2 = config.plugins;
2645
+ const crx = plugins2.findIndex(({ name }) => name === "crx:manifest-post");
2646
+ const [plugin] = plugins2.splice(crx, 1);
2647
+ plugins2.push(plugin);
2648
+ },
2649
+ async transform(code, id) {
2650
+ if (id !== manifestId)
2651
+ return;
2652
+ let manifest2 = decodeManifest.call(this, code);
2653
+ for (const plugin of plugins) {
2654
+ try {
2655
+ const m = structuredClone(manifest2);
2656
+ const result = await plugin.transformCrxManifest?.call(this, m);
2657
+ manifest2 = result ?? manifest2;
2658
+ } catch (error) {
2659
+ if (error instanceof Error)
2660
+ error.message = `[${plugin.name}] ${error.message}`;
2661
+ throw error;
2662
+ }
2663
+ }
2664
+ if (manifest2.content_scripts?.length) {
2665
+ manifest2.content_scripts = manifest2.content_scripts.map(({ js = [], ...rest }) => {
2666
+ const refJS = js.map((file) => this.emitFile({
2667
+ type: "chunk",
2668
+ id: file,
2669
+ name: basename(file)
2670
+ }));
2671
+ return { js: refJS, ...rest };
2672
+ });
2673
+ }
2674
+ if (!this.meta.watchMode) {
2675
+ if (manifest2.background?.service_worker) {
2676
+ const file = manifest2.background.service_worker;
2677
+ const refId2 = this.emitFile({
2678
+ type: "chunk",
2679
+ id: file,
2680
+ name: basename(file)
2681
+ });
2682
+ manifest2.background.service_worker = refId2;
2683
+ }
2684
+ for (const file of htmlFiles(manifest2)) {
2685
+ this.emitFile({
2686
+ type: "chunk",
2687
+ id: file,
2688
+ name: basename(file)
2689
+ });
2690
+ }
2691
+ }
2692
+ const encoded = encodeManifest(manifest2);
2693
+ return encoded;
2694
+ },
2695
+ async generateBundle(options, bundle) {
2696
+ const manifestName = this.getFileName(refId);
2697
+ const manifestJs = bundle[manifestName];
2698
+ let manifest2 = decodeManifest.call(this, manifestJs.code);
2699
+ if (manifest2.background?.service_worker && !this.meta.watchMode) {
2700
+ const ref = manifest2.background.service_worker;
2701
+ const name = this.getFileName(ref);
2702
+ manifest2.background.service_worker = name;
2703
+ }
2704
+ manifest2.content_scripts = manifest2.content_scripts?.map(({ js = [], ...rest }) => {
2705
+ const refJS = js.map((ref) => this.getFileName(ref));
2706
+ return { js: refJS, ...rest };
2707
+ });
2708
+ for (const plugin of plugins) {
2709
+ try {
2710
+ const m = structuredClone(manifest2);
2711
+ const result = await plugin.renderCrxManifest?.call(this, m, bundle);
2712
+ manifest2 = result ?? manifest2;
2713
+ } catch (error) {
2714
+ const name = `[${plugin.name}]`;
2715
+ let message = error;
2716
+ if (error instanceof Error) {
2717
+ message = colors__default["default"].red(`${name} ${error.stack ? error.stack : error.message}`);
2718
+ } else if (typeof error === "string") {
2719
+ message = colors__default["default"].red(`${name} ${error}`);
2720
+ }
2721
+ console.log(message);
2722
+ throw new Error(`Error in ${plugin.name}.renderCrxManifest`);
2723
+ }
2724
+ }
2725
+ const assetTypes = [
2726
+ "icons",
2727
+ "locales",
2728
+ "rulesets",
2729
+ "webAccessibleResources"
2730
+ ];
2731
+ const files = await manifestFiles(manifest2);
2732
+ await Promise.all(assetTypes.map((k) => files[k]).flat().map(async (f) => {
2733
+ if (typeof bundle[f] === "undefined") {
2734
+ const filename = join(config.root, f);
2735
+ this.emitFile({
2736
+ type: "asset",
2737
+ fileName: f,
2738
+ source: await fsExtra.readFile(filename)
2739
+ });
2740
+ }
2741
+ }));
2742
+ const manifestJson = bundle["manifest.json"];
2743
+ if (typeof manifestJson === "undefined") {
2744
+ this.emitFile({
2745
+ type: "asset",
2746
+ fileName: "manifest.json",
2747
+ source: JSON.stringify(manifest2, null, 2)
2748
+ });
2749
+ } else {
2750
+ manifestJson.source = JSON.stringify(manifest2, null, 2);
2751
+ }
2752
+ delete bundle[manifestName];
2753
+ }
2754
+ }
2755
+ ];
2756
+ };
2757
+
2546
2758
  var contentHmrPort = "function isCrxHMRPayload(x) {\n return x.type === \"custom\" && x.event.startsWith(\"crx:\");\n}\nclass HMRPort {\n port;\n callbacks = /* @__PURE__ */ new Map();\n constructor() {\n setInterval(() => {\n try {\n this.port?.postMessage({ data: \"ping\" });\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"Extension context invalidated.\")) {\n location.reload();\n } else\n throw error;\n }\n }, __CRX_HMR_TIMEOUT__);\n setInterval(this.initPort, 5 * 60 * 1e3);\n this.initPort();\n }\n initPort = () => {\n this.port?.disconnect();\n this.port = chrome.runtime.connect({ name: \"@crx/client\" });\n this.port.onDisconnect.addListener(this.handleDisconnect.bind(this));\n this.port.onMessage.addListener(this.handleMessage.bind(this));\n this.port.postMessage({ type: \"connected\" });\n };\n handleDisconnect = () => {\n if (this.callbacks.has(\"close\"))\n for (const cb of this.callbacks.get(\"close\")) {\n cb({ wasClean: true });\n }\n };\n handleMessage = (message) => {\n const forward = (data) => {\n if (this.callbacks.has(\"message\"))\n for (const cb of this.callbacks.get(\"message\")) {\n cb({ data });\n }\n };\n const payload = JSON.parse(message.data);\n if (isCrxHMRPayload(payload)) {\n if (payload.event === \"crx:runtime-reload\") {\n console.log(\"[crx] runtime reload\");\n setTimeout(() => location.reload(), 500);\n } else {\n forward(JSON.stringify(payload.data));\n }\n } else {\n forward(message.data);\n }\n };\n addEventListener = (event, callback) => {\n const cbs = this.callbacks.get(event) ?? /* @__PURE__ */ new Set();\n cbs.add(callback);\n this.callbacks.set(event, cbs);\n };\n send = (data) => {\n if (this.port)\n this.port.postMessage({ data });\n else\n throw new Error(\"HMRPort is not initialized\");\n };\n}\n\nexport { HMRPort };\n";
2547
2759
 
2548
2760
  var contentDevLoader = "(function () {\n 'use strict';\n\n (async () => {\n if (__PREAMBLE__)\n await import(\n /* @vite-ignore */\n chrome.runtime.getURL(__PREAMBLE__)\n );\n await import(\n /* @vite-ignore */\n chrome.runtime.getURL(__CLIENT__)\n );\n await import(\n /* @vite-ignore */\n chrome.runtime.getURL(__SCRIPT__)\n );\n })().catch(console.error);\n\n})();\n";
@@ -2981,220 +3193,6 @@ const pluginResources = ({ contentScripts = {} }) => {
2981
3193
  ];
2982
3194
  };
2983
3195
 
2984
- const pluginManifest = (_manifest) => () => {
2985
- let manifest;
2986
- let plugins;
2987
- let refId;
2988
- let config;
2989
- return [
2990
- {
2991
- name: "crx:manifest-init",
2992
- enforce: "pre",
2993
- async config(config2, env) {
2994
- manifest = await (typeof _manifest === "function" ? _manifest(env) : _manifest);
2995
- if (manifest.manifest_version !== 3)
2996
- throw new Error(`Manifest v${manifest.manifest_version} is currently unsupported, please use manifest v3`);
2997
- if (env.command === "serve") {
2998
- const {
2999
- contentScripts: js,
3000
- background: sw,
3001
- html
3002
- } = await manifestFiles(manifest);
3003
- let { entries = [] } = config2.optimizeDeps ?? {};
3004
- entries = [entries].flat();
3005
- const set = new Set(entries);
3006
- for (const x of [...js, ...sw, ...html])
3007
- set.add(x);
3008
- return {
3009
- ...config2,
3010
- optimizeDeps: {
3011
- ...config2.optimizeDeps,
3012
- entries: [...set]
3013
- }
3014
- };
3015
- }
3016
- },
3017
- buildStart(options) {
3018
- if (options.plugins)
3019
- plugins = options.plugins;
3020
- }
3021
- },
3022
- {
3023
- name: "crx:manifest-loader",
3024
- apply: "build",
3025
- enforce: "pre",
3026
- buildStart() {
3027
- refId = this.emitFile({
3028
- type: "chunk",
3029
- id: manifestId,
3030
- name: "crx-manifest.js",
3031
- preserveSignature: "strict"
3032
- });
3033
- },
3034
- resolveId(source) {
3035
- if (source === manifestId)
3036
- return manifestId;
3037
- return null;
3038
- },
3039
- load(id) {
3040
- if (id === manifestId)
3041
- return encodeManifest(manifest);
3042
- return null;
3043
- }
3044
- },
3045
- {
3046
- name: "crx:stub-input",
3047
- apply: "build",
3048
- enforce: "pre",
3049
- options({ input, ...options }) {
3050
- return {
3051
- input: isString(input) && input.endsWith("index.html") ? stubId : input,
3052
- ...options
3053
- };
3054
- },
3055
- resolveId(source) {
3056
- if (source === stubId)
3057
- return stubId;
3058
- return null;
3059
- },
3060
- load(id) {
3061
- if (id === stubId)
3062
- return `console.log('stub')`;
3063
- return null;
3064
- },
3065
- generateBundle(options, bundle) {
3066
- for (const [key, chunk] of Object.entries(bundle)) {
3067
- if (chunk.type === "chunk" && chunk.facadeModuleId === stubId) {
3068
- delete bundle[key];
3069
- break;
3070
- }
3071
- }
3072
- }
3073
- },
3074
- {
3075
- name: "crx:manifest-post",
3076
- apply: "build",
3077
- enforce: "post",
3078
- configResolved(_config) {
3079
- config = _config;
3080
- const plugins2 = config.plugins;
3081
- const crx = plugins2.findIndex(({ name }) => name === "crx:manifest-post");
3082
- const [plugin] = plugins2.splice(crx, 1);
3083
- plugins2.push(plugin);
3084
- },
3085
- async transform(code, id) {
3086
- if (id !== manifestId)
3087
- return;
3088
- let manifest2 = decodeManifest.call(this, code);
3089
- for (const plugin of plugins) {
3090
- try {
3091
- const m = structuredClone(manifest2);
3092
- const result = await plugin.transformCrxManifest?.call(this, m);
3093
- manifest2 = result ?? manifest2;
3094
- } catch (error) {
3095
- if (error instanceof Error)
3096
- error.message = `[${plugin.name}] ${error.message}`;
3097
- throw error;
3098
- }
3099
- }
3100
- if (manifest2.content_scripts?.length) {
3101
- manifest2.content_scripts = manifest2.content_scripts.map(({ js = [], ...rest }) => {
3102
- const refJS = js.map((file) => this.emitFile({
3103
- type: "chunk",
3104
- id: file,
3105
- name: basename(file)
3106
- }));
3107
- return { js: refJS, ...rest };
3108
- });
3109
- }
3110
- if (!this.meta.watchMode) {
3111
- if (manifest2.background?.service_worker) {
3112
- const file = manifest2.background.service_worker;
3113
- const refId2 = this.emitFile({
3114
- type: "chunk",
3115
- id: file,
3116
- name: basename(file)
3117
- });
3118
- manifest2.background.service_worker = refId2;
3119
- }
3120
- for (const file of htmlFiles(manifest2)) {
3121
- this.emitFile({
3122
- type: "chunk",
3123
- id: file,
3124
- name: basename(file)
3125
- });
3126
- }
3127
- }
3128
- const encoded = encodeManifest(manifest2);
3129
- return encoded;
3130
- },
3131
- async generateBundle(options, bundle) {
3132
- const manifestName = this.getFileName(refId);
3133
- const manifestJs = bundle[manifestName];
3134
- let manifest2 = decodeManifest.call(this, manifestJs.code);
3135
- if (manifest2.background?.service_worker && !this.meta.watchMode) {
3136
- const ref = manifest2.background.service_worker;
3137
- const name = this.getFileName(ref);
3138
- manifest2.background.service_worker = name;
3139
- }
3140
- manifest2.content_scripts = manifest2.content_scripts?.map(({ js = [], ...rest }) => {
3141
- const refJS = js.map((ref) => this.getFileName(ref));
3142
- return { js: refJS, ...rest };
3143
- });
3144
- manifest2.web_accessible_resources = manifest2.web_accessible_resources?.map(({ resources, ...rest }) => ({
3145
- resources: resources.map((r) => fg__default["default"].isDynamicPattern(r) || r === dynamicResourcesName ? r : this.getFileName(r)),
3146
- ...rest
3147
- }));
3148
- for (const plugin of plugins) {
3149
- try {
3150
- const m = structuredClone(manifest2);
3151
- const result = await plugin.renderCrxManifest?.call(this, m, bundle);
3152
- manifest2 = result ?? manifest2;
3153
- } catch (error) {
3154
- const name = `[${plugin.name}]`;
3155
- let message = error;
3156
- if (error instanceof Error) {
3157
- message = colors__default["default"].red(`${name} ${error.stack ? error.stack : error.message}`);
3158
- } else if (typeof error === "string") {
3159
- message = colors__default["default"].red(`${name} ${error}`);
3160
- }
3161
- console.log(message);
3162
- throw new Error(`Error in ${plugin.name}.renderCrxManifest`);
3163
- }
3164
- }
3165
- const assetTypes = [
3166
- "icons",
3167
- "locales",
3168
- "rulesets",
3169
- "webAccessibleResources"
3170
- ];
3171
- const files = await manifestFiles(manifest2);
3172
- await Promise.all(assetTypes.map((k) => files[k]).flat().map(async (f) => {
3173
- if (typeof bundle[f] === "undefined") {
3174
- const filename = join(config.root, f);
3175
- this.emitFile({
3176
- type: "asset",
3177
- fileName: f,
3178
- source: await fsExtra.readFile(filename)
3179
- });
3180
- }
3181
- }));
3182
- const manifestJson = bundle["manifest.json"];
3183
- if (typeof manifestJson === "undefined") {
3184
- this.emitFile({
3185
- type: "asset",
3186
- fileName: "manifest.json",
3187
- source: JSON.stringify(manifest2, null, 2)
3188
- });
3189
- } else {
3190
- manifestJson.source = JSON.stringify(manifest2, null, 2);
3191
- }
3192
- delete bundle[manifestName];
3193
- }
3194
- }
3195
- ];
3196
- };
3197
-
3198
3196
  var workerHmrClient = "const ownOrigin = new URL(chrome.runtime.getURL(\"/\")).origin;\nself.addEventListener(\"fetch\", (fetchEvent) => {\n const url = new URL(fetchEvent.request.url);\n if (url.origin === ownOrigin) {\n fetchEvent.respondWith(sendToServer(url));\n }\n});\nasync function sendToServer(url) {\n url.protocol = \"http:\";\n url.host = \"localhost\";\n url.port = __SERVER_PORT__;\n url.searchParams.set(\"t\", Date.now().toString());\n const response = await fetch(url.href.replace(/=$|=(?=&)/g, \"\"));\n return new Response(response.body, {\n headers: {\n \"Content-Type\": response.headers.get(\"Content-Type\") ?? \"text/javascript\"\n }\n });\n}\nconst ports = /* @__PURE__ */ new Set();\nchrome.runtime.onConnect.addListener((port) => {\n if (port.name === \"@crx/client\") {\n ports.add(port);\n port.onDisconnect.addListener((port2) => ports.delete(port2));\n port.onMessage.addListener((message) => {\n });\n port.postMessage({ data: JSON.stringify({ type: \"connected\" }) });\n }\n});\nfunction notifyContentScripts(payload) {\n const data = JSON.stringify(payload);\n for (const port of ports)\n port.postMessage({ data });\n}\nconsole.log(\"[vite] connecting...\");\nconst socketProtocol = __HMR_PROTOCOL__ || (location.protocol === \"https:\" ? \"wss\" : \"ws\");\nconst socketHost = `${__HMR_HOSTNAME__ || location.hostname}:${__HMR_PORT__}`;\nconst socket = new WebSocket(`${socketProtocol}://${socketHost}`, \"vite-hmr\");\nconst base = __BASE__ || \"/\";\nsocket.addEventListener(\"message\", async ({ data }) => {\n handleSocketMessage(JSON.parse(data));\n});\nfunction isCrxHmrPayload(x) {\n return x.type === \"custom\" && x.event.startsWith(\"crx:\");\n}\nfunction handleSocketMessage(payload) {\n if (isCrxHmrPayload(payload)) {\n handleCrxHmrPayload(payload);\n } else if (payload.type === \"connected\") {\n console.log(`[vite] connected.`);\n const interval = setInterval(() => socket.send(\"ping\"), __HMR_TIMEOUT__);\n socket.addEventListener(\"close\", () => clearInterval(interval));\n }\n}\nfunction handleCrxHmrPayload(payload) {\n notifyContentScripts(payload);\n switch (payload.event) {\n case \"crx:runtime-reload\":\n console.log(\"[crx] runtime reload\");\n chrome.runtime.reload();\n break;\n }\n}\nasync function waitForSuccessfulPing(ms = 1e3) {\n while (true) {\n try {\n await fetch(`${base}__vite_ping`);\n break;\n } catch (e) {\n await new Promise((resolve) => setTimeout(resolve, ms));\n }\n }\n}\nsocket.addEventListener(\"close\", async ({ wasClean }) => {\n if (wasClean)\n return;\n console.log(`[vite] server connection lost. polling for restart...`);\n await waitForSuccessfulPing();\n chrome.runtime.reload();\n});\n";
3199
3197
 
3200
3198
  function defineClientValues(code, config) {
package/dist/index.mjs CHANGED
@@ -4,7 +4,7 @@ import { createHash as createHash$1 } from 'crypto';
4
4
  import debug$5 from 'debug';
5
5
  import fg from 'fast-glob';
6
6
  import v8 from 'v8';
7
- import { readFile, outputFile, existsSync, statSync, readFileSync } from 'fs-extra';
7
+ import fsExtra, { readFile, readFileSync } from 'fs-extra';
8
8
  import MagicString from 'magic-string';
9
9
  import { posix } from 'path';
10
10
  import { performance } from 'perf_hooks';
@@ -69,7 +69,7 @@ function htmlFiles(manifest) {
69
69
  manifest.options_page,
70
70
  manifest.options_ui?.page,
71
71
  manifest.sandbox?.pages
72
- ].flat().filter(isString).sort();
72
+ ].flat().filter(isString).map((s) => s.split("#")[0]).sort();
73
73
  return [...new Set(files)];
74
74
  }
75
75
  function decodeManifest(code) {
@@ -1949,6 +1949,7 @@ function withLatestFrom() {
1949
1949
  });
1950
1950
  }
1951
1951
 
1952
+ const { pathExistsSync, outputFile, statSync } = fsExtra;
1952
1953
  const debug$3 = _debug("file-writer").extend("events");
1953
1954
  const writerEvent$ = new BehaviorSubject({
1954
1955
  type: "init"
@@ -2031,7 +2032,7 @@ const pluginFileWriterEvents = () => {
2031
2032
  async buildStart(options) {
2032
2033
  start = performance.now();
2033
2034
  const filename = await triggerName;
2034
- if (!existsSync(filename)) {
2035
+ if (!pathExistsSync(filename)) {
2035
2036
  await outputFile(filename, Date.now().toString());
2036
2037
  }
2037
2038
  this.addWatchFile(filename);
@@ -2059,7 +2060,7 @@ const pluginFileWriterEvents = () => {
2059
2060
  };
2060
2061
  };
2061
2062
 
2062
- var preControllerScript = "setTimeout(() => location.reload(), 100);\n";
2063
+ var preControllerScript = "const id = setInterval(() => location.reload(), 100);\nsetTimeout(() => clearInterval(id), 5e3);\n";
2063
2064
 
2064
2065
  var preControllerHtml = "<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <title>Waiting for the extension service worker...</title>\n <script src=\"%PATH%\"></script>\n </head>\n <body>\n <h1>Waiting for service worker</h1>\n\n <p>\n If you see this message, it means the service worker has not loaded fully.\n </p>\n\n <p>\n During development, the service worker reroutes HTML requests to the dev\n server, so this file isn't used unless the extension service worker opens\n a page immediately after a full extension reload, and before the service\n worker takes control of fetch (e.g., in the onInstalled event). In that\n case, this page will continuously reload until the service worker is\n ready, always less than 100 ms.\n </p>\n\n <p>This page is never added in production.</p>\n </body>\n</html>\n";
2065
2066
 
@@ -2511,6 +2512,216 @@ const pluginHtmlAuditor = () => {
2511
2512
  };
2512
2513
  };
2513
2514
 
2515
+ const pluginManifest = (_manifest) => () => {
2516
+ let manifest;
2517
+ let plugins;
2518
+ let refId;
2519
+ let config;
2520
+ return [
2521
+ {
2522
+ name: "crx:manifest-init",
2523
+ enforce: "pre",
2524
+ async config(config2, env) {
2525
+ manifest = await (typeof _manifest === "function" ? _manifest(env) : _manifest);
2526
+ if (manifest.manifest_version !== 3)
2527
+ throw new Error(`Manifest v${manifest.manifest_version} is currently unsupported, please use manifest v3`);
2528
+ if (env.command === "serve") {
2529
+ const {
2530
+ contentScripts: js,
2531
+ background: sw,
2532
+ html
2533
+ } = await manifestFiles(manifest);
2534
+ let { entries = [] } = config2.optimizeDeps ?? {};
2535
+ entries = [entries].flat();
2536
+ const set = new Set(entries);
2537
+ for (const x of [...js, ...sw, ...html])
2538
+ set.add(x);
2539
+ return {
2540
+ ...config2,
2541
+ optimizeDeps: {
2542
+ ...config2.optimizeDeps,
2543
+ entries: [...set]
2544
+ }
2545
+ };
2546
+ }
2547
+ },
2548
+ buildStart(options) {
2549
+ if (options.plugins)
2550
+ plugins = options.plugins;
2551
+ }
2552
+ },
2553
+ {
2554
+ name: "crx:manifest-loader",
2555
+ apply: "build",
2556
+ enforce: "pre",
2557
+ buildStart() {
2558
+ refId = this.emitFile({
2559
+ type: "chunk",
2560
+ id: manifestId,
2561
+ name: "crx-manifest.js",
2562
+ preserveSignature: "strict"
2563
+ });
2564
+ },
2565
+ resolveId(source) {
2566
+ if (source === manifestId)
2567
+ return manifestId;
2568
+ return null;
2569
+ },
2570
+ load(id) {
2571
+ if (id === manifestId)
2572
+ return encodeManifest(manifest);
2573
+ return null;
2574
+ }
2575
+ },
2576
+ {
2577
+ name: "crx:stub-input",
2578
+ apply: "build",
2579
+ enforce: "pre",
2580
+ options({ input, ...options }) {
2581
+ return {
2582
+ input: isString(input) && input.endsWith("index.html") ? stubId : input,
2583
+ ...options
2584
+ };
2585
+ },
2586
+ resolveId(source) {
2587
+ if (source === stubId)
2588
+ return stubId;
2589
+ return null;
2590
+ },
2591
+ load(id) {
2592
+ if (id === stubId)
2593
+ return `console.log('stub')`;
2594
+ return null;
2595
+ },
2596
+ generateBundle(options, bundle) {
2597
+ for (const [key, chunk] of Object.entries(bundle)) {
2598
+ if (chunk.type === "chunk" && chunk.facadeModuleId === stubId) {
2599
+ delete bundle[key];
2600
+ break;
2601
+ }
2602
+ }
2603
+ }
2604
+ },
2605
+ {
2606
+ name: "crx:manifest-post",
2607
+ apply: "build",
2608
+ enforce: "post",
2609
+ configResolved(_config) {
2610
+ config = _config;
2611
+ const plugins2 = config.plugins;
2612
+ const crx = plugins2.findIndex(({ name }) => name === "crx:manifest-post");
2613
+ const [plugin] = plugins2.splice(crx, 1);
2614
+ plugins2.push(plugin);
2615
+ },
2616
+ async transform(code, id) {
2617
+ if (id !== manifestId)
2618
+ return;
2619
+ let manifest2 = decodeManifest.call(this, code);
2620
+ for (const plugin of plugins) {
2621
+ try {
2622
+ const m = structuredClone(manifest2);
2623
+ const result = await plugin.transformCrxManifest?.call(this, m);
2624
+ manifest2 = result ?? manifest2;
2625
+ } catch (error) {
2626
+ if (error instanceof Error)
2627
+ error.message = `[${plugin.name}] ${error.message}`;
2628
+ throw error;
2629
+ }
2630
+ }
2631
+ if (manifest2.content_scripts?.length) {
2632
+ manifest2.content_scripts = manifest2.content_scripts.map(({ js = [], ...rest }) => {
2633
+ const refJS = js.map((file) => this.emitFile({
2634
+ type: "chunk",
2635
+ id: file,
2636
+ name: basename(file)
2637
+ }));
2638
+ return { js: refJS, ...rest };
2639
+ });
2640
+ }
2641
+ if (!this.meta.watchMode) {
2642
+ if (manifest2.background?.service_worker) {
2643
+ const file = manifest2.background.service_worker;
2644
+ const refId2 = this.emitFile({
2645
+ type: "chunk",
2646
+ id: file,
2647
+ name: basename(file)
2648
+ });
2649
+ manifest2.background.service_worker = refId2;
2650
+ }
2651
+ for (const file of htmlFiles(manifest2)) {
2652
+ this.emitFile({
2653
+ type: "chunk",
2654
+ id: file,
2655
+ name: basename(file)
2656
+ });
2657
+ }
2658
+ }
2659
+ const encoded = encodeManifest(manifest2);
2660
+ return encoded;
2661
+ },
2662
+ async generateBundle(options, bundle) {
2663
+ const manifestName = this.getFileName(refId);
2664
+ const manifestJs = bundle[manifestName];
2665
+ let manifest2 = decodeManifest.call(this, manifestJs.code);
2666
+ if (manifest2.background?.service_worker && !this.meta.watchMode) {
2667
+ const ref = manifest2.background.service_worker;
2668
+ const name = this.getFileName(ref);
2669
+ manifest2.background.service_worker = name;
2670
+ }
2671
+ manifest2.content_scripts = manifest2.content_scripts?.map(({ js = [], ...rest }) => {
2672
+ const refJS = js.map((ref) => this.getFileName(ref));
2673
+ return { js: refJS, ...rest };
2674
+ });
2675
+ for (const plugin of plugins) {
2676
+ try {
2677
+ const m = structuredClone(manifest2);
2678
+ const result = await plugin.renderCrxManifest?.call(this, m, bundle);
2679
+ manifest2 = result ?? manifest2;
2680
+ } catch (error) {
2681
+ const name = `[${plugin.name}]`;
2682
+ let message = error;
2683
+ if (error instanceof Error) {
2684
+ message = colors.red(`${name} ${error.stack ? error.stack : error.message}`);
2685
+ } else if (typeof error === "string") {
2686
+ message = colors.red(`${name} ${error}`);
2687
+ }
2688
+ console.log(message);
2689
+ throw new Error(`Error in ${plugin.name}.renderCrxManifest`);
2690
+ }
2691
+ }
2692
+ const assetTypes = [
2693
+ "icons",
2694
+ "locales",
2695
+ "rulesets",
2696
+ "webAccessibleResources"
2697
+ ];
2698
+ const files = await manifestFiles(manifest2);
2699
+ await Promise.all(assetTypes.map((k) => files[k]).flat().map(async (f) => {
2700
+ if (typeof bundle[f] === "undefined") {
2701
+ const filename = join(config.root, f);
2702
+ this.emitFile({
2703
+ type: "asset",
2704
+ fileName: f,
2705
+ source: await readFile(filename)
2706
+ });
2707
+ }
2708
+ }));
2709
+ const manifestJson = bundle["manifest.json"];
2710
+ if (typeof manifestJson === "undefined") {
2711
+ this.emitFile({
2712
+ type: "asset",
2713
+ fileName: "manifest.json",
2714
+ source: JSON.stringify(manifest2, null, 2)
2715
+ });
2716
+ } else {
2717
+ manifestJson.source = JSON.stringify(manifest2, null, 2);
2718
+ }
2719
+ delete bundle[manifestName];
2720
+ }
2721
+ }
2722
+ ];
2723
+ };
2724
+
2514
2725
  var contentHmrPort = "function isCrxHMRPayload(x) {\n return x.type === \"custom\" && x.event.startsWith(\"crx:\");\n}\nclass HMRPort {\n port;\n callbacks = /* @__PURE__ */ new Map();\n constructor() {\n setInterval(() => {\n try {\n this.port?.postMessage({ data: \"ping\" });\n } catch (error) {\n if (error instanceof Error && error.message.includes(\"Extension context invalidated.\")) {\n location.reload();\n } else\n throw error;\n }\n }, __CRX_HMR_TIMEOUT__);\n setInterval(this.initPort, 5 * 60 * 1e3);\n this.initPort();\n }\n initPort = () => {\n this.port?.disconnect();\n this.port = chrome.runtime.connect({ name: \"@crx/client\" });\n this.port.onDisconnect.addListener(this.handleDisconnect.bind(this));\n this.port.onMessage.addListener(this.handleMessage.bind(this));\n this.port.postMessage({ type: \"connected\" });\n };\n handleDisconnect = () => {\n if (this.callbacks.has(\"close\"))\n for (const cb of this.callbacks.get(\"close\")) {\n cb({ wasClean: true });\n }\n };\n handleMessage = (message) => {\n const forward = (data) => {\n if (this.callbacks.has(\"message\"))\n for (const cb of this.callbacks.get(\"message\")) {\n cb({ data });\n }\n };\n const payload = JSON.parse(message.data);\n if (isCrxHMRPayload(payload)) {\n if (payload.event === \"crx:runtime-reload\") {\n console.log(\"[crx] runtime reload\");\n setTimeout(() => location.reload(), 500);\n } else {\n forward(JSON.stringify(payload.data));\n }\n } else {\n forward(message.data);\n }\n };\n addEventListener = (event, callback) => {\n const cbs = this.callbacks.get(event) ?? /* @__PURE__ */ new Set();\n cbs.add(callback);\n this.callbacks.set(event, cbs);\n };\n send = (data) => {\n if (this.port)\n this.port.postMessage({ data });\n else\n throw new Error(\"HMRPort is not initialized\");\n };\n}\n\nexport { HMRPort };\n";
2515
2726
 
2516
2727
  var contentDevLoader = "(function () {\n 'use strict';\n\n (async () => {\n if (__PREAMBLE__)\n await import(\n /* @vite-ignore */\n chrome.runtime.getURL(__PREAMBLE__)\n );\n await import(\n /* @vite-ignore */\n chrome.runtime.getURL(__CLIENT__)\n );\n await import(\n /* @vite-ignore */\n chrome.runtime.getURL(__SCRIPT__)\n );\n })().catch(console.error);\n\n})();\n";
@@ -2949,220 +3160,6 @@ const pluginResources = ({ contentScripts = {} }) => {
2949
3160
  ];
2950
3161
  };
2951
3162
 
2952
- const pluginManifest = (_manifest) => () => {
2953
- let manifest;
2954
- let plugins;
2955
- let refId;
2956
- let config;
2957
- return [
2958
- {
2959
- name: "crx:manifest-init",
2960
- enforce: "pre",
2961
- async config(config2, env) {
2962
- manifest = await (typeof _manifest === "function" ? _manifest(env) : _manifest);
2963
- if (manifest.manifest_version !== 3)
2964
- throw new Error(`Manifest v${manifest.manifest_version} is currently unsupported, please use manifest v3`);
2965
- if (env.command === "serve") {
2966
- const {
2967
- contentScripts: js,
2968
- background: sw,
2969
- html
2970
- } = await manifestFiles(manifest);
2971
- let { entries = [] } = config2.optimizeDeps ?? {};
2972
- entries = [entries].flat();
2973
- const set = new Set(entries);
2974
- for (const x of [...js, ...sw, ...html])
2975
- set.add(x);
2976
- return {
2977
- ...config2,
2978
- optimizeDeps: {
2979
- ...config2.optimizeDeps,
2980
- entries: [...set]
2981
- }
2982
- };
2983
- }
2984
- },
2985
- buildStart(options) {
2986
- if (options.plugins)
2987
- plugins = options.plugins;
2988
- }
2989
- },
2990
- {
2991
- name: "crx:manifest-loader",
2992
- apply: "build",
2993
- enforce: "pre",
2994
- buildStart() {
2995
- refId = this.emitFile({
2996
- type: "chunk",
2997
- id: manifestId,
2998
- name: "crx-manifest.js",
2999
- preserveSignature: "strict"
3000
- });
3001
- },
3002
- resolveId(source) {
3003
- if (source === manifestId)
3004
- return manifestId;
3005
- return null;
3006
- },
3007
- load(id) {
3008
- if (id === manifestId)
3009
- return encodeManifest(manifest);
3010
- return null;
3011
- }
3012
- },
3013
- {
3014
- name: "crx:stub-input",
3015
- apply: "build",
3016
- enforce: "pre",
3017
- options({ input, ...options }) {
3018
- return {
3019
- input: isString(input) && input.endsWith("index.html") ? stubId : input,
3020
- ...options
3021
- };
3022
- },
3023
- resolveId(source) {
3024
- if (source === stubId)
3025
- return stubId;
3026
- return null;
3027
- },
3028
- load(id) {
3029
- if (id === stubId)
3030
- return `console.log('stub')`;
3031
- return null;
3032
- },
3033
- generateBundle(options, bundle) {
3034
- for (const [key, chunk] of Object.entries(bundle)) {
3035
- if (chunk.type === "chunk" && chunk.facadeModuleId === stubId) {
3036
- delete bundle[key];
3037
- break;
3038
- }
3039
- }
3040
- }
3041
- },
3042
- {
3043
- name: "crx:manifest-post",
3044
- apply: "build",
3045
- enforce: "post",
3046
- configResolved(_config) {
3047
- config = _config;
3048
- const plugins2 = config.plugins;
3049
- const crx = plugins2.findIndex(({ name }) => name === "crx:manifest-post");
3050
- const [plugin] = plugins2.splice(crx, 1);
3051
- plugins2.push(plugin);
3052
- },
3053
- async transform(code, id) {
3054
- if (id !== manifestId)
3055
- return;
3056
- let manifest2 = decodeManifest.call(this, code);
3057
- for (const plugin of plugins) {
3058
- try {
3059
- const m = structuredClone(manifest2);
3060
- const result = await plugin.transformCrxManifest?.call(this, m);
3061
- manifest2 = result ?? manifest2;
3062
- } catch (error) {
3063
- if (error instanceof Error)
3064
- error.message = `[${plugin.name}] ${error.message}`;
3065
- throw error;
3066
- }
3067
- }
3068
- if (manifest2.content_scripts?.length) {
3069
- manifest2.content_scripts = manifest2.content_scripts.map(({ js = [], ...rest }) => {
3070
- const refJS = js.map((file) => this.emitFile({
3071
- type: "chunk",
3072
- id: file,
3073
- name: basename(file)
3074
- }));
3075
- return { js: refJS, ...rest };
3076
- });
3077
- }
3078
- if (!this.meta.watchMode) {
3079
- if (manifest2.background?.service_worker) {
3080
- const file = manifest2.background.service_worker;
3081
- const refId2 = this.emitFile({
3082
- type: "chunk",
3083
- id: file,
3084
- name: basename(file)
3085
- });
3086
- manifest2.background.service_worker = refId2;
3087
- }
3088
- for (const file of htmlFiles(manifest2)) {
3089
- this.emitFile({
3090
- type: "chunk",
3091
- id: file,
3092
- name: basename(file)
3093
- });
3094
- }
3095
- }
3096
- const encoded = encodeManifest(manifest2);
3097
- return encoded;
3098
- },
3099
- async generateBundle(options, bundle) {
3100
- const manifestName = this.getFileName(refId);
3101
- const manifestJs = bundle[manifestName];
3102
- let manifest2 = decodeManifest.call(this, manifestJs.code);
3103
- if (manifest2.background?.service_worker && !this.meta.watchMode) {
3104
- const ref = manifest2.background.service_worker;
3105
- const name = this.getFileName(ref);
3106
- manifest2.background.service_worker = name;
3107
- }
3108
- manifest2.content_scripts = manifest2.content_scripts?.map(({ js = [], ...rest }) => {
3109
- const refJS = js.map((ref) => this.getFileName(ref));
3110
- return { js: refJS, ...rest };
3111
- });
3112
- manifest2.web_accessible_resources = manifest2.web_accessible_resources?.map(({ resources, ...rest }) => ({
3113
- resources: resources.map((r) => fg.isDynamicPattern(r) || r === dynamicResourcesName ? r : this.getFileName(r)),
3114
- ...rest
3115
- }));
3116
- for (const plugin of plugins) {
3117
- try {
3118
- const m = structuredClone(manifest2);
3119
- const result = await plugin.renderCrxManifest?.call(this, m, bundle);
3120
- manifest2 = result ?? manifest2;
3121
- } catch (error) {
3122
- const name = `[${plugin.name}]`;
3123
- let message = error;
3124
- if (error instanceof Error) {
3125
- message = colors.red(`${name} ${error.stack ? error.stack : error.message}`);
3126
- } else if (typeof error === "string") {
3127
- message = colors.red(`${name} ${error}`);
3128
- }
3129
- console.log(message);
3130
- throw new Error(`Error in ${plugin.name}.renderCrxManifest`);
3131
- }
3132
- }
3133
- const assetTypes = [
3134
- "icons",
3135
- "locales",
3136
- "rulesets",
3137
- "webAccessibleResources"
3138
- ];
3139
- const files = await manifestFiles(manifest2);
3140
- await Promise.all(assetTypes.map((k) => files[k]).flat().map(async (f) => {
3141
- if (typeof bundle[f] === "undefined") {
3142
- const filename = join(config.root, f);
3143
- this.emitFile({
3144
- type: "asset",
3145
- fileName: f,
3146
- source: await readFile(filename)
3147
- });
3148
- }
3149
- }));
3150
- const manifestJson = bundle["manifest.json"];
3151
- if (typeof manifestJson === "undefined") {
3152
- this.emitFile({
3153
- type: "asset",
3154
- fileName: "manifest.json",
3155
- source: JSON.stringify(manifest2, null, 2)
3156
- });
3157
- } else {
3158
- manifestJson.source = JSON.stringify(manifest2, null, 2);
3159
- }
3160
- delete bundle[manifestName];
3161
- }
3162
- }
3163
- ];
3164
- };
3165
-
3166
3163
  var workerHmrClient = "const ownOrigin = new URL(chrome.runtime.getURL(\"/\")).origin;\nself.addEventListener(\"fetch\", (fetchEvent) => {\n const url = new URL(fetchEvent.request.url);\n if (url.origin === ownOrigin) {\n fetchEvent.respondWith(sendToServer(url));\n }\n});\nasync function sendToServer(url) {\n url.protocol = \"http:\";\n url.host = \"localhost\";\n url.port = __SERVER_PORT__;\n url.searchParams.set(\"t\", Date.now().toString());\n const response = await fetch(url.href.replace(/=$|=(?=&)/g, \"\"));\n return new Response(response.body, {\n headers: {\n \"Content-Type\": response.headers.get(\"Content-Type\") ?? \"text/javascript\"\n }\n });\n}\nconst ports = /* @__PURE__ */ new Set();\nchrome.runtime.onConnect.addListener((port) => {\n if (port.name === \"@crx/client\") {\n ports.add(port);\n port.onDisconnect.addListener((port2) => ports.delete(port2));\n port.onMessage.addListener((message) => {\n });\n port.postMessage({ data: JSON.stringify({ type: \"connected\" }) });\n }\n});\nfunction notifyContentScripts(payload) {\n const data = JSON.stringify(payload);\n for (const port of ports)\n port.postMessage({ data });\n}\nconsole.log(\"[vite] connecting...\");\nconst socketProtocol = __HMR_PROTOCOL__ || (location.protocol === \"https:\" ? \"wss\" : \"ws\");\nconst socketHost = `${__HMR_HOSTNAME__ || location.hostname}:${__HMR_PORT__}`;\nconst socket = new WebSocket(`${socketProtocol}://${socketHost}`, \"vite-hmr\");\nconst base = __BASE__ || \"/\";\nsocket.addEventListener(\"message\", async ({ data }) => {\n handleSocketMessage(JSON.parse(data));\n});\nfunction isCrxHmrPayload(x) {\n return x.type === \"custom\" && x.event.startsWith(\"crx:\");\n}\nfunction handleSocketMessage(payload) {\n if (isCrxHmrPayload(payload)) {\n handleCrxHmrPayload(payload);\n } else if (payload.type === \"connected\") {\n console.log(`[vite] connected.`);\n const interval = setInterval(() => socket.send(\"ping\"), __HMR_TIMEOUT__);\n socket.addEventListener(\"close\", () => clearInterval(interval));\n }\n}\nfunction handleCrxHmrPayload(payload) {\n notifyContentScripts(payload);\n switch (payload.event) {\n case \"crx:runtime-reload\":\n console.log(\"[crx] runtime reload\");\n chrome.runtime.reload();\n break;\n }\n}\nasync function waitForSuccessfulPing(ms = 1e3) {\n while (true) {\n try {\n await fetch(`${base}__vite_ping`);\n break;\n } catch (e) {\n await new Promise((resolve) => setTimeout(resolve, ms));\n }\n }\n}\nsocket.addEventListener(\"close\", async ({ wasClean }) => {\n if (wasClean)\n return;\n console.log(`[vite] server connection lost. polling for restart...`);\n await waitForSuccessfulPing();\n chrome.runtime.reload();\n});\n";
3167
3164
 
3168
3165
  function defineClientValues(code, config) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crxjs/vite-plugin",
3
- "version": "1.0.0",
3
+ "version": "1.0.3",
4
4
  "description": "Build Chrome Extensions with this Vite plugin.",
5
5
  "keywords": [
6
6
  "rollup-plugin",
@@ -72,17 +72,17 @@
72
72
  "jsesc": "^3.0.2",
73
73
  "magic-string": "^0.26.0",
74
74
  "picocolors": "^1.0.0",
75
- "react-refresh": "^0.12.0",
75
+ "react-refresh": "^0.13.0",
76
76
  "rollup": "^2.70.2"
77
77
  },
78
78
  "devDependencies": {
79
79
  "@extend-chrome/messages": "1.2.2",
80
80
  "@extend-chrome/storage": "1.5.0",
81
81
  "@rollup/plugin-alias": "3.1.9",
82
- "@rollup/plugin-commonjs": "21.0.3",
82
+ "@rollup/plugin-commonjs": "21.1.0",
83
83
  "@rollup/plugin-node-resolve": "13.2.0",
84
84
  "@types/acorn": "4.0.6",
85
- "@types/chrome": "0.0.181",
85
+ "@types/chrome": "0.0.183",
86
86
  "@types/debug": "4.1.7",
87
87
  "@types/fs-extra": "9.0.13",
88
88
  "@types/jest": "27.4.1",
@@ -90,28 +90,25 @@
90
90
  "@types/jsesc": "3.0.1",
91
91
  "@types/node": "17.0.18",
92
92
  "@types/react": "17.0.44",
93
- "@types/react-dom": "17.0.11",
94
- "@typescript-eslint/eslint-plugin": "5.19.0",
95
- "@typescript-eslint/parser": "5.19.0",
93
+ "@types/react-dom": "17.0.16",
94
+ "@typescript-eslint/eslint-plugin": "5.21.0",
95
+ "@typescript-eslint/parser": "5.21.0",
96
96
  "@vitejs/plugin-react": "1.3.1",
97
97
  "@vitejs/plugin-vue": "2.3.1",
98
- "@vue/compiler-sfc": "3.2.33",
99
- "@vueuse/core": "7.6.2",
100
- "@vueuse/router": "8.2.6",
101
- "esbuild": "0.14.23",
98
+ "esbuild": "0.14.38",
102
99
  "esbuild-runner": "2.2.1",
100
+ "eslint": "^8.14.0",
103
101
  "jest": "27.5.1",
104
102
  "jest-image-snapshot": "4.5.1",
105
- "playwright-chromium": "1.21.0",
103
+ "playwright-chromium": "1.21.1",
106
104
  "react": "17.0.2",
107
105
  "react-dom": "17.0.2",
108
106
  "rimraf": "3.0.2",
109
107
  "rollup-plugin-dts": "^4.2.0",
110
108
  "rollup-plugin-esbuild": "4.9.1",
111
109
  "rxjs": "7.5.5",
112
- "typescript": "4.6.3",
113
110
  "vite": "^2.9.5",
114
- "vite-plugin-inspect": "0.4.3",
111
+ "vite-plugin-inspect": "0.5.0",
115
112
  "vue": "3.2.33"
116
113
  },
117
114
  "peerDependencies": {