@atlaspack/core 2.12.1-canary.3354

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 (215) hide show
  1. package/LICENSE +201 -0
  2. package/index.d.ts +22 -0
  3. package/lib/AssetGraph.js +518 -0
  4. package/lib/Atlaspack.js +587 -0
  5. package/lib/AtlaspackConfig.js +298 -0
  6. package/lib/AtlaspackConfig.schema.js +125 -0
  7. package/lib/BundleGraph.js +1445 -0
  8. package/lib/CommittedAsset.js +133 -0
  9. package/lib/Dependency.js +88 -0
  10. package/lib/Environment.js +128 -0
  11. package/lib/InternalConfig.js +48 -0
  12. package/lib/PackagerRunner.js +519 -0
  13. package/lib/ReporterRunner.js +151 -0
  14. package/lib/RequestTracker.js +1089 -0
  15. package/lib/SymbolPropagation.js +625 -0
  16. package/lib/TargetDescriptor.schema.js +115 -0
  17. package/lib/Transformation.js +536 -0
  18. package/lib/UncommittedAsset.js +342 -0
  19. package/lib/Validation.js +215 -0
  20. package/lib/applyRuntimes.js +279 -0
  21. package/lib/assetUtils.js +189 -0
  22. package/lib/atlaspack-v3/AtlaspackV3.js +74 -0
  23. package/lib/atlaspack-v3/fs.js +30 -0
  24. package/lib/atlaspack-v3/index.js +19 -0
  25. package/lib/atlaspack-v3/jsCallable.js +15 -0
  26. package/lib/atlaspack-v3/plugins/Resolver.js +12 -0
  27. package/lib/atlaspack-v3/plugins/index.js +16 -0
  28. package/lib/atlaspack-v3/worker/index.js +3 -0
  29. package/lib/atlaspack-v3/worker/worker.js +30 -0
  30. package/lib/buildCache.js +18 -0
  31. package/lib/constants.js +21 -0
  32. package/lib/dumpGraphToGraphViz.js +206 -0
  33. package/lib/index.js +106 -0
  34. package/lib/loadAtlaspackPlugin.js +148 -0
  35. package/lib/loadDotEnv.js +54 -0
  36. package/lib/projectPath.js +86 -0
  37. package/lib/public/Asset.js +259 -0
  38. package/lib/public/Bundle.js +231 -0
  39. package/lib/public/BundleGraph.js +193 -0
  40. package/lib/public/BundleGroup.js +44 -0
  41. package/lib/public/Config.js +202 -0
  42. package/lib/public/Dependency.js +131 -0
  43. package/lib/public/Environment.js +244 -0
  44. package/lib/public/MutableBundleGraph.js +184 -0
  45. package/lib/public/PluginOptions.js +71 -0
  46. package/lib/public/Symbols.js +247 -0
  47. package/lib/public/Target.js +64 -0
  48. package/lib/registerCoreWithSerializer.js +45 -0
  49. package/lib/requests/AssetGraphRequest.js +427 -0
  50. package/lib/requests/AssetGraphRequestRust.js +187 -0
  51. package/lib/requests/AssetRequest.js +137 -0
  52. package/lib/requests/AtlaspackBuildRequest.js +78 -0
  53. package/lib/requests/AtlaspackConfigRequest.js +473 -0
  54. package/lib/requests/BundleGraphRequest.js +419 -0
  55. package/lib/requests/ConfigRequest.js +198 -0
  56. package/lib/requests/DevDepRequest.js +166 -0
  57. package/lib/requests/EntryRequest.js +295 -0
  58. package/lib/requests/PackageRequest.js +88 -0
  59. package/lib/requests/PathRequest.js +349 -0
  60. package/lib/requests/TargetRequest.js +1177 -0
  61. package/lib/requests/ValidationRequest.js +66 -0
  62. package/lib/requests/WriteBundleRequest.js +252 -0
  63. package/lib/requests/WriteBundlesRequest.js +153 -0
  64. package/lib/resolveOptions.js +234 -0
  65. package/lib/serializer.js +216 -0
  66. package/lib/serializerCore.browser.js +29 -0
  67. package/lib/serializerCore.js +16 -0
  68. package/lib/summarizeRequest.js +55 -0
  69. package/lib/types.js +35 -0
  70. package/lib/utils.js +160 -0
  71. package/lib/worker.js +170 -0
  72. package/package.json +59 -0
  73. package/src/AssetGraph.js +646 -0
  74. package/src/Atlaspack.js +632 -0
  75. package/src/AtlaspackConfig.js +490 -0
  76. package/src/AtlaspackConfig.schema.js +141 -0
  77. package/src/BundleGraph.js +2193 -0
  78. package/src/CommittedAsset.js +143 -0
  79. package/src/Dependency.js +142 -0
  80. package/src/Environment.js +151 -0
  81. package/src/InternalConfig.js +72 -0
  82. package/src/PackagerRunner.js +790 -0
  83. package/src/ReporterRunner.js +158 -0
  84. package/src/RequestTracker.js +1697 -0
  85. package/src/SymbolPropagation.js +794 -0
  86. package/src/TargetDescriptor.schema.js +136 -0
  87. package/src/Transformation.js +752 -0
  88. package/src/UncommittedAsset.js +426 -0
  89. package/src/Validation.js +223 -0
  90. package/src/applyRuntimes.js +341 -0
  91. package/src/assetUtils.js +254 -0
  92. package/src/atlaspack-v3/AtlaspackV3.js +73 -0
  93. package/src/atlaspack-v3/fs.js +36 -0
  94. package/src/atlaspack-v3/index.js +5 -0
  95. package/src/atlaspack-v3/jsCallable.js +13 -0
  96. package/src/atlaspack-v3/plugins/Resolver.js +9 -0
  97. package/src/atlaspack-v3/plugins/index.js +3 -0
  98. package/src/atlaspack-v3/worker/index.js +8 -0
  99. package/src/atlaspack-v3/worker/worker.js +14 -0
  100. package/src/buildCache.js +15 -0
  101. package/src/constants.js +22 -0
  102. package/src/dumpGraphToGraphViz.js +244 -0
  103. package/src/index.js +22 -0
  104. package/src/loadAtlaspackPlugin.js +239 -0
  105. package/src/loadDotEnv.js +56 -0
  106. package/src/projectPath.js +87 -0
  107. package/src/public/Asset.js +359 -0
  108. package/src/public/Bundle.js +337 -0
  109. package/src/public/BundleGraph.js +335 -0
  110. package/src/public/BundleGroup.js +55 -0
  111. package/src/public/Config.js +261 -0
  112. package/src/public/Dependency.js +176 -0
  113. package/src/public/Environment.js +316 -0
  114. package/src/public/MutableBundleGraph.js +320 -0
  115. package/src/public/PluginOptions.js +99 -0
  116. package/src/public/Symbols.js +315 -0
  117. package/src/public/Target.js +71 -0
  118. package/src/registerCoreWithSerializer.js +34 -0
  119. package/src/requests/AssetGraphRequest.js +577 -0
  120. package/src/requests/AssetGraphRequestRust.js +222 -0
  121. package/src/requests/AssetRequest.js +179 -0
  122. package/src/requests/AtlaspackBuildRequest.js +109 -0
  123. package/src/requests/AtlaspackConfigRequest.js +709 -0
  124. package/src/requests/BundleGraphRequest.js +547 -0
  125. package/src/requests/ConfigRequest.js +287 -0
  126. package/src/requests/DevDepRequest.js +246 -0
  127. package/src/requests/EntryRequest.js +385 -0
  128. package/src/requests/PackageRequest.js +105 -0
  129. package/src/requests/PathRequest.js +454 -0
  130. package/src/requests/TargetRequest.js +1632 -0
  131. package/src/requests/ValidationRequest.js +79 -0
  132. package/src/requests/WriteBundleRequest.js +362 -0
  133. package/src/requests/WriteBundlesRequest.js +209 -0
  134. package/src/resolveOptions.js +278 -0
  135. package/src/serializer.js +255 -0
  136. package/src/serializerCore.browser.js +8 -0
  137. package/src/serializerCore.js +5 -0
  138. package/src/summarizeRequest.js +47 -0
  139. package/src/types.js +581 -0
  140. package/src/utils.js +211 -0
  141. package/src/worker.js +189 -0
  142. package/test/AssetGraph.test.js +679 -0
  143. package/test/Atlaspack.test.js +142 -0
  144. package/test/AtlaspackConfig.test.js +405 -0
  145. package/test/AtlaspackConfigRequest.test.js +993 -0
  146. package/test/BundleGraph.test.js +121 -0
  147. package/test/EntryRequest.test.js +215 -0
  148. package/test/Environment.test.js +99 -0
  149. package/test/InternalAsset.test.js +76 -0
  150. package/test/PackagerRunner.test.js +27 -0
  151. package/test/PublicAsset.test.js +40 -0
  152. package/test/PublicBundle.test.js +68 -0
  153. package/test/PublicDependency.test.js +22 -0
  154. package/test/PublicEnvironment.test.js +27 -0
  155. package/test/PublicMutableBundleGraph.test.js +192 -0
  156. package/test/RequestTracker.test.js +448 -0
  157. package/test/SymbolPropagation.test.js +716 -0
  158. package/test/TargetRequest.test.js +1715 -0
  159. package/test/fixtures/application-targets/package.json +3 -0
  160. package/test/fixtures/atlaspack/index.js +1 -0
  161. package/test/fixtures/atlaspack/other.js +3 -0
  162. package/test/fixtures/atlaspack/package.json +1 -0
  163. package/test/fixtures/atlaspack/yarn.lock +0 -0
  164. package/test/fixtures/bundle.js +10 -0
  165. package/test/fixtures/common-targets/package.json +24 -0
  166. package/test/fixtures/common-targets-ignore/package.json +13 -0
  167. package/test/fixtures/config/.atlaspackrc +6 -0
  168. package/test/fixtures/config/subfolder/.atlaspackrc +6 -0
  169. package/test/fixtures/config-extends-not-found/.atlaspackrc +3 -0
  170. package/test/fixtures/config-extends-not-found/.atlaspackrc-json5 +3 -0
  171. package/test/fixtures/config-extends-not-found/.atlaspackrc-multiple +3 -0
  172. package/test/fixtures/config-extends-not-found/.atlaspackrc-node-modules +3 -0
  173. package/test/fixtures/config-malformed/.atlaspackrc +3 -0
  174. package/test/fixtures/config-node-pipeline/.atlaspackrc +6 -0
  175. package/test/fixtures/config-plugin-not-found/.atlaspackrc +6 -0
  176. package/test/fixtures/context/package.json +8 -0
  177. package/test/fixtures/custom-format-infer-ext/package.json +6 -0
  178. package/test/fixtures/custom-format-infer-type/package.json +7 -0
  179. package/test/fixtures/custom-format-mismatch/package.json +8 -0
  180. package/test/fixtures/custom-targets/package.json +20 -0
  181. package/test/fixtures/custom-targets-distdir/package.json +11 -0
  182. package/test/fixtures/duplicate-targets/package.json +4 -0
  183. package/test/fixtures/glob-like/[entry].js +0 -0
  184. package/test/fixtures/invalid-distpath/package.json +11 -0
  185. package/test/fixtures/invalid-engines/package.json +12 -0
  186. package/test/fixtures/invalid-source-missing/package.json +5 -0
  187. package/test/fixtures/invalid-source-not-file/package.json +5 -0
  188. package/test/fixtures/invalid-source-not-file/src/index.js +1 -0
  189. package/test/fixtures/invalid-target-source-missing/package.json +9 -0
  190. package/test/fixtures/invalid-target-source-not-file/package.json +9 -0
  191. package/test/fixtures/invalid-target-source-not-file/src/index.js +1 -0
  192. package/test/fixtures/invalid-targets/package.json +19 -0
  193. package/test/fixtures/library-custom-scopehoist/package.json +9 -0
  194. package/test/fixtures/library-scopehoist/package.json +8 -0
  195. package/test/fixtures/local-plugin-config-pkg/.atlaspackrc +3 -0
  196. package/test/fixtures/local-plugin-config-pkg/node_modules/atlaspack-config-local/index.json +8 -0
  197. package/test/fixtures/local-plugin-config-pkg/node_modules/atlaspack-config-local/local-plugin.js +7 -0
  198. package/test/fixtures/local-plugin-config-pkg/node_modules/atlaspack-config-local/package.json +7 -0
  199. package/test/fixtures/main-format-mismatch/package.json +8 -0
  200. package/test/fixtures/main-global/package.json +8 -0
  201. package/test/fixtures/main-mjs/package.json +8 -0
  202. package/test/fixtures/module-a.js +1 -0
  203. package/test/fixtures/module-b.js +1 -0
  204. package/test/fixtures/plugins/local-plugin.js +7 -0
  205. package/test/fixtures/plugins/node_modules/atlaspack-transformer-bad-engines/index.js +7 -0
  206. package/test/fixtures/plugins/node_modules/atlaspack-transformer-bad-engines/package.json +7 -0
  207. package/test/fixtures/plugins/node_modules/atlaspack-transformer-no-engines/index.js +7 -0
  208. package/test/fixtures/plugins/node_modules/atlaspack-transformer-no-engines/package.json +4 -0
  209. package/test/fixtures/targets-default-distdir-none/package.json +5 -0
  210. package/test/fixtures/targets-default-distdir-one/package.json +8 -0
  211. package/test/fixtures/targets-default-distdir-two/package.json +18 -0
  212. package/test/requests/ConfigRequest.test.js +254 -0
  213. package/test/serializer.test.js +302 -0
  214. package/test/test-utils.js +80 -0
  215. package/test/utils.test.js +43 -0
@@ -0,0 +1,632 @@
1
+ // @flow strict-local
2
+
3
+ import type {
4
+ Asset,
5
+ AsyncSubscription,
6
+ BuildEvent,
7
+ BuildSuccessEvent,
8
+ InitialAtlaspackOptions,
9
+ PackagedBundle as IPackagedBundle,
10
+ AtlaspackTransformOptions,
11
+ AtlaspackResolveOptions,
12
+ AtlaspackResolveResult,
13
+ } from '@atlaspack/types';
14
+ import path from 'path';
15
+ import type {AtlaspackOptions} from './types';
16
+ // eslint-disable-next-line no-unused-vars
17
+ import type {FarmOptions, SharedReference} from '@atlaspack/workers';
18
+ import type {Diagnostic} from '@atlaspack/diagnostic';
19
+
20
+ import invariant from 'assert';
21
+ import ThrowableDiagnostic, {anyToDiagnostic} from '@atlaspack/diagnostic';
22
+ import {assetFromValue} from './public/Asset';
23
+ import {PackagedBundle} from './public/Bundle';
24
+ import BundleGraph from './public/BundleGraph';
25
+ import WorkerFarm from '@atlaspack/workers';
26
+ import nullthrows from 'nullthrows';
27
+ import {BuildAbortError} from './utils';
28
+ import {loadAtlaspackConfig} from './requests/AtlaspackConfigRequest';
29
+ import ReporterRunner from './ReporterRunner';
30
+ import dumpGraphToGraphViz from './dumpGraphToGraphViz';
31
+ import resolveOptions from './resolveOptions';
32
+ import {ValueEmitter} from '@atlaspack/events';
33
+ import {registerCoreWithSerializer} from './registerCoreWithSerializer';
34
+ import {PromiseQueue} from '@atlaspack/utils';
35
+ import AtlaspackConfig from './AtlaspackConfig';
36
+ import logger from '@atlaspack/logger';
37
+ import RequestTracker, {
38
+ getWatcherOptions,
39
+ requestGraphEdgeTypes,
40
+ } from './RequestTracker';
41
+ import createValidationRequest from './requests/ValidationRequest';
42
+ import createAtlaspackBuildRequest from './requests/AtlaspackBuildRequest';
43
+ import createAssetRequest from './requests/AssetRequest';
44
+ import createPathRequest from './requests/PathRequest';
45
+ import {createEnvironment} from './Environment';
46
+ import {createDependency} from './Dependency';
47
+ import {Disposable} from '@atlaspack/events';
48
+ import {init as initSourcemaps} from '@parcel/source-map';
49
+ import {
50
+ init as initRust,
51
+ initializeMonitoring,
52
+ closeMonitoring,
53
+ } from '@atlaspack/rust';
54
+ import {
55
+ fromProjectPath,
56
+ toProjectPath,
57
+ fromProjectPathRelative,
58
+ } from './projectPath';
59
+ import {tracer} from '@atlaspack/profiler';
60
+ import {setFeatureFlags} from '@atlaspack/feature-flags';
61
+ import {AtlaspackV3, toFileSystemV3} from './atlaspack-v3';
62
+
63
+ registerCoreWithSerializer();
64
+
65
+ export const INTERNAL_TRANSFORM: symbol = Symbol('internal_transform');
66
+ export const INTERNAL_RESOLVE: symbol = Symbol('internal_resolve');
67
+
68
+ export default class Atlaspack {
69
+ #requestTracker /*: RequestTracker*/;
70
+ #config /*: AtlaspackConfig*/;
71
+ #farm /*: WorkerFarm*/;
72
+ #initialized /*: boolean*/ = false;
73
+ #disposable /*: Disposable */;
74
+ #initialOptions /*: InitialAtlaspackOptions */;
75
+ #atlaspackV3: AtlaspackV3;
76
+ #reporterRunner /*: ReporterRunner*/;
77
+ #resolvedOptions /*: ?AtlaspackOptions*/ = null;
78
+ #optionsRef /*: SharedReference */;
79
+ #watchAbortController /*: AbortController*/;
80
+ #watchQueue /*: PromiseQueue<?BuildEvent>*/ = new PromiseQueue<?BuildEvent>({
81
+ maxConcurrent: 1,
82
+ });
83
+ #watchEvents /*: ValueEmitter<
84
+ | {|
85
+ +error: Error,
86
+ +buildEvent?: void,
87
+ |}
88
+ | {|
89
+ +buildEvent: BuildEvent,
90
+ +error?: void,
91
+ |},
92
+ > */;
93
+ #watcherSubscription /*: ?AsyncSubscription*/;
94
+ #watcherCount /*: number*/ = 0;
95
+ #requestedAssetIds /*: Set<string>*/ = new Set();
96
+
97
+ isProfiling /*: boolean */;
98
+
99
+ constructor(options: InitialAtlaspackOptions) {
100
+ this.#initialOptions = options;
101
+ }
102
+
103
+ async _init(): Promise<void> {
104
+ if (this.#initialized) {
105
+ return;
106
+ }
107
+
108
+ await initSourcemaps;
109
+ await initRust?.();
110
+ try {
111
+ initializeMonitoring?.();
112
+ process.on('exit', () => {
113
+ closeMonitoring?.();
114
+ });
115
+ } catch (e) {
116
+ // Fallthrough
117
+ logger.warn(e);
118
+ }
119
+
120
+ let resolvedOptions: AtlaspackOptions = await resolveOptions(
121
+ this.#initialOptions,
122
+ );
123
+ this.#resolvedOptions = resolvedOptions;
124
+
125
+ let rustAtlaspack: AtlaspackV3;
126
+ if (resolvedOptions.featureFlags.atlaspackV3) {
127
+ // eslint-disable-next-line no-unused-vars
128
+ let {entries, inputFS, outputFS, ...options} = this.#initialOptions;
129
+
130
+ rustAtlaspack = new AtlaspackV3({
131
+ ...options,
132
+ corePath: path.join(__dirname, '..'),
133
+ entries: Array.isArray(entries)
134
+ ? entries
135
+ : entries == null
136
+ ? undefined
137
+ : [entries],
138
+ fs: inputFS && toFileSystemV3(inputFS),
139
+ });
140
+ }
141
+
142
+ let {config} = await loadAtlaspackConfig(resolvedOptions);
143
+ this.#config = new AtlaspackConfig(config, resolvedOptions);
144
+
145
+ setFeatureFlags(resolvedOptions.featureFlags);
146
+
147
+ if (this.#initialOptions.workerFarm) {
148
+ if (this.#initialOptions.workerFarm.ending) {
149
+ throw new Error('Supplied WorkerFarm is ending');
150
+ }
151
+ this.#farm = this.#initialOptions.workerFarm;
152
+ } else {
153
+ this.#farm = createWorkerFarm({
154
+ shouldPatchConsole: resolvedOptions.shouldPatchConsole,
155
+ shouldTrace: resolvedOptions.shouldTrace,
156
+ });
157
+ }
158
+
159
+ await resolvedOptions.cache.ensure();
160
+
161
+ let {dispose: disposeOptions, ref: optionsRef} =
162
+ await this.#farm.createSharedReference(resolvedOptions, false);
163
+ this.#optionsRef = optionsRef;
164
+
165
+ this.#disposable = new Disposable();
166
+ if (this.#initialOptions.workerFarm) {
167
+ // If we don't own the farm, dispose of only these references when
168
+ // Atlaspack ends.
169
+ this.#disposable.add(disposeOptions);
170
+ } else {
171
+ // Otherwise, when shutting down, end the entire farm we created.
172
+ this.#disposable.add(() => this.#farm.end());
173
+ }
174
+
175
+ this.#watchEvents = new ValueEmitter();
176
+ this.#disposable.add(() => this.#watchEvents.dispose());
177
+
178
+ this.#reporterRunner = new ReporterRunner({
179
+ options: resolvedOptions,
180
+ reporters: await this.#config.getReporters(),
181
+ workerFarm: this.#farm,
182
+ });
183
+ this.#disposable.add(this.#reporterRunner);
184
+
185
+ logger.verbose({
186
+ origin: '@atlaspack/core',
187
+ message: 'Intializing request tracker...',
188
+ });
189
+
190
+ this.#requestTracker = await RequestTracker.init({
191
+ farm: this.#farm,
192
+ options: resolvedOptions,
193
+ rustAtlaspack,
194
+ });
195
+
196
+ this.#initialized = true;
197
+ }
198
+
199
+ async run(): Promise<BuildSuccessEvent> {
200
+ let startTime = Date.now();
201
+ if (!this.#initialized) {
202
+ await this._init();
203
+ }
204
+
205
+ let result = await this._build({startTime});
206
+
207
+ await this.#requestTracker.writeToCache();
208
+ await this._end();
209
+
210
+ if (result.type === 'buildFailure') {
211
+ throw new BuildError(result.diagnostics);
212
+ }
213
+
214
+ return result;
215
+ }
216
+
217
+ async _end(): Promise<void> {
218
+ this.#initialized = false;
219
+
220
+ await this.#disposable.dispose();
221
+ }
222
+
223
+ async writeRequestTrackerToCache(): Promise<void> {
224
+ if (this.#watchQueue.getNumWaiting() === 0) {
225
+ // If there's no queued events, we are safe to write the request graph to disk
226
+ const abortController = new AbortController();
227
+
228
+ const unsubscribe = this.#watchQueue.subscribeToAdd(() => {
229
+ abortController.abort();
230
+ });
231
+
232
+ try {
233
+ await this.#requestTracker.writeToCache(abortController.signal);
234
+ } catch (err) {
235
+ if (!abortController.signal.aborted) {
236
+ // We expect abort errors if we interrupt the cache write
237
+ throw err;
238
+ }
239
+ }
240
+
241
+ unsubscribe();
242
+ }
243
+ }
244
+
245
+ async _startNextBuild(): Promise<?BuildEvent> {
246
+ this.#watchAbortController = new AbortController();
247
+ await this.#farm.callAllWorkers('clearConfigCache', []);
248
+
249
+ try {
250
+ let buildEvent = await this._build({
251
+ signal: this.#watchAbortController.signal,
252
+ });
253
+
254
+ this.#watchEvents.emit({
255
+ buildEvent,
256
+ });
257
+
258
+ return buildEvent;
259
+ } catch (err) {
260
+ // Ignore BuildAbortErrors and only emit critical errors.
261
+ if (!(err instanceof BuildAbortError)) {
262
+ throw err;
263
+ }
264
+ } finally {
265
+ // If the build passes or fails, we want to cache the request graph
266
+ await this.writeRequestTrackerToCache();
267
+ }
268
+ }
269
+
270
+ async watch(
271
+ cb?: (err: ?Error, buildEvent?: BuildEvent) => mixed,
272
+ ): Promise<AsyncSubscription> {
273
+ if (!this.#initialized) {
274
+ await this._init();
275
+ }
276
+
277
+ let watchEventsDisposable;
278
+ if (cb) {
279
+ watchEventsDisposable = this.#watchEvents.addListener(
280
+ ({error, buildEvent}) => cb(error, buildEvent),
281
+ );
282
+ }
283
+
284
+ if (this.#watcherCount === 0) {
285
+ this.#watcherSubscription = await this._getWatcherSubscription();
286
+ await this.#reporterRunner.report({type: 'watchStart'});
287
+
288
+ // Kick off a first build, but don't await its results. Its results will
289
+ // be provided to the callback.
290
+ this.#watchQueue.add(() => this._startNextBuild());
291
+ this.#watchQueue.run();
292
+ }
293
+
294
+ this.#watcherCount++;
295
+
296
+ let unsubscribePromise;
297
+ const unsubscribe = async () => {
298
+ if (watchEventsDisposable) {
299
+ watchEventsDisposable.dispose();
300
+ }
301
+
302
+ this.#watcherCount--;
303
+ if (this.#watcherCount === 0) {
304
+ await nullthrows(this.#watcherSubscription).unsubscribe();
305
+ this.#watcherSubscription = null;
306
+ await this.#reporterRunner.report({type: 'watchEnd'});
307
+ this.#watchAbortController.abort();
308
+ await this.#watchQueue.run();
309
+ await this._end();
310
+ }
311
+ };
312
+
313
+ return {
314
+ unsubscribe() {
315
+ if (unsubscribePromise == null) {
316
+ unsubscribePromise = unsubscribe();
317
+ }
318
+
319
+ return unsubscribePromise;
320
+ },
321
+ };
322
+ }
323
+
324
+ async _build({
325
+ signal,
326
+ startTime = Date.now(),
327
+ }: {|
328
+ signal?: AbortSignal,
329
+ startTime?: number,
330
+ |} = {
331
+ /*::...null*/
332
+ }): Promise<BuildEvent> {
333
+ this.#requestTracker.setSignal(signal);
334
+ let options = nullthrows(this.#resolvedOptions);
335
+ try {
336
+ if (options.shouldProfile) {
337
+ await this.startProfiling();
338
+ }
339
+ if (options.shouldTrace) {
340
+ tracer.enable();
341
+ }
342
+ await this.#reporterRunner.report({
343
+ type: 'buildStart',
344
+ });
345
+
346
+ this.#requestTracker.graph.invalidateOnBuildNodes();
347
+
348
+ let request = createAtlaspackBuildRequest({
349
+ optionsRef: this.#optionsRef,
350
+ requestedAssetIds: this.#requestedAssetIds,
351
+ signal,
352
+ });
353
+
354
+ let {bundleGraph, bundleInfo, changedAssets, assetRequests} =
355
+ await this.#requestTracker.runRequest(request, {force: true});
356
+
357
+ this.#requestedAssetIds.clear();
358
+
359
+ await dumpGraphToGraphViz(
360
+ // $FlowFixMe
361
+ this.#requestTracker.graph,
362
+ 'RequestGraph',
363
+ requestGraphEdgeTypes,
364
+ );
365
+
366
+ let event = {
367
+ type: 'buildSuccess',
368
+ changedAssets: new Map(
369
+ Array.from(changedAssets).map(([id, asset]) => [
370
+ id,
371
+ assetFromValue(asset, options),
372
+ ]),
373
+ ),
374
+ bundleGraph: new BundleGraph<IPackagedBundle>(
375
+ bundleGraph,
376
+ (bundle, bundleGraph, options) =>
377
+ PackagedBundle.getWithInfo(
378
+ bundle,
379
+ bundleGraph,
380
+ options,
381
+ bundleInfo.get(bundle.id),
382
+ ),
383
+ options,
384
+ ),
385
+ buildTime: Date.now() - startTime,
386
+ requestBundle: async bundle => {
387
+ let bundleNode = bundleGraph._graph.getNodeByContentKey(bundle.id);
388
+ invariant(bundleNode?.type === 'bundle', 'Bundle does not exist');
389
+
390
+ if (!bundleNode.value.isPlaceholder) {
391
+ // Nothing to do.
392
+ return {
393
+ type: 'buildSuccess',
394
+ changedAssets: new Map(),
395
+ bundleGraph: event.bundleGraph,
396
+ buildTime: 0,
397
+ requestBundle: event.requestBundle,
398
+ unstable_requestStats: {},
399
+ };
400
+ }
401
+
402
+ for (let assetId of bundleNode.value.entryAssetIds) {
403
+ this.#requestedAssetIds.add(assetId);
404
+ }
405
+
406
+ if (this.#watchQueue.getNumWaiting() === 0) {
407
+ if (this.#watchAbortController) {
408
+ this.#watchAbortController.abort();
409
+ }
410
+
411
+ this.#watchQueue.add(() => this._startNextBuild());
412
+ }
413
+
414
+ let results = await this.#watchQueue.run();
415
+ let result = results.filter(Boolean).pop();
416
+ if (result.type === 'buildFailure') {
417
+ throw new BuildError(result.diagnostics);
418
+ }
419
+
420
+ return result;
421
+ },
422
+ unstable_requestStats: this.#requestTracker.flushStats(),
423
+ };
424
+
425
+ await this.#reporterRunner.report(event);
426
+ await this.#requestTracker.runRequest(
427
+ createValidationRequest({optionsRef: this.#optionsRef, assetRequests}),
428
+ {force: assetRequests.length > 0},
429
+ );
430
+
431
+ if (this.#reporterRunner.errors.length) {
432
+ throw this.#reporterRunner.errors;
433
+ }
434
+
435
+ return event;
436
+ } catch (e) {
437
+ if (e instanceof BuildAbortError) {
438
+ throw e;
439
+ }
440
+
441
+ let diagnostic = anyToDiagnostic(e);
442
+ let event = {
443
+ type: 'buildFailure',
444
+ diagnostics: Array.isArray(diagnostic) ? diagnostic : [diagnostic],
445
+ unstable_requestStats: this.#requestTracker.flushStats(),
446
+ };
447
+
448
+ await this.#reporterRunner.report(event);
449
+ return event;
450
+ } finally {
451
+ if (this.isProfiling) {
452
+ await this.stopProfiling();
453
+ }
454
+
455
+ await this.#farm.callAllWorkers('clearConfigCache', []);
456
+ }
457
+ }
458
+
459
+ async _getWatcherSubscription(): Promise<AsyncSubscription> {
460
+ invariant(this.#watcherSubscription == null);
461
+
462
+ let resolvedOptions = nullthrows(this.#resolvedOptions);
463
+ let opts = getWatcherOptions(resolvedOptions);
464
+ let sub = await resolvedOptions.inputFS.watch(
465
+ resolvedOptions.watchDir,
466
+ async (err, events) => {
467
+ if (err) {
468
+ logger.verbose({
469
+ message: `File watch event error occured`,
470
+ meta: {err},
471
+ });
472
+ this.#watchEvents.emit({error: err});
473
+ return;
474
+ }
475
+
476
+ logger.verbose({
477
+ message: `File watch event emitted with ${events.length} events. Sample event: [${events[0]?.type}] ${events[0]?.path}`,
478
+ });
479
+
480
+ let isInvalid = await this.#requestTracker.respondToFSEvents(
481
+ events,
482
+ Number.POSITIVE_INFINITY,
483
+ );
484
+ if (isInvalid && this.#watchQueue.getNumWaiting() === 0) {
485
+ if (this.#watchAbortController) {
486
+ this.#watchAbortController.abort();
487
+ }
488
+
489
+ this.#watchQueue.add(() => this._startNextBuild());
490
+ this.#watchQueue.run();
491
+ }
492
+ },
493
+ opts,
494
+ );
495
+ return {unsubscribe: () => sub.unsubscribe()};
496
+ }
497
+
498
+ // This is mainly for integration tests and it not public api!
499
+ _getResolvedAtlaspackOptions(): AtlaspackOptions {
500
+ return nullthrows(
501
+ this.#resolvedOptions,
502
+ 'Resolved options is null, please let atlaspack initialize before accessing this.',
503
+ );
504
+ }
505
+
506
+ async startProfiling(): Promise<void> {
507
+ if (this.isProfiling) {
508
+ throw new Error('Atlaspack is already profiling');
509
+ }
510
+
511
+ logger.info({origin: '@atlaspack/core', message: 'Starting profiling...'});
512
+ this.isProfiling = true;
513
+ await this.#farm.startProfile();
514
+ }
515
+
516
+ stopProfiling(): Promise<void> {
517
+ if (!this.isProfiling) {
518
+ throw new Error('Atlaspack is not profiling');
519
+ }
520
+
521
+ logger.info({origin: '@atlaspack/core', message: 'Stopping profiling...'});
522
+ this.isProfiling = false;
523
+ return this.#farm.endProfile();
524
+ }
525
+
526
+ takeHeapSnapshot(): Promise<void> {
527
+ logger.info({
528
+ origin: '@atlaspack/core',
529
+ message: 'Taking heap snapshot...',
530
+ });
531
+ return this.#farm.takeHeapSnapshot();
532
+ }
533
+
534
+ async unstable_transform(
535
+ options: AtlaspackTransformOptions,
536
+ ): Promise<Array<Asset>> {
537
+ if (!this.#initialized) {
538
+ await this._init();
539
+ }
540
+
541
+ let projectRoot = nullthrows(this.#resolvedOptions).projectRoot;
542
+ let request = createAssetRequest({
543
+ ...options,
544
+ filePath: toProjectPath(projectRoot, options.filePath),
545
+ optionsRef: this.#optionsRef,
546
+ env: createEnvironment({
547
+ ...options.env,
548
+ loc:
549
+ options.env?.loc != null
550
+ ? {
551
+ ...options.env.loc,
552
+ filePath: toProjectPath(projectRoot, options.env.loc.filePath),
553
+ }
554
+ : undefined,
555
+ }),
556
+ });
557
+
558
+ let res = await this.#requestTracker.runRequest(request, {
559
+ force: true,
560
+ });
561
+ return res.map(asset =>
562
+ assetFromValue(asset, nullthrows(this.#resolvedOptions)),
563
+ );
564
+ }
565
+
566
+ async unstable_resolve(
567
+ request: AtlaspackResolveOptions,
568
+ ): Promise<?AtlaspackResolveResult> {
569
+ if (!this.#initialized) {
570
+ await this._init();
571
+ }
572
+
573
+ let projectRoot = nullthrows(this.#resolvedOptions).projectRoot;
574
+ if (request.resolveFrom == null && path.isAbsolute(request.specifier)) {
575
+ request.specifier = fromProjectPathRelative(
576
+ toProjectPath(projectRoot, request.specifier),
577
+ );
578
+ }
579
+
580
+ let dependency = createDependency(projectRoot, {
581
+ ...request,
582
+ env: createEnvironment({
583
+ ...request.env,
584
+ loc:
585
+ request.env?.loc != null
586
+ ? {
587
+ ...request.env.loc,
588
+ filePath: toProjectPath(projectRoot, request.env.loc.filePath),
589
+ }
590
+ : undefined,
591
+ }),
592
+ });
593
+
594
+ let req = createPathRequest({
595
+ dependency,
596
+ name: request.specifier,
597
+ });
598
+
599
+ let res = await this.#requestTracker.runRequest(req, {
600
+ force: true,
601
+ });
602
+ if (!res) {
603
+ return null;
604
+ }
605
+
606
+ return {
607
+ filePath: fromProjectPath(projectRoot, res.filePath),
608
+ code: res.code,
609
+ query: res.query,
610
+ sideEffects: res.sideEffects,
611
+ };
612
+ }
613
+ }
614
+
615
+ export class BuildError extends ThrowableDiagnostic {
616
+ constructor(diagnostic: Array<Diagnostic> | Diagnostic) {
617
+ super({diagnostic});
618
+ this.name = 'BuildError';
619
+ }
620
+ }
621
+
622
+ export function createWorkerFarm(
623
+ options: $Shape<FarmOptions> = {},
624
+ ): WorkerFarm {
625
+ return new WorkerFarm({
626
+ ...options,
627
+ // $FlowFixMe
628
+ workerPath: process.browser
629
+ ? '@atlaspack/core/src/worker.js'
630
+ : require.resolve('./worker'),
631
+ });
632
+ }