@crxjs/vite-plugin 1.0.5 → 1.0.6

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 CHANGED
@@ -1,5 +1,16 @@
1
1
  # @crxjs/vite-plugin
2
2
 
3
+ ## 1.0.6
4
+
5
+ ### Patch Changes
6
+
7
+ - 63d102f: Automatically ignores `build.outDir` for server HMR, so the file
8
+ writer doesn't trigger a full reload.
9
+
10
+ Fixes flaky HMR updates for content scripts; Tailwind should work fine now 🥳
11
+
12
+ - a1e2728: Fix isImporter recursion
13
+
3
14
  ## 1.0.5
4
15
 
5
16
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -185,6 +185,7 @@ const setOutputMeta = ({
185
185
  outputByOwner.set(ownerName, output);
186
186
  outputById.set(id, output);
187
187
  };
188
+ const transformResultByOwner = /* @__PURE__ */ new Map();
188
189
 
189
190
  const {
190
191
  basename,
@@ -231,17 +232,12 @@ function sourceToUrlMeta(source) {
231
232
  }
232
233
  const pluginFileWriterChunks = () => {
233
234
  let server;
234
- const ownerToTransformResultMap = /* @__PURE__ */ new Map();
235
235
  return {
236
236
  name: "crx:file-writer-chunks",
237
237
  apply: "build",
238
238
  fileWriterStart(_server) {
239
239
  server = _server;
240
240
  },
241
- watchChange(fileName) {
242
- for (const owner of ownersByFile.get(fileName) ?? /* @__PURE__ */ new Set())
243
- ownerToTransformResultMap.delete(owner);
244
- },
245
241
  async resolveId(source, importer) {
246
242
  if (this.meta.watchMode) {
247
243
  if (idBySource.has(source)) {
@@ -277,12 +273,12 @@ const pluginFileWriterChunks = () => {
277
273
  if (!serverModule)
278
274
  throw new Error(`Unable to load "${url}" from server.`);
279
275
  const { file, url: owner } = serverModule;
280
- transformResult = transformResult ?? ownerToTransformResultMap.get(owner) ?? serverModule.transformResult;
276
+ transformResult = transformResult ?? transformResultByOwner.get(owner) ?? serverModule.transformResult;
281
277
  if (!transformResult)
282
278
  transformResult = await server.transformRequest(url);
283
279
  if (!transformResult)
284
280
  throw new TypeError(`Unable to load "${url}" from server.`);
285
- ownerToTransformResultMap.set(owner, transformResult);
281
+ transformResultByOwner.set(owner, transformResult);
286
282
  if (file) {
287
283
  setFileMeta({ id, file });
288
284
  this.addWatchFile(file);
@@ -369,7 +365,7 @@ const pluginFileWriterChunks = () => {
369
365
  };
370
366
  };
371
367
 
372
- /*! *****************************************************************************
368
+ /******************************************************************************
373
369
  Copyright (c) Microsoft Corporation.
374
370
 
375
371
  Permission to use, copy, modify, and/or distribute this software for any
@@ -1481,6 +1477,12 @@ function last(arr) {
1481
1477
  function popResultSelector(args) {
1482
1478
  return isFunction(last(args)) ? args.pop() : undefined;
1483
1479
  }
1480
+ function popScheduler(args) {
1481
+ return isScheduler(last(args)) ? args.pop() : undefined;
1482
+ }
1483
+ function popNumber(args, defaultValue) {
1484
+ return typeof last(args) === 'number' ? args.pop() : defaultValue;
1485
+ }
1484
1486
 
1485
1487
  var isArrayLike = (function (x) { return x && typeof x.length === 'number' && typeof x !== 'function'; });
1486
1488
 
@@ -1697,6 +1699,126 @@ function executeSchedule(parentSubscription, scheduler, work, delay, repeat) {
1697
1699
  }
1698
1700
  }
1699
1701
 
1702
+ function observeOn(scheduler, delay) {
1703
+ if (delay === void 0) { delay = 0; }
1704
+ return operate(function (source, subscriber) {
1705
+ source.subscribe(createOperatorSubscriber(subscriber, function (value) { return executeSchedule(subscriber, scheduler, function () { return subscriber.next(value); }, delay); }, function () { return executeSchedule(subscriber, scheduler, function () { return subscriber.complete(); }, delay); }, function (err) { return executeSchedule(subscriber, scheduler, function () { return subscriber.error(err); }, delay); }));
1706
+ });
1707
+ }
1708
+
1709
+ function subscribeOn(scheduler, delay) {
1710
+ if (delay === void 0) { delay = 0; }
1711
+ return operate(function (source, subscriber) {
1712
+ subscriber.add(scheduler.schedule(function () { return source.subscribe(subscriber); }, delay));
1713
+ });
1714
+ }
1715
+
1716
+ function scheduleObservable(input, scheduler) {
1717
+ return innerFrom(input).pipe(subscribeOn(scheduler), observeOn(scheduler));
1718
+ }
1719
+
1720
+ function schedulePromise(input, scheduler) {
1721
+ return innerFrom(input).pipe(subscribeOn(scheduler), observeOn(scheduler));
1722
+ }
1723
+
1724
+ function scheduleArray(input, scheduler) {
1725
+ return new Observable(function (subscriber) {
1726
+ var i = 0;
1727
+ return scheduler.schedule(function () {
1728
+ if (i === input.length) {
1729
+ subscriber.complete();
1730
+ }
1731
+ else {
1732
+ subscriber.next(input[i++]);
1733
+ if (!subscriber.closed) {
1734
+ this.schedule();
1735
+ }
1736
+ }
1737
+ });
1738
+ });
1739
+ }
1740
+
1741
+ function scheduleIterable(input, scheduler) {
1742
+ return new Observable(function (subscriber) {
1743
+ var iterator$1;
1744
+ executeSchedule(subscriber, scheduler, function () {
1745
+ iterator$1 = input[iterator]();
1746
+ executeSchedule(subscriber, scheduler, function () {
1747
+ var _a;
1748
+ var value;
1749
+ var done;
1750
+ try {
1751
+ (_a = iterator$1.next(), value = _a.value, done = _a.done);
1752
+ }
1753
+ catch (err) {
1754
+ subscriber.error(err);
1755
+ return;
1756
+ }
1757
+ if (done) {
1758
+ subscriber.complete();
1759
+ }
1760
+ else {
1761
+ subscriber.next(value);
1762
+ }
1763
+ }, 0, true);
1764
+ });
1765
+ return function () { return isFunction(iterator$1 === null || iterator$1 === void 0 ? void 0 : iterator$1.return) && iterator$1.return(); };
1766
+ });
1767
+ }
1768
+
1769
+ function scheduleAsyncIterable(input, scheduler) {
1770
+ if (!input) {
1771
+ throw new Error('Iterable cannot be null');
1772
+ }
1773
+ return new Observable(function (subscriber) {
1774
+ executeSchedule(subscriber, scheduler, function () {
1775
+ var iterator = input[Symbol.asyncIterator]();
1776
+ executeSchedule(subscriber, scheduler, function () {
1777
+ iterator.next().then(function (result) {
1778
+ if (result.done) {
1779
+ subscriber.complete();
1780
+ }
1781
+ else {
1782
+ subscriber.next(result.value);
1783
+ }
1784
+ });
1785
+ }, 0, true);
1786
+ });
1787
+ });
1788
+ }
1789
+
1790
+ function scheduleReadableStreamLike(input, scheduler) {
1791
+ return scheduleAsyncIterable(readableStreamLikeToAsyncGenerator(input), scheduler);
1792
+ }
1793
+
1794
+ function scheduled(input, scheduler) {
1795
+ if (input != null) {
1796
+ if (isInteropObservable(input)) {
1797
+ return scheduleObservable(input, scheduler);
1798
+ }
1799
+ if (isArrayLike(input)) {
1800
+ return scheduleArray(input, scheduler);
1801
+ }
1802
+ if (isPromise(input)) {
1803
+ return schedulePromise(input, scheduler);
1804
+ }
1805
+ if (isAsyncIterable(input)) {
1806
+ return scheduleAsyncIterable(input, scheduler);
1807
+ }
1808
+ if (isIterable(input)) {
1809
+ return scheduleIterable(input, scheduler);
1810
+ }
1811
+ if (isReadableStreamLike(input)) {
1812
+ return scheduleReadableStreamLike(input, scheduler);
1813
+ }
1814
+ }
1815
+ throw createInvalidObservableTypeError(input);
1816
+ }
1817
+
1818
+ function from(input, scheduler) {
1819
+ return scheduler ? scheduled(input, scheduler) : innerFrom(input);
1820
+ }
1821
+
1700
1822
  var EmptyError = createErrorClass(function (_super) { return function EmptyErrorImpl() {
1701
1823
  _super(this);
1702
1824
  this.name = 'EmptyError';
@@ -1807,6 +1929,11 @@ function mergeMap(project, resultSelector, concurrent) {
1807
1929
  return operate(function (source, subscriber) { return mergeInternals(source, subscriber, project, concurrent); });
1808
1930
  }
1809
1931
 
1932
+ function mergeAll(concurrent) {
1933
+ if (concurrent === void 0) { concurrent = Infinity; }
1934
+ return mergeMap(identity, concurrent);
1935
+ }
1936
+
1810
1937
  function timer(dueTime, intervalOrScheduler, scheduler) {
1811
1938
  if (dueTime === void 0) { dueTime = 0; }
1812
1939
  if (scheduler === void 0) { scheduler = async; }
@@ -1839,13 +1966,22 @@ function timer(dueTime, intervalOrScheduler, scheduler) {
1839
1966
  });
1840
1967
  }
1841
1968
 
1842
- function interval(period, scheduler) {
1843
- if (period === void 0) { period = 0; }
1844
- if (scheduler === void 0) { scheduler = asyncScheduler; }
1845
- if (period < 0) {
1846
- period = 0;
1969
+ function merge() {
1970
+ var args = [];
1971
+ for (var _i = 0; _i < arguments.length; _i++) {
1972
+ args[_i] = arguments[_i];
1847
1973
  }
1848
- return timer(period, period, scheduler);
1974
+ var scheduler = popScheduler(args);
1975
+ var concurrent = popNumber(args, Infinity);
1976
+ var sources = args;
1977
+ return !sources.length
1978
+ ?
1979
+ EMPTY
1980
+ : sources.length === 1
1981
+ ?
1982
+ innerFrom(sources[0])
1983
+ :
1984
+ mergeAll(concurrent)(from(sources, scheduler));
1849
1985
  }
1850
1986
 
1851
1987
  function filter(predicate, thisArg) {
@@ -1873,6 +2009,36 @@ function buffer(closingNotifier) {
1873
2009
  });
1874
2010
  }
1875
2011
 
2012
+ function debounce(durationSelector) {
2013
+ return operate(function (source, subscriber) {
2014
+ var hasValue = false;
2015
+ var lastValue = null;
2016
+ var durationSubscriber = null;
2017
+ var emit = function () {
2018
+ durationSubscriber === null || durationSubscriber === void 0 ? void 0 : durationSubscriber.unsubscribe();
2019
+ durationSubscriber = null;
2020
+ if (hasValue) {
2021
+ hasValue = false;
2022
+ var value = lastValue;
2023
+ lastValue = null;
2024
+ subscriber.next(value);
2025
+ }
2026
+ };
2027
+ source.subscribe(createOperatorSubscriber(subscriber, function (value) {
2028
+ durationSubscriber === null || durationSubscriber === void 0 ? void 0 : durationSubscriber.unsubscribe();
2029
+ hasValue = true;
2030
+ lastValue = value;
2031
+ durationSubscriber = createOperatorSubscriber(subscriber, emit, noop);
2032
+ innerFrom(durationSelector(value)).subscribe(durationSubscriber);
2033
+ }, function () {
2034
+ emit();
2035
+ subscriber.complete();
2036
+ }, undefined, function () {
2037
+ lastValue = durationSubscriber = null;
2038
+ }));
2039
+ });
2040
+ }
2041
+
1876
2042
  function defaultIfEmpty(defaultValue) {
1877
2043
  return operate(function (source, subscriber) {
1878
2044
  var hasValue = false;
@@ -1905,10 +2071,6 @@ function take(count) {
1905
2071
  });
1906
2072
  }
1907
2073
 
1908
- function mapTo(value) {
1909
- return map(function () { return value; });
1910
- }
1911
-
1912
2074
  function throwIfEmpty(errorFactory) {
1913
2075
  if (errorFactory === void 0) { errorFactory = defaultErrorFactory; }
1914
2076
  return operate(function (source, subscriber) {
@@ -2003,7 +2165,7 @@ const filesStart$ = writerEvent$.pipe(filter((x) => {
2003
2165
  const filesStart = () => firstValueFrom(filesStart$);
2004
2166
  const filesReady$ = writerEvent$.pipe(filter((x) => {
2005
2167
  return x.type === "writeBundle";
2006
- }), switchMap((event) => interval(100).pipe(mapTo(event), first(({ bundle, options, timestamp }) => {
2168
+ }), switchMap((event) => timer(0, 100).pipe(map(() => event), first(({ bundle, options, timestamp }) => {
2007
2169
  const result = Object.keys(bundle).every((p) => {
2008
2170
  const stats = statSync(join(options.dir, p));
2009
2171
  return stats.mtimeMs > timestamp;
@@ -2152,7 +2314,6 @@ const pluginFileWriterPublic = () => {
2152
2314
  const source = await fsExtra.readFile(file);
2153
2315
  const fileName = relative(config.publicDir, file);
2154
2316
  this.emitFile({ type: "asset", fileName, source });
2155
- this.addWatchFile(file);
2156
2317
  }
2157
2318
  }
2158
2319
  }
@@ -2187,6 +2348,94 @@ const pluginFileWriterPolyfill = () => {
2187
2348
  };
2188
2349
  };
2189
2350
 
2351
+ function isUpdatePayload(p) {
2352
+ return p.type === "update";
2353
+ }
2354
+ function isFullReloadPayload(p) {
2355
+ return p.type === "full-reload";
2356
+ }
2357
+ function isPrunePayload(p) {
2358
+ return p.type === "prune";
2359
+ }
2360
+ function isCrxHMRPayload(x) {
2361
+ return x.type === "custom" && x.event.startsWith("crx:");
2362
+ }
2363
+ const hmrPayload$ = new Subject();
2364
+ const hmrPrune$ = hmrPayload$.pipe(filter(isPrunePayload));
2365
+ const hmrFullReload$ = hmrPayload$.pipe(filter(isFullReloadPayload));
2366
+ const hmrUpdate$ = hmrPayload$.pipe(filter(isUpdatePayload));
2367
+ const payload$ = merge(hmrFullReload$, hmrPrune$, hmrUpdate$);
2368
+ const rebuildSignal$ = payload$.pipe(buffer(payload$.pipe(debounce(() => filesReady$))), map((payloads) => {
2369
+ if (payloads.every(isUpdatePayload)) {
2370
+ const owners = /* @__PURE__ */ new Set();
2371
+ for (const { updates } of payloads)
2372
+ for (const { path } of updates)
2373
+ if (transformResultByOwner.has(path))
2374
+ owners.add(path);
2375
+ return { type: "partial", owners };
2376
+ }
2377
+ return { type: "full" };
2378
+ }), filter((rebuild) => rebuild.type === "partial" ? rebuild.owners.size > 0 : true));
2379
+ const crxHmrPayload$ = hmrPayload$.pipe(filter((p) => !isCrxHMRPayload(p)), buffer(filesReady$), mergeMap((pps) => {
2380
+ let fullReload;
2381
+ const payloads = [];
2382
+ for (const p of pps.slice(-50))
2383
+ if (p.type === "full-reload") {
2384
+ fullReload = p;
2385
+ } else {
2386
+ payloads.push(p);
2387
+ }
2388
+ if (fullReload)
2389
+ payloads.push(fullReload);
2390
+ return payloads;
2391
+ }), map((p) => {
2392
+ switch (p.type) {
2393
+ case "full-reload": {
2394
+ const path = p.path && outputByOwner.get(p.path);
2395
+ const fullReload = {
2396
+ type: "full-reload",
2397
+ path
2398
+ };
2399
+ return fullReload;
2400
+ }
2401
+ case "prune": {
2402
+ const paths = [];
2403
+ for (const owner of p.paths)
2404
+ if (outputByOwner.has(owner))
2405
+ paths.push(outputByOwner.get(owner));
2406
+ return { type: "prune", paths };
2407
+ }
2408
+ case "update": {
2409
+ const updates = [];
2410
+ for (const { acceptedPath, path, ...rest } of p.updates)
2411
+ if (outputByOwner.has(acceptedPath) && outputByOwner.has(path))
2412
+ updates.push({
2413
+ ...rest,
2414
+ acceptedPath: outputByOwner.get(acceptedPath),
2415
+ path: outputByOwner.get(path)
2416
+ });
2417
+ return { type: "update", updates };
2418
+ }
2419
+ default:
2420
+ return p;
2421
+ }
2422
+ }), withLatestFrom(filesReady$), filter(([p, { bundle }]) => {
2423
+ switch (p.type) {
2424
+ case "full-reload":
2425
+ return typeof p.path === "undefined" || p.path in bundle;
2426
+ case "prune":
2427
+ return p.paths.length > 0;
2428
+ case "update":
2429
+ return p.updates.length > 0;
2430
+ default:
2431
+ return true;
2432
+ }
2433
+ }), map(([p]) => ({
2434
+ type: "custom",
2435
+ event: "crx:content-script-payload",
2436
+ data: p
2437
+ })));
2438
+
2190
2439
  function sortPlugins(plugins, command) {
2191
2440
  const pre = [];
2192
2441
  const mid = [];
@@ -2283,6 +2532,18 @@ const pluginFileWriter = (crxPlugins) => (options) => {
2283
2532
  writerEvent$.next({ type: "error", error, code, frame });
2284
2533
  }
2285
2534
  });
2535
+ const rebuildSub = rebuildSignal$.subscribe((rebuild) => {
2536
+ if (rebuild.type === "partial") {
2537
+ for (const owner of rebuild.owners)
2538
+ transformResultByOwner.delete(owner);
2539
+ } else {
2540
+ transformResultByOwner.clear();
2541
+ }
2542
+ rebuildFiles();
2543
+ });
2544
+ watcher.on("close", () => {
2545
+ rebuildSub.unsubscribe();
2546
+ });
2286
2547
  });
2287
2548
  },
2288
2549
  closeBundle() {
@@ -2291,87 +2552,30 @@ const pluginFileWriter = (crxPlugins) => (options) => {
2291
2552
  };
2292
2553
  };
2293
2554
 
2294
- const debug$2 = _debug("hmr");
2295
2555
  function isImporter(file) {
2296
- const pred = (node) => {
2297
- if (node.file === file)
2556
+ const seen = /* @__PURE__ */ new Set();
2557
+ const pred = (changedNode) => {
2558
+ seen.add(changedNode);
2559
+ if (changedNode.file === file)
2298
2560
  return true;
2299
- for (const node2 of node.importers)
2300
- if (pred(node2))
2561
+ for (const parentNode of changedNode.importers) {
2562
+ const unseen = !seen.has(parentNode);
2563
+ if (unseen && pred(parentNode))
2301
2564
  return true;
2565
+ }
2566
+ return false;
2302
2567
  };
2303
2568
  return pred;
2304
2569
  }
2305
- function isCrxHMRPayload(x) {
2306
- return x.type === "custom" && x.event.startsWith("crx:");
2307
- }
2308
- const hmrPayload$ = new Subject();
2309
- const crxHmrPayload$ = hmrPayload$.pipe(filter((p) => !isCrxHMRPayload(p)), buffer(filesReady$), mergeMap((pps) => {
2310
- let fullReload;
2311
- const payloads = [];
2312
- for (const p of pps.slice(-50))
2313
- if (p.type === "full-reload") {
2314
- fullReload = p;
2315
- } else {
2316
- payloads.push(p);
2317
- }
2318
- if (fullReload)
2319
- payloads.push(fullReload);
2320
- return payloads;
2321
- }), map((p) => {
2322
- switch (p.type) {
2323
- case "full-reload": {
2324
- const path = p.path && outputByOwner.get(p.path);
2325
- const fullReload = {
2326
- type: "full-reload",
2327
- path
2328
- };
2329
- return fullReload;
2330
- }
2331
- case "prune": {
2332
- const paths = [];
2333
- for (const owner of p.paths)
2334
- if (outputByOwner.has(owner))
2335
- paths.push(outputByOwner.get(owner));
2336
- return { type: "prune", paths };
2337
- }
2338
- case "update": {
2339
- const updates = [];
2340
- for (const { acceptedPath, path, ...rest } of p.updates)
2341
- if (outputByOwner.has(acceptedPath) && outputByOwner.has(path))
2342
- updates.push({
2343
- ...rest,
2344
- acceptedPath: outputByOwner.get(acceptedPath),
2345
- path: outputByOwner.get(path)
2346
- });
2347
- return { type: "update", updates };
2348
- }
2349
- default:
2350
- return p;
2351
- }
2352
- }), withLatestFrom(filesReady$), filter(([p, { bundle }]) => {
2353
- switch (p.type) {
2354
- case "full-reload":
2355
- return typeof p.path === "undefined" || p.path in bundle;
2356
- case "prune":
2357
- return p.paths.length > 0;
2358
- case "update":
2359
- return p.updates.length > 0;
2360
- default:
2361
- return true;
2362
- }
2363
- }), map(([p]) => ({
2364
- type: "custom",
2365
- event: "crx:content-script-payload",
2366
- data: p
2367
- })));
2570
+
2571
+ const debug$2 = _debug("hmr");
2368
2572
  const crxRuntimeReload = {
2369
2573
  type: "custom",
2370
2574
  event: "crx:runtime-reload"
2371
2575
  };
2372
2576
  const pluginHMR = () => {
2373
2577
  let files;
2374
- let server;
2578
+ let decoratedSend;
2375
2579
  return [
2376
2580
  {
2377
2581
  name: "crx:hmr",
@@ -2388,38 +2592,41 @@ const pluginHMR = () => {
2388
2592
  name: "crx:hmr",
2389
2593
  apply: "serve",
2390
2594
  enforce: "pre",
2391
- config({ server: server2 = {}, ...config }) {
2392
- if (server2.hmr === false)
2595
+ config({ server = {}, ...config }) {
2596
+ if (server.hmr === false)
2393
2597
  return;
2394
- if (server2.hmr === true)
2395
- server2.hmr = {};
2396
- server2.hmr = server2.hmr ?? {};
2397
- server2.hmr.host = "localhost";
2398
- return { server: server2, ...config };
2598
+ if (server.hmr === true)
2599
+ server.hmr = {};
2600
+ server.hmr = server.hmr ?? {};
2601
+ server.hmr.host = "localhost";
2602
+ return { server, ...config };
2399
2603
  },
2400
2604
  configResolved(config) {
2401
2605
  const { watch = {} } = config.server;
2402
2606
  config.server.watch = watch;
2403
2607
  watch.ignored = watch.ignored ? [...new Set([watch.ignored].flat())] : [];
2404
- watch.ignored.push(config.build.outDir);
2608
+ const outDir = isAbsolute(config.build.outDir) ? config.build.outDir : join(config.root, config.build.outDir, "**/*");
2609
+ watch.ignored.push(outDir);
2405
2610
  },
2406
- configureServer(_server) {
2407
- server = _server;
2408
- const { send } = server.ws;
2409
- server.ws.send = (payload) => {
2410
- hmrPayload$.next(payload);
2411
- send(payload);
2412
- };
2413
- crxHmrPayload$.subscribe((payload) => {
2414
- send(payload);
2415
- });
2611
+ configureServer(server) {
2612
+ if (server.ws.send !== decoratedSend) {
2613
+ const { send } = server.ws;
2614
+ decoratedSend = (payload) => {
2615
+ hmrPayload$.next(payload);
2616
+ send(payload);
2617
+ };
2618
+ server.ws.send = decoratedSend;
2619
+ crxHmrPayload$.subscribe((payload) => {
2620
+ send(payload);
2621
+ });
2622
+ }
2416
2623
  },
2417
- handleHotUpdate({ file, modules, server: server2 }) {
2418
- const background = files.background[0] && join(server2.config.root, files.background[0]);
2624
+ handleHotUpdate({ file, modules, server }) {
2625
+ const background = files.background[0] && join(server.config.root, files.background[0]);
2419
2626
  if (background) {
2420
2627
  if (file === background || modules.some(isImporter(background))) {
2421
2628
  debug$2("sending runtime reload");
2422
- server2.ws.send(crxRuntimeReload);
2629
+ server.ws.send(crxRuntimeReload);
2423
2630
  return [];
2424
2631
  }
2425
2632
  }
package/dist/index.mjs CHANGED
@@ -152,6 +152,7 @@ const setOutputMeta = ({
152
152
  outputByOwner.set(ownerName, output);
153
153
  outputById.set(id, output);
154
154
  };
155
+ const transformResultByOwner = /* @__PURE__ */ new Map();
155
156
 
156
157
  const {
157
158
  basename,
@@ -198,17 +199,12 @@ function sourceToUrlMeta(source) {
198
199
  }
199
200
  const pluginFileWriterChunks = () => {
200
201
  let server;
201
- const ownerToTransformResultMap = /* @__PURE__ */ new Map();
202
202
  return {
203
203
  name: "crx:file-writer-chunks",
204
204
  apply: "build",
205
205
  fileWriterStart(_server) {
206
206
  server = _server;
207
207
  },
208
- watchChange(fileName) {
209
- for (const owner of ownersByFile.get(fileName) ?? /* @__PURE__ */ new Set())
210
- ownerToTransformResultMap.delete(owner);
211
- },
212
208
  async resolveId(source, importer) {
213
209
  if (this.meta.watchMode) {
214
210
  if (idBySource.has(source)) {
@@ -244,12 +240,12 @@ const pluginFileWriterChunks = () => {
244
240
  if (!serverModule)
245
241
  throw new Error(`Unable to load "${url}" from server.`);
246
242
  const { file, url: owner } = serverModule;
247
- transformResult = transformResult ?? ownerToTransformResultMap.get(owner) ?? serverModule.transformResult;
243
+ transformResult = transformResult ?? transformResultByOwner.get(owner) ?? serverModule.transformResult;
248
244
  if (!transformResult)
249
245
  transformResult = await server.transformRequest(url);
250
246
  if (!transformResult)
251
247
  throw new TypeError(`Unable to load "${url}" from server.`);
252
- ownerToTransformResultMap.set(owner, transformResult);
248
+ transformResultByOwner.set(owner, transformResult);
253
249
  if (file) {
254
250
  setFileMeta({ id, file });
255
251
  this.addWatchFile(file);
@@ -336,7 +332,7 @@ const pluginFileWriterChunks = () => {
336
332
  };
337
333
  };
338
334
 
339
- /*! *****************************************************************************
335
+ /******************************************************************************
340
336
  Copyright (c) Microsoft Corporation.
341
337
 
342
338
  Permission to use, copy, modify, and/or distribute this software for any
@@ -1448,6 +1444,12 @@ function last(arr) {
1448
1444
  function popResultSelector(args) {
1449
1445
  return isFunction(last(args)) ? args.pop() : undefined;
1450
1446
  }
1447
+ function popScheduler(args) {
1448
+ return isScheduler(last(args)) ? args.pop() : undefined;
1449
+ }
1450
+ function popNumber(args, defaultValue) {
1451
+ return typeof last(args) === 'number' ? args.pop() : defaultValue;
1452
+ }
1451
1453
 
1452
1454
  var isArrayLike = (function (x) { return x && typeof x.length === 'number' && typeof x !== 'function'; });
1453
1455
 
@@ -1664,6 +1666,126 @@ function executeSchedule(parentSubscription, scheduler, work, delay, repeat) {
1664
1666
  }
1665
1667
  }
1666
1668
 
1669
+ function observeOn(scheduler, delay) {
1670
+ if (delay === void 0) { delay = 0; }
1671
+ return operate(function (source, subscriber) {
1672
+ source.subscribe(createOperatorSubscriber(subscriber, function (value) { return executeSchedule(subscriber, scheduler, function () { return subscriber.next(value); }, delay); }, function () { return executeSchedule(subscriber, scheduler, function () { return subscriber.complete(); }, delay); }, function (err) { return executeSchedule(subscriber, scheduler, function () { return subscriber.error(err); }, delay); }));
1673
+ });
1674
+ }
1675
+
1676
+ function subscribeOn(scheduler, delay) {
1677
+ if (delay === void 0) { delay = 0; }
1678
+ return operate(function (source, subscriber) {
1679
+ subscriber.add(scheduler.schedule(function () { return source.subscribe(subscriber); }, delay));
1680
+ });
1681
+ }
1682
+
1683
+ function scheduleObservable(input, scheduler) {
1684
+ return innerFrom(input).pipe(subscribeOn(scheduler), observeOn(scheduler));
1685
+ }
1686
+
1687
+ function schedulePromise(input, scheduler) {
1688
+ return innerFrom(input).pipe(subscribeOn(scheduler), observeOn(scheduler));
1689
+ }
1690
+
1691
+ function scheduleArray(input, scheduler) {
1692
+ return new Observable(function (subscriber) {
1693
+ var i = 0;
1694
+ return scheduler.schedule(function () {
1695
+ if (i === input.length) {
1696
+ subscriber.complete();
1697
+ }
1698
+ else {
1699
+ subscriber.next(input[i++]);
1700
+ if (!subscriber.closed) {
1701
+ this.schedule();
1702
+ }
1703
+ }
1704
+ });
1705
+ });
1706
+ }
1707
+
1708
+ function scheduleIterable(input, scheduler) {
1709
+ return new Observable(function (subscriber) {
1710
+ var iterator$1;
1711
+ executeSchedule(subscriber, scheduler, function () {
1712
+ iterator$1 = input[iterator]();
1713
+ executeSchedule(subscriber, scheduler, function () {
1714
+ var _a;
1715
+ var value;
1716
+ var done;
1717
+ try {
1718
+ (_a = iterator$1.next(), value = _a.value, done = _a.done);
1719
+ }
1720
+ catch (err) {
1721
+ subscriber.error(err);
1722
+ return;
1723
+ }
1724
+ if (done) {
1725
+ subscriber.complete();
1726
+ }
1727
+ else {
1728
+ subscriber.next(value);
1729
+ }
1730
+ }, 0, true);
1731
+ });
1732
+ return function () { return isFunction(iterator$1 === null || iterator$1 === void 0 ? void 0 : iterator$1.return) && iterator$1.return(); };
1733
+ });
1734
+ }
1735
+
1736
+ function scheduleAsyncIterable(input, scheduler) {
1737
+ if (!input) {
1738
+ throw new Error('Iterable cannot be null');
1739
+ }
1740
+ return new Observable(function (subscriber) {
1741
+ executeSchedule(subscriber, scheduler, function () {
1742
+ var iterator = input[Symbol.asyncIterator]();
1743
+ executeSchedule(subscriber, scheduler, function () {
1744
+ iterator.next().then(function (result) {
1745
+ if (result.done) {
1746
+ subscriber.complete();
1747
+ }
1748
+ else {
1749
+ subscriber.next(result.value);
1750
+ }
1751
+ });
1752
+ }, 0, true);
1753
+ });
1754
+ });
1755
+ }
1756
+
1757
+ function scheduleReadableStreamLike(input, scheduler) {
1758
+ return scheduleAsyncIterable(readableStreamLikeToAsyncGenerator(input), scheduler);
1759
+ }
1760
+
1761
+ function scheduled(input, scheduler) {
1762
+ if (input != null) {
1763
+ if (isInteropObservable(input)) {
1764
+ return scheduleObservable(input, scheduler);
1765
+ }
1766
+ if (isArrayLike(input)) {
1767
+ return scheduleArray(input, scheduler);
1768
+ }
1769
+ if (isPromise(input)) {
1770
+ return schedulePromise(input, scheduler);
1771
+ }
1772
+ if (isAsyncIterable(input)) {
1773
+ return scheduleAsyncIterable(input, scheduler);
1774
+ }
1775
+ if (isIterable(input)) {
1776
+ return scheduleIterable(input, scheduler);
1777
+ }
1778
+ if (isReadableStreamLike(input)) {
1779
+ return scheduleReadableStreamLike(input, scheduler);
1780
+ }
1781
+ }
1782
+ throw createInvalidObservableTypeError(input);
1783
+ }
1784
+
1785
+ function from(input, scheduler) {
1786
+ return scheduler ? scheduled(input, scheduler) : innerFrom(input);
1787
+ }
1788
+
1667
1789
  var EmptyError = createErrorClass(function (_super) { return function EmptyErrorImpl() {
1668
1790
  _super(this);
1669
1791
  this.name = 'EmptyError';
@@ -1774,6 +1896,11 @@ function mergeMap(project, resultSelector, concurrent) {
1774
1896
  return operate(function (source, subscriber) { return mergeInternals(source, subscriber, project, concurrent); });
1775
1897
  }
1776
1898
 
1899
+ function mergeAll(concurrent) {
1900
+ if (concurrent === void 0) { concurrent = Infinity; }
1901
+ return mergeMap(identity, concurrent);
1902
+ }
1903
+
1777
1904
  function timer(dueTime, intervalOrScheduler, scheduler) {
1778
1905
  if (dueTime === void 0) { dueTime = 0; }
1779
1906
  if (scheduler === void 0) { scheduler = async; }
@@ -1806,13 +1933,22 @@ function timer(dueTime, intervalOrScheduler, scheduler) {
1806
1933
  });
1807
1934
  }
1808
1935
 
1809
- function interval(period, scheduler) {
1810
- if (period === void 0) { period = 0; }
1811
- if (scheduler === void 0) { scheduler = asyncScheduler; }
1812
- if (period < 0) {
1813
- period = 0;
1936
+ function merge() {
1937
+ var args = [];
1938
+ for (var _i = 0; _i < arguments.length; _i++) {
1939
+ args[_i] = arguments[_i];
1814
1940
  }
1815
- return timer(period, period, scheduler);
1941
+ var scheduler = popScheduler(args);
1942
+ var concurrent = popNumber(args, Infinity);
1943
+ var sources = args;
1944
+ return !sources.length
1945
+ ?
1946
+ EMPTY
1947
+ : sources.length === 1
1948
+ ?
1949
+ innerFrom(sources[0])
1950
+ :
1951
+ mergeAll(concurrent)(from(sources, scheduler));
1816
1952
  }
1817
1953
 
1818
1954
  function filter(predicate, thisArg) {
@@ -1840,6 +1976,36 @@ function buffer(closingNotifier) {
1840
1976
  });
1841
1977
  }
1842
1978
 
1979
+ function debounce(durationSelector) {
1980
+ return operate(function (source, subscriber) {
1981
+ var hasValue = false;
1982
+ var lastValue = null;
1983
+ var durationSubscriber = null;
1984
+ var emit = function () {
1985
+ durationSubscriber === null || durationSubscriber === void 0 ? void 0 : durationSubscriber.unsubscribe();
1986
+ durationSubscriber = null;
1987
+ if (hasValue) {
1988
+ hasValue = false;
1989
+ var value = lastValue;
1990
+ lastValue = null;
1991
+ subscriber.next(value);
1992
+ }
1993
+ };
1994
+ source.subscribe(createOperatorSubscriber(subscriber, function (value) {
1995
+ durationSubscriber === null || durationSubscriber === void 0 ? void 0 : durationSubscriber.unsubscribe();
1996
+ hasValue = true;
1997
+ lastValue = value;
1998
+ durationSubscriber = createOperatorSubscriber(subscriber, emit, noop);
1999
+ innerFrom(durationSelector(value)).subscribe(durationSubscriber);
2000
+ }, function () {
2001
+ emit();
2002
+ subscriber.complete();
2003
+ }, undefined, function () {
2004
+ lastValue = durationSubscriber = null;
2005
+ }));
2006
+ });
2007
+ }
2008
+
1843
2009
  function defaultIfEmpty(defaultValue) {
1844
2010
  return operate(function (source, subscriber) {
1845
2011
  var hasValue = false;
@@ -1872,10 +2038,6 @@ function take(count) {
1872
2038
  });
1873
2039
  }
1874
2040
 
1875
- function mapTo(value) {
1876
- return map(function () { return value; });
1877
- }
1878
-
1879
2041
  function throwIfEmpty(errorFactory) {
1880
2042
  if (errorFactory === void 0) { errorFactory = defaultErrorFactory; }
1881
2043
  return operate(function (source, subscriber) {
@@ -1970,7 +2132,7 @@ const filesStart$ = writerEvent$.pipe(filter((x) => {
1970
2132
  const filesStart = () => firstValueFrom(filesStart$);
1971
2133
  const filesReady$ = writerEvent$.pipe(filter((x) => {
1972
2134
  return x.type === "writeBundle";
1973
- }), switchMap((event) => interval(100).pipe(mapTo(event), first(({ bundle, options, timestamp }) => {
2135
+ }), switchMap((event) => timer(0, 100).pipe(map(() => event), first(({ bundle, options, timestamp }) => {
1974
2136
  const result = Object.keys(bundle).every((p) => {
1975
2137
  const stats = statSync(join(options.dir, p));
1976
2138
  return stats.mtimeMs > timestamp;
@@ -2119,7 +2281,6 @@ const pluginFileWriterPublic = () => {
2119
2281
  const source = await readFile(file);
2120
2282
  const fileName = relative(config.publicDir, file);
2121
2283
  this.emitFile({ type: "asset", fileName, source });
2122
- this.addWatchFile(file);
2123
2284
  }
2124
2285
  }
2125
2286
  }
@@ -2154,6 +2315,94 @@ const pluginFileWriterPolyfill = () => {
2154
2315
  };
2155
2316
  };
2156
2317
 
2318
+ function isUpdatePayload(p) {
2319
+ return p.type === "update";
2320
+ }
2321
+ function isFullReloadPayload(p) {
2322
+ return p.type === "full-reload";
2323
+ }
2324
+ function isPrunePayload(p) {
2325
+ return p.type === "prune";
2326
+ }
2327
+ function isCrxHMRPayload(x) {
2328
+ return x.type === "custom" && x.event.startsWith("crx:");
2329
+ }
2330
+ const hmrPayload$ = new Subject();
2331
+ const hmrPrune$ = hmrPayload$.pipe(filter(isPrunePayload));
2332
+ const hmrFullReload$ = hmrPayload$.pipe(filter(isFullReloadPayload));
2333
+ const hmrUpdate$ = hmrPayload$.pipe(filter(isUpdatePayload));
2334
+ const payload$ = merge(hmrFullReload$, hmrPrune$, hmrUpdate$);
2335
+ const rebuildSignal$ = payload$.pipe(buffer(payload$.pipe(debounce(() => filesReady$))), map((payloads) => {
2336
+ if (payloads.every(isUpdatePayload)) {
2337
+ const owners = /* @__PURE__ */ new Set();
2338
+ for (const { updates } of payloads)
2339
+ for (const { path } of updates)
2340
+ if (transformResultByOwner.has(path))
2341
+ owners.add(path);
2342
+ return { type: "partial", owners };
2343
+ }
2344
+ return { type: "full" };
2345
+ }), filter((rebuild) => rebuild.type === "partial" ? rebuild.owners.size > 0 : true));
2346
+ const crxHmrPayload$ = hmrPayload$.pipe(filter((p) => !isCrxHMRPayload(p)), buffer(filesReady$), mergeMap((pps) => {
2347
+ let fullReload;
2348
+ const payloads = [];
2349
+ for (const p of pps.slice(-50))
2350
+ if (p.type === "full-reload") {
2351
+ fullReload = p;
2352
+ } else {
2353
+ payloads.push(p);
2354
+ }
2355
+ if (fullReload)
2356
+ payloads.push(fullReload);
2357
+ return payloads;
2358
+ }), map((p) => {
2359
+ switch (p.type) {
2360
+ case "full-reload": {
2361
+ const path = p.path && outputByOwner.get(p.path);
2362
+ const fullReload = {
2363
+ type: "full-reload",
2364
+ path
2365
+ };
2366
+ return fullReload;
2367
+ }
2368
+ case "prune": {
2369
+ const paths = [];
2370
+ for (const owner of p.paths)
2371
+ if (outputByOwner.has(owner))
2372
+ paths.push(outputByOwner.get(owner));
2373
+ return { type: "prune", paths };
2374
+ }
2375
+ case "update": {
2376
+ const updates = [];
2377
+ for (const { acceptedPath, path, ...rest } of p.updates)
2378
+ if (outputByOwner.has(acceptedPath) && outputByOwner.has(path))
2379
+ updates.push({
2380
+ ...rest,
2381
+ acceptedPath: outputByOwner.get(acceptedPath),
2382
+ path: outputByOwner.get(path)
2383
+ });
2384
+ return { type: "update", updates };
2385
+ }
2386
+ default:
2387
+ return p;
2388
+ }
2389
+ }), withLatestFrom(filesReady$), filter(([p, { bundle }]) => {
2390
+ switch (p.type) {
2391
+ case "full-reload":
2392
+ return typeof p.path === "undefined" || p.path in bundle;
2393
+ case "prune":
2394
+ return p.paths.length > 0;
2395
+ case "update":
2396
+ return p.updates.length > 0;
2397
+ default:
2398
+ return true;
2399
+ }
2400
+ }), map(([p]) => ({
2401
+ type: "custom",
2402
+ event: "crx:content-script-payload",
2403
+ data: p
2404
+ })));
2405
+
2157
2406
  function sortPlugins(plugins, command) {
2158
2407
  const pre = [];
2159
2408
  const mid = [];
@@ -2250,6 +2499,18 @@ const pluginFileWriter = (crxPlugins) => (options) => {
2250
2499
  writerEvent$.next({ type: "error", error, code, frame });
2251
2500
  }
2252
2501
  });
2502
+ const rebuildSub = rebuildSignal$.subscribe((rebuild) => {
2503
+ if (rebuild.type === "partial") {
2504
+ for (const owner of rebuild.owners)
2505
+ transformResultByOwner.delete(owner);
2506
+ } else {
2507
+ transformResultByOwner.clear();
2508
+ }
2509
+ rebuildFiles();
2510
+ });
2511
+ watcher.on("close", () => {
2512
+ rebuildSub.unsubscribe();
2513
+ });
2253
2514
  });
2254
2515
  },
2255
2516
  closeBundle() {
@@ -2258,87 +2519,30 @@ const pluginFileWriter = (crxPlugins) => (options) => {
2258
2519
  };
2259
2520
  };
2260
2521
 
2261
- const debug$2 = _debug("hmr");
2262
2522
  function isImporter(file) {
2263
- const pred = (node) => {
2264
- if (node.file === file)
2523
+ const seen = /* @__PURE__ */ new Set();
2524
+ const pred = (changedNode) => {
2525
+ seen.add(changedNode);
2526
+ if (changedNode.file === file)
2265
2527
  return true;
2266
- for (const node2 of node.importers)
2267
- if (pred(node2))
2528
+ for (const parentNode of changedNode.importers) {
2529
+ const unseen = !seen.has(parentNode);
2530
+ if (unseen && pred(parentNode))
2268
2531
  return true;
2532
+ }
2533
+ return false;
2269
2534
  };
2270
2535
  return pred;
2271
2536
  }
2272
- function isCrxHMRPayload(x) {
2273
- return x.type === "custom" && x.event.startsWith("crx:");
2274
- }
2275
- const hmrPayload$ = new Subject();
2276
- const crxHmrPayload$ = hmrPayload$.pipe(filter((p) => !isCrxHMRPayload(p)), buffer(filesReady$), mergeMap((pps) => {
2277
- let fullReload;
2278
- const payloads = [];
2279
- for (const p of pps.slice(-50))
2280
- if (p.type === "full-reload") {
2281
- fullReload = p;
2282
- } else {
2283
- payloads.push(p);
2284
- }
2285
- if (fullReload)
2286
- payloads.push(fullReload);
2287
- return payloads;
2288
- }), map((p) => {
2289
- switch (p.type) {
2290
- case "full-reload": {
2291
- const path = p.path && outputByOwner.get(p.path);
2292
- const fullReload = {
2293
- type: "full-reload",
2294
- path
2295
- };
2296
- return fullReload;
2297
- }
2298
- case "prune": {
2299
- const paths = [];
2300
- for (const owner of p.paths)
2301
- if (outputByOwner.has(owner))
2302
- paths.push(outputByOwner.get(owner));
2303
- return { type: "prune", paths };
2304
- }
2305
- case "update": {
2306
- const updates = [];
2307
- for (const { acceptedPath, path, ...rest } of p.updates)
2308
- if (outputByOwner.has(acceptedPath) && outputByOwner.has(path))
2309
- updates.push({
2310
- ...rest,
2311
- acceptedPath: outputByOwner.get(acceptedPath),
2312
- path: outputByOwner.get(path)
2313
- });
2314
- return { type: "update", updates };
2315
- }
2316
- default:
2317
- return p;
2318
- }
2319
- }), withLatestFrom(filesReady$), filter(([p, { bundle }]) => {
2320
- switch (p.type) {
2321
- case "full-reload":
2322
- return typeof p.path === "undefined" || p.path in bundle;
2323
- case "prune":
2324
- return p.paths.length > 0;
2325
- case "update":
2326
- return p.updates.length > 0;
2327
- default:
2328
- return true;
2329
- }
2330
- }), map(([p]) => ({
2331
- type: "custom",
2332
- event: "crx:content-script-payload",
2333
- data: p
2334
- })));
2537
+
2538
+ const debug$2 = _debug("hmr");
2335
2539
  const crxRuntimeReload = {
2336
2540
  type: "custom",
2337
2541
  event: "crx:runtime-reload"
2338
2542
  };
2339
2543
  const pluginHMR = () => {
2340
2544
  let files;
2341
- let server;
2545
+ let decoratedSend;
2342
2546
  return [
2343
2547
  {
2344
2548
  name: "crx:hmr",
@@ -2355,38 +2559,41 @@ const pluginHMR = () => {
2355
2559
  name: "crx:hmr",
2356
2560
  apply: "serve",
2357
2561
  enforce: "pre",
2358
- config({ server: server2 = {}, ...config }) {
2359
- if (server2.hmr === false)
2562
+ config({ server = {}, ...config }) {
2563
+ if (server.hmr === false)
2360
2564
  return;
2361
- if (server2.hmr === true)
2362
- server2.hmr = {};
2363
- server2.hmr = server2.hmr ?? {};
2364
- server2.hmr.host = "localhost";
2365
- return { server: server2, ...config };
2565
+ if (server.hmr === true)
2566
+ server.hmr = {};
2567
+ server.hmr = server.hmr ?? {};
2568
+ server.hmr.host = "localhost";
2569
+ return { server, ...config };
2366
2570
  },
2367
2571
  configResolved(config) {
2368
2572
  const { watch = {} } = config.server;
2369
2573
  config.server.watch = watch;
2370
2574
  watch.ignored = watch.ignored ? [...new Set([watch.ignored].flat())] : [];
2371
- watch.ignored.push(config.build.outDir);
2575
+ const outDir = isAbsolute(config.build.outDir) ? config.build.outDir : join(config.root, config.build.outDir, "**/*");
2576
+ watch.ignored.push(outDir);
2372
2577
  },
2373
- configureServer(_server) {
2374
- server = _server;
2375
- const { send } = server.ws;
2376
- server.ws.send = (payload) => {
2377
- hmrPayload$.next(payload);
2378
- send(payload);
2379
- };
2380
- crxHmrPayload$.subscribe((payload) => {
2381
- send(payload);
2382
- });
2578
+ configureServer(server) {
2579
+ if (server.ws.send !== decoratedSend) {
2580
+ const { send } = server.ws;
2581
+ decoratedSend = (payload) => {
2582
+ hmrPayload$.next(payload);
2583
+ send(payload);
2584
+ };
2585
+ server.ws.send = decoratedSend;
2586
+ crxHmrPayload$.subscribe((payload) => {
2587
+ send(payload);
2588
+ });
2589
+ }
2383
2590
  },
2384
- handleHotUpdate({ file, modules, server: server2 }) {
2385
- const background = files.background[0] && join(server2.config.root, files.background[0]);
2591
+ handleHotUpdate({ file, modules, server }) {
2592
+ const background = files.background[0] && join(server.config.root, files.background[0]);
2386
2593
  if (background) {
2387
2594
  if (file === background || modules.some(isImporter(background))) {
2388
2595
  debug$2("sending runtime reload");
2389
- server2.ws.send(crxRuntimeReload);
2596
+ server.ws.send(crxRuntimeReload);
2390
2597
  return [];
2391
2598
  }
2392
2599
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crxjs/vite-plugin",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "Build Chrome Extensions with this Vite plugin.",
5
5
  "keywords": [
6
6
  "rollup-plugin",
@@ -50,12 +50,13 @@
50
50
  "lint": "run-s lint:eslint lint:types",
51
51
  "lint:eslint": "eslint \"{src,test}/**/*.ts\"",
52
52
  "lint:types": "tsc --noEmit",
53
- "test": "run-s test:update:*",
53
+ "test": "run-s test:units test:update:*",
54
54
  "test:ci:e2e:build": "node --expose-gc ./node_modules/jest/bin/jest.js --logHeapUsage --runInBand --forceExit --testPathIgnorePatterns=\\(/node_modules/ /templates/ /mv3/\\) -t build",
55
55
  "test:ci:e2e:serve": "npm run test:ci:e2e:serve:cmd || npm run test:ci:e2e:serve:cmd",
56
56
  "test:ci:e2e:serve:cmd": "node --expose-gc ./node_modules/jest/bin/jest.js --logHeapUsage --runInBand --forceExit --testPathIgnorePatterns=\\(/node_modules/ /templates/ /mv3/\\) -t serve",
57
57
  "test:ci:mv3:build": "node --expose-gc ./node_modules/jest/bin/jest.js --logHeapUsage --runInBand --forceExit --testPathIgnorePatterns=\\(/node_modules/ /templates/ /e2e/\\) --updateSnapshot build",
58
58
  "test:ci:mv3:serve": "node --expose-gc ./node_modules/jest/bin/jest.js --logHeapUsage --runInBand --forceExit --testPathIgnorePatterns=\\(/node_modules/ /templates/ /e2e/\\) --updateSnapshot serve",
59
+ "test:units": "jest src",
59
60
  "test:update:build": "jest build -u",
60
61
  "test:update:serve": "jest serve -u"
61
62
  },
@@ -91,13 +92,13 @@
91
92
  "@types/node": "17.0.18",
92
93
  "@types/react": "17.0.44",
93
94
  "@types/react-dom": "17.0.16",
94
- "@typescript-eslint/eslint-plugin": "5.21.0",
95
- "@typescript-eslint/parser": "5.21.0",
96
- "@vitejs/plugin-react": "1.3.1",
95
+ "@typescript-eslint/eslint-plugin": "5.23.0",
96
+ "@typescript-eslint/parser": "5.23.0",
97
+ "@vitejs/plugin-react": "1.3.2",
97
98
  "@vitejs/plugin-vue": "2.3.2",
98
99
  "esbuild": "0.14.38",
99
100
  "esbuild-runner": "2.2.1",
100
- "eslint": "^8.14.0",
101
+ "eslint": "8.15.0",
101
102
  "jest": "27.5.1",
102
103
  "jest-image-snapshot": "4.5.1",
103
104
  "playwright-chromium": "1.21.1",
@@ -107,6 +108,7 @@
107
108
  "rollup-plugin-dts": "^4.2.0",
108
109
  "rollup-plugin-esbuild": "4.9.1",
109
110
  "rxjs": "7.5.5",
111
+ "typescript": "^4.6.4",
110
112
  "vite": "^2.9.5",
111
113
  "vite-plugin-inspect": "0.5.0",
112
114
  "vue": "3.2.33"