@atlaspack/core 2.32.0 → 2.33.0
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 +50 -0
- package/dist/BundleGraph.js +78 -8
- package/dist/atlaspack-v3/AtlaspackV3.js +7 -4
- 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/dist/requests/PackageRequest.js +27 -10
- package/lib/BundleGraph.js +85 -8
- package/lib/atlaspack-v3/AtlaspackV3.js +9 -4
- 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/requests/PackageRequest.js +38 -10
- package/lib/types/BundleGraph.d.ts +34 -4
- package/lib/types/atlaspack-v3/AtlaspackV3.d.ts +4 -1
- 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/BundleGraph.ts +83 -8
- package/src/atlaspack-v3/AtlaspackV3.ts +17 -5
- 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/src/requests/PackageRequest.ts +20 -5
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.default = createBundleGraphRequestRust;
|
|
40
|
+
exports.getBundleGraph = getBundleGraph;
|
|
41
|
+
const assert_1 = __importDefault(require("assert"));
|
|
42
|
+
const diagnostic_1 = __importDefault(require("@atlaspack/diagnostic"));
|
|
43
|
+
const graph_1 = require("@atlaspack/graph");
|
|
44
|
+
const logger_1 = require("@atlaspack/logger");
|
|
45
|
+
const feature_flags_1 = require("@atlaspack/feature-flags");
|
|
46
|
+
const BundleGraph_1 = __importStar(require("../BundleGraph"));
|
|
47
|
+
const dumpGraphToGraphViz_1 = __importDefault(require("../dumpGraphToGraphViz"));
|
|
48
|
+
const nullthrows_1 = __importDefault(require("nullthrows"));
|
|
49
|
+
const rust_1 = require("@atlaspack/rust");
|
|
50
|
+
const PluginOptions_1 = __importDefault(require("../public/PluginOptions"));
|
|
51
|
+
const applyRuntimes_1 = __importDefault(require("../applyRuntimes"));
|
|
52
|
+
const constants_1 = require("../constants");
|
|
53
|
+
const utils_1 = require("../utils");
|
|
54
|
+
const DevDepRequest_1 = require("./DevDepRequest");
|
|
55
|
+
const RequestTracker_1 = require("../RequestTracker");
|
|
56
|
+
const AtlaspackConfigRequest_1 = __importStar(require("./AtlaspackConfigRequest"));
|
|
57
|
+
const BundleGraphRequestUtils_1 = require("./BundleGraphRequestUtils");
|
|
58
|
+
const EnvironmentManager_1 = require("../EnvironmentManager");
|
|
59
|
+
const Environment_1 = require("../Environment");
|
|
60
|
+
function createBundleGraphRequestRust(input) {
|
|
61
|
+
return {
|
|
62
|
+
type: RequestTracker_1.requestTypes.bundle_graph_request,
|
|
63
|
+
id: 'BundleGraphRust',
|
|
64
|
+
run: async (runInput) => {
|
|
65
|
+
const { api, options, rustAtlaspack } = runInput;
|
|
66
|
+
(0, assert_1.default)(rustAtlaspack, 'BundleGraphRequestRust requires rustAtlaspack');
|
|
67
|
+
let { bundleGraphPromise, commitPromise } = await rustAtlaspack.buildBundleGraph();
|
|
68
|
+
let [serializedBundleGraph, bundleGraphError] = (await bundleGraphPromise);
|
|
69
|
+
if (bundleGraphError) {
|
|
70
|
+
throw new diagnostic_1.default({ diagnostic: bundleGraphError });
|
|
71
|
+
}
|
|
72
|
+
// Don’t reuse previous JS result yet; we just rebuild from scratch.
|
|
73
|
+
let { bundleGraph, changedAssets } = (0, logger_1.instrument)('atlaspack_v3_getBundleGraph', () => getBundleGraph(serializedBundleGraph));
|
|
74
|
+
const runner = new NativeBundlerRunner({ api, options }, input.optionsRef);
|
|
75
|
+
await runner.loadConfigs();
|
|
76
|
+
// Name all bundles
|
|
77
|
+
const namers = await runner.config.getNamers();
|
|
78
|
+
const bundles = bundleGraph.getBundles({ includeInline: true });
|
|
79
|
+
await Promise.all(bundles.map((b) => (0, BundleGraphRequestUtils_1.nameBundle)(namers, b, bundleGraph, options, runner.pluginOptions, runner.configs)));
|
|
80
|
+
// Apply runtimes
|
|
81
|
+
const changedRuntimes = await (0, logger_1.instrumentAsync)('applyRuntimes', () => (0, applyRuntimes_1.default)({
|
|
82
|
+
bundleGraph,
|
|
83
|
+
api,
|
|
84
|
+
config: runner.config,
|
|
85
|
+
options,
|
|
86
|
+
optionsRef: input.optionsRef,
|
|
87
|
+
pluginOptions: runner.pluginOptions,
|
|
88
|
+
previousDevDeps: runner.previousDevDeps,
|
|
89
|
+
devDepRequests: runner.devDepRequests,
|
|
90
|
+
configs: runner.configs,
|
|
91
|
+
}));
|
|
92
|
+
// Add dev deps for namers
|
|
93
|
+
for (const namer of namers) {
|
|
94
|
+
const devDepRequest = await (0, DevDepRequest_1.createDevDependency)({
|
|
95
|
+
specifier: namer.name,
|
|
96
|
+
resolveFrom: namer.resolveFrom,
|
|
97
|
+
}, runner.previousDevDeps, options);
|
|
98
|
+
await (0, BundleGraphRequestUtils_1.runDevDepRequest)(api, devDepRequest, runner.devDepRequests);
|
|
99
|
+
}
|
|
100
|
+
(0, BundleGraphRequestUtils_1.validateBundles)(bundleGraph);
|
|
101
|
+
bundleGraph.getBundleGraphHash();
|
|
102
|
+
await (0, dumpGraphToGraphViz_1.default)(
|
|
103
|
+
// @ts-expect-error Accessing internal graph for debug output
|
|
104
|
+
bundleGraph._graph, 'after_runtimes_native', BundleGraph_1.bundleGraphEdgeTypes);
|
|
105
|
+
let [_commitResult, commitError] = await commitPromise;
|
|
106
|
+
if (commitError) {
|
|
107
|
+
throw new diagnostic_1.default({
|
|
108
|
+
diagnostic: {
|
|
109
|
+
message: 'Error committing bundle graph in Rust: ' + commitError.message,
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
bundleGraph,
|
|
115
|
+
// Not accurate yet — ok for now.
|
|
116
|
+
assetGraphBundlingVersion: 0,
|
|
117
|
+
changedAssets: changedRuntimes,
|
|
118
|
+
assetRequests: [],
|
|
119
|
+
};
|
|
120
|
+
},
|
|
121
|
+
input,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function mapSymbols({ exported, ...symbol }) {
|
|
125
|
+
let jsSymbol = {
|
|
126
|
+
local: symbol.local ?? undefined,
|
|
127
|
+
loc: symbol.loc ?? undefined,
|
|
128
|
+
isWeak: symbol.isWeak,
|
|
129
|
+
meta: {
|
|
130
|
+
isEsm: symbol.isEsmExport,
|
|
131
|
+
isStaticBindingSafe: symbol.isStaticBindingSafe,
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
if (symbol.exported) {
|
|
135
|
+
jsSymbol.exported = symbol.exported;
|
|
136
|
+
}
|
|
137
|
+
return [exported, jsSymbol];
|
|
138
|
+
}
|
|
139
|
+
function normalizeEnv(env) {
|
|
140
|
+
if (!env)
|
|
141
|
+
return env;
|
|
142
|
+
env.id = env.id || (0, Environment_1.getEnvironmentHash)(env);
|
|
143
|
+
return (0, EnvironmentManager_1.toEnvironmentRef)(env);
|
|
144
|
+
}
|
|
145
|
+
function getBundleGraph(serializedGraph) {
|
|
146
|
+
// Build a fresh internal bundle graph.
|
|
147
|
+
const publicIdByAssetId = new Map(Object.entries(serializedGraph.publicIdByAssetId ?? {}));
|
|
148
|
+
const assetPublicIds = new Set(serializedGraph.assetPublicIds ?? []);
|
|
149
|
+
// BundleGraph constructor expects a ContentGraph under `_graph`.
|
|
150
|
+
// We reuse the internal graph class by creating an empty instance and then adding nodes.
|
|
151
|
+
const graph = new BundleGraph_1.default({
|
|
152
|
+
// We intentionally start with an empty graph and add nodes/edges from the Rust payload.
|
|
153
|
+
// `ContentGraph` will allocate as needed.
|
|
154
|
+
graph: new graph_1.ContentGraph(),
|
|
155
|
+
bundleContentHashes: new Map(),
|
|
156
|
+
publicIdByAssetId,
|
|
157
|
+
assetPublicIds,
|
|
158
|
+
conditions: new Map(),
|
|
159
|
+
});
|
|
160
|
+
// Root must exist at node id 0.
|
|
161
|
+
const rootNodeId = graph._graph.addNodeByContentKey('@@root', {
|
|
162
|
+
id: '@@root',
|
|
163
|
+
type: 'root',
|
|
164
|
+
value: null,
|
|
165
|
+
});
|
|
166
|
+
graph._graph.setRootNodeId(rootNodeId);
|
|
167
|
+
let entry = 0;
|
|
168
|
+
const changedAssets = new Map();
|
|
169
|
+
const decoder = new TextDecoder();
|
|
170
|
+
// Create nodes in order.
|
|
171
|
+
for (let i = 0; i < serializedGraph.nodes.length; i++) {
|
|
172
|
+
// Nodes come back as buffers (same as AssetGraphRequestRust)
|
|
173
|
+
let node = JSON.parse(decoder.decode(serializedGraph.nodes[i]));
|
|
174
|
+
if (node.type === 'root') {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (node.type === 'entry') {
|
|
178
|
+
let id = 'entry:' + ++entry;
|
|
179
|
+
graph._graph.addNodeByContentKey(id, { id, type: 'root', value: null });
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
if (node.type === 'asset') {
|
|
183
|
+
let asset = node.value;
|
|
184
|
+
let id = asset.id;
|
|
185
|
+
asset.committed = true;
|
|
186
|
+
asset.contentKey = id;
|
|
187
|
+
asset.env = { ...asset.env };
|
|
188
|
+
asset.env.id = (0, feature_flags_1.getFeatureFlag)('environmentDeduplication')
|
|
189
|
+
? (0, Environment_1.getEnvironmentHash)(asset.env)
|
|
190
|
+
: (0, Environment_1.getEnvironmentHash)(asset.env);
|
|
191
|
+
asset.env = normalizeEnv(asset.env);
|
|
192
|
+
asset.mapKey = `map:${asset.id}`;
|
|
193
|
+
asset.dependencies = new Map();
|
|
194
|
+
asset.meta.isV3 = true;
|
|
195
|
+
if (asset.symbols != null) {
|
|
196
|
+
asset.symbols = new Map(asset.symbols.map(mapSymbols));
|
|
197
|
+
}
|
|
198
|
+
changedAssets.set(id, asset);
|
|
199
|
+
const assetNode = {
|
|
200
|
+
id,
|
|
201
|
+
type: 'asset',
|
|
202
|
+
usedSymbols: new Set(),
|
|
203
|
+
usedSymbolsDownDirty: true,
|
|
204
|
+
usedSymbolsUpDirty: true,
|
|
205
|
+
value: asset,
|
|
206
|
+
};
|
|
207
|
+
graph._graph.addNodeByContentKey(id, assetNode);
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
if (node.type === 'dependency') {
|
|
211
|
+
let { dependency, id } = node.value;
|
|
212
|
+
dependency.id = id;
|
|
213
|
+
dependency.env = { ...dependency.env };
|
|
214
|
+
dependency.env.id = (0, Environment_1.getEnvironmentHash)(dependency.env);
|
|
215
|
+
dependency.env = normalizeEnv(dependency.env);
|
|
216
|
+
if (dependency.symbols != null) {
|
|
217
|
+
dependency.symbols = new Map(dependency.symbols?.map(mapSymbols));
|
|
218
|
+
}
|
|
219
|
+
let usedSymbolsDown = new Set();
|
|
220
|
+
let usedSymbolsUp = new Map();
|
|
221
|
+
if (dependency.isEntry && dependency.isLibrary) {
|
|
222
|
+
usedSymbolsDown.add('*');
|
|
223
|
+
usedSymbolsUp.set('*', undefined);
|
|
224
|
+
}
|
|
225
|
+
const depNode = {
|
|
226
|
+
id,
|
|
227
|
+
type: 'dependency',
|
|
228
|
+
deferred: false,
|
|
229
|
+
excluded: false,
|
|
230
|
+
hasDeferred: node.has_deferred,
|
|
231
|
+
// @ts-expect-error Flow types expect a more specific symbol set type
|
|
232
|
+
usedSymbolsDown,
|
|
233
|
+
usedSymbolsDownDirty: true,
|
|
234
|
+
usedSymbolsUp,
|
|
235
|
+
usedSymbolsUpDirtyDown: true,
|
|
236
|
+
usedSymbolsUpDirtyUp: true,
|
|
237
|
+
value: dependency,
|
|
238
|
+
};
|
|
239
|
+
graph._graph.addNodeByContentKey(id, depNode);
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
if (node.type === 'bundle') {
|
|
243
|
+
node.value.env = normalizeEnv(node.value.env);
|
|
244
|
+
node.value.target.env = normalizeEnv(node.value.target.env);
|
|
245
|
+
graph._graph.addNodeByContentKey(node.id, node);
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
if (node.type === 'bundle_group' || node.type === 'bundleGroup') {
|
|
249
|
+
// Rust serializer may emit bundleGroup nodes either as `{id,type,value:{...}}`
|
|
250
|
+
// or as `{type:"bundleGroup", id, target, entryAssetId}`.
|
|
251
|
+
if (node.value == null) {
|
|
252
|
+
node.value = {
|
|
253
|
+
target: node.target,
|
|
254
|
+
entryAssetId: node.entryAssetId ?? node.entry_asset_id,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
// Normalize entry asset id field naming
|
|
258
|
+
if (node.value.entryAssetId == null &&
|
|
259
|
+
node.value.entry_asset_id != null) {
|
|
260
|
+
node.value.entryAssetId = node.value.entry_asset_id;
|
|
261
|
+
}
|
|
262
|
+
node.value.target.env = normalizeEnv(node.value.target.env);
|
|
263
|
+
// Normalise to the expected snake_case type
|
|
264
|
+
node.type = 'bundle_group';
|
|
265
|
+
graph._graph.addNodeByContentKey(node.id, node);
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
// Apply edges
|
|
270
|
+
for (let i = 0; i < serializedGraph.edges.length; i += 3) {
|
|
271
|
+
const from = serializedGraph.edges[i];
|
|
272
|
+
const to = serializedGraph.edges[i + 1];
|
|
273
|
+
const type = serializedGraph.edges[i + 2];
|
|
274
|
+
const fromNode = graph._graph.getNode(from);
|
|
275
|
+
const toNode = graph._graph.getNode(to);
|
|
276
|
+
if (fromNode?.type === 'asset' && toNode?.type === 'dependency') {
|
|
277
|
+
fromNode.value.dependencies.set(toNode.value.id, toNode.value);
|
|
278
|
+
}
|
|
279
|
+
// If we are adding a references edge, remove existing null edge.
|
|
280
|
+
if (type === BundleGraph_1.bundleGraphEdgeTypes.references &&
|
|
281
|
+
graph._graph.hasEdge(from, to, BundleGraph_1.bundleGraphEdgeTypes.null)) {
|
|
282
|
+
graph._graph.removeEdge(from, to, BundleGraph_1.bundleGraphEdgeTypes.null);
|
|
283
|
+
}
|
|
284
|
+
graph._graph.addEdge(from, to, type);
|
|
285
|
+
}
|
|
286
|
+
return { bundleGraph: graph, changedAssets };
|
|
287
|
+
}
|
|
288
|
+
class NativeBundlerRunner {
|
|
289
|
+
constructor({ api, options }, optionsRef) {
|
|
290
|
+
this.options = options;
|
|
291
|
+
this.api = api;
|
|
292
|
+
this.optionsRef = optionsRef;
|
|
293
|
+
this.previousDevDeps = new Map();
|
|
294
|
+
this.devDepRequests = new Map();
|
|
295
|
+
this.configs = new Map();
|
|
296
|
+
this.pluginOptions = new PluginOptions_1.default((0, utils_1.optionsProxy)(this.options, api.invalidateOnOptionChange));
|
|
297
|
+
const key = (0, rust_1.hashString)(`${constants_1.ATLASPACK_VERSION}:BundleGraph:${JSON.stringify(options.entries) ?? ''}${options.mode}${options.shouldBuildLazily ? 'lazy' : 'eager'}`);
|
|
298
|
+
this.cacheKey = `BundleGraph/${constants_1.ATLASPACK_VERSION}/${options.mode}/${key}`;
|
|
299
|
+
}
|
|
300
|
+
async loadConfigs() {
|
|
301
|
+
const configResult = (0, nullthrows_1.default)(await this.api.runRequest((0, AtlaspackConfigRequest_1.default)()));
|
|
302
|
+
this.config = (0, AtlaspackConfigRequest_1.getCachedAtlaspackConfig)(configResult, this.options);
|
|
303
|
+
const { devDeps, invalidDevDeps } = await (0, DevDepRequest_1.getDevDepRequests)(this.api);
|
|
304
|
+
this.previousDevDeps = devDeps;
|
|
305
|
+
(0, DevDepRequest_1.invalidateDevDeps)(invalidDevDeps, this.options, this.config);
|
|
306
|
+
const bundler = await this.config.getBundler();
|
|
307
|
+
await this.loadPluginConfig(bundler);
|
|
308
|
+
const namers = await this.config.getNamers();
|
|
309
|
+
for (const namer of namers) {
|
|
310
|
+
await this.loadPluginConfig(namer);
|
|
311
|
+
}
|
|
312
|
+
const runtimes = await this.config.getRuntimes();
|
|
313
|
+
for (const runtime of runtimes) {
|
|
314
|
+
await this.loadPluginConfig(runtime);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
async loadPluginConfig(plugin) {
|
|
318
|
+
await (0, BundleGraphRequestUtils_1.loadPluginConfigWithDevDeps)(plugin, this.options, this.api, this.previousDevDeps, this.devDepRequests, this.configs);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.validateBundles = validateBundles;
|
|
40
|
+
exports.nameBundle = nameBundle;
|
|
41
|
+
exports.loadPluginConfigWithDevDeps = loadPluginConfigWithDevDeps;
|
|
42
|
+
exports.runDevDepRequest = runDevDepRequest;
|
|
43
|
+
const assert_1 = __importDefault(require("assert"));
|
|
44
|
+
const nullthrows_1 = __importDefault(require("nullthrows"));
|
|
45
|
+
const logger_1 = require("@atlaspack/logger");
|
|
46
|
+
const diagnostic_1 = __importStar(require("@atlaspack/diagnostic"));
|
|
47
|
+
const utils_1 = require("@atlaspack/utils");
|
|
48
|
+
const BundleGraph_1 = __importDefault(require("../public/BundleGraph"));
|
|
49
|
+
const Bundle_1 = require("../public/Bundle");
|
|
50
|
+
const InternalConfig_1 = require("../InternalConfig");
|
|
51
|
+
const DevDepRequest_1 = require("./DevDepRequest");
|
|
52
|
+
const ConfigRequest_1 = require("./ConfigRequest");
|
|
53
|
+
const projectPath_1 = require("../projectPath");
|
|
54
|
+
const profiler_1 = require("@atlaspack/profiler");
|
|
55
|
+
/**
|
|
56
|
+
* Validates that all bundles have unique names.
|
|
57
|
+
* Throws an assertion error if duplicate bundle names are found.
|
|
58
|
+
*/
|
|
59
|
+
function validateBundles(bundleGraph) {
|
|
60
|
+
const bundles = bundleGraph.getBundles();
|
|
61
|
+
const bundleNames = bundles.map((b) => (0, projectPath_1.joinProjectPath)(b.target.distDir, (0, nullthrows_1.default)(b.name)));
|
|
62
|
+
assert_1.default.deepEqual(bundleNames, (0, utils_1.unique)(bundleNames), 'Bundles must have unique name. Conflicting names: ' +
|
|
63
|
+
[
|
|
64
|
+
...(0, utils_1.setSymmetricDifference)(new Set(bundleNames), new Set((0, utils_1.unique)(bundleNames))),
|
|
65
|
+
].join());
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Names a bundle by running through the configured namers until one returns a name.
|
|
69
|
+
*/
|
|
70
|
+
async function nameBundle(namers, internalBundle, internalBundleGraph, options, pluginOptions, configs) {
|
|
71
|
+
const bundle = Bundle_1.Bundle.get(internalBundle, internalBundleGraph, options);
|
|
72
|
+
const bundleGraph = new BundleGraph_1.default(internalBundleGraph, Bundle_1.NamedBundle.get.bind(Bundle_1.NamedBundle), options);
|
|
73
|
+
for (const namer of namers) {
|
|
74
|
+
let measurement;
|
|
75
|
+
try {
|
|
76
|
+
measurement = profiler_1.tracer.createMeasurement(namer.name, 'namer', bundle.id);
|
|
77
|
+
const name = await namer.plugin.name({
|
|
78
|
+
bundle,
|
|
79
|
+
bundleGraph,
|
|
80
|
+
config: configs.get(namer.name)?.result,
|
|
81
|
+
options: pluginOptions,
|
|
82
|
+
logger: new logger_1.PluginLogger({ origin: namer.name }),
|
|
83
|
+
tracer: new profiler_1.PluginTracer({ origin: namer.name, category: 'namer' }),
|
|
84
|
+
});
|
|
85
|
+
if (name != null) {
|
|
86
|
+
internalBundle.name = name;
|
|
87
|
+
const { hashReference } = internalBundle;
|
|
88
|
+
internalBundle.displayName = name.includes(hashReference)
|
|
89
|
+
? name.replace(hashReference, '[hash]')
|
|
90
|
+
: name;
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
throw new diagnostic_1.default({
|
|
96
|
+
diagnostic: (0, diagnostic_1.errorToDiagnostic)(e, {
|
|
97
|
+
origin: namer.name,
|
|
98
|
+
}),
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
measurement && measurement.end();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
throw new Error('Unable to name bundle');
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Loads configuration for a plugin and tracks its dev dependencies.
|
|
109
|
+
*/
|
|
110
|
+
async function loadPluginConfigWithDevDeps(plugin, options, api, previousDevDeps, devDepRequests, configs) {
|
|
111
|
+
const config = (0, InternalConfig_1.createConfig)({
|
|
112
|
+
plugin: plugin.name,
|
|
113
|
+
searchPath: (0, projectPath_1.toProjectPathUnsafe)('index'),
|
|
114
|
+
});
|
|
115
|
+
await (0, ConfigRequest_1.loadPluginConfig)(plugin, config, options);
|
|
116
|
+
await (0, ConfigRequest_1.runConfigRequest)(api, config);
|
|
117
|
+
for (const devDep of config.devDeps) {
|
|
118
|
+
const devDepRequest = await (0, DevDepRequest_1.createDevDependency)(devDep, previousDevDeps, options);
|
|
119
|
+
await runDevDepRequest(api, devDepRequest, devDepRequests);
|
|
120
|
+
}
|
|
121
|
+
configs.set(plugin.name, config);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Runs a dev dependency request and tracks it in the devDepRequests map.
|
|
125
|
+
*/
|
|
126
|
+
async function runDevDepRequest(api, devDepRequest, devDepRequests) {
|
|
127
|
+
const { specifier, resolveFrom } = devDepRequest;
|
|
128
|
+
const key = `${specifier}:${(0, projectPath_1.fromProjectPathRelative)(resolveFrom)}`;
|
|
129
|
+
devDepRequests.set(key, devDepRequest);
|
|
130
|
+
await (0, DevDepRequest_1.runDevDepRequest)(api, devDepRequest);
|
|
131
|
+
}
|
|
@@ -11,6 +11,8 @@ const DevDepRequest_1 = require("./DevDepRequest");
|
|
|
11
11
|
const AtlaspackConfigRequest_1 = __importDefault(require("./AtlaspackConfigRequest"));
|
|
12
12
|
const EnvironmentManager_1 = require("../EnvironmentManager");
|
|
13
13
|
const feature_flags_1 = require("@atlaspack/feature-flags");
|
|
14
|
+
const logger_1 = __importDefault(require("@atlaspack/logger"));
|
|
15
|
+
const diagnostic_1 = __importDefault(require("@atlaspack/diagnostic"));
|
|
14
16
|
function createPackageRequest(input) {
|
|
15
17
|
return {
|
|
16
18
|
type: RequestTracker_1.requestTypes.package_request,
|
|
@@ -25,23 +27,38 @@ async function run({ input, api, farm, rustAtlaspack }) {
|
|
|
25
27
|
let start = Date.now();
|
|
26
28
|
let { devDeps, invalidDevDeps } = await (0, DevDepRequest_1.getDevDepRequests)(api);
|
|
27
29
|
let { cachePath } = (0, nullthrows_1.default)(await api.runRequest((0, AtlaspackConfigRequest_1.default)()));
|
|
30
|
+
let packagingResult;
|
|
28
31
|
if ((0, feature_flags_1.getFeatureFlag)('nativePackager') &&
|
|
29
32
|
(0, feature_flags_1.getFeatureFlag)('nativePackagerSSRDev') &&
|
|
30
33
|
rustAtlaspack &&
|
|
31
34
|
(0, EnvironmentManager_1.fromEnvironmentId)(bundle.env).context === 'tesseract' &&
|
|
32
35
|
bundle.type === 'js') {
|
|
33
36
|
// Once this actually does something, the code below will be in an `else` block (i.e. we'll only run one or the other)
|
|
34
|
-
await rustAtlaspack.package();
|
|
37
|
+
let result = await rustAtlaspack.package(bundle.id);
|
|
38
|
+
let error = null;
|
|
39
|
+
[packagingResult, error] = result;
|
|
40
|
+
if (error) {
|
|
41
|
+
throw new diagnostic_1.default({
|
|
42
|
+
diagnostic: error,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
logger_1.default.verbose({
|
|
46
|
+
message: JSON.stringify(packagingResult, null, 2),
|
|
47
|
+
origin: '@atlaspack/core',
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
packagingResult = (await runPackage({
|
|
52
|
+
bundle,
|
|
53
|
+
bundleGraphReference,
|
|
54
|
+
optionsRef,
|
|
55
|
+
configCachePath: cachePath,
|
|
56
|
+
previousDevDeps: devDeps,
|
|
57
|
+
invalidDevDeps,
|
|
58
|
+
previousInvalidations: api.getInvalidations(),
|
|
59
|
+
}));
|
|
35
60
|
}
|
|
36
|
-
let { devDepRequests, configRequests, bundleInfo, invalidations } =
|
|
37
|
-
bundle,
|
|
38
|
-
bundleGraphReference,
|
|
39
|
-
optionsRef,
|
|
40
|
-
configCachePath: cachePath,
|
|
41
|
-
previousDevDeps: devDeps,
|
|
42
|
-
invalidDevDeps,
|
|
43
|
-
previousInvalidations: api.getInvalidations(),
|
|
44
|
-
}));
|
|
61
|
+
let { devDepRequests, configRequests, bundleInfo, invalidations } = packagingResult;
|
|
45
62
|
for (let devDepRequest of devDepRequests) {
|
|
46
63
|
await (0, DevDepRequest_1.runDevDepRequest)(api, devDepRequest);
|
|
47
64
|
}
|
package/lib/BundleGraph.js
CHANGED
|
@@ -85,7 +85,7 @@ const bundleGraphEdgeTypes = exports.bundleGraphEdgeTypes = {
|
|
|
85
85
|
internal_async: 5,
|
|
86
86
|
// This type is used to mark an edge between a bundle and a conditional bundle.
|
|
87
87
|
// This allows efficient discovery of conditional bundles in packaging
|
|
88
|
-
conditional:
|
|
88
|
+
conditional: 6
|
|
89
89
|
};
|
|
90
90
|
function makeReadOnlySet(set) {
|
|
91
91
|
return new Proxy(set, {
|
|
@@ -438,7 +438,7 @@ class BundleGraph {
|
|
|
438
438
|
|
|
439
439
|
/**
|
|
440
440
|
* Serialize the bundle graph for efficient transfer to native Rust code.
|
|
441
|
-
* Returns a JSON string of nodes
|
|
441
|
+
* Returns a JSON string of nodes, an array of edges, and a map of asset IDs to public IDs.
|
|
442
442
|
*/
|
|
443
443
|
serializeForNative() {
|
|
444
444
|
const start = performance.now();
|
|
@@ -452,18 +452,67 @@ class BundleGraph {
|
|
|
452
452
|
next = edgeIterator.next();
|
|
453
453
|
}
|
|
454
454
|
|
|
455
|
+
// Extract and deduplicate environments
|
|
456
|
+
const environmentMap = new Map();
|
|
457
|
+
const extractEnvironment = envRef => {
|
|
458
|
+
const env = (0, _EnvironmentManager.fromEnvironmentId)(envRef);
|
|
459
|
+
const envId = env.id;
|
|
460
|
+
if (!environmentMap.has(envId)) {
|
|
461
|
+
environmentMap.set(envId, env);
|
|
462
|
+
}
|
|
463
|
+
return envId;
|
|
464
|
+
};
|
|
465
|
+
|
|
466
|
+
// Replace env objects with env IDs in nodes
|
|
467
|
+
const processedNodes = nodes.map(node => {
|
|
468
|
+
var _node$value, _node$value2, _node$value3;
|
|
469
|
+
const processedNode = {
|
|
470
|
+
...node
|
|
471
|
+
};
|
|
472
|
+
if (node.type === 'asset' && (_node$value = node.value) !== null && _node$value !== void 0 && _node$value.env) {
|
|
473
|
+
processedNode.value = {
|
|
474
|
+
...node.value,
|
|
475
|
+
env: extractEnvironment(node.value.env)
|
|
476
|
+
};
|
|
477
|
+
} else if (node.type === 'dependency' && (_node$value2 = node.value) !== null && _node$value2 !== void 0 && _node$value2.env) {
|
|
478
|
+
processedNode.value = {
|
|
479
|
+
...node.value,
|
|
480
|
+
env: extractEnvironment(node.value.env)
|
|
481
|
+
};
|
|
482
|
+
} else if (node.type === 'bundle' && (_node$value3 = node.value) !== null && _node$value3 !== void 0 && _node$value3.env) {
|
|
483
|
+
processedNode.value = {
|
|
484
|
+
...node.value,
|
|
485
|
+
env: extractEnvironment(node.value.env)
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
return processedNode;
|
|
489
|
+
});
|
|
490
|
+
|
|
455
491
|
// Optimize nodes by omitting null/undefined values to reduce JSON size
|
|
456
|
-
const optimizedNodes =
|
|
492
|
+
const optimizedNodes = processedNodes.map(node => this._omitNulls(node));
|
|
457
493
|
const nodesJson = JSON.stringify(optimizedNodes);
|
|
494
|
+
|
|
495
|
+
// Serialize environments as array
|
|
496
|
+
const environments = Array.from(environmentMap.values());
|
|
497
|
+
const environmentsJson = JSON.stringify(environments);
|
|
498
|
+
|
|
499
|
+
// Convert Map to plain object for serialization
|
|
500
|
+
const publicIdByAssetId = {};
|
|
501
|
+
for (const [assetId, publicId] of this._publicIdByAssetId) {
|
|
502
|
+
publicIdByAssetId[assetId] = publicId;
|
|
503
|
+
}
|
|
458
504
|
const duration = performance.now() - start;
|
|
459
|
-
const
|
|
505
|
+
const nodesSizeMB = (nodesJson.length / (1024 * 1024)).toFixed(2);
|
|
506
|
+
const envsSizeMB = (environmentsJson.length / (1024 * 1024)).toFixed(2);
|
|
460
507
|
_logger().default.verbose({
|
|
461
508
|
origin: '@atlaspack/core',
|
|
462
|
-
message: `serializeForNative: ${duration.toFixed(1)}ms, ${
|
|
509
|
+
message: `serializeForNative: ${duration.toFixed(1)}ms, ${nodesSizeMB}MB nodes, ${envsSizeMB}MB envs (${environmentMap.size} unique), ${nodes.length} nodes, ${edges.length} edges`
|
|
463
510
|
});
|
|
464
511
|
return {
|
|
465
512
|
nodesJson,
|
|
466
|
-
edges
|
|
513
|
+
edges,
|
|
514
|
+
publicIdByAssetId,
|
|
515
|
+
environmentsJson
|
|
467
516
|
};
|
|
468
517
|
}
|
|
469
518
|
|
|
@@ -1152,8 +1201,36 @@ class BundleGraph {
|
|
|
1152
1201
|
}
|
|
1153
1202
|
|
|
1154
1203
|
/**
|
|
1155
|
-
*
|
|
1156
|
-
*
|
|
1204
|
+
* Performs a depth-first traversal of all assets and dependencies contained
|
|
1205
|
+
* within a bundle. Only visits nodes that are directly contained in the bundle
|
|
1206
|
+
* (connected via a `contains` edge).
|
|
1207
|
+
*
|
|
1208
|
+
* Entry Asset Ordering:
|
|
1209
|
+
* The traversal guarantees that entry assets are visited in the exact order they
|
|
1210
|
+
* appear in `bundle.entryAssetIds`. This ordering is critical for several reasons:
|
|
1211
|
+
*
|
|
1212
|
+
* 1. **Code Execution Order in Packagers**: Packagers (ScopeHoistingPackager,
|
|
1213
|
+
* DevPackager) use this traversal to concatenate assets into the final bundle.
|
|
1214
|
+
* The traversal order determines the execution order of code in the output.
|
|
1215
|
+
* Entry assets must be processed in their defined order to ensure correct
|
|
1216
|
+
* initialization sequences.
|
|
1217
|
+
*
|
|
1218
|
+
* 2. **Runtime Injection**: Runtime assets (HMR, bundle manifests) are prepended
|
|
1219
|
+
* to `entryAssetIds` via `unshift()` in `applyRuntimes.ts`. By honoring the
|
|
1220
|
+
* array order, runtimes are guaranteed to be visited (and thus output) before
|
|
1221
|
+
* application entry points, ensuring the runtime infrastructure is available
|
|
1222
|
+
* when application code executes.
|
|
1223
|
+
*
|
|
1224
|
+
* 3. **Deterministic Builds**: Consistent traversal order ensures reproducible
|
|
1225
|
+
* bundle output, which is essential for caching and build verification.
|
|
1226
|
+
*
|
|
1227
|
+
* The sorting only applies at the first traversal level (direct children of the
|
|
1228
|
+
* start node). Subsequent levels follow standard DFS order based on the graph's
|
|
1229
|
+
* edge structure.
|
|
1230
|
+
*
|
|
1231
|
+
* @param bundle - The bundle to traverse
|
|
1232
|
+
* @param visit - Visitor callback receiving asset or dependency nodes
|
|
1233
|
+
* @param startAsset - Optional asset to start traversal from (defaults to bundle root)
|
|
1157
1234
|
*/
|
|
1158
1235
|
traverseBundle(bundle, visit, startAsset) {
|
|
1159
1236
|
let entries = !startAsset;
|
|
@@ -72,15 +72,20 @@ class AtlaspackV3 {
|
|
|
72
72
|
buildAssetGraph() {
|
|
73
73
|
return (0, _rust().atlaspackNapiBuildAssetGraph)(this._atlaspack_napi);
|
|
74
74
|
}
|
|
75
|
+
buildBundleGraph() {
|
|
76
|
+
return (0, _rust().atlaspackNapiBuildBundleGraph)(this._atlaspack_napi);
|
|
77
|
+
}
|
|
75
78
|
loadBundleGraph(bundleGraph) {
|
|
76
79
|
const {
|
|
77
80
|
nodesJson,
|
|
78
|
-
edges
|
|
81
|
+
edges,
|
|
82
|
+
publicIdByAssetId,
|
|
83
|
+
environmentsJson
|
|
79
84
|
} = bundleGraph.serializeForNative();
|
|
80
|
-
return (0, _rust().atlaspackNapiLoadBundleGraph)(this._atlaspack_napi, nodesJson, edges);
|
|
85
|
+
return (0, _rust().atlaspackNapiLoadBundleGraph)(this._atlaspack_napi, nodesJson, edges, publicIdByAssetId, environmentsJson);
|
|
81
86
|
}
|
|
82
|
-
package() {
|
|
83
|
-
return (0, _rust().atlaspackNapiPackage)(this._atlaspack_napi);
|
|
87
|
+
package(bundleId) {
|
|
88
|
+
return (0, _rust().atlaspackNapiPackage)(this._atlaspack_napi, bundleId);
|
|
84
89
|
}
|
|
85
90
|
async respondToFsEvents(events) {
|
|
86
91
|
// @ts-expect-error TS2488
|
|
@@ -381,7 +381,8 @@ class AtlaspackWorker {
|
|
|
381
381
|
setup = {
|
|
382
382
|
conditions: setupResult === null || setupResult === void 0 ? void 0 : setupResult.conditions,
|
|
383
383
|
config,
|
|
384
|
-
env: allowedEnv
|
|
384
|
+
env: allowedEnv,
|
|
385
|
+
disableCache: setupResult === null || setupResult === void 0 ? void 0 : setupResult.disableCache
|
|
385
386
|
};
|
|
386
387
|
}
|
|
387
388
|
this.#transformers.set(specifier, {
|