vite 2.9.0-beta.8 → 2.9.1

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.

Potentially problematic release.


This version of vite might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./dep-a7fb482c.js');
3
+ var index = require('./dep-611778e0.js');
4
4
 
5
5
  function _mergeNamespaces(n, m) {
6
6
  for (var i = 0; i < m.length; i++) {
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./dep-a7fb482c.js');
3
+ var index = require('./dep-611778e0.js');
4
4
  var require$$1 = require('crypto');
5
5
  require('fs');
6
6
  require('path');
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var require$$0 = require('postcss');
4
- var index$1 = require('./dep-a7fb482c.js');
4
+ var index$1 = require('./dep-611778e0.js');
5
5
  var path$2 = require('path');
6
6
  var require$$1 = require('crypto');
7
7
  var fs = require('fs');
@@ -39,6 +39,14 @@ var joinMedia$1 = function (parentMedia, childMedia) {
39
39
  return media
40
40
  };
41
41
 
42
+ var joinLayer$1 = function (parentLayer, childLayer) {
43
+ if (!parentLayer.length && childLayer.length) return childLayer
44
+ if (parentLayer.length && !childLayer.length) return parentLayer
45
+ if (!parentLayer.length && !childLayer.length) return []
46
+
47
+ return parentLayer.concat(childLayer)
48
+ };
49
+
42
50
  // external tooling
43
51
  const resolve$1 = resolve__default;
44
52
 
@@ -330,6 +338,7 @@ var parseStatements$1 = function (result, styles) {
330
338
  type: "nodes",
331
339
  nodes,
332
340
  media: [],
341
+ layer: [],
333
342
  });
334
343
  nodes = [];
335
344
  }
@@ -342,6 +351,7 @@ var parseStatements$1 = function (result, styles) {
342
351
  type: "nodes",
343
352
  nodes,
344
353
  media: [],
354
+ layer: [],
345
355
  });
346
356
  }
347
357
 
@@ -354,6 +364,7 @@ function parseMedia(result, atRule) {
354
364
  type: "media",
355
365
  node: atRule,
356
366
  media: split(params, 0),
367
+ layer: [],
357
368
  }
358
369
  }
359
370
 
@@ -367,6 +378,7 @@ function parseCharset(result, atRule) {
367
378
  type: "charset",
368
379
  node: atRule,
369
380
  media: [],
381
+ layer: [],
370
382
  }
371
383
  }
372
384
 
@@ -377,10 +389,12 @@ function parseImport(result, atRule) {
377
389
  if (
378
390
  prev.type !== "comment" &&
379
391
  (prev.type !== "atrule" ||
380
- (prev.name !== "import" && prev.name !== "charset"))
392
+ (prev.name !== "import" &&
393
+ prev.name !== "charset" &&
394
+ !(prev.name === "layer" && !prev.nodes)))
381
395
  ) {
382
396
  return result.warn(
383
- "@import must precede all other statements (besides @charset)",
397
+ "@import must precede all other statements (besides @charset or empty @layer)",
384
398
  { node: atRule }
385
399
  )
386
400
  }
@@ -401,6 +415,7 @@ function parseImport(result, atRule) {
401
415
  type: "import",
402
416
  node: atRule,
403
417
  media: [],
418
+ layer: [],
404
419
  };
405
420
 
406
421
  // prettier-ignore
@@ -426,11 +441,31 @@ function parseImport(result, atRule) {
426
441
  else stmt.uri = params[0].nodes[0].value;
427
442
  stmt.fullUri = stringify(params[0]);
428
443
 
429
- if (params.length > 2) {
430
- if (params[1].type !== "space") {
444
+ let remainder = params;
445
+ if (remainder.length > 2) {
446
+ if (
447
+ (remainder[2].type === "word" || remainder[2].type === "function") &&
448
+ remainder[2].value === "layer"
449
+ ) {
450
+ if (remainder[1].type !== "space") {
451
+ return result.warn("Invalid import layer statement", { node: atRule })
452
+ }
453
+
454
+ if (remainder[2].nodes) {
455
+ stmt.layer = [stringify(remainder[2].nodes)];
456
+ } else {
457
+ stmt.layer = [""];
458
+ }
459
+ remainder = remainder.slice(2);
460
+ }
461
+ }
462
+
463
+ if (remainder.length > 2) {
464
+ if (remainder[1].type !== "space") {
431
465
  return result.warn("Invalid import media statement", { node: atRule })
432
466
  }
433
- stmt.media = split(params, 2);
467
+
468
+ stmt.media = split(remainder, 2);
434
469
  }
435
470
 
436
471
  return stmt
@@ -441,6 +476,7 @@ const path = path__default;
441
476
 
442
477
  // internal tooling
443
478
  const joinMedia = joinMedia$1;
479
+ const joinLayer = joinLayer$1;
444
480
  const resolveId = resolveId$1;
445
481
  const loadContent = loadContent$1;
446
482
  const processContent = processContent$1;
@@ -483,11 +519,13 @@ function AtImport(options) {
483
519
  throw new Error("plugins option must be an array")
484
520
  }
485
521
 
486
- return parseStyles(result, styles, options, state, []).then(bundle => {
487
- applyRaws(bundle);
488
- applyMedia(bundle);
489
- applyStyles(bundle, styles);
490
- })
522
+ return parseStyles(result, styles, options, state, [], []).then(
523
+ bundle => {
524
+ applyRaws(bundle);
525
+ applyMedia(bundle);
526
+ applyStyles(bundle, styles);
527
+ }
528
+ )
491
529
 
492
530
  function applyRaws(bundle) {
493
531
  bundle.forEach((stmt, index) => {
@@ -505,21 +543,60 @@ function AtImport(options) {
505
543
 
506
544
  function applyMedia(bundle) {
507
545
  bundle.forEach(stmt => {
508
- if (!stmt.media.length || stmt.type === "charset") return
546
+ if (
547
+ (!stmt.media.length && !stmt.layer.length) ||
548
+ stmt.type === "charset"
549
+ ) {
550
+ return
551
+ }
552
+
509
553
  if (stmt.type === "import") {
510
554
  stmt.node.params = `${stmt.fullUri} ${stmt.media.join(", ")}`;
511
- } else if (stmt.type === "media")
555
+ } else if (stmt.type === "media") {
512
556
  stmt.node.params = stmt.media.join(", ");
513
- else {
557
+ } else {
514
558
  const { nodes } = stmt;
515
559
  const { parent } = nodes[0];
516
- const mediaNode = atRule({
517
- name: "media",
518
- params: stmt.media.join(", "),
519
- source: parent.source,
520
- });
521
560
 
522
- parent.insertBefore(nodes[0], mediaNode);
561
+ let outerAtRule;
562
+ let innerAtRule;
563
+ if (stmt.media.length && stmt.layer.length) {
564
+ const mediaNode = atRule({
565
+ name: "media",
566
+ params: stmt.media.join(", "),
567
+ source: parent.source,
568
+ });
569
+
570
+ const layerNode = atRule({
571
+ name: "layer",
572
+ params: stmt.layer.filter(layer => layer !== "").join("."),
573
+ source: parent.source,
574
+ });
575
+
576
+ mediaNode.append(layerNode);
577
+ innerAtRule = layerNode;
578
+ outerAtRule = mediaNode;
579
+ } else if (stmt.media.length) {
580
+ const mediaNode = atRule({
581
+ name: "media",
582
+ params: stmt.media.join(", "),
583
+ source: parent.source,
584
+ });
585
+
586
+ innerAtRule = mediaNode;
587
+ outerAtRule = mediaNode;
588
+ } else if (stmt.layer.length) {
589
+ const layerNode = atRule({
590
+ name: "layer",
591
+ params: stmt.layer.filter(layer => layer !== "").join("."),
592
+ source: parent.source,
593
+ });
594
+
595
+ innerAtRule = layerNode;
596
+ outerAtRule = layerNode;
597
+ }
598
+
599
+ parent.insertBefore(nodes[0], outerAtRule);
523
600
 
524
601
  // remove nodes
525
602
  nodes.forEach(node => {
@@ -529,11 +606,11 @@ function AtImport(options) {
529
606
  // better output
530
607
  nodes[0].raws.before = nodes[0].raws.before || "\n";
531
608
 
532
- // wrap new rules with media query
533
- mediaNode.append(nodes);
609
+ // wrap new rules with media query and/or layer at rule
610
+ innerAtRule.append(nodes);
534
611
 
535
612
  stmt.type = "media";
536
- stmt.node = mediaNode;
613
+ stmt.node = outerAtRule;
537
614
  delete stmt.nodes;
538
615
  }
539
616
  });
@@ -556,7 +633,7 @@ function AtImport(options) {
556
633
  });
557
634
  }
558
635
 
559
- function parseStyles(result, styles, options, state, media) {
636
+ function parseStyles(result, styles, options, state, media, layer) {
560
637
  const statements = parseStatements(result, styles);
561
638
 
562
639
  return Promise.resolve(statements)
@@ -565,6 +642,7 @@ function AtImport(options) {
565
642
  return stmts.reduce((promise, stmt) => {
566
643
  return promise.then(() => {
567
644
  stmt.media = joinMedia(media, stmt.media || []);
645
+ stmt.layer = joinLayer(layer, stmt.layer || []);
568
646
 
569
647
  // skip protocol base uri (protocol://url) or protocol-relative
570
648
  if (
@@ -676,7 +754,7 @@ function AtImport(options) {
676
754
 
677
755
  function loadImportContent(result, stmt, filename, options, state) {
678
756
  const atRule = stmt.node;
679
- const { media } = stmt;
757
+ const { media, layer } = stmt;
680
758
  if (options.skipDuplicates) {
681
759
  // skip files already imported at the same scope
682
760
  if (
@@ -724,7 +802,7 @@ function AtImport(options) {
724
802
  }
725
803
 
726
804
  // recursion: import @import from imported file
727
- return parseStyles(result, styles, options, state, media)
805
+ return parseStyles(result, styles, options, state, media, layer)
728
806
  })
729
807
  }
730
808
  )
package/dist/node/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var require$$0 = require('events');
4
- var index = require('./chunks/dep-a7fb482c.js');
4
+ var index = require('./chunks/dep-611778e0.js');
5
5
  var perf_hooks = require('perf_hooks');
6
6
  require('fs');
7
7
  require('path');
@@ -683,7 +683,7 @@ cli
683
683
  .action(async (root, options) => {
684
684
  // output structure is preserved even after bundling so require()
685
685
  // is ok here
686
- const { createServer } = await Promise.resolve().then(function () { return require('./chunks/dep-a7fb482c.js'); }).then(function (n) { return n.index$1; });
686
+ const { createServer } = await Promise.resolve().then(function () { return require('./chunks/dep-611778e0.js'); }).then(function (n) { return n.index$1; });
687
687
  try {
688
688
  const server = await createServer({
689
689
  root,
@@ -732,7 +732,7 @@ cli
732
732
  .option('--emptyOutDir', `[boolean] force empty outDir when it's outside of root`)
733
733
  .option('-w, --watch', `[boolean] rebuilds when modules have changed on disk`)
734
734
  .action(async (root, options) => {
735
- const { build } = await Promise.resolve().then(function () { return require('./chunks/dep-a7fb482c.js'); }).then(function (n) { return n.build$1; });
735
+ const { build } = await Promise.resolve().then(function () { return require('./chunks/dep-611778e0.js'); }).then(function (n) { return n.build$1; });
736
736
  const buildOptions = cleanOptions(options);
737
737
  try {
738
738
  await build({
@@ -755,7 +755,7 @@ cli
755
755
  .command('optimize [root]', 'pre-bundle dependencies')
756
756
  .option('--force', `[boolean] force the optimizer to ignore the cache and re-bundle`)
757
757
  .action(async (root, options) => {
758
- const { optimizeDeps } = await Promise.resolve().then(function () { return require('./chunks/dep-a7fb482c.js'); }).then(function (n) { return n.index; });
758
+ const { optimizeDeps } = await Promise.resolve().then(function () { return require('./chunks/dep-611778e0.js'); }).then(function (n) { return n.index; });
759
759
  try {
760
760
  const config = await index.resolveConfig({
761
761
  root,
@@ -778,7 +778,7 @@ cli
778
778
  .option('--https', `[boolean] use TLS + HTTP/2`)
779
779
  .option('--open [path]', `[boolean | string] open browser on startup`)
780
780
  .action(async (root, options) => {
781
- const { preview } = await Promise.resolve().then(function () { return require('./chunks/dep-a7fb482c.js'); }).then(function (n) { return n.preview$1; });
781
+ const { preview } = await Promise.resolve().then(function () { return require('./chunks/dep-611778e0.js'); }).then(function (n) { return n.preview$1; });
782
782
  try {
783
783
  const server = await preview({
784
784
  root,
@@ -35,8 +35,8 @@ import type { RollupOutput } from 'rollup';
35
35
  import type { RollupWatcher } from 'rollup';
36
36
  import type { SecureContextOptions } from 'tls';
37
37
  import type { Server } from 'http';
38
- import type { Server as Server_2 } from 'https';
39
- import type { Server as Server_3 } from 'net';
38
+ import type { Server as Server_2 } from 'net';
39
+ import type { Server as Server_3 } from 'https';
40
40
  import type { ServerOptions as ServerOptions_2 } from 'https';
41
41
  import type { ServerResponse } from 'http';
42
42
  import type { SourceDescription } from 'rollup';
@@ -48,6 +48,8 @@ import type { TransformResult as TransformResult_3 } from 'rollup';
48
48
  import type * as url from 'url';
49
49
  import type { URL as URL_2 } from 'url';
50
50
  import type { WatcherOptions } from 'rollup';
51
+ import type { WebSocket as WebSocket_2 } from 'ws';
52
+ import { WebSocketServer as WebSocketServer_2 } from 'ws';
51
53
  import type { ZlibOptions } from 'zlib';
52
54
 
53
55
  export declare interface Alias {
@@ -485,6 +487,19 @@ export declare interface CSSOptions {
485
487
  postcss?: string | (Postcss.ProcessOptions & {
486
488
  plugins?: Postcss.Plugin[];
487
489
  });
490
+ /**
491
+ * Enables css sourcemaps during dev
492
+ * @default false
493
+ * @experimental
494
+ */
495
+ devSourcemap?: boolean;
496
+ }
497
+
498
+ export declare interface CustomEventMap {
499
+ 'vite:beforeUpdate': UpdatePayload
500
+ 'vite:beforePrune': PrunePayload
501
+ 'vite:beforeFullReload': FullReloadPayload
502
+ 'vite:error': ErrorPayload
488
503
  }
489
504
 
490
505
  export declare interface CustomPayload {
@@ -747,7 +762,7 @@ export declare interface HmrContext {
747
762
  export declare interface HmrOptions {
748
763
  protocol?: string;
749
764
  host?: string;
750
- port?: number | false;
765
+ port?: number;
751
766
  clientPort?: number;
752
767
  path?: string;
753
768
  timeout?: number;
@@ -1022,6 +1037,9 @@ export declare type IndexHtmlTransformResult = string | HtmlTagDescriptor[] | {
1022
1037
  tags: HtmlTagDescriptor[];
1023
1038
  };
1024
1039
 
1040
+ export declare type InferCustomEventPayload<T extends string> =
1041
+ T extends keyof CustomEventMap ? CustomEventMap[T] : any
1042
+
1025
1043
  export declare interface InlineConfig extends UserConfig {
1026
1044
  configFile?: string | false;
1027
1045
  envFile?: false;
@@ -1384,7 +1402,7 @@ export declare interface PreviewServer {
1384
1402
  /**
1385
1403
  * @deprecated Use `server.printUrls()` instead
1386
1404
  */
1387
- export declare function printHttpServerUrls(server: Server_3, config: ResolvedConfig): void;
1405
+ export declare function printHttpServerUrls(server: Server_2, config: ResolvedConfig): void;
1388
1406
 
1389
1407
  export declare interface ProxyOptions extends HttpProxy.ServerOptions {
1390
1408
  /**
@@ -1420,6 +1438,7 @@ export declare type ResolvedConfig = Readonly<Omit<UserConfig, 'plugins' | 'alia
1420
1438
  cacheDir: string;
1421
1439
  command: 'build' | 'serve';
1422
1440
  mode: string;
1441
+ isWorker: boolean;
1423
1442
  isProduction: boolean;
1424
1443
  env: Record<string, any>;
1425
1444
  resolve: ResolveOptions & {
@@ -2699,7 +2718,7 @@ export declare namespace WebSocket {
2699
2718
  host?: string | undefined
2700
2719
  port?: number | undefined
2701
2720
  backlog?: number | undefined
2702
- server?: Server | Server_2 | undefined
2721
+ server?: Server | Server_3 | undefined
2703
2722
  verifyClient?:
2704
2723
  | VerifyClientCallbackAsync
2705
2724
  | VerifyClientCallbackSync
@@ -2831,11 +2850,53 @@ export declare const WebSocketAlias: typeof WebSocket;
2831
2850
 
2832
2851
  export declare interface WebSocketAlias extends WebSocket {}
2833
2852
 
2853
+ export declare interface WebSocketClient {
2854
+ /**
2855
+ * Send event to the client
2856
+ */
2857
+ send(payload: HMRPayload): void;
2858
+ /**
2859
+ * Send custom event
2860
+ */
2861
+ send(event: string, payload?: CustomPayload['data']): void;
2862
+ /**
2863
+ * The raw WebSocket instance
2864
+ * @advanced
2865
+ */
2866
+ socket: WebSocket_2;
2867
+ }
2868
+
2869
+ export declare type WebSocketCustomListener<T> = (data: T, client: WebSocketClient) => void;
2870
+
2834
2871
  export declare interface WebSocketServer {
2835
- on: WebSocket.Server['on'];
2836
- off: WebSocket.Server['off'];
2872
+ /**
2873
+ * Get all connected clients.
2874
+ */
2875
+ clients: Set<WebSocketClient>;
2876
+ /**
2877
+ * Boardcast events to all clients
2878
+ */
2837
2879
  send(payload: HMRPayload): void;
2880
+ /**
2881
+ * Send custom event
2882
+ */
2883
+ send<T extends string>(event: T, payload?: InferCustomEventPayload<T>): void;
2884
+ /**
2885
+ * Disconnect all clients and terminate the server.
2886
+ */
2838
2887
  close(): Promise<void>;
2888
+ /**
2889
+ * Handle custom event emitted by `import.meta.hot.send`
2890
+ */
2891
+ on: WebSocketServer_2['on'] & {
2892
+ <T extends string>(event: T, listener: WebSocketCustomListener<InferCustomEventPayload<T>>): void;
2893
+ };
2894
+ /**
2895
+ * Unregister event listener.
2896
+ */
2897
+ off: WebSocketServer_2['off'] & {
2898
+ (event: string, listener: Function): void;
2899
+ };
2839
2900
  }
2840
2901
 
2841
2902
  export { }
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('./chunks/dep-a7fb482c.js');
5
+ var index = require('./chunks/dep-611778e0.js');
6
6
  require('fs');
7
7
  require('path');
8
8
  require('tty');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite",
3
- "version": "2.9.0-beta.8",
3
+ "version": "2.9.1",
4
4
  "license": "MIT",
5
5
  "author": "Evan You",
6
6
  "description": "Native-ESM powered web dev build tool",
@@ -57,7 +57,7 @@
57
57
  "@babel/types": "^7.17.0",
58
58
  "@jridgewell/trace-mapping": "^0.3.4",
59
59
  "@rollup/plugin-alias": "^3.1.9",
60
- "@rollup/plugin-commonjs": "^21.0.2",
60
+ "@rollup/plugin-commonjs": "^21.0.3",
61
61
  "@rollup/plugin-dynamic-import-vars": "^1.4.2",
62
62
  "@rollup/plugin-json": "^4.1.0",
63
63
  "@rollup/plugin-node-resolve": "13.1.3",
@@ -96,14 +96,14 @@
96
96
  "json5": "^2.2.1",
97
97
  "launch-editor-middleware": "^2.3.0",
98
98
  "magic-string": "^0.26.1",
99
- "micromatch": "^4.0.4",
99
+ "micromatch": "^4.0.5",
100
100
  "mrmime": "^1.0.0",
101
101
  "node-forge": "^1.3.0",
102
102
  "okie": "^1.0.1",
103
103
  "open": "^8.4.0",
104
104
  "periscopic": "^2.0.3",
105
105
  "picocolors": "^1.0.0",
106
- "postcss-import": "^14.0.2",
106
+ "postcss-import": "^14.1.0",
107
107
  "postcss-load-config": "^3.1.3",
108
108
  "postcss-modules": "^4.3.1",
109
109
  "resolve.exports": "^1.1.0",
@@ -1,12 +1,6 @@
1
- import type {
2
- ErrorPayload,
3
- FullReloadPayload,
4
- HMRPayload,
5
- PrunePayload,
6
- Update,
7
- UpdatePayload
8
- } from 'types/hmrPayload'
9
- import type { CustomEventName } from 'types/customEvent'
1
+ import type { ErrorPayload, HMRPayload, Update } from 'types/hmrPayload'
2
+ import type { ViteHotContext } from 'types/hot'
3
+ import type { InferCustomEventPayload } from 'types/customEvent'
10
4
  import { ErrorOverlay, overlayId } from './overlay'
11
5
  // eslint-disable-next-line node/no-missing-import
12
6
  import '@vite/env'
@@ -15,7 +9,7 @@ import '@vite/env'
15
9
  declare const __BASE__: string
16
10
  declare const __HMR_PROTOCOL__: string
17
11
  declare const __HMR_HOSTNAME__: string
18
- declare const __HMR_PORT__: string | false
12
+ declare const __HMR_PORT__: string
19
13
  declare const __HMR_TIMEOUT__: number
20
14
  declare const __HMR_ENABLE_OVERLAY__: boolean
21
15
 
@@ -24,12 +18,10 @@ console.log('[vite] connecting...')
24
18
  // use server configuration, then fallback to inference
25
19
  const socketProtocol =
26
20
  __HMR_PROTOCOL__ || (location.protocol === 'https:' ? 'wss' : 'ws')
27
- const socketHost = __HMR_PORT__
28
- ? `${__HMR_HOSTNAME__ || location.hostname}:${__HMR_PORT__}`
29
- : `${__HMR_HOSTNAME__ || location.hostname}`
30
-
21
+ const socketHost = `${__HMR_HOSTNAME__ || location.hostname}:${__HMR_PORT__}`
31
22
  const socket = new WebSocket(`${socketProtocol}://${socketHost}`, 'vite-hmr')
32
23
  const base = __BASE__ || '/'
24
+ const messageBuffer: string[] = []
33
25
 
34
26
  function warnFailedFetch(err: Error, path: string | string[]) {
35
27
  if (!err.message.match('fetch')) {
@@ -59,9 +51,10 @@ async function handleMessage(payload: HMRPayload) {
59
51
  switch (payload.type) {
60
52
  case 'connected':
61
53
  console.log(`[vite] connected.`)
54
+ sendMessageBuffer()
62
55
  // proxy(nginx, docker) hmr ws maybe caused timeout,
63
56
  // so send ping package let ws keep alive.
64
- setInterval(() => socket.send('ping'), __HMR_TIMEOUT__)
57
+ setInterval(() => socket.send('{"type":"ping"}'), __HMR_TIMEOUT__)
65
58
  break
66
59
  case 'update':
67
60
  notifyListeners('vite:beforeUpdate', payload)
@@ -101,7 +94,7 @@ async function handleMessage(payload: HMRPayload) {
101
94
  })
102
95
  break
103
96
  case 'custom': {
104
- notifyListeners(payload.event as CustomEventName<any>, payload.data)
97
+ notifyListeners(payload.event, payload.data)
105
98
  break
106
99
  }
107
100
  case 'full-reload':
@@ -154,19 +147,9 @@ async function handleMessage(payload: HMRPayload) {
154
147
  }
155
148
  }
156
149
 
157
- function notifyListeners(
158
- event: 'vite:beforeUpdate',
159
- payload: UpdatePayload
160
- ): void
161
- function notifyListeners(event: 'vite:beforePrune', payload: PrunePayload): void
162
- function notifyListeners(
163
- event: 'vite:beforeFullReload',
164
- payload: FullReloadPayload
165
- ): void
166
- function notifyListeners(event: 'vite:error', payload: ErrorPayload): void
167
150
  function notifyListeners<T extends string>(
168
- event: CustomEventName<T>,
169
- data: any
151
+ event: T,
152
+ data: InferCustomEventPayload<T>
170
153
  ): void
171
154
  function notifyListeners(event: string, data: any): void {
172
155
  const cbs = customListenersMap.get(event)
@@ -361,6 +344,13 @@ async function fetchUpdate({ path, acceptedPath, timestamp }: Update) {
361
344
  }
362
345
  }
363
346
 
347
+ function sendMessageBuffer() {
348
+ if (socket.readyState === 1) {
349
+ messageBuffer.forEach((msg) => socket.send(msg))
350
+ messageBuffer.length = 0
351
+ }
352
+ }
353
+
364
354
  interface HotModule {
365
355
  id: string
366
356
  callbacks: HotCallback[]
@@ -382,9 +372,7 @@ const ctxToListenersMap = new Map<
382
372
  Map<string, ((data: any) => void)[]>
383
373
  >()
384
374
 
385
- // Just infer the return type for now
386
- // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
387
- export const createHotContext = (ownerPath: string) => {
375
+ export function createHotContext(ownerPath: string): ViteHotContext {
388
376
  if (!dataMap.has(ownerPath)) {
389
377
  dataMap.set(ownerPath, {})
390
378
  }
@@ -425,12 +413,12 @@ export const createHotContext = (ownerPath: string) => {
425
413
  hotModulesMap.set(ownerPath, mod)
426
414
  }
427
415
 
428
- const hot = {
416
+ const hot: ViteHotContext = {
429
417
  get data() {
430
418
  return dataMap.get(ownerPath)
431
419
  },
432
420
 
433
- accept(deps: any, callback?: any) {
421
+ accept(deps?: any, callback?: any) {
434
422
  if (typeof deps === 'function' || !deps) {
435
423
  // self-accept: hot.accept(() => {})
436
424
  acceptDeps([ownerPath], ([mod]) => deps && deps(mod))
@@ -451,10 +439,11 @@ export const createHotContext = (ownerPath: string) => {
451
439
  )
452
440
  },
453
441
 
454
- dispose(cb: (data: any) => void) {
442
+ dispose(cb) {
455
443
  disposeMap.set(ownerPath, cb)
456
444
  },
457
445
 
446
+ // @ts-expect-error untyped
458
447
  prune(cb: (data: any) => void) {
459
448
  pruneMap.set(ownerPath, cb)
460
449
  },
@@ -470,7 +459,7 @@ export const createHotContext = (ownerPath: string) => {
470
459
  },
471
460
 
472
461
  // custom events
473
- on: (event: string, cb: (data: any) => void) => {
462
+ on(event, cb) {
474
463
  const addToMap = (map: Map<string, any[]>) => {
475
464
  const existing = map.get(event) || []
476
465
  existing.push(cb)
@@ -478,6 +467,11 @@ export const createHotContext = (ownerPath: string) => {
478
467
  }
479
468
  addToMap(customListenersMap)
480
469
  addToMap(newListeners)
470
+ },
471
+
472
+ send(event, data) {
473
+ messageBuffer.push(JSON.stringify({ type: 'custom', event, data }))
474
+ sendMessageBuffer()
481
475
  }
482
476
  }
483
477
 
@@ -1,5 +1,16 @@
1
- // See https://stackoverflow.com/a/63549561.
2
- export type CustomEventName<T extends string> = (T extends `vite:${T}`
3
- ? never
4
- : T) &
5
- (`vite:${T}` extends T ? never : T)
1
+ import type {
2
+ ErrorPayload,
3
+ FullReloadPayload,
4
+ PrunePayload,
5
+ UpdatePayload
6
+ } from './hmrPayload'
7
+
8
+ export interface CustomEventMap {
9
+ 'vite:beforeUpdate': UpdatePayload
10
+ 'vite:beforePrune': PrunePayload
11
+ 'vite:beforeFullReload': FullReloadPayload
12
+ 'vite:error': ErrorPayload
13
+ }
14
+
15
+ export type InferCustomEventPayload<T extends string> =
16
+ T extends keyof CustomEventMap ? CustomEventMap[T] : any