@wyw-in-js/transform 1.0.6 → 1.0.8

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.
Files changed (98) hide show
  1. package/esm/cache.js +160 -12
  2. package/esm/cache.js.map +1 -1
  3. package/esm/debug/fileReporter.js.map +1 -1
  4. package/esm/module.js +59 -5
  5. package/esm/module.js.map +1 -1
  6. package/esm/plugins/shaker.js +152 -13
  7. package/esm/plugins/shaker.js.map +1 -1
  8. package/esm/shaker.js +51 -23
  9. package/esm/shaker.js.map +1 -1
  10. package/esm/transform/BaseEntrypoint.js +3 -1
  11. package/esm/transform/BaseEntrypoint.js.map +1 -1
  12. package/esm/transform/Entrypoint.js +68 -20
  13. package/esm/transform/Entrypoint.js.map +1 -1
  14. package/esm/transform/EvaluatedEntrypoint.js.map +1 -1
  15. package/esm/transform/actions/BaseAction.js +2 -1
  16. package/esm/transform/actions/BaseAction.js.map +1 -1
  17. package/esm/transform/actions/actionRunner.js +2 -2
  18. package/esm/transform/actions/actionRunner.js.map +1 -1
  19. package/esm/transform/barrelManifest.js +291 -0
  20. package/esm/transform/barrelManifest.js.map +1 -0
  21. package/esm/transform/generators/getExports.js +5 -0
  22. package/esm/transform/generators/getExports.js.map +1 -1
  23. package/esm/transform/generators/processEntrypoint.js +31 -1
  24. package/esm/transform/generators/processEntrypoint.js.map +1 -1
  25. package/esm/transform/generators/resolveImports.js +29 -5
  26. package/esm/transform/generators/resolveImports.js.map +1 -1
  27. package/esm/transform/generators/rewriteBarrelImports.js +733 -0
  28. package/esm/transform/generators/rewriteBarrelImports.js.map +1 -0
  29. package/esm/transform/generators/transform.js +154 -21
  30. package/esm/transform/generators/transform.js.map +1 -1
  31. package/esm/transform/types.js.map +1 -1
  32. package/esm/transform.js +45 -23
  33. package/esm/transform.js.map +1 -1
  34. package/esm/utils/collectTemplateDependencies.js +9 -0
  35. package/esm/utils/collectTemplateDependencies.js.map +1 -1
  36. package/lib/cache.js +163 -12
  37. package/lib/cache.js.map +1 -1
  38. package/lib/debug/fileReporter.js.map +1 -1
  39. package/lib/module.js +61 -7
  40. package/lib/module.js.map +1 -1
  41. package/lib/plugins/shaker.js +152 -13
  42. package/lib/plugins/shaker.js.map +1 -1
  43. package/lib/shaker.js +58 -26
  44. package/lib/shaker.js.map +1 -1
  45. package/lib/transform/BaseEntrypoint.js +3 -1
  46. package/lib/transform/BaseEntrypoint.js.map +1 -1
  47. package/lib/transform/Entrypoint.js +69 -20
  48. package/lib/transform/Entrypoint.js.map +1 -1
  49. package/lib/transform/EvaluatedEntrypoint.js.map +1 -1
  50. package/lib/transform/actions/BaseAction.js +2 -1
  51. package/lib/transform/actions/BaseAction.js.map +1 -1
  52. package/lib/transform/actions/actionRunner.js +2 -2
  53. package/lib/transform/actions/actionRunner.js.map +1 -1
  54. package/lib/transform/barrelManifest.js +300 -0
  55. package/lib/transform/barrelManifest.js.map +1 -0
  56. package/lib/transform/generators/getExports.js +5 -0
  57. package/lib/transform/generators/getExports.js.map +1 -1
  58. package/lib/transform/generators/processEntrypoint.js +31 -1
  59. package/lib/transform/generators/processEntrypoint.js.map +1 -1
  60. package/lib/transform/generators/resolveImports.js +29 -5
  61. package/lib/transform/generators/resolveImports.js.map +1 -1
  62. package/lib/transform/generators/rewriteBarrelImports.js +743 -0
  63. package/lib/transform/generators/rewriteBarrelImports.js.map +1 -0
  64. package/lib/transform/generators/transform.js +158 -22
  65. package/lib/transform/generators/transform.js.map +1 -1
  66. package/lib/transform/types.js.map +1 -1
  67. package/lib/transform.js +45 -23
  68. package/lib/transform.js.map +1 -1
  69. package/lib/utils/collectTemplateDependencies.js +9 -0
  70. package/lib/utils/collectTemplateDependencies.js.map +1 -1
  71. package/package.json +8 -4
  72. package/types/cache.d.ts +23 -2
  73. package/types/cache.js +170 -10
  74. package/types/debug/fileReporter.d.ts +1 -0
  75. package/types/module.d.ts +3 -0
  76. package/types/module.js +65 -5
  77. package/types/plugins/shaker.js +161 -16
  78. package/types/shaker.d.ts +10 -1
  79. package/types/shaker.js +56 -28
  80. package/types/transform/BaseEntrypoint.d.ts +3 -1
  81. package/types/transform/BaseEntrypoint.js +5 -1
  82. package/types/transform/Entrypoint.d.ts +10 -1
  83. package/types/transform/Entrypoint.js +81 -23
  84. package/types/transform/EvaluatedEntrypoint.d.ts +2 -0
  85. package/types/transform/actions/BaseAction.d.ts +2 -1
  86. package/types/transform/actions/BaseAction.js +3 -1
  87. package/types/transform/actions/actionRunner.js +2 -2
  88. package/types/transform/barrelManifest.d.ts +42 -0
  89. package/types/transform/barrelManifest.js +300 -0
  90. package/types/transform/generators/getExports.js +5 -0
  91. package/types/transform/generators/processEntrypoint.js +29 -1
  92. package/types/transform/generators/resolveImports.js +29 -5
  93. package/types/transform/generators/rewriteBarrelImports.d.ts +15 -0
  94. package/types/transform/generators/rewriteBarrelImports.js +815 -0
  95. package/types/transform/generators/transform.js +148 -19
  96. package/types/transform/types.d.ts +3 -0
  97. package/types/transform.js +47 -23
  98. package/types/utils/collectTemplateDependencies.js +9 -0
@@ -13,13 +13,14 @@ export declare class BaseAction<TAction extends ActionQueueItem> implements GetB
13
13
  readonly entrypoint: Entrypoint;
14
14
  readonly data: TAction['data'];
15
15
  readonly abortSignal: AbortSignal | null;
16
+ readonly actionContext: unknown;
16
17
  readonly idx: string;
17
18
  result: TypeOfResult<TAction> | typeof Pending;
18
19
  private activeScenario;
19
20
  private activeScenarioError?;
20
21
  private activeScenarioNextResults;
21
22
  private handler;
22
- constructor(type: TAction['type'], services: Services, entrypoint: Entrypoint, data: TAction['data'], abortSignal: AbortSignal | null);
23
+ constructor(type: TAction['type'], services: Services, entrypoint: Entrypoint, data: TAction['data'], abortSignal: AbortSignal | null, actionContext: unknown);
23
24
  get log(): Debugger;
24
25
  get ref(): string;
25
26
  createAbortSignal(): AbortSignal & Disposable;
@@ -11,18 +11,20 @@ class BaseAction {
11
11
  entrypoint;
12
12
  data;
13
13
  abortSignal;
14
+ actionContext;
14
15
  idx;
15
16
  result = types_1.Pending;
16
17
  activeScenario = null;
17
18
  activeScenarioError;
18
19
  activeScenarioNextResults = [];
19
20
  handler = null;
20
- constructor(type, services, entrypoint, data, abortSignal) {
21
+ constructor(type, services, entrypoint, data, abortSignal, actionContext) {
21
22
  this.type = type;
22
23
  this.services = services;
23
24
  this.entrypoint = entrypoint;
24
25
  this.data = data;
25
26
  this.abortSignal = abortSignal;
27
+ this.actionContext = actionContext;
26
28
  actionIdx += 1;
27
29
  this.idx = actionIdx.toString(16).padStart(6, '0');
28
30
  }
@@ -36,7 +36,7 @@ async function asyncActionRunner(action, actionHandlers, stack = [getActionRef(a
36
36
  return result.value;
37
37
  }
38
38
  const [type, entrypoint, data, abortSignal] = result.value;
39
- const nextAction = entrypoint.createAction(type, data, abortSignal);
39
+ const nextAction = entrypoint.createAction(type, data, abortSignal, action.actionContext);
40
40
  try {
41
41
  actionResult = await asyncActionRunner(nextAction, actionHandlers, [
42
42
  ...stack,
@@ -70,7 +70,7 @@ function syncActionRunner(action, actionHandlers, stack = [getActionRef(action.t
70
70
  return result.value;
71
71
  }
72
72
  const [type, entrypoint, data, abortSignal] = result.value;
73
- const nextAction = entrypoint.createAction(type, data, abortSignal);
73
+ const nextAction = entrypoint.createAction(type, data, abortSignal, action.actionContext);
74
74
  try {
75
75
  actionResult = syncActionRunner(nextAction, actionHandlers, [
76
76
  ...stack,
@@ -0,0 +1,42 @@
1
+ import type { File } from '@babel/types';
2
+ export type BarrelSkipReason = 'custom-evaluator' | 'empty' | 'ignored' | 'impure' | 'namespace-barrel' | 'unknown-star';
3
+ export type BarrelBlockedReason = 'ambiguous' | 'cycle' | 'namespace-barrel' | 'unknown-star' | 'unresolved';
4
+ export type BarrelResolvedBinding = {
5
+ imported: string;
6
+ kind: 'named';
7
+ source: string;
8
+ } | {
9
+ kind: 'namespace';
10
+ source: string;
11
+ };
12
+ export type BarrelManifestExport = BarrelResolvedBinding | {
13
+ kind: 'blocked';
14
+ reason: BarrelBlockedReason;
15
+ };
16
+ export type BarrelManifest = {
17
+ complete: boolean;
18
+ exports: Record<string, BarrelManifestExport>;
19
+ kind: 'barrel';
20
+ };
21
+ export type BarrelManifestCacheEntry = BarrelManifest | {
22
+ kind: 'ineligible';
23
+ reason: BarrelSkipReason;
24
+ };
25
+ export type RawBarrelReexport = {
26
+ exported: string;
27
+ imported: string;
28
+ kind: 'named';
29
+ source: string;
30
+ } | {
31
+ exported: string;
32
+ kind: 'namespace';
33
+ source: string;
34
+ };
35
+ export type RawBarrelManifest = {
36
+ complete: boolean;
37
+ explicitExports: string[];
38
+ exportAll: string[];
39
+ kind: 'barrel';
40
+ reexports: RawBarrelReexport[];
41
+ };
42
+ export declare function analyzeBarrelFile(ast: File): BarrelManifestCacheEntry | RawBarrelManifest;
@@ -0,0 +1,300 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.analyzeBarrelFile = analyzeBarrelFile;
7
+ /* eslint-disable no-continue, @typescript-eslint/no-use-before-define */
8
+ const traverse_1 = __importDefault(require("@babel/traverse"));
9
+ const types_1 = require("@babel/types");
10
+ const isTypeOnlyImport = (statement) => {
11
+ if (statement.importKind === 'type') {
12
+ return true;
13
+ }
14
+ if (statement.specifiers.length === 0) {
15
+ return false;
16
+ }
17
+ return statement.specifiers.every((specifier) => specifier.type === 'ImportSpecifier' && specifier.importKind === 'type');
18
+ };
19
+ const isTypeOnlyExport = (statement) => statement.exportKind === 'type';
20
+ const getModuleExportName = (node) => node.type === 'Identifier' ? node.name : node.value;
21
+ const isTypeOnlyStatement = (statement) => {
22
+ switch (statement.type) {
23
+ case 'EmptyStatement':
24
+ case 'TSDeclareFunction':
25
+ case 'TSInterfaceDeclaration':
26
+ case 'TSTypeAliasDeclaration':
27
+ return true;
28
+ default:
29
+ return false;
30
+ }
31
+ };
32
+ function collectExportNamedDeclaration(statement, reexports, explicitExports) {
33
+ if (!statement.source) {
34
+ return isTypeOnlyExport(statement);
35
+ }
36
+ if (isTypeOnlyExport(statement)) {
37
+ return true;
38
+ }
39
+ const source = statement.source.value;
40
+ for (const specifier of statement.specifiers) {
41
+ if (specifier.type === 'ExportSpecifier') {
42
+ if (specifier.exportKind === 'type') {
43
+ continue;
44
+ }
45
+ explicitExports.add(getModuleExportName(specifier.exported));
46
+ reexports.push(getNamedReexport(specifier, source));
47
+ continue;
48
+ }
49
+ if (specifier.type === 'ExportDefaultSpecifier') {
50
+ explicitExports.add(getModuleExportName(specifier.exported));
51
+ reexports.push(getDefaultReexport(specifier, source));
52
+ continue;
53
+ }
54
+ if (specifier.type === 'ExportNamespaceSpecifier') {
55
+ explicitExports.add(getModuleExportName(specifier.exported));
56
+ reexports.push(getNamespaceReexport(specifier, source));
57
+ continue;
58
+ }
59
+ return false;
60
+ }
61
+ return statement.specifiers.length > 0;
62
+ }
63
+ function getNamedReexport(specifier, source) {
64
+ return {
65
+ exported: getModuleExportName(specifier.exported),
66
+ imported: getModuleExportName(specifier.local),
67
+ kind: 'named',
68
+ source,
69
+ };
70
+ }
71
+ function getDefaultReexport(specifier, source) {
72
+ return {
73
+ exported: getModuleExportName(specifier.exported),
74
+ imported: 'default',
75
+ kind: 'named',
76
+ source,
77
+ };
78
+ }
79
+ function getNamespaceReexport(specifier, source) {
80
+ return {
81
+ exported: getModuleExportName(specifier.exported),
82
+ kind: 'namespace',
83
+ source,
84
+ };
85
+ }
86
+ const collectImportBinding = (statement, imports) => {
87
+ if (statement.importKind === 'type') {
88
+ return true;
89
+ }
90
+ if (statement.specifiers.length === 0) {
91
+ return false;
92
+ }
93
+ let sawValueImport = false;
94
+ for (const specifier of statement.specifiers) {
95
+ if (specifier.type === 'ImportSpecifier' &&
96
+ specifier.importKind === 'type') {
97
+ continue;
98
+ }
99
+ sawValueImport = true;
100
+ if (specifier.type === 'ImportSpecifier') {
101
+ imports.set(specifier.local.name, {
102
+ imported: getImportSpecifierName(specifier),
103
+ kind: 'named',
104
+ source: statement.source.value,
105
+ });
106
+ continue;
107
+ }
108
+ if (specifier.type === 'ImportDefaultSpecifier') {
109
+ imports.set(specifier.local.name, {
110
+ imported: 'default',
111
+ kind: 'named',
112
+ source: statement.source.value,
113
+ });
114
+ continue;
115
+ }
116
+ imports.set(specifier.local.name, {
117
+ kind: 'namespace',
118
+ source: statement.source.value,
119
+ });
120
+ }
121
+ return sawValueImport || isTypeOnlyImport(statement);
122
+ };
123
+ const getImportSpecifierName = (specifier) => getModuleExportName(specifier.imported);
124
+ const getLocalDeclarationNames = (declaration) => {
125
+ if (declaration.type === 'VariableDeclaration' ||
126
+ declaration.type === 'FunctionDeclaration' ||
127
+ declaration.type === 'ClassDeclaration') {
128
+ return Object.keys((0, types_1.getBindingIdentifiers)(declaration));
129
+ }
130
+ if (declaration.type === 'TSEnumDeclaration' ||
131
+ declaration.type === 'TSModuleDeclaration') {
132
+ return null;
133
+ }
134
+ return [];
135
+ };
136
+ const collectLocalExportNamedDeclaration = (statement, importedBindings, passthroughCandidates, explicitExports) => {
137
+ let complete = true;
138
+ if (isTypeOnlyExport(statement)) {
139
+ return {
140
+ complete: true,
141
+ ok: true,
142
+ };
143
+ }
144
+ if (statement.declaration) {
145
+ const names = getLocalDeclarationNames(statement.declaration);
146
+ if (names === null) {
147
+ return {
148
+ complete: false,
149
+ ok: false,
150
+ };
151
+ }
152
+ for (const name of names) {
153
+ explicitExports.add(name);
154
+ }
155
+ return {
156
+ complete: names.length === 0,
157
+ ok: true,
158
+ };
159
+ }
160
+ for (const specifier of statement.specifiers) {
161
+ if (specifier.type !== 'ExportSpecifier') {
162
+ return {
163
+ complete: false,
164
+ ok: false,
165
+ };
166
+ }
167
+ if (specifier.exportKind === 'type') {
168
+ continue;
169
+ }
170
+ const exported = getModuleExportName(specifier.exported);
171
+ explicitExports.add(exported);
172
+ if (specifier.local.type !== 'Identifier') {
173
+ complete = false;
174
+ continue;
175
+ }
176
+ if (!importedBindings.has(specifier.local.name)) {
177
+ complete = false;
178
+ continue;
179
+ }
180
+ if (!passthroughCandidates.has(specifier.local.name)) {
181
+ passthroughCandidates.set(specifier.local.name, []);
182
+ }
183
+ passthroughCandidates.get(specifier.local.name).push(exported);
184
+ }
185
+ return {
186
+ complete: complete && statement.specifiers.length > 0,
187
+ ok: true,
188
+ };
189
+ };
190
+ const collectPassthroughReexports = (ast, importedBindings, passthroughCandidates, reexports) => {
191
+ let complete = true;
192
+ const bindingReferenceCounts = new Map();
193
+ (0, traverse_1.default)(ast, {
194
+ Program(path) {
195
+ for (const localName of passthroughCandidates.keys()) {
196
+ bindingReferenceCounts.set(localName, path.scope.getBinding(localName)?.referencePaths.length ?? -1);
197
+ }
198
+ path.stop();
199
+ },
200
+ });
201
+ for (const [localName, exportedNames] of passthroughCandidates) {
202
+ if (bindingReferenceCounts.get(localName) !== exportedNames.length) {
203
+ complete = false;
204
+ continue;
205
+ }
206
+ const imported = importedBindings.get(localName);
207
+ for (const exported of exportedNames) {
208
+ if (imported.kind === 'namespace') {
209
+ reexports.push({
210
+ exported,
211
+ kind: 'namespace',
212
+ source: imported.source,
213
+ });
214
+ continue;
215
+ }
216
+ reexports.push({
217
+ exported,
218
+ imported: imported.imported,
219
+ kind: 'named',
220
+ source: imported.source,
221
+ });
222
+ }
223
+ }
224
+ return {
225
+ complete,
226
+ ok: true,
227
+ };
228
+ };
229
+ function analyzeBarrelProgram(ast) {
230
+ const reexports = [];
231
+ const explicitExports = new Set();
232
+ const exportAll = [];
233
+ const importedBindings = new Map();
234
+ const passthroughCandidates = new Map();
235
+ let complete = true;
236
+ for (const statement of ast.program.body) {
237
+ if (statement.type === 'ImportDeclaration') {
238
+ if (!collectImportBinding(statement, importedBindings)) {
239
+ return null;
240
+ }
241
+ continue;
242
+ }
243
+ if (statement.type === 'ExportNamedDeclaration') {
244
+ if (statement.source) {
245
+ if (!collectExportNamedDeclaration(statement, reexports, explicitExports)) {
246
+ return null;
247
+ }
248
+ continue;
249
+ }
250
+ const localResult = collectLocalExportNamedDeclaration(statement, importedBindings, passthroughCandidates, explicitExports);
251
+ if (!localResult.ok) {
252
+ return null;
253
+ }
254
+ complete = complete && localResult.complete;
255
+ continue;
256
+ }
257
+ if (statement.type === 'ExportAllDeclaration') {
258
+ if (statement.exportKind === 'type') {
259
+ continue;
260
+ }
261
+ if (!statement.source) {
262
+ return null;
263
+ }
264
+ exportAll.push(getExportAllSource(statement));
265
+ continue;
266
+ }
267
+ if (statement.type === 'ExportDefaultDeclaration') {
268
+ return null;
269
+ }
270
+ if (!isTypeOnlyStatement(statement)) {
271
+ return null;
272
+ }
273
+ }
274
+ const passthroughResult = collectPassthroughReexports(ast, importedBindings, passthroughCandidates, reexports);
275
+ if (!passthroughResult.ok) {
276
+ return null;
277
+ }
278
+ complete = complete && passthroughResult.complete;
279
+ if (reexports.length === 0 && exportAll.length === 0) {
280
+ return null;
281
+ }
282
+ return {
283
+ complete,
284
+ explicitExports: [...explicitExports],
285
+ exportAll,
286
+ kind: 'barrel',
287
+ reexports,
288
+ };
289
+ }
290
+ const getExportAllSource = (statement) => statement.source.value;
291
+ function analyzeBarrelFile(ast) {
292
+ const result = analyzeBarrelProgram(ast);
293
+ if (!result) {
294
+ return {
295
+ kind: 'ineligible',
296
+ reason: 'impure',
297
+ };
298
+ }
299
+ return result;
300
+ }
@@ -52,11 +52,16 @@ function* getExports() {
52
52
  const resolvedImports = yield* this.getNext('resolveImports', entrypoint, {
53
53
  imports: new Map(withWildcardReexport.map((i) => [i.source, []])),
54
54
  });
55
+ const dependencyFilenames = resolvedImports.flatMap((dependency) => dependency.resolved ? [dependency.resolved] : []);
55
56
  const importedEntrypoints = findExportsInImports(entrypoint, resolvedImports);
56
57
  for (const importedEntrypoint of importedEntrypoints) {
57
58
  const exports = yield* this.getNext('getExports', importedEntrypoint.entrypoint, undefined);
58
59
  result.push(...exports);
59
60
  }
61
+ cache.add('exports', entrypoint.name, result);
62
+ cache.setCacheDependencies('exports', entrypoint.name, dependencyFilenames);
63
+ entrypoint.log(`exports: %o`, result);
64
+ return result;
60
65
  }
61
66
  entrypoint.log(`exports: %o`, result);
62
67
  cache.add('exports', entrypoint.name, result);
@@ -53,7 +53,20 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
53
53
  });
54
54
  Object.defineProperty(exports, "__esModule", { value: true });
55
55
  exports.processEntrypoint = processEntrypoint;
56
+ const shaker_1 = require("../../shaker");
56
57
  const AbortError_1 = require("../actions/AbortError");
58
+ const barrelManifest_1 = require("../barrelManifest");
59
+ const shouldSkipExplodeReexports = (action) => {
60
+ const { loadedAndParsed, only } = action.entrypoint;
61
+ if (only.length === 1 && only[0] === '__wywPreval') {
62
+ return true;
63
+ }
64
+ if (loadedAndParsed.evaluator !== shaker_1.shaker || !loadedAndParsed.ast) {
65
+ return false;
66
+ }
67
+ const barrelAnalysis = (0, barrelManifest_1.analyzeBarrelFile)(loadedAndParsed.ast);
68
+ return barrelAnalysis.kind === 'barrel' && barrelAnalysis.complete;
69
+ };
57
70
  /**
58
71
  * The first stage of processing an entrypoint.
59
72
  * This stage is responsible for:
@@ -64,14 +77,26 @@ const AbortError_1 = require("../actions/AbortError");
64
77
  function* processEntrypoint() {
65
78
  const { only, log } = this.entrypoint;
66
79
  log('start processing (only: %o)', only);
80
+ this.entrypoint.beginProcessing();
67
81
  try {
68
82
  const env_1 = { stack: [], error: void 0, hasError: false };
69
83
  try {
70
84
  const abortSignal = __addDisposableResource(env_1, this.createAbortSignal(), false);
71
- yield ['explodeReexports', this.entrypoint, undefined, abortSignal];
85
+ if (shouldSkipExplodeReexports(this)) {
86
+ log('skip explodeReexports for pure barrel');
87
+ }
88
+ else {
89
+ yield ['explodeReexports', this.entrypoint, undefined, abortSignal];
90
+ }
72
91
  const result = yield* this.getNext('transform', this.entrypoint, undefined, abortSignal);
73
92
  this.entrypoint.assertNotSuperseded();
74
93
  this.entrypoint.setTransformResult(result);
94
+ const supersededWith = this.entrypoint.applyDeferredSupersede();
95
+ if (supersededWith) {
96
+ log('processing finished, deferred only detected; schedule next attempt');
97
+ yield* this.getNext('processEntrypoint', supersededWith, undefined, null);
98
+ return;
99
+ }
75
100
  log('entrypoint processing finished');
76
101
  }
77
102
  catch (e_1) {
@@ -91,4 +116,7 @@ function* processEntrypoint() {
91
116
  log(`Unhandled error: %O`, e);
92
117
  throw e;
93
118
  }
119
+ finally {
120
+ this.entrypoint.endProcessing();
121
+ }
94
122
  }
@@ -40,11 +40,12 @@ function applyImportOverrides(services, entrypoint, resolvedImports) {
40
40
  };
41
41
  });
42
42
  }
43
- function emitDependency(emitter, entrypoint, imports) {
43
+ function emitDependency(emitter, entrypoint, imports, phase) {
44
44
  emitter.single({
45
45
  type: 'dependency',
46
46
  file: entrypoint.name,
47
47
  only: entrypoint.only,
48
+ phase,
48
49
  imports: imports.map(({ resolved, only }) => ({
49
50
  from: resolved,
50
51
  what: only,
@@ -61,19 +62,32 @@ function filterUnresolved(entrypoint, resolvedImports) {
61
62
  return true;
62
63
  });
63
64
  }
65
+ function getPreResolvedImports(preResolved) {
66
+ return new Map((preResolved ?? []).map((dependency) => [dependency.source, dependency]));
67
+ }
64
68
  /**
65
69
  * Synchronously resolves specified imports with a provided resolver.
66
70
  */
67
71
  function* syncResolveImports(resolve) {
68
72
  const { data: { imports }, entrypoint, services: { eventEmitter }, } = this;
69
73
  const listOfImports = Array.from(imports?.entries() ?? []);
74
+ const preResolvedImports = getPreResolvedImports(this.data.preResolved);
70
75
  const { log } = entrypoint;
71
76
  if (listOfImports.length === 0) {
72
- emitDependency(eventEmitter, entrypoint, []);
77
+ emitDependency(eventEmitter, entrypoint, [], this.data.phase);
73
78
  log('%s has no imports', entrypoint.name);
74
79
  return [];
75
80
  }
76
81
  const resolvedImports = listOfImports.map(([source, only]) => {
82
+ const preResolved = preResolvedImports.get(source);
83
+ if (preResolved) {
84
+ const mergedOnly = (0, Entrypoint_helpers_1.mergeOnly)(preResolved.only, only);
85
+ log('[sync-resolve] ♻️ %s -> %s (only: %o)', source, preResolved.resolved, mergedOnly);
86
+ return {
87
+ ...preResolved,
88
+ only: mergedOnly,
89
+ };
90
+ }
77
91
  let resolved = null;
78
92
  try {
79
93
  resolved = resolve(source, entrypoint.name, (0, Entrypoint_helpers_1.getStack)(entrypoint));
@@ -90,7 +104,7 @@ function* syncResolveImports(resolve) {
90
104
  });
91
105
  const overriddenImports = applyImportOverrides(this.services, entrypoint, resolvedImports);
92
106
  const filteredImports = filterUnresolved(entrypoint, overriddenImports);
93
- emitDependency(eventEmitter, entrypoint, filteredImports);
107
+ emitDependency(eventEmitter, entrypoint, filteredImports, this.data.phase);
94
108
  return filteredImports;
95
109
  }
96
110
  /**
@@ -99,9 +113,10 @@ function* syncResolveImports(resolve) {
99
113
  async function* asyncResolveImports(resolve) {
100
114
  const { data: { imports }, entrypoint, services: { eventEmitter }, } = this;
101
115
  const listOfImports = Array.from(imports?.entries() ?? []);
116
+ const preResolvedImports = getPreResolvedImports(this.data.preResolved);
102
117
  const { log } = entrypoint;
103
118
  if (listOfImports.length === 0) {
104
- emitDependency(eventEmitter, entrypoint, []);
119
+ emitDependency(eventEmitter, entrypoint, [], this.data.phase);
105
120
  log('%s has no imports', entrypoint.name);
106
121
  return [];
107
122
  }
@@ -124,6 +139,15 @@ async function* asyncResolveImports(resolve) {
124
139
  };
125
140
  };
126
141
  const resolvedImports = await Promise.all(listOfImports.map(([source, importsOnly]) => {
142
+ const preResolved = preResolvedImports.get(source);
143
+ if (preResolved) {
144
+ const mergedOnly = (0, Entrypoint_helpers_1.mergeOnly)(preResolved.only, importsOnly);
145
+ log('[async-resolve] ♻️ %s (%o) in %s -> %s', source, mergedOnly, entrypoint.name, preResolved.resolved);
146
+ return {
147
+ ...preResolved,
148
+ only: mergedOnly,
149
+ };
150
+ }
127
151
  const cached = entrypoint.getDependency(source);
128
152
  if (cached) {
129
153
  return {
@@ -155,6 +179,6 @@ async function* asyncResolveImports(resolve) {
155
179
  log('resolved %d imports', resolvedImports.length);
156
180
  const overriddenImports = applyImportOverrides(this.services, entrypoint, resolvedImports);
157
181
  const filteredImports = filterUnresolved(entrypoint, overriddenImports);
158
- emitDependency(eventEmitter, entrypoint, filteredImports);
182
+ emitDependency(eventEmitter, entrypoint, filteredImports, this.data.phase);
159
183
  return filteredImports;
160
184
  }
@@ -0,0 +1,15 @@
1
+ import * as t from '@babel/types';
2
+ import type { IEntrypointDependency } from '../Entrypoint.types';
3
+ import type { ITransformAction } from '../types';
4
+ type RewriteResult = {
5
+ ast: t.File;
6
+ code: string;
7
+ fullyRewrittenSources: string[];
8
+ imports: Map<string, string[]> | null;
9
+ optimizedCount: number;
10
+ partialFallbackSources: string[];
11
+ preResolvedImports: IEntrypointDependency[];
12
+ skippedCount: number;
13
+ };
14
+ export declare function rewriteOptimizedBarrelImports(this: ITransformAction, ast: t.File, code: string, resolvedImports: IEntrypointDependency[]): Generator<any, RewriteResult, any>;
15
+ export {};