@atlaspack/core 2.32.1 → 2.33.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/CHANGELOG.md +46 -0
- package/dist/atlaspack-v3/AtlaspackV3.js +3 -0
- package/dist/atlaspack-v3/worker/worker.js +1 -0
- package/dist/requests/AtlaspackBuildRequest.js +12 -5
- package/dist/requests/BundleGraphRequest.js +15 -78
- package/dist/requests/BundleGraphRequestRust.js +320 -0
- package/dist/requests/BundleGraphRequestUtils.js +131 -0
- package/lib/atlaspack-v3/AtlaspackV3.js +3 -0
- package/lib/atlaspack-v3/worker/worker.js +2 -1
- package/lib/requests/AtlaspackBuildRequest.js +6 -1
- package/lib/requests/BundleGraphRequest.js +15 -87
- package/lib/requests/BundleGraphRequestRust.js +378 -0
- package/lib/requests/BundleGraphRequestUtils.js +151 -0
- package/lib/types/atlaspack-v3/AtlaspackV3.d.ts +1 -0
- package/lib/types/atlaspack-v3/worker/worker.d.ts +1 -0
- package/lib/types/requests/BundleGraphRequestRust.d.ts +34 -0
- package/lib/types/requests/BundleGraphRequestUtils.d.ts +31 -0
- package/package.json +15 -15
- package/src/atlaspack-v3/AtlaspackV3.ts +5 -0
- package/src/atlaspack-v3/worker/worker.ts +1 -0
- package/src/requests/AtlaspackBuildRequest.ts +13 -5
- package/src/requests/BundleGraphRequest.ts +25 -100
- package/src/requests/BundleGraphRequestRust.ts +464 -0
- package/src/requests/BundleGraphRequestUtils.ts +167 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -9,6 +9,7 @@ import type BundleGraph from '../BundleGraph';
|
|
|
9
9
|
import createBundleGraphRequest, {
|
|
10
10
|
BundleGraphResult,
|
|
11
11
|
} from './BundleGraphRequest';
|
|
12
|
+
import createBundleGraphRequestRust from './BundleGraphRequestRust';
|
|
12
13
|
import createWriteBundlesRequest from './WriteBundlesRequest';
|
|
13
14
|
import {assertSignalNotAborted} from '../utils';
|
|
14
15
|
import dumpGraphToGraphViz from '../dumpGraphToGraphViz';
|
|
@@ -73,11 +74,18 @@ async function run({
|
|
|
73
74
|
}: RunInput<AtlaspackBuildRequestResult>) {
|
|
74
75
|
let {optionsRef, requestedAssetIds, signal} = input;
|
|
75
76
|
|
|
76
|
-
let bundleGraphRequest =
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
let bundleGraphRequest =
|
|
78
|
+
getFeatureFlag('nativeBundling') && rustAtlaspack
|
|
79
|
+
? createBundleGraphRequestRust({
|
|
80
|
+
optionsRef,
|
|
81
|
+
requestedAssetIds,
|
|
82
|
+
signal,
|
|
83
|
+
})
|
|
84
|
+
: createBundleGraphRequest({
|
|
85
|
+
optionsRef,
|
|
86
|
+
requestedAssetIds,
|
|
87
|
+
signal,
|
|
88
|
+
});
|
|
81
89
|
|
|
82
90
|
let {bundleGraph, changedAssets, assetRequests}: BundleGraphResult =
|
|
83
91
|
await api.runRequest(bundleGraphRequest, {
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import type {Async
|
|
1
|
+
import type {Async} from '@atlaspack/types';
|
|
2
2
|
import type {SharedReference} from '@atlaspack/workers';
|
|
3
3
|
import type {AtlaspackConfig, LoadedPlugin} from '../AtlaspackConfig';
|
|
4
4
|
import type {StaticRunOpts, RunAPI} from '../RequestTracker';
|
|
5
5
|
import type {
|
|
6
6
|
Asset,
|
|
7
7
|
AssetGroup,
|
|
8
|
-
Bundle as InternalBundle,
|
|
9
8
|
Config,
|
|
10
9
|
DevDepRequest,
|
|
11
10
|
AtlaspackOptions,
|
|
@@ -21,13 +20,10 @@ import {instrumentAsync, PluginLogger} from '@atlaspack/logger';
|
|
|
21
20
|
import {getFeatureFlag} from '@atlaspack/feature-flags';
|
|
22
21
|
import ThrowableDiagnostic, {errorToDiagnostic} from '@atlaspack/diagnostic';
|
|
23
22
|
import AssetGraph from '../AssetGraph';
|
|
24
|
-
import BundleGraph from '../public/BundleGraph';
|
|
25
23
|
import InternalBundleGraph, {bundleGraphEdgeTypes} from '../BundleGraph';
|
|
26
24
|
import MutableBundleGraph from '../public/MutableBundleGraph';
|
|
27
|
-
import {Bundle, NamedBundle} from '../public/Bundle';
|
|
28
25
|
import {report} from '../ReporterRunner';
|
|
29
26
|
import dumpGraphToGraphViz from '../dumpGraphToGraphViz';
|
|
30
|
-
import {unique, setSymmetricDifference} from '@atlaspack/utils';
|
|
31
27
|
import {hashString} from '@atlaspack/rust';
|
|
32
28
|
import PluginOptions from '../public/PluginOptions';
|
|
33
29
|
import applyRuntimes from '../applyRuntimes';
|
|
@@ -42,17 +38,18 @@ import {
|
|
|
42
38
|
invalidateDevDeps,
|
|
43
39
|
runDevDepRequest,
|
|
44
40
|
} from './DevDepRequest';
|
|
45
|
-
import {createConfig} from '../InternalConfig';
|
|
46
41
|
import {
|
|
47
42
|
loadPluginConfig,
|
|
48
43
|
runConfigRequest,
|
|
49
44
|
PluginWithLoadConfig,
|
|
50
45
|
} from './ConfigRequest';
|
|
46
|
+
import {fromProjectPathRelative} from '../projectPath';
|
|
51
47
|
import {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
48
|
+
validateBundles,
|
|
49
|
+
nameBundle,
|
|
50
|
+
loadPluginConfigWithDevDeps,
|
|
51
|
+
runDevDepRequest as runDevDepRequestShared,
|
|
52
|
+
} from './BundleGraphRequestUtils';
|
|
56
53
|
import createAssetGraphRequestJS from './AssetGraphRequest';
|
|
57
54
|
import {createAssetGraphRequestRust} from './AssetGraphRequestRust';
|
|
58
55
|
import {tracer, PluginTracer} from '@atlaspack/profiler';
|
|
@@ -319,30 +316,18 @@ class BundlerRunner {
|
|
|
319
316
|
}
|
|
320
317
|
|
|
321
318
|
async loadConfig<T extends PluginWithLoadConfig>(plugin: LoadedPlugin<T>) {
|
|
322
|
-
|
|
323
|
-
plugin
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
let devDepRequest = await createDevDependency(
|
|
331
|
-
devDep,
|
|
332
|
-
this.previousDevDeps,
|
|
333
|
-
this.options,
|
|
334
|
-
);
|
|
335
|
-
await this.runDevDepRequest(devDepRequest);
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
this.configs.set(plugin.name, config);
|
|
319
|
+
await loadPluginConfigWithDevDeps(
|
|
320
|
+
plugin,
|
|
321
|
+
this.options,
|
|
322
|
+
this.api,
|
|
323
|
+
this.previousDevDeps,
|
|
324
|
+
this.devDepRequests,
|
|
325
|
+
this.configs,
|
|
326
|
+
);
|
|
339
327
|
}
|
|
340
328
|
|
|
341
329
|
async runDevDepRequest(devDepRequest: DevDepRequest | DevDepRequestRef) {
|
|
342
|
-
|
|
343
|
-
let key = `${specifier}:${fromProjectPathRelative(resolveFrom)}`;
|
|
344
|
-
this.devDepRequests.set(key, devDepRequest);
|
|
345
|
-
await runDevDepRequest(this.api, devDepRequest);
|
|
330
|
+
await runDevDepRequestShared(this.api, devDepRequest, this.devDepRequests);
|
|
346
331
|
}
|
|
347
332
|
|
|
348
333
|
async bundle({
|
|
@@ -520,7 +505,14 @@ class BundlerRunner {
|
|
|
520
505
|
let bundles = internalBundleGraph.getBundles({includeInline: true});
|
|
521
506
|
await Promise.all(
|
|
522
507
|
bundles.map((bundle) =>
|
|
523
|
-
|
|
508
|
+
nameBundle(
|
|
509
|
+
namers,
|
|
510
|
+
bundle,
|
|
511
|
+
internalBundleGraph,
|
|
512
|
+
this.options,
|
|
513
|
+
this.pluginOptions,
|
|
514
|
+
this.configs,
|
|
515
|
+
),
|
|
524
516
|
),
|
|
525
517
|
);
|
|
526
518
|
|
|
@@ -551,7 +543,7 @@ class BundlerRunner {
|
|
|
551
543
|
await this.runDevDepRequest(devDepRequest);
|
|
552
544
|
}
|
|
553
545
|
|
|
554
|
-
|
|
546
|
+
validateBundles(internalBundleGraph);
|
|
555
547
|
|
|
556
548
|
// Pre-compute the hashes for each bundle so they are only computed once and shared between workers.
|
|
557
549
|
internalBundleGraph.getBundleGraphHash();
|
|
@@ -581,71 +573,4 @@ class BundlerRunner {
|
|
|
581
573
|
assetRequests,
|
|
582
574
|
};
|
|
583
575
|
}
|
|
584
|
-
|
|
585
|
-
validateBundles(bundleGraph: InternalBundleGraph): void {
|
|
586
|
-
let bundles = bundleGraph.getBundles();
|
|
587
|
-
|
|
588
|
-
let bundleNames = bundles.map((b) =>
|
|
589
|
-
joinProjectPath(b.target.distDir, nullthrows(b.name)),
|
|
590
|
-
);
|
|
591
|
-
assert.deepEqual(
|
|
592
|
-
bundleNames,
|
|
593
|
-
unique(bundleNames),
|
|
594
|
-
'Bundles must have unique name. Conflicting names: ' +
|
|
595
|
-
[
|
|
596
|
-
...setSymmetricDifference(
|
|
597
|
-
new Set(bundleNames),
|
|
598
|
-
new Set(unique(bundleNames)),
|
|
599
|
-
),
|
|
600
|
-
].join(),
|
|
601
|
-
);
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
async nameBundle(
|
|
605
|
-
namers: Array<LoadedPlugin<Namer<unknown>>>,
|
|
606
|
-
internalBundle: InternalBundle,
|
|
607
|
-
internalBundleGraph: InternalBundleGraph,
|
|
608
|
-
): Promise<void> {
|
|
609
|
-
let bundle = Bundle.get(internalBundle, internalBundleGraph, this.options);
|
|
610
|
-
let bundleGraph = new BundleGraph<IBundle>(
|
|
611
|
-
internalBundleGraph,
|
|
612
|
-
NamedBundle.get.bind(NamedBundle),
|
|
613
|
-
this.options,
|
|
614
|
-
);
|
|
615
|
-
|
|
616
|
-
for (let namer of namers) {
|
|
617
|
-
let measurement;
|
|
618
|
-
try {
|
|
619
|
-
measurement = tracer.createMeasurement(namer.name, 'namer', bundle.id);
|
|
620
|
-
let name = await namer.plugin.name({
|
|
621
|
-
bundle,
|
|
622
|
-
bundleGraph,
|
|
623
|
-
config: this.configs.get(namer.name)?.result,
|
|
624
|
-
options: this.pluginOptions,
|
|
625
|
-
logger: new PluginLogger({origin: namer.name}),
|
|
626
|
-
tracer: new PluginTracer({origin: namer.name, category: 'namer'}),
|
|
627
|
-
});
|
|
628
|
-
|
|
629
|
-
if (name != null) {
|
|
630
|
-
internalBundle.name = name;
|
|
631
|
-
let {hashReference} = internalBundle;
|
|
632
|
-
internalBundle.displayName = name.includes(hashReference)
|
|
633
|
-
? name.replace(hashReference, '[hash]')
|
|
634
|
-
: name;
|
|
635
|
-
|
|
636
|
-
return;
|
|
637
|
-
}
|
|
638
|
-
} catch (e: any) {
|
|
639
|
-
throw new ThrowableDiagnostic({
|
|
640
|
-
diagnostic: errorToDiagnostic(e, {
|
|
641
|
-
origin: namer.name,
|
|
642
|
-
}),
|
|
643
|
-
});
|
|
644
|
-
} finally {
|
|
645
|
-
measurement && measurement.end();
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
throw new Error('Unable to name bundle');
|
|
650
|
-
}
|
|
651
576
|
}
|
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
import invariant from 'assert';
|
|
2
|
+
|
|
3
|
+
import ThrowableDiagnostic from '@atlaspack/diagnostic';
|
|
4
|
+
import type {Async} from '@atlaspack/types';
|
|
5
|
+
import {ContentGraph} from '@atlaspack/graph';
|
|
6
|
+
import {instrument, instrumentAsync, PluginLogger} from '@atlaspack/logger';
|
|
7
|
+
import {getFeatureFlag} from '@atlaspack/feature-flags';
|
|
8
|
+
|
|
9
|
+
import InternalBundleGraph, {bundleGraphEdgeTypes} from '../BundleGraph';
|
|
10
|
+
import dumpGraphToGraphViz from '../dumpGraphToGraphViz';
|
|
11
|
+
import nullthrows from 'nullthrows';
|
|
12
|
+
import {hashString} from '@atlaspack/rust';
|
|
13
|
+
import PluginOptions from '../public/PluginOptions';
|
|
14
|
+
import applyRuntimes from '../applyRuntimes';
|
|
15
|
+
import {ATLASPACK_VERSION} from '../constants';
|
|
16
|
+
import {optionsProxy} from '../utils';
|
|
17
|
+
import {
|
|
18
|
+
createDevDependency,
|
|
19
|
+
getDevDepRequests,
|
|
20
|
+
invalidateDevDeps,
|
|
21
|
+
} from './DevDepRequest';
|
|
22
|
+
import {PluginWithLoadConfig} from './ConfigRequest';
|
|
23
|
+
import {requestTypes, StaticRunOpts} from '../RequestTracker';
|
|
24
|
+
import type {AtlaspackV3} from '../atlaspack-v3';
|
|
25
|
+
import type {BundleGraphResult} from './BundleGraphRequest';
|
|
26
|
+
import createAtlaspackConfigRequest, {
|
|
27
|
+
getCachedAtlaspackConfig,
|
|
28
|
+
ConfigAndCachePath,
|
|
29
|
+
} from './AtlaspackConfigRequest';
|
|
30
|
+
import {
|
|
31
|
+
validateBundles,
|
|
32
|
+
nameBundle,
|
|
33
|
+
loadPluginConfigWithDevDeps,
|
|
34
|
+
runDevDepRequest,
|
|
35
|
+
} from './BundleGraphRequestUtils';
|
|
36
|
+
import {toEnvironmentRef} from '../EnvironmentManager';
|
|
37
|
+
import {getEnvironmentHash} from '../Environment';
|
|
38
|
+
import type {
|
|
39
|
+
Asset,
|
|
40
|
+
BundleGraphNode,
|
|
41
|
+
BundleNode,
|
|
42
|
+
BundleGroupNode,
|
|
43
|
+
DependencyNode,
|
|
44
|
+
AssetNode,
|
|
45
|
+
Environment,
|
|
46
|
+
} from '../types';
|
|
47
|
+
import {tracer, PluginTracer} from '@atlaspack/profiler';
|
|
48
|
+
import ThrowableDiagnostic2, {errorToDiagnostic} from '@atlaspack/diagnostic';
|
|
49
|
+
import type {AtlaspackConfig, LoadedPlugin} from '../AtlaspackConfig';
|
|
50
|
+
import type {RunAPI} from '../RequestTracker';
|
|
51
|
+
import type {
|
|
52
|
+
Config,
|
|
53
|
+
DevDepRequest,
|
|
54
|
+
AtlaspackOptions,
|
|
55
|
+
DevDepRequestRef,
|
|
56
|
+
Bundle as InternalBundle,
|
|
57
|
+
} from '../types';
|
|
58
|
+
import type {Namer, Bundle as IBundle} from '@atlaspack/types';
|
|
59
|
+
import BundleGraph from '../public/BundleGraph';
|
|
60
|
+
import {Bundle, NamedBundle} from '../public/Bundle';
|
|
61
|
+
|
|
62
|
+
type BundleGraphRequestInput = {
|
|
63
|
+
requestedAssetIds: Set<string>;
|
|
64
|
+
signal?: AbortSignal;
|
|
65
|
+
optionsRef: any;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
type RunInput = {
|
|
69
|
+
input: BundleGraphRequestInput;
|
|
70
|
+
} & StaticRunOpts<BundleGraphResult>;
|
|
71
|
+
|
|
72
|
+
type BundleGraphRequestRust = {
|
|
73
|
+
id: string;
|
|
74
|
+
readonly type: typeof requestTypes.bundle_graph_request;
|
|
75
|
+
run: (arg1: RunInput) => Async<BundleGraphResult>;
|
|
76
|
+
input: BundleGraphRequestInput;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
type SerializedBundleGraph = {
|
|
80
|
+
nodes: Array<any>;
|
|
81
|
+
edges: Array<number>;
|
|
82
|
+
publicIdByAssetId: {[k: string]: string};
|
|
83
|
+
assetPublicIds: Array<string>;
|
|
84
|
+
hadPreviousGraph: boolean;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export default function createBundleGraphRequestRust(
|
|
88
|
+
input: BundleGraphRequestInput,
|
|
89
|
+
): BundleGraphRequestRust {
|
|
90
|
+
return {
|
|
91
|
+
type: requestTypes.bundle_graph_request,
|
|
92
|
+
id: 'BundleGraphRust',
|
|
93
|
+
run: async (runInput) => {
|
|
94
|
+
const {api, options, rustAtlaspack} = runInput;
|
|
95
|
+
invariant(rustAtlaspack, 'BundleGraphRequestRust requires rustAtlaspack');
|
|
96
|
+
|
|
97
|
+
let {bundleGraphPromise, commitPromise} =
|
|
98
|
+
await rustAtlaspack.buildBundleGraph();
|
|
99
|
+
let [serializedBundleGraph, bundleGraphError] =
|
|
100
|
+
(await bundleGraphPromise) as [SerializedBundleGraph, Error | null];
|
|
101
|
+
|
|
102
|
+
if (bundleGraphError) {
|
|
103
|
+
throw new ThrowableDiagnostic({diagnostic: bundleGraphError});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Don’t reuse previous JS result yet; we just rebuild from scratch.
|
|
107
|
+
let {bundleGraph, changedAssets} = instrument(
|
|
108
|
+
'atlaspack_v3_getBundleGraph',
|
|
109
|
+
() => getBundleGraph(serializedBundleGraph),
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
const runner = new NativeBundlerRunner(
|
|
113
|
+
{api, options} as any,
|
|
114
|
+
input.optionsRef,
|
|
115
|
+
);
|
|
116
|
+
await runner.loadConfigs();
|
|
117
|
+
|
|
118
|
+
// Name all bundles
|
|
119
|
+
const namers = await runner.config.getNamers();
|
|
120
|
+
const bundles = bundleGraph.getBundles({includeInline: true});
|
|
121
|
+
await Promise.all(
|
|
122
|
+
bundles.map((b) =>
|
|
123
|
+
nameBundle(
|
|
124
|
+
namers,
|
|
125
|
+
b,
|
|
126
|
+
bundleGraph,
|
|
127
|
+
options,
|
|
128
|
+
runner.pluginOptions,
|
|
129
|
+
runner.configs,
|
|
130
|
+
),
|
|
131
|
+
),
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
// Apply runtimes
|
|
135
|
+
const changedRuntimes = await instrumentAsync('applyRuntimes', () =>
|
|
136
|
+
applyRuntimes({
|
|
137
|
+
bundleGraph,
|
|
138
|
+
api,
|
|
139
|
+
config: runner.config,
|
|
140
|
+
options,
|
|
141
|
+
optionsRef: input.optionsRef,
|
|
142
|
+
pluginOptions: runner.pluginOptions,
|
|
143
|
+
previousDevDeps: runner.previousDevDeps,
|
|
144
|
+
devDepRequests: runner.devDepRequests,
|
|
145
|
+
configs: runner.configs,
|
|
146
|
+
}),
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
// Add dev deps for namers
|
|
150
|
+
for (const namer of namers) {
|
|
151
|
+
const devDepRequest = await createDevDependency(
|
|
152
|
+
{
|
|
153
|
+
specifier: namer.name,
|
|
154
|
+
resolveFrom: namer.resolveFrom,
|
|
155
|
+
},
|
|
156
|
+
runner.previousDevDeps,
|
|
157
|
+
options,
|
|
158
|
+
);
|
|
159
|
+
await runDevDepRequest(api, devDepRequest, runner.devDepRequests);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
validateBundles(bundleGraph);
|
|
163
|
+
bundleGraph.getBundleGraphHash();
|
|
164
|
+
|
|
165
|
+
await dumpGraphToGraphViz(
|
|
166
|
+
// @ts-expect-error Accessing internal graph for debug output
|
|
167
|
+
bundleGraph._graph,
|
|
168
|
+
'after_runtimes_native',
|
|
169
|
+
bundleGraphEdgeTypes,
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
let [_commitResult, commitError] = await commitPromise;
|
|
173
|
+
if (commitError) {
|
|
174
|
+
throw new ThrowableDiagnostic({
|
|
175
|
+
diagnostic: {
|
|
176
|
+
message:
|
|
177
|
+
'Error committing bundle graph in Rust: ' + commitError.message,
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
bundleGraph,
|
|
184
|
+
// Not accurate yet — ok for now.
|
|
185
|
+
assetGraphBundlingVersion: 0,
|
|
186
|
+
changedAssets: changedRuntimes,
|
|
187
|
+
assetRequests: [],
|
|
188
|
+
};
|
|
189
|
+
},
|
|
190
|
+
input,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function mapSymbols({exported, ...symbol}: any) {
|
|
195
|
+
let jsSymbol: any = {
|
|
196
|
+
local: symbol.local ?? undefined,
|
|
197
|
+
loc: symbol.loc ?? undefined,
|
|
198
|
+
isWeak: symbol.isWeak,
|
|
199
|
+
meta: {
|
|
200
|
+
isEsm: symbol.isEsmExport,
|
|
201
|
+
isStaticBindingSafe: symbol.isStaticBindingSafe,
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
if (symbol.exported) {
|
|
206
|
+
jsSymbol.exported = symbol.exported;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return [exported, jsSymbol];
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function normalizeEnv(env: Environment): any {
|
|
213
|
+
if (!env) return env;
|
|
214
|
+
env.id = env.id || getEnvironmentHash(env);
|
|
215
|
+
return toEnvironmentRef(env);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export function getBundleGraph(serializedGraph: SerializedBundleGraph): {
|
|
219
|
+
bundleGraph: InternalBundleGraph;
|
|
220
|
+
changedAssets: Map<string, Asset>;
|
|
221
|
+
} {
|
|
222
|
+
// Build a fresh internal bundle graph.
|
|
223
|
+
const publicIdByAssetId = new Map(
|
|
224
|
+
Object.entries(serializedGraph.publicIdByAssetId ?? {}),
|
|
225
|
+
);
|
|
226
|
+
const assetPublicIds = new Set(serializedGraph.assetPublicIds ?? []);
|
|
227
|
+
|
|
228
|
+
// BundleGraph constructor expects a ContentGraph under `_graph`.
|
|
229
|
+
// We reuse the internal graph class by creating an empty instance and then adding nodes.
|
|
230
|
+
const graph = new InternalBundleGraph({
|
|
231
|
+
// We intentionally start with an empty graph and add nodes/edges from the Rust payload.
|
|
232
|
+
// `ContentGraph` will allocate as needed.
|
|
233
|
+
graph: new ContentGraph(),
|
|
234
|
+
bundleContentHashes: new Map(),
|
|
235
|
+
publicIdByAssetId,
|
|
236
|
+
assetPublicIds,
|
|
237
|
+
conditions: new Map(),
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// Root must exist at node id 0.
|
|
241
|
+
const rootNodeId = graph._graph.addNodeByContentKey('@@root', {
|
|
242
|
+
id: '@@root',
|
|
243
|
+
type: 'root',
|
|
244
|
+
value: null,
|
|
245
|
+
});
|
|
246
|
+
graph._graph.setRootNodeId(rootNodeId);
|
|
247
|
+
|
|
248
|
+
let entry = 0;
|
|
249
|
+
const changedAssets = new Map<string, Asset>();
|
|
250
|
+
|
|
251
|
+
const decoder = new TextDecoder();
|
|
252
|
+
|
|
253
|
+
// Create nodes in order.
|
|
254
|
+
for (let i = 0; i < serializedGraph.nodes.length; i++) {
|
|
255
|
+
// Nodes come back as buffers (same as AssetGraphRequestRust)
|
|
256
|
+
let node = JSON.parse(decoder.decode(serializedGraph.nodes[i]));
|
|
257
|
+
|
|
258
|
+
if (node.type === 'root') {
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (node.type === 'entry') {
|
|
263
|
+
let id = 'entry:' + ++entry;
|
|
264
|
+
graph._graph.addNodeByContentKey(id, {id, type: 'root', value: null});
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (node.type === 'asset') {
|
|
269
|
+
let asset = node.value;
|
|
270
|
+
let id = asset.id;
|
|
271
|
+
|
|
272
|
+
asset.committed = true;
|
|
273
|
+
asset.contentKey = id;
|
|
274
|
+
asset.env = {...asset.env};
|
|
275
|
+
asset.env.id = getFeatureFlag('environmentDeduplication')
|
|
276
|
+
? getEnvironmentHash(asset.env)
|
|
277
|
+
: getEnvironmentHash(asset.env);
|
|
278
|
+
asset.env = normalizeEnv(asset.env);
|
|
279
|
+
asset.mapKey = `map:${asset.id}`;
|
|
280
|
+
asset.dependencies = new Map();
|
|
281
|
+
asset.meta.isV3 = true;
|
|
282
|
+
if (asset.symbols != null) {
|
|
283
|
+
asset.symbols = new Map(asset.symbols.map(mapSymbols));
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
changedAssets.set(id, asset);
|
|
287
|
+
|
|
288
|
+
const assetNode: AssetNode = {
|
|
289
|
+
id,
|
|
290
|
+
type: 'asset',
|
|
291
|
+
usedSymbols: new Set(),
|
|
292
|
+
usedSymbolsDownDirty: true,
|
|
293
|
+
usedSymbolsUpDirty: true,
|
|
294
|
+
value: asset,
|
|
295
|
+
};
|
|
296
|
+
graph._graph.addNodeByContentKey(id, assetNode);
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (node.type === 'dependency') {
|
|
301
|
+
let {dependency, id} = node.value;
|
|
302
|
+
dependency.id = id;
|
|
303
|
+
dependency.env = {...dependency.env};
|
|
304
|
+
dependency.env.id = getEnvironmentHash(dependency.env);
|
|
305
|
+
dependency.env = normalizeEnv(dependency.env);
|
|
306
|
+
if (dependency.symbols != null) {
|
|
307
|
+
dependency.symbols = new Map(dependency.symbols?.map(mapSymbols));
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
let usedSymbolsDown = new Set();
|
|
311
|
+
let usedSymbolsUp = new Map();
|
|
312
|
+
if (dependency.isEntry && dependency.isLibrary) {
|
|
313
|
+
usedSymbolsDown.add('*');
|
|
314
|
+
usedSymbolsUp.set('*', undefined);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const depNode: DependencyNode = {
|
|
318
|
+
id,
|
|
319
|
+
type: 'dependency',
|
|
320
|
+
deferred: false,
|
|
321
|
+
excluded: false,
|
|
322
|
+
hasDeferred: node.has_deferred,
|
|
323
|
+
// @ts-expect-error Flow types expect a more specific symbol set type
|
|
324
|
+
usedSymbolsDown,
|
|
325
|
+
usedSymbolsDownDirty: true,
|
|
326
|
+
usedSymbolsUp,
|
|
327
|
+
usedSymbolsUpDirtyDown: true,
|
|
328
|
+
usedSymbolsUpDirtyUp: true,
|
|
329
|
+
value: dependency,
|
|
330
|
+
};
|
|
331
|
+
graph._graph.addNodeByContentKey(id, depNode);
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (node.type === 'bundle') {
|
|
336
|
+
node.value.env = normalizeEnv(node.value.env);
|
|
337
|
+
node.value.target.env = normalizeEnv(node.value.target.env);
|
|
338
|
+
graph._graph.addNodeByContentKey(node.id, node as BundleNode);
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
if (node.type === 'bundle_group' || node.type === 'bundleGroup') {
|
|
343
|
+
// Rust serializer may emit bundleGroup nodes either as `{id,type,value:{...}}`
|
|
344
|
+
// or as `{type:"bundleGroup", id, target, entryAssetId}`.
|
|
345
|
+
if (node.value == null) {
|
|
346
|
+
node.value = {
|
|
347
|
+
target: node.target,
|
|
348
|
+
entryAssetId: node.entryAssetId ?? node.entry_asset_id,
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Normalize entry asset id field naming
|
|
353
|
+
if (
|
|
354
|
+
node.value.entryAssetId == null &&
|
|
355
|
+
node.value.entry_asset_id != null
|
|
356
|
+
) {
|
|
357
|
+
node.value.entryAssetId = node.value.entry_asset_id;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
node.value.target.env = normalizeEnv(node.value.target.env);
|
|
361
|
+
// Normalise to the expected snake_case type
|
|
362
|
+
node.type = 'bundle_group';
|
|
363
|
+
graph._graph.addNodeByContentKey(node.id, node as BundleGroupNode);
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Apply edges
|
|
369
|
+
for (let i = 0; i < serializedGraph.edges.length; i += 3) {
|
|
370
|
+
const from = serializedGraph.edges[i];
|
|
371
|
+
const to = serializedGraph.edges[i + 1];
|
|
372
|
+
const type = serializedGraph.edges[i + 2];
|
|
373
|
+
|
|
374
|
+
const fromNode = graph._graph.getNode(from);
|
|
375
|
+
const toNode = graph._graph.getNode(to);
|
|
376
|
+
|
|
377
|
+
if (fromNode?.type === 'asset' && toNode?.type === 'dependency') {
|
|
378
|
+
fromNode.value.dependencies.set(toNode.value.id, toNode.value);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// If we are adding a references edge, remove existing null edge.
|
|
382
|
+
if (
|
|
383
|
+
type === bundleGraphEdgeTypes.references &&
|
|
384
|
+
graph._graph.hasEdge(from, to, bundleGraphEdgeTypes.null)
|
|
385
|
+
) {
|
|
386
|
+
graph._graph.removeEdge(from, to, bundleGraphEdgeTypes.null);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
graph._graph.addEdge(from, to, type as any);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
return {bundleGraph: graph, changedAssets};
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
class NativeBundlerRunner {
|
|
396
|
+
options: AtlaspackOptions;
|
|
397
|
+
optionsRef: any;
|
|
398
|
+
config!: AtlaspackConfig;
|
|
399
|
+
pluginOptions: PluginOptions;
|
|
400
|
+
api: RunAPI<BundleGraphResult>;
|
|
401
|
+
previousDevDeps: Map<string, string>;
|
|
402
|
+
devDepRequests: Map<string, DevDepRequest | DevDepRequestRef>;
|
|
403
|
+
configs: Map<string, Config>;
|
|
404
|
+
cacheKey: string;
|
|
405
|
+
|
|
406
|
+
constructor({api, options}: any, optionsRef: any) {
|
|
407
|
+
this.options = options;
|
|
408
|
+
this.api = api;
|
|
409
|
+
this.optionsRef = optionsRef;
|
|
410
|
+
this.previousDevDeps = new Map();
|
|
411
|
+
this.devDepRequests = new Map();
|
|
412
|
+
this.configs = new Map();
|
|
413
|
+
this.pluginOptions = new PluginOptions(
|
|
414
|
+
optionsProxy(this.options, api.invalidateOnOptionChange),
|
|
415
|
+
);
|
|
416
|
+
|
|
417
|
+
const key = hashString(
|
|
418
|
+
`${ATLASPACK_VERSION}:BundleGraph:${
|
|
419
|
+
JSON.stringify(options.entries) ?? ''
|
|
420
|
+
}${options.mode}${options.shouldBuildLazily ? 'lazy' : 'eager'}`,
|
|
421
|
+
);
|
|
422
|
+
this.cacheKey = `BundleGraph/${ATLASPACK_VERSION}/${options.mode}/${key}`;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
async loadConfigs() {
|
|
426
|
+
const configResult = nullthrows(
|
|
427
|
+
await this.api.runRequest<null, ConfigAndCachePath>(
|
|
428
|
+
createAtlaspackConfigRequest(),
|
|
429
|
+
),
|
|
430
|
+
);
|
|
431
|
+
|
|
432
|
+
this.config = getCachedAtlaspackConfig(configResult, this.options);
|
|
433
|
+
|
|
434
|
+
const {devDeps, invalidDevDeps} = await getDevDepRequests(this.api);
|
|
435
|
+
this.previousDevDeps = devDeps;
|
|
436
|
+
invalidateDevDeps(invalidDevDeps, this.options, this.config);
|
|
437
|
+
|
|
438
|
+
const bundler = await this.config.getBundler();
|
|
439
|
+
await this.loadPluginConfig(bundler);
|
|
440
|
+
|
|
441
|
+
const namers = await this.config.getNamers();
|
|
442
|
+
for (const namer of namers) {
|
|
443
|
+
await this.loadPluginConfig(namer);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
const runtimes = await this.config.getRuntimes();
|
|
447
|
+
for (const runtime of runtimes) {
|
|
448
|
+
await this.loadPluginConfig(runtime);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
async loadPluginConfig<T extends PluginWithLoadConfig>(
|
|
453
|
+
plugin: LoadedPlugin<T>,
|
|
454
|
+
) {
|
|
455
|
+
await loadPluginConfigWithDevDeps(
|
|
456
|
+
plugin,
|
|
457
|
+
this.options,
|
|
458
|
+
this.api,
|
|
459
|
+
this.previousDevDeps,
|
|
460
|
+
this.devDepRequests,
|
|
461
|
+
this.configs,
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
}
|