metro-runtime 0.70.2 → 0.71.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "metro-runtime",
3
- "version": "0.70.2",
3
+ "version": "0.71.1",
4
4
  "description": "🚇 Module required for evaluating Metro bundles.",
5
5
  "main": "src",
6
6
  "repository": {
@@ -12,6 +12,9 @@
12
12
  "cleanup-release": "test ! -e build && mv src build && mv src.real src"
13
13
  },
14
14
  "license": "MIT",
15
+ "dependencies": {
16
+ "@babel/runtime": "^7.0.0"
17
+ },
15
18
  "devDependencies": {
16
19
  "@babel/core": "^7.14.0"
17
20
  }
@@ -13,70 +13,70 @@
13
13
  export type ModuleMap = $ReadOnlyArray<[number, string]>;
14
14
  export type BytecodeModuleMap = $ReadOnlyArray<[number, Array<Buffer>]>;
15
15
 
16
- export type Bundle = {|
16
+ export type Bundle = {
17
17
  +modules: ModuleMap,
18
18
  +post: string,
19
19
  +pre: string,
20
- |};
20
+ };
21
21
 
22
- export type BytecodeBundle = {|
22
+ export type BytecodeBundle = {
23
23
  +modules: BytecodeModuleMap,
24
24
  +post: Array<Buffer>,
25
25
  +pre: Array<Buffer>,
26
- |};
26
+ };
27
27
 
28
- export type DeltaBundle = {|
28
+ export type DeltaBundle = {
29
29
  +added: ModuleMap,
30
30
  +modified: ModuleMap,
31
31
  +deleted: $ReadOnlyArray<number>,
32
- |};
32
+ };
33
33
 
34
34
  export type BundleVariant =
35
- | {|+base: true, +revisionId: string, ...Bundle|}
36
- | {|+base: false, +revisionId: string, ...DeltaBundle|};
35
+ | {+base: true, +revisionId: string, ...Bundle}
36
+ | {+base: false, +revisionId: string, ...DeltaBundle};
37
37
 
38
- export type BundleMetadata = {|
38
+ export type BundleMetadata = {
39
39
  +pre: number,
40
40
  +post: number,
41
41
  +modules: $ReadOnlyArray<[number, number]>,
42
- |};
42
+ };
43
43
 
44
- export type FormattedError = {|
44
+ export type FormattedError = {
45
45
  +type: string,
46
46
  +message: string,
47
47
  +errors: Array<{description: string, ...}>,
48
- |};
48
+ };
49
49
 
50
- export type HmrModule = {|
50
+ export type HmrModule = {
51
51
  +module: [number, string],
52
52
  +sourceMappingURL: string,
53
53
  +sourceURL: string,
54
- |};
54
+ };
55
55
 
56
- export type HmrUpdate = {|
56
+ export type HmrUpdate = {
57
57
  +added: $ReadOnlyArray<HmrModule>,
58
58
  +deleted: $ReadOnlyArray<number>,
59
59
  +isInitialUpdate: boolean,
60
60
  +modified: $ReadOnlyArray<HmrModule>,
61
61
  +revisionId: string,
62
- |};
62
+ };
63
63
 
64
- export type HmrUpdateMessage = {|
64
+ export type HmrUpdateMessage = {
65
65
  +type: 'update',
66
66
  +body: HmrUpdate,
67
- |};
67
+ };
68
68
 
69
- export type HmrErrorMessage = {|
69
+ export type HmrErrorMessage = {
70
70
  +type: 'error',
71
71
  +body: FormattedError,
72
- |};
72
+ };
73
73
 
74
74
  export type HmrClientMessage =
75
- | {|
75
+ | {
76
76
  +type: 'register-entrypoints',
77
77
  +entryPoints: Array<string>,
78
- |}
79
- | {|
78
+ }
79
+ | {
80
80
  +type: 'log',
81
81
  +level:
82
82
  | 'trace'
@@ -89,23 +89,23 @@ export type HmrClientMessage =
89
89
  | 'debug',
90
90
  +data: Array<mixed>,
91
91
  +mode: 'BRIDGE' | 'NOBRIDGE',
92
- |}
93
- | {|
92
+ }
93
+ | {
94
94
  +type: 'log-opt-in',
95
- |};
95
+ };
96
96
 
97
97
  export type HmrMessage =
98
- | {|
98
+ | {
99
99
  +type: 'bundle-registered',
100
- |}
101
- | {|
100
+ }
101
+ | {
102
102
  +type: 'update-start',
103
- +body: {|
103
+ +body: {
104
104
  +isInitialUpdate: boolean,
105
- |},
106
- |}
107
- | {|
105
+ },
106
+ }
107
+ | {
108
108
  +type: 'update-done',
109
- |}
109
+ }
110
110
  | HmrUpdateMessage
111
111
  | HmrErrorMessage;
@@ -19,6 +19,7 @@ var modules = clear(); // Don't use a Symbol here, it would pull in an extra pol
19
19
  // additional stuff (e.g. Array.from).
20
20
 
21
21
  const EMPTY = {};
22
+ const CYCLE_DETECTED = {};
22
23
  const { hasOwnProperty } = {};
23
24
 
24
25
  if (__DEV__) {
@@ -473,63 +474,76 @@ if (__DEV__) {
473
474
  // have side effects and lead to confusing and meaningless crashes.
474
475
 
475
476
  let didBailOut = false;
476
- const updatedModuleIDs = topologicalSort(
477
- [id], // Start with the changed module and go upwards
478
- (pendingID) => {
479
- const pendingModule = modules[pendingID];
480
-
481
- if (pendingModule == null) {
482
- // Nothing to do.
483
- return [];
484
- }
477
+ let updatedModuleIDs;
485
478
 
486
- const pendingHot = pendingModule.hot;
479
+ try {
480
+ updatedModuleIDs = topologicalSort(
481
+ [id], // Start with the changed module and go upwards
482
+ (pendingID) => {
483
+ const pendingModule = modules[pendingID];
484
+
485
+ if (pendingModule == null) {
486
+ // Nothing to do.
487
+ return [];
488
+ }
487
489
 
488
- if (pendingHot == null) {
489
- throw new Error(
490
- "[Refresh] Expected module.hot to always exist in DEV."
491
- );
492
- } // A module can be accepted manually from within itself.
490
+ const pendingHot = pendingModule.hot;
493
491
 
494
- let canAccept = pendingHot._didAccept;
492
+ if (pendingHot == null) {
493
+ throw new Error(
494
+ "[Refresh] Expected module.hot to always exist in DEV."
495
+ );
496
+ } // A module can be accepted manually from within itself.
495
497
 
496
- if (!canAccept && Refresh != null) {
497
- // Or React Refresh may mark it accepted based on exports.
498
- const isBoundary = isReactRefreshBoundary(
499
- Refresh,
500
- pendingModule.publicModule.exports
501
- );
498
+ let canAccept = pendingHot._didAccept;
499
+
500
+ if (!canAccept && Refresh != null) {
501
+ // Or React Refresh may mark it accepted based on exports.
502
+ const isBoundary = isReactRefreshBoundary(
503
+ Refresh,
504
+ pendingModule.publicModule.exports
505
+ );
502
506
 
503
- if (isBoundary) {
504
- canAccept = true;
505
- refreshBoundaryIDs.add(pendingID);
507
+ if (isBoundary) {
508
+ canAccept = true;
509
+ refreshBoundaryIDs.add(pendingID);
510
+ }
506
511
  }
507
- }
508
512
 
509
- if (canAccept) {
510
- // Don't look at parents.
511
- return [];
512
- } // If we bubble through the roof, there is no way to do a hot update.
513
- // Bail out altogether. This is the failure case.
514
-
515
- const parentIDs = inverseDependencies[pendingID];
516
-
517
- if (parentIDs.length === 0) {
518
- // Reload the app because the hot reload can't succeed.
519
- // This should work both on web and React Native.
520
- performFullRefresh("No root boundary", {
521
- source: mod,
522
- failed: pendingModule,
523
- });
524
- didBailOut = true;
525
- return [];
526
- } // This module can't handle the update but maybe all its parents can?
527
- // Put them all in the queue to run the same set of checks.
528
-
529
- return parentIDs;
530
- },
531
- () => didBailOut // Should we stop?
532
- ).reverse();
513
+ if (canAccept) {
514
+ // Don't look at parents.
515
+ return [];
516
+ } // If we bubble through the roof, there is no way to do a hot update.
517
+ // Bail out altogether. This is the failure case.
518
+
519
+ const parentIDs = inverseDependencies[pendingID];
520
+
521
+ if (parentIDs.length === 0) {
522
+ // Reload the app because the hot reload can't succeed.
523
+ // This should work both on web and React Native.
524
+ performFullRefresh("No root boundary", {
525
+ source: mod,
526
+ failed: pendingModule,
527
+ });
528
+ didBailOut = true;
529
+ return [];
530
+ } // This module can't handle the update but maybe all its parents can?
531
+ // Put them all in the queue to run the same set of checks.
532
+
533
+ return parentIDs;
534
+ },
535
+ () => didBailOut // Should we stop?
536
+ ).reverse();
537
+ } catch (e) {
538
+ if (e === CYCLE_DETECTED) {
539
+ performFullRefresh("Dependency cycle", {
540
+ source: mod,
541
+ });
542
+ return;
543
+ }
544
+
545
+ throw e;
546
+ }
533
547
 
534
548
  if (didBailOut) {
535
549
  return;
@@ -539,7 +553,6 @@ if (__DEV__) {
539
553
  const seenModuleIDs = new Set();
540
554
 
541
555
  for (let i = 0; i < updatedModuleIDs.length; i++) {
542
- // Don't process twice if we have a cycle.
543
556
  const updatedID = updatedModuleIDs[i];
544
557
 
545
558
  if (seenModuleIDs.has(updatedID)) {
@@ -651,29 +664,35 @@ if (__DEV__) {
651
664
  const topologicalSort = function (roots, getEdges, earlyStop) {
652
665
  const result = [];
653
666
  const visited = new Set();
667
+ const stack = new Set();
654
668
 
655
669
  function traverseDependentNodes(node) {
670
+ if (stack.has(node)) {
671
+ throw CYCLE_DETECTED;
672
+ }
673
+
674
+ if (visited.has(node)) {
675
+ return;
676
+ }
677
+
656
678
  visited.add(node);
679
+ stack.add(node);
657
680
  const dependentNodes = getEdges(node);
658
681
 
659
682
  if (earlyStop(node)) {
683
+ stack.delete(node);
660
684
  return;
661
685
  }
662
686
 
663
687
  dependentNodes.forEach((dependent) => {
664
- if (visited.has(dependent)) {
665
- return;
666
- }
667
-
668
688
  traverseDependentNodes(dependent);
669
689
  });
690
+ stack.delete(node);
670
691
  result.push(node);
671
692
  }
672
693
 
673
694
  roots.forEach((root) => {
674
- if (!visited.has(root)) {
675
- traverseDependentNodes(root);
676
- }
695
+ traverseDependentNodes(root);
677
696
  });
678
697
  return result;
679
698
  };
@@ -28,13 +28,13 @@ type FactoryFn = (
28
28
  dependencyMap: ?DependencyMap,
29
29
  ) => void;
30
30
  type HotModuleReloadingCallback = () => void;
31
- type HotModuleReloadingData = {|
31
+ type HotModuleReloadingData = {
32
32
  _acceptCallback: ?HotModuleReloadingCallback,
33
33
  _disposeCallback: ?HotModuleReloadingCallback,
34
34
  _didAccept: boolean,
35
35
  accept: (callback?: HotModuleReloadingCallback) => void,
36
36
  dispose: (callback?: HotModuleReloadingCallback) => void,
37
- |};
37
+ };
38
38
  type ModuleID = number;
39
39
  type Module = {
40
40
  id?: ModuleID,
@@ -42,7 +42,7 @@ type Module = {
42
42
  hot?: HotModuleReloadingData,
43
43
  ...
44
44
  };
45
- type ModuleDefinition = {|
45
+ type ModuleDefinition = {
46
46
  dependencyMap: ?DependencyMap,
47
47
  error?: any,
48
48
  factory: FactoryFn,
@@ -54,7 +54,7 @@ type ModuleDefinition = {|
54
54
  path?: string,
55
55
  publicModule: Module,
56
56
  verboseName?: string,
57
- |};
57
+ };
58
58
  type ModuleList = {
59
59
  [number]: ?ModuleDefinition,
60
60
  __proto__: null,
@@ -74,6 +74,7 @@ var modules = clear();
74
74
  // Don't use a Symbol here, it would pull in an extra polyfill with all sorts of
75
75
  // additional stuff (e.g. Array.from).
76
76
  const EMPTY = {};
77
+ const CYCLE_DETECTED = {};
77
78
  const {hasOwnProperty} = {};
78
79
 
79
80
  if (__DEV__) {
@@ -240,7 +241,7 @@ function metroImportAll(moduleId: ModuleID | VerboseModuleNameForDev | number) {
240
241
  if (exports && exports.__esModule) {
241
242
  importedAll = exports;
242
243
  } else {
243
- importedAll = {};
244
+ importedAll = ({}: {[string]: any});
244
245
 
245
246
  // Refrain from using Object.assign, it has to work in ES3 environments.
246
247
  if (exports) {
@@ -542,56 +543,67 @@ if (__DEV__) {
542
543
  // have side effects and lead to confusing and meaningless crashes.
543
544
 
544
545
  let didBailOut = false;
545
- const updatedModuleIDs = topologicalSort(
546
- [id], // Start with the changed module and go upwards
547
- pendingID => {
548
- const pendingModule = modules[pendingID];
549
- if (pendingModule == null) {
550
- // Nothing to do.
551
- return [];
552
- }
553
- const pendingHot = pendingModule.hot;
554
- if (pendingHot == null) {
555
- throw new Error(
556
- '[Refresh] Expected module.hot to always exist in DEV.',
557
- );
558
- }
559
- // A module can be accepted manually from within itself.
560
- let canAccept = pendingHot._didAccept;
561
- if (!canAccept && Refresh != null) {
562
- // Or React Refresh may mark it accepted based on exports.
563
- const isBoundary = isReactRefreshBoundary(
564
- Refresh,
565
- pendingModule.publicModule.exports,
566
- );
567
- if (isBoundary) {
568
- canAccept = true;
569
- refreshBoundaryIDs.add(pendingID);
546
+ let updatedModuleIDs;
547
+ try {
548
+ updatedModuleIDs = topologicalSort(
549
+ [id], // Start with the changed module and go upwards
550
+ pendingID => {
551
+ const pendingModule = modules[pendingID];
552
+ if (pendingModule == null) {
553
+ // Nothing to do.
554
+ return [];
570
555
  }
571
- }
572
- if (canAccept) {
573
- // Don't look at parents.
574
- return [];
575
- }
576
- // If we bubble through the roof, there is no way to do a hot update.
577
- // Bail out altogether. This is the failure case.
578
- const parentIDs = inverseDependencies[pendingID];
579
- if (parentIDs.length === 0) {
580
- // Reload the app because the hot reload can't succeed.
581
- // This should work both on web and React Native.
582
- performFullRefresh('No root boundary', {
583
- source: mod,
584
- failed: pendingModule,
585
- });
586
- didBailOut = true;
587
- return [];
588
- }
589
- // This module can't handle the update but maybe all its parents can?
590
- // Put them all in the queue to run the same set of checks.
591
- return parentIDs;
592
- },
593
- () => didBailOut, // Should we stop?
594
- ).reverse();
556
+ const pendingHot = pendingModule.hot;
557
+ if (pendingHot == null) {
558
+ throw new Error(
559
+ '[Refresh] Expected module.hot to always exist in DEV.',
560
+ );
561
+ }
562
+ // A module can be accepted manually from within itself.
563
+ let canAccept = pendingHot._didAccept;
564
+ if (!canAccept && Refresh != null) {
565
+ // Or React Refresh may mark it accepted based on exports.
566
+ const isBoundary = isReactRefreshBoundary(
567
+ Refresh,
568
+ pendingModule.publicModule.exports,
569
+ );
570
+ if (isBoundary) {
571
+ canAccept = true;
572
+ refreshBoundaryIDs.add(pendingID);
573
+ }
574
+ }
575
+ if (canAccept) {
576
+ // Don't look at parents.
577
+ return [];
578
+ }
579
+ // If we bubble through the roof, there is no way to do a hot update.
580
+ // Bail out altogether. This is the failure case.
581
+ const parentIDs = inverseDependencies[pendingID];
582
+ if (parentIDs.length === 0) {
583
+ // Reload the app because the hot reload can't succeed.
584
+ // This should work both on web and React Native.
585
+ performFullRefresh('No root boundary', {
586
+ source: mod,
587
+ failed: pendingModule,
588
+ });
589
+ didBailOut = true;
590
+ return [];
591
+ }
592
+ // This module can't handle the update but maybe all its parents can?
593
+ // Put them all in the queue to run the same set of checks.
594
+ return parentIDs;
595
+ },
596
+ () => didBailOut, // Should we stop?
597
+ ).reverse();
598
+ } catch (e) {
599
+ if (e === CYCLE_DETECTED) {
600
+ performFullRefresh('Dependency cycle', {
601
+ source: mod,
602
+ });
603
+ return;
604
+ }
605
+ throw e;
606
+ }
595
607
 
596
608
  if (didBailOut) {
597
609
  return;
@@ -601,7 +613,6 @@ if (__DEV__) {
601
613
  // Run the actual factories.
602
614
  const seenModuleIDs = new Set();
603
615
  for (let i = 0; i < updatedModuleIDs.length; i++) {
604
- // Don't process twice if we have a cycle.
605
616
  const updatedID = updatedModuleIDs[i];
606
617
  if (seenModuleIDs.has(updatedID)) {
607
618
  continue;
@@ -709,24 +720,29 @@ if (__DEV__) {
709
720
  ): Array<T> {
710
721
  const result = [];
711
722
  const visited = new Set();
723
+ const stack = new Set();
712
724
  function traverseDependentNodes(node: T) {
725
+ if (stack.has(node)) {
726
+ throw CYCLE_DETECTED;
727
+ }
728
+ if (visited.has(node)) {
729
+ return;
730
+ }
713
731
  visited.add(node);
732
+ stack.add(node);
714
733
  const dependentNodes = getEdges(node);
715
734
  if (earlyStop(node)) {
735
+ stack.delete(node);
716
736
  return;
717
737
  }
718
738
  dependentNodes.forEach(dependent => {
719
- if (visited.has(dependent)) {
720
- return;
721
- }
722
739
  traverseDependentNodes(dependent);
723
740
  });
741
+ stack.delete(node);
724
742
  result.push(node);
725
743
  }
726
744
  roots.forEach(root => {
727
- if (!visited.has(root)) {
728
- traverseDependentNodes(root);
729
- }
745
+ traverseDependentNodes(root);
730
746
  });
731
747
  return result;
732
748
  };
@@ -806,7 +822,10 @@ if (__DEV__) {
806
822
 
807
823
  const performFullRefresh = (
808
824
  reason: string,
809
- modules: $ReadOnly<{source: ModuleDefinition, failed: ModuleDefinition}>,
825
+ modules: $ReadOnly<{
826
+ source?: ModuleDefinition,
827
+ failed?: ModuleDefinition,
828
+ }>,
810
829
  ) => {
811
830
  /* global window */
812
831
  if (