@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,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.loadPluginConfigWithDevDeps = loadPluginConfigWithDevDeps;
|
|
7
|
+
exports.nameBundle = nameBundle;
|
|
8
|
+
exports.runDevDepRequest = runDevDepRequest;
|
|
9
|
+
exports.validateBundles = validateBundles;
|
|
10
|
+
function _assert() {
|
|
11
|
+
const data = _interopRequireDefault(require("assert"));
|
|
12
|
+
_assert = function () {
|
|
13
|
+
return data;
|
|
14
|
+
};
|
|
15
|
+
return data;
|
|
16
|
+
}
|
|
17
|
+
function _nullthrows() {
|
|
18
|
+
const data = _interopRequireDefault(require("nullthrows"));
|
|
19
|
+
_nullthrows = function () {
|
|
20
|
+
return data;
|
|
21
|
+
};
|
|
22
|
+
return data;
|
|
23
|
+
}
|
|
24
|
+
function _logger() {
|
|
25
|
+
const data = require("@atlaspack/logger");
|
|
26
|
+
_logger = function () {
|
|
27
|
+
return data;
|
|
28
|
+
};
|
|
29
|
+
return data;
|
|
30
|
+
}
|
|
31
|
+
function _diagnostic() {
|
|
32
|
+
const data = _interopRequireWildcard(require("@atlaspack/diagnostic"));
|
|
33
|
+
_diagnostic = function () {
|
|
34
|
+
return data;
|
|
35
|
+
};
|
|
36
|
+
return data;
|
|
37
|
+
}
|
|
38
|
+
function _utils() {
|
|
39
|
+
const data = require("@atlaspack/utils");
|
|
40
|
+
_utils = function () {
|
|
41
|
+
return data;
|
|
42
|
+
};
|
|
43
|
+
return data;
|
|
44
|
+
}
|
|
45
|
+
var _BundleGraph = _interopRequireDefault(require("../public/BundleGraph"));
|
|
46
|
+
var _Bundle = require("../public/Bundle");
|
|
47
|
+
var _InternalConfig = require("../InternalConfig");
|
|
48
|
+
var _DevDepRequest = require("./DevDepRequest");
|
|
49
|
+
var _ConfigRequest = require("./ConfigRequest");
|
|
50
|
+
var _projectPath = require("../projectPath");
|
|
51
|
+
function _profiler() {
|
|
52
|
+
const data = require("@atlaspack/profiler");
|
|
53
|
+
_profiler = function () {
|
|
54
|
+
return data;
|
|
55
|
+
};
|
|
56
|
+
return data;
|
|
57
|
+
}
|
|
58
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
59
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
60
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
61
|
+
/**
|
|
62
|
+
* Shared utilities for BundleGraphRequest and BundleGraphRequestRust.
|
|
63
|
+
*
|
|
64
|
+
* This module contains common functionality used by both the JS and native
|
|
65
|
+
* bundling paths, such as bundle validation, naming, and configuration loading.
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Validates that all bundles have unique names.
|
|
70
|
+
* Throws an assertion error if duplicate bundle names are found.
|
|
71
|
+
*/
|
|
72
|
+
function validateBundles(bundleGraph) {
|
|
73
|
+
const bundles = bundleGraph.getBundles();
|
|
74
|
+
const bundleNames = bundles.map(b => (0, _projectPath.joinProjectPath)(b.target.distDir, (0, _nullthrows().default)(b.name)));
|
|
75
|
+
_assert().default.deepEqual(bundleNames, (0, _utils().unique)(bundleNames), 'Bundles must have unique name. Conflicting names: ' + [...(0, _utils().setSymmetricDifference)(new Set(bundleNames), new Set((0, _utils().unique)(bundleNames)))].join());
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Names a bundle by running through the configured namers until one returns a name.
|
|
80
|
+
*/
|
|
81
|
+
async function nameBundle(namers, internalBundle, internalBundleGraph, options, pluginOptions, configs) {
|
|
82
|
+
const bundle = _Bundle.Bundle.get(internalBundle, internalBundleGraph, options);
|
|
83
|
+
const bundleGraph = new _BundleGraph.default(internalBundleGraph, _Bundle.NamedBundle.get.bind(_Bundle.NamedBundle), options);
|
|
84
|
+
for (const namer of namers) {
|
|
85
|
+
let measurement;
|
|
86
|
+
try {
|
|
87
|
+
var _configs$get;
|
|
88
|
+
measurement = _profiler().tracer.createMeasurement(namer.name, 'namer', bundle.id);
|
|
89
|
+
const name = await namer.plugin.name({
|
|
90
|
+
bundle,
|
|
91
|
+
bundleGraph,
|
|
92
|
+
config: (_configs$get = configs.get(namer.name)) === null || _configs$get === void 0 ? void 0 : _configs$get.result,
|
|
93
|
+
options: pluginOptions,
|
|
94
|
+
logger: new (_logger().PluginLogger)({
|
|
95
|
+
origin: namer.name
|
|
96
|
+
}),
|
|
97
|
+
tracer: new (_profiler().PluginTracer)({
|
|
98
|
+
origin: namer.name,
|
|
99
|
+
category: 'namer'
|
|
100
|
+
})
|
|
101
|
+
});
|
|
102
|
+
if (name != null) {
|
|
103
|
+
internalBundle.name = name;
|
|
104
|
+
const {
|
|
105
|
+
hashReference
|
|
106
|
+
} = internalBundle;
|
|
107
|
+
internalBundle.displayName = name.includes(hashReference) ? name.replace(hashReference, '[hash]') : name;
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
} catch (e) {
|
|
111
|
+
throw new (_diagnostic().default)({
|
|
112
|
+
diagnostic: (0, _diagnostic().errorToDiagnostic)(e, {
|
|
113
|
+
origin: namer.name
|
|
114
|
+
})
|
|
115
|
+
});
|
|
116
|
+
} finally {
|
|
117
|
+
measurement && measurement.end();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
throw new Error('Unable to name bundle');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Loads configuration for a plugin and tracks its dev dependencies.
|
|
125
|
+
*/
|
|
126
|
+
async function loadPluginConfigWithDevDeps(plugin, options, api, previousDevDeps, devDepRequests, configs) {
|
|
127
|
+
const config = (0, _InternalConfig.createConfig)({
|
|
128
|
+
plugin: plugin.name,
|
|
129
|
+
searchPath: (0, _projectPath.toProjectPathUnsafe)('index')
|
|
130
|
+
});
|
|
131
|
+
await (0, _ConfigRequest.loadPluginConfig)(plugin, config, options);
|
|
132
|
+
await (0, _ConfigRequest.runConfigRequest)(api, config);
|
|
133
|
+
for (const devDep of config.devDeps) {
|
|
134
|
+
const devDepRequest = await (0, _DevDepRequest.createDevDependency)(devDep, previousDevDeps, options);
|
|
135
|
+
await runDevDepRequest(api, devDepRequest, devDepRequests);
|
|
136
|
+
}
|
|
137
|
+
configs.set(plugin.name, config);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Runs a dev dependency request and tracks it in the devDepRequests map.
|
|
142
|
+
*/
|
|
143
|
+
async function runDevDepRequest(api, devDepRequest, devDepRequests) {
|
|
144
|
+
const {
|
|
145
|
+
specifier,
|
|
146
|
+
resolveFrom
|
|
147
|
+
} = devDepRequest;
|
|
148
|
+
const key = `${specifier}:${(0, _projectPath.fromProjectPathRelative)(resolveFrom)}`;
|
|
149
|
+
devDepRequests.set(key, devDepRequest);
|
|
150
|
+
await (0, _DevDepRequest.runDevDepRequest)(api, devDepRequest);
|
|
151
|
+
}
|
|
@@ -23,6 +23,20 @@ function _featureFlags() {
|
|
|
23
23
|
};
|
|
24
24
|
return data;
|
|
25
25
|
}
|
|
26
|
+
function _logger() {
|
|
27
|
+
const data = _interopRequireDefault(require("@atlaspack/logger"));
|
|
28
|
+
_logger = function () {
|
|
29
|
+
return data;
|
|
30
|
+
};
|
|
31
|
+
return data;
|
|
32
|
+
}
|
|
33
|
+
function _diagnostic() {
|
|
34
|
+
const data = _interopRequireDefault(require("@atlaspack/diagnostic"));
|
|
35
|
+
_diagnostic = function () {
|
|
36
|
+
return data;
|
|
37
|
+
};
|
|
38
|
+
return data;
|
|
39
|
+
}
|
|
26
40
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
27
41
|
function createPackageRequest(input) {
|
|
28
42
|
return {
|
|
@@ -53,24 +67,38 @@ async function run({
|
|
|
53
67
|
let {
|
|
54
68
|
cachePath
|
|
55
69
|
} = (0, _nullthrows().default)(await api.runRequest((0, _AtlaspackConfigRequest.default)()));
|
|
70
|
+
let packagingResult;
|
|
56
71
|
if ((0, _featureFlags().getFeatureFlag)('nativePackager') && (0, _featureFlags().getFeatureFlag)('nativePackagerSSRDev') && rustAtlaspack && (0, _EnvironmentManager.fromEnvironmentId)(bundle.env).context === 'tesseract' && bundle.type === 'js') {
|
|
57
72
|
// Once this actually does something, the code below will be in an `else` block (i.e. we'll only run one or the other)
|
|
58
|
-
await rustAtlaspack.package();
|
|
73
|
+
let result = await rustAtlaspack.package(bundle.id);
|
|
74
|
+
let error = null;
|
|
75
|
+
[packagingResult, error] = result;
|
|
76
|
+
if (error) {
|
|
77
|
+
throw new (_diagnostic().default)({
|
|
78
|
+
diagnostic: error
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
_logger().default.verbose({
|
|
82
|
+
message: JSON.stringify(packagingResult, null, 2),
|
|
83
|
+
origin: '@atlaspack/core'
|
|
84
|
+
});
|
|
85
|
+
} else {
|
|
86
|
+
packagingResult = await runPackage({
|
|
87
|
+
bundle,
|
|
88
|
+
bundleGraphReference,
|
|
89
|
+
optionsRef,
|
|
90
|
+
configCachePath: cachePath,
|
|
91
|
+
previousDevDeps: devDeps,
|
|
92
|
+
invalidDevDeps,
|
|
93
|
+
previousInvalidations: api.getInvalidations()
|
|
94
|
+
});
|
|
59
95
|
}
|
|
60
96
|
let {
|
|
61
97
|
devDepRequests,
|
|
62
98
|
configRequests,
|
|
63
99
|
bundleInfo,
|
|
64
100
|
invalidations
|
|
65
|
-
} =
|
|
66
|
-
bundle,
|
|
67
|
-
bundleGraphReference,
|
|
68
|
-
optionsRef,
|
|
69
|
-
configCachePath: cachePath,
|
|
70
|
-
previousDevDeps: devDeps,
|
|
71
|
-
invalidDevDeps,
|
|
72
|
-
previousInvalidations: api.getInvalidations()
|
|
73
|
-
});
|
|
101
|
+
} = packagingResult;
|
|
74
102
|
for (let devDepRequest of devDepRequests) {
|
|
75
103
|
await (0, _DevDepRequest.runDevDepRequest)(api, devDepRequest);
|
|
76
104
|
}
|
|
@@ -11,7 +11,7 @@ export declare const bundleGraphEdgeTypes: {
|
|
|
11
11
|
readonly bundle: 3;
|
|
12
12
|
readonly references: 4;
|
|
13
13
|
readonly internal_async: 5;
|
|
14
|
-
readonly conditional:
|
|
14
|
+
readonly conditional: 6;
|
|
15
15
|
};
|
|
16
16
|
export type BundleGraphEdgeType = (typeof bundleGraphEdgeTypes)[keyof typeof bundleGraphEdgeTypes];
|
|
17
17
|
type InternalSymbolResolution = {
|
|
@@ -79,11 +79,13 @@ export default class BundleGraph {
|
|
|
79
79
|
static deserialize(serialized: BundleGraphOpts): BundleGraph;
|
|
80
80
|
/**
|
|
81
81
|
* Serialize the bundle graph for efficient transfer to native Rust code.
|
|
82
|
-
* Returns a JSON string of nodes
|
|
82
|
+
* Returns a JSON string of nodes, an array of edges, and a map of asset IDs to public IDs.
|
|
83
83
|
*/
|
|
84
84
|
serializeForNative(): {
|
|
85
85
|
nodesJson: string;
|
|
86
86
|
edges: [number, number, BundleGraphEdgeType][];
|
|
87
|
+
publicIdByAssetId: Record<string, string>;
|
|
88
|
+
environmentsJson: string;
|
|
87
89
|
};
|
|
88
90
|
/**
|
|
89
91
|
* Remove null and undefined values from an object to reduce JSON size.
|
|
@@ -148,8 +150,36 @@ export default class BundleGraph {
|
|
|
148
150
|
getParentBundles(bundle: Bundle): Array<Bundle>;
|
|
149
151
|
isAssetReachableFromBundle(asset: Asset, bundle: Bundle): boolean;
|
|
150
152
|
/**
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
+
* Performs a depth-first traversal of all assets and dependencies contained
|
|
154
|
+
* within a bundle. Only visits nodes that are directly contained in the bundle
|
|
155
|
+
* (connected via a `contains` edge).
|
|
156
|
+
*
|
|
157
|
+
* Entry Asset Ordering:
|
|
158
|
+
* The traversal guarantees that entry assets are visited in the exact order they
|
|
159
|
+
* appear in `bundle.entryAssetIds`. This ordering is critical for several reasons:
|
|
160
|
+
*
|
|
161
|
+
* 1. **Code Execution Order in Packagers**: Packagers (ScopeHoistingPackager,
|
|
162
|
+
* DevPackager) use this traversal to concatenate assets into the final bundle.
|
|
163
|
+
* The traversal order determines the execution order of code in the output.
|
|
164
|
+
* Entry assets must be processed in their defined order to ensure correct
|
|
165
|
+
* initialization sequences.
|
|
166
|
+
*
|
|
167
|
+
* 2. **Runtime Injection**: Runtime assets (HMR, bundle manifests) are prepended
|
|
168
|
+
* to `entryAssetIds` via `unshift()` in `applyRuntimes.ts`. By honoring the
|
|
169
|
+
* array order, runtimes are guaranteed to be visited (and thus output) before
|
|
170
|
+
* application entry points, ensuring the runtime infrastructure is available
|
|
171
|
+
* when application code executes.
|
|
172
|
+
*
|
|
173
|
+
* 3. **Deterministic Builds**: Consistent traversal order ensures reproducible
|
|
174
|
+
* bundle output, which is essential for caching and build verification.
|
|
175
|
+
*
|
|
176
|
+
* The sorting only applies at the first traversal level (direct children of the
|
|
177
|
+
* start node). Subsequent levels follow standard DFS order based on the graph's
|
|
178
|
+
* edge structure.
|
|
179
|
+
*
|
|
180
|
+
* @param bundle - The bundle to traverse
|
|
181
|
+
* @param visit - Visitor callback receiving asset or dependency nodes
|
|
182
|
+
* @param startAsset - Optional asset to start traversal from (defaults to bundle root)
|
|
153
183
|
*/
|
|
154
184
|
traverseBundle<TContext>(bundle: Bundle, visit: GraphVisitor<AssetNode | DependencyNode, TContext>, startAsset?: Asset): TContext | null | undefined;
|
|
155
185
|
traverse<TContext>(visit: GraphVisitor<AssetNode | DependencyNode, TContext>, start?: Asset): TContext | null | undefined;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { AtlaspackNapi, Lmdb, AtlaspackNapiOptions, CacheStats } from '@atlaspack/rust';
|
|
2
|
+
import { Diagnostic } from '@atlaspack/diagnostic';
|
|
2
3
|
import type { Event } from '@parcel/watcher';
|
|
3
4
|
import type { NapiWorkerPool as INapiWorkerPool } from '@atlaspack/types';
|
|
4
5
|
import type BundleGraph from '../BundleGraph';
|
|
6
|
+
import { RunPackagerRunnerResult } from '../PackagerRunner';
|
|
5
7
|
export type AtlaspackV3Options = {
|
|
6
8
|
fs?: AtlaspackNapiOptions['fs'];
|
|
7
9
|
packageManager?: AtlaspackNapiOptions['packageManager'];
|
|
@@ -23,8 +25,9 @@ export declare class AtlaspackV3 {
|
|
|
23
25
|
static create({ fs, packageManager, threads, lmdb, napiWorkerPool, ...options }: AtlaspackV3Options): Promise<AtlaspackV3>;
|
|
24
26
|
end(): void;
|
|
25
27
|
buildAssetGraph(): Promise<any>;
|
|
28
|
+
buildBundleGraph(): Promise<any>;
|
|
26
29
|
loadBundleGraph(bundleGraph: BundleGraph): Promise<void>;
|
|
27
|
-
package(): Promise<
|
|
30
|
+
package(bundleId: string): Promise<[RunPackagerRunnerResult, Diagnostic | null]>;
|
|
28
31
|
respondToFsEvents(events: Array<Event>): Promise<boolean>;
|
|
29
32
|
completeCacheSession(): Promise<CacheStats>;
|
|
30
33
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Async } from '@atlaspack/types';
|
|
2
|
+
import InternalBundleGraph from '../BundleGraph';
|
|
3
|
+
import { requestTypes, StaticRunOpts } from '../RequestTracker';
|
|
4
|
+
import type { BundleGraphResult } from './BundleGraphRequest';
|
|
5
|
+
import type { Asset } from '../types';
|
|
6
|
+
type BundleGraphRequestInput = {
|
|
7
|
+
requestedAssetIds: Set<string>;
|
|
8
|
+
signal?: AbortSignal;
|
|
9
|
+
optionsRef: any;
|
|
10
|
+
};
|
|
11
|
+
type RunInput = {
|
|
12
|
+
input: BundleGraphRequestInput;
|
|
13
|
+
} & StaticRunOpts<BundleGraphResult>;
|
|
14
|
+
type BundleGraphRequestRust = {
|
|
15
|
+
id: string;
|
|
16
|
+
readonly type: typeof requestTypes.bundle_graph_request;
|
|
17
|
+
run: (arg1: RunInput) => Async<BundleGraphResult>;
|
|
18
|
+
input: BundleGraphRequestInput;
|
|
19
|
+
};
|
|
20
|
+
type SerializedBundleGraph = {
|
|
21
|
+
nodes: Array<any>;
|
|
22
|
+
edges: Array<number>;
|
|
23
|
+
publicIdByAssetId: {
|
|
24
|
+
[k: string]: string;
|
|
25
|
+
};
|
|
26
|
+
assetPublicIds: Array<string>;
|
|
27
|
+
hadPreviousGraph: boolean;
|
|
28
|
+
};
|
|
29
|
+
export default function createBundleGraphRequestRust(input: BundleGraphRequestInput): BundleGraphRequestRust;
|
|
30
|
+
export declare function getBundleGraph(serializedGraph: SerializedBundleGraph): {
|
|
31
|
+
bundleGraph: InternalBundleGraph;
|
|
32
|
+
changedAssets: Map<string, Asset>;
|
|
33
|
+
};
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for BundleGraphRequest and BundleGraphRequestRust.
|
|
3
|
+
*
|
|
4
|
+
* This module contains common functionality used by both the JS and native
|
|
5
|
+
* bundling paths, such as bundle validation, naming, and configuration loading.
|
|
6
|
+
*/
|
|
7
|
+
import type { Namer } from '@atlaspack/types';
|
|
8
|
+
import type { LoadedPlugin } from '../AtlaspackConfig';
|
|
9
|
+
import type { RunAPI } from '../RequestTracker';
|
|
10
|
+
import type { Bundle as InternalBundle, Config, DevDepRequest, AtlaspackOptions, DevDepRequestRef } from '../types';
|
|
11
|
+
import InternalBundleGraph from '../BundleGraph';
|
|
12
|
+
import PluginOptions from '../public/PluginOptions';
|
|
13
|
+
import { PluginWithLoadConfig } from './ConfigRequest';
|
|
14
|
+
import type { BundleGraphResult } from './BundleGraphRequest';
|
|
15
|
+
/**
|
|
16
|
+
* Validates that all bundles have unique names.
|
|
17
|
+
* Throws an assertion error if duplicate bundle names are found.
|
|
18
|
+
*/
|
|
19
|
+
export declare function validateBundles(bundleGraph: InternalBundleGraph): void;
|
|
20
|
+
/**
|
|
21
|
+
* Names a bundle by running through the configured namers until one returns a name.
|
|
22
|
+
*/
|
|
23
|
+
export declare function nameBundle(namers: Array<LoadedPlugin<Namer<unknown>>>, internalBundle: InternalBundle, internalBundleGraph: InternalBundleGraph, options: AtlaspackOptions, pluginOptions: PluginOptions, configs: Map<string, Config>): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Loads configuration for a plugin and tracks its dev dependencies.
|
|
26
|
+
*/
|
|
27
|
+
export declare function loadPluginConfigWithDevDeps<T extends PluginWithLoadConfig>(plugin: LoadedPlugin<T>, options: AtlaspackOptions, api: RunAPI<BundleGraphResult>, previousDevDeps: Map<string, string>, devDepRequests: Map<string, DevDepRequest | DevDepRequestRef>, configs: Map<string, Config>): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Runs a dev dependency request and tracks it in the devDepRequests map.
|
|
30
|
+
*/
|
|
31
|
+
export declare function runDevDepRequest(api: RunAPI<BundleGraphResult>, devDepRequest: DevDepRequest | DevDepRequestRef, devDepRequests: Map<string, DevDepRequest | DevDepRequestRef>): Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaspack/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.33.0",
|
|
4
4
|
"license": "(MIT OR Apache-2.0)",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -23,22 +23,22 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@mischnic/json-sourcemap": "^0.1.0",
|
|
26
|
-
"@atlaspack/build-cache": "2.13.
|
|
27
|
-
"@atlaspack/cache": "3.2.
|
|
26
|
+
"@atlaspack/build-cache": "2.13.10",
|
|
27
|
+
"@atlaspack/cache": "3.2.47",
|
|
28
28
|
"@atlaspack/diagnostic": "2.14.4",
|
|
29
29
|
"@atlaspack/events": "2.14.4",
|
|
30
|
-
"@atlaspack/feature-flags": "2.
|
|
31
|
-
"@atlaspack/fs": "2.15.
|
|
32
|
-
"@atlaspack/graph": "3.6.
|
|
33
|
-
"@atlaspack/logger": "2.14.
|
|
34
|
-
"@atlaspack/package-manager": "2.14.
|
|
35
|
-
"@atlaspack/plugin": "2.14.
|
|
36
|
-
"@atlaspack/profiler": "2.15.
|
|
37
|
-
"@atlaspack/rust": "3.
|
|
38
|
-
"@atlaspack/types": "2.15.
|
|
39
|
-
"@atlaspack/utils": "3.3.
|
|
40
|
-
"@atlaspack/workers": "2.14.
|
|
41
|
-
"@atlaspack/source-map": "3.2.
|
|
30
|
+
"@atlaspack/feature-flags": "2.29.0",
|
|
31
|
+
"@atlaspack/fs": "2.15.47",
|
|
32
|
+
"@atlaspack/graph": "3.6.14",
|
|
33
|
+
"@atlaspack/logger": "2.14.44",
|
|
34
|
+
"@atlaspack/package-manager": "2.14.52",
|
|
35
|
+
"@atlaspack/plugin": "2.14.52",
|
|
36
|
+
"@atlaspack/profiler": "2.15.13",
|
|
37
|
+
"@atlaspack/rust": "3.22.0",
|
|
38
|
+
"@atlaspack/types": "2.15.42",
|
|
39
|
+
"@atlaspack/utils": "3.3.4",
|
|
40
|
+
"@atlaspack/workers": "2.14.52",
|
|
41
|
+
"@atlaspack/source-map": "3.2.7",
|
|
42
42
|
"base-x": "^3.0.8",
|
|
43
43
|
"browserslist": "^4.6.6",
|
|
44
44
|
"clone": "^2.1.1",
|
package/src/BundleGraph.ts
CHANGED
|
@@ -22,6 +22,7 @@ import type {
|
|
|
22
22
|
BundleNode,
|
|
23
23
|
Dependency,
|
|
24
24
|
DependencyNode,
|
|
25
|
+
Environment,
|
|
25
26
|
InternalSourceLocation,
|
|
26
27
|
Target,
|
|
27
28
|
Condition,
|
|
@@ -75,7 +76,7 @@ export const bundleGraphEdgeTypes = {
|
|
|
75
76
|
internal_async: 5,
|
|
76
77
|
// This type is used to mark an edge between a bundle and a conditional bundle.
|
|
77
78
|
// This allows efficient discovery of conditional bundles in packaging
|
|
78
|
-
conditional:
|
|
79
|
+
conditional: 6,
|
|
79
80
|
} as const;
|
|
80
81
|
|
|
81
82
|
export type BundleGraphEdgeType =
|
|
@@ -574,11 +575,13 @@ export default class BundleGraph {
|
|
|
574
575
|
|
|
575
576
|
/**
|
|
576
577
|
* Serialize the bundle graph for efficient transfer to native Rust code.
|
|
577
|
-
* Returns a JSON string of nodes
|
|
578
|
+
* Returns a JSON string of nodes, an array of edges, and a map of asset IDs to public IDs.
|
|
578
579
|
*/
|
|
579
580
|
serializeForNative(): {
|
|
580
581
|
nodesJson: string;
|
|
581
582
|
edges: [number, number, BundleGraphEdgeType][];
|
|
583
|
+
publicIdByAssetId: Record<string, string>;
|
|
584
|
+
environmentsJson: string;
|
|
582
585
|
} {
|
|
583
586
|
const start = performance.now();
|
|
584
587
|
|
|
@@ -593,18 +596,62 @@ export default class BundleGraph {
|
|
|
593
596
|
next = edgeIterator.next();
|
|
594
597
|
}
|
|
595
598
|
|
|
599
|
+
// Extract and deduplicate environments
|
|
600
|
+
const environmentMap = new Map<string, Environment>();
|
|
601
|
+
const extractEnvironment = (envRef: EnvironmentRef): string => {
|
|
602
|
+
const env = fromEnvironmentId(envRef);
|
|
603
|
+
const envId = env.id;
|
|
604
|
+
if (!environmentMap.has(envId)) {
|
|
605
|
+
environmentMap.set(envId, env);
|
|
606
|
+
}
|
|
607
|
+
return envId;
|
|
608
|
+
};
|
|
609
|
+
|
|
610
|
+
// Replace env objects with env IDs in nodes
|
|
611
|
+
const processedNodes = nodes.map((node) => {
|
|
612
|
+
const processedNode = {...node};
|
|
613
|
+
if (node.type === 'asset' && node.value?.env) {
|
|
614
|
+
processedNode.value = {
|
|
615
|
+
...node.value,
|
|
616
|
+
env: extractEnvironment(node.value.env),
|
|
617
|
+
};
|
|
618
|
+
} else if (node.type === 'dependency' && node.value?.env) {
|
|
619
|
+
processedNode.value = {
|
|
620
|
+
...node.value,
|
|
621
|
+
env: extractEnvironment(node.value.env),
|
|
622
|
+
};
|
|
623
|
+
} else if (node.type === 'bundle' && node.value?.env) {
|
|
624
|
+
processedNode.value = {
|
|
625
|
+
...node.value,
|
|
626
|
+
env: extractEnvironment(node.value.env),
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
return processedNode;
|
|
630
|
+
});
|
|
631
|
+
|
|
596
632
|
// Optimize nodes by omitting null/undefined values to reduce JSON size
|
|
597
|
-
const optimizedNodes =
|
|
633
|
+
const optimizedNodes = processedNodes.map((node) => this._omitNulls(node));
|
|
598
634
|
const nodesJson = JSON.stringify(optimizedNodes);
|
|
599
635
|
|
|
636
|
+
// Serialize environments as array
|
|
637
|
+
const environments = Array.from(environmentMap.values());
|
|
638
|
+
const environmentsJson = JSON.stringify(environments);
|
|
639
|
+
|
|
640
|
+
// Convert Map to plain object for serialization
|
|
641
|
+
const publicIdByAssetId: Record<string, string> = {};
|
|
642
|
+
for (const [assetId, publicId] of this._publicIdByAssetId) {
|
|
643
|
+
publicIdByAssetId[assetId] = publicId;
|
|
644
|
+
}
|
|
645
|
+
|
|
600
646
|
const duration = performance.now() - start;
|
|
601
|
-
const
|
|
647
|
+
const nodesSizeMB = (nodesJson.length / (1024 * 1024)).toFixed(2);
|
|
648
|
+
const envsSizeMB = (environmentsJson.length / (1024 * 1024)).toFixed(2);
|
|
602
649
|
logger.verbose({
|
|
603
650
|
origin: '@atlaspack/core',
|
|
604
|
-
message: `serializeForNative: ${duration.toFixed(1)}ms, ${
|
|
651
|
+
message: `serializeForNative: ${duration.toFixed(1)}ms, ${nodesSizeMB}MB nodes, ${envsSizeMB}MB envs (${environmentMap.size} unique), ${nodes.length} nodes, ${edges.length} edges`,
|
|
605
652
|
});
|
|
606
653
|
|
|
607
|
-
return {nodesJson, edges};
|
|
654
|
+
return {nodesJson, edges, publicIdByAssetId, environmentsJson};
|
|
608
655
|
}
|
|
609
656
|
|
|
610
657
|
/**
|
|
@@ -1773,8 +1820,36 @@ export default class BundleGraph {
|
|
|
1773
1820
|
}
|
|
1774
1821
|
|
|
1775
1822
|
/**
|
|
1776
|
-
*
|
|
1777
|
-
*
|
|
1823
|
+
* Performs a depth-first traversal of all assets and dependencies contained
|
|
1824
|
+
* within a bundle. Only visits nodes that are directly contained in the bundle
|
|
1825
|
+
* (connected via a `contains` edge).
|
|
1826
|
+
*
|
|
1827
|
+
* Entry Asset Ordering:
|
|
1828
|
+
* The traversal guarantees that entry assets are visited in the exact order they
|
|
1829
|
+
* appear in `bundle.entryAssetIds`. This ordering is critical for several reasons:
|
|
1830
|
+
*
|
|
1831
|
+
* 1. **Code Execution Order in Packagers**: Packagers (ScopeHoistingPackager,
|
|
1832
|
+
* DevPackager) use this traversal to concatenate assets into the final bundle.
|
|
1833
|
+
* The traversal order determines the execution order of code in the output.
|
|
1834
|
+
* Entry assets must be processed in their defined order to ensure correct
|
|
1835
|
+
* initialization sequences.
|
|
1836
|
+
*
|
|
1837
|
+
* 2. **Runtime Injection**: Runtime assets (HMR, bundle manifests) are prepended
|
|
1838
|
+
* to `entryAssetIds` via `unshift()` in `applyRuntimes.ts`. By honoring the
|
|
1839
|
+
* array order, runtimes are guaranteed to be visited (and thus output) before
|
|
1840
|
+
* application entry points, ensuring the runtime infrastructure is available
|
|
1841
|
+
* when application code executes.
|
|
1842
|
+
*
|
|
1843
|
+
* 3. **Deterministic Builds**: Consistent traversal order ensures reproducible
|
|
1844
|
+
* bundle output, which is essential for caching and build verification.
|
|
1845
|
+
*
|
|
1846
|
+
* The sorting only applies at the first traversal level (direct children of the
|
|
1847
|
+
* start node). Subsequent levels follow standard DFS order based on the graph's
|
|
1848
|
+
* edge structure.
|
|
1849
|
+
*
|
|
1850
|
+
* @param bundle - The bundle to traverse
|
|
1851
|
+
* @param visit - Visitor callback receiving asset or dependency nodes
|
|
1852
|
+
* @param startAsset - Optional asset to start traversal from (defaults to bundle root)
|
|
1778
1853
|
*/
|
|
1779
1854
|
traverseBundle<TContext>(
|
|
1780
1855
|
bundle: Bundle,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
atlaspackNapiCreate,
|
|
3
3
|
atlaspackNapiBuildAssetGraph,
|
|
4
|
+
atlaspackNapiBuildBundleGraph,
|
|
4
5
|
atlaspackNapiRespondToFsEvents,
|
|
5
6
|
atlaspackNapiCompleteSession,
|
|
6
7
|
atlaspackNapiLoadBundleGraph,
|
|
@@ -11,11 +12,11 @@ import {
|
|
|
11
12
|
CacheStats,
|
|
12
13
|
} from '@atlaspack/rust';
|
|
13
14
|
import {NapiWorkerPool} from './NapiWorkerPool';
|
|
14
|
-
import ThrowableDiagnostic from '@atlaspack/diagnostic';
|
|
15
|
+
import ThrowableDiagnostic, {Diagnostic} from '@atlaspack/diagnostic';
|
|
15
16
|
import type {Event} from '@parcel/watcher';
|
|
16
17
|
import type {NapiWorkerPool as INapiWorkerPool} from '@atlaspack/types';
|
|
17
|
-
import invariant from 'assert';
|
|
18
18
|
import type BundleGraph from '../BundleGraph';
|
|
19
|
+
import {RunPackagerRunnerResult} from '../PackagerRunner';
|
|
19
20
|
|
|
20
21
|
export type AtlaspackV3Options = {
|
|
21
22
|
fs?: AtlaspackNapiOptions['fs'];
|
|
@@ -101,18 +102,29 @@ export class AtlaspackV3 {
|
|
|
101
102
|
return atlaspackNapiBuildAssetGraph(this._atlaspack_napi) as Promise<any>;
|
|
102
103
|
}
|
|
103
104
|
|
|
105
|
+
buildBundleGraph(): Promise<any> {
|
|
106
|
+
return atlaspackNapiBuildBundleGraph(this._atlaspack_napi) as Promise<any>;
|
|
107
|
+
}
|
|
108
|
+
|
|
104
109
|
loadBundleGraph(bundleGraph: BundleGraph): Promise<void> {
|
|
105
|
-
const {nodesJson, edges} =
|
|
110
|
+
const {nodesJson, edges, publicIdByAssetId, environmentsJson} =
|
|
111
|
+
bundleGraph.serializeForNative();
|
|
106
112
|
|
|
107
113
|
return atlaspackNapiLoadBundleGraph(
|
|
108
114
|
this._atlaspack_napi,
|
|
109
115
|
nodesJson,
|
|
110
116
|
edges,
|
|
117
|
+
publicIdByAssetId,
|
|
118
|
+
environmentsJson,
|
|
111
119
|
) as Promise<void>;
|
|
112
120
|
}
|
|
113
121
|
|
|
114
|
-
package(
|
|
115
|
-
|
|
122
|
+
package(
|
|
123
|
+
bundleId: string,
|
|
124
|
+
): Promise<[RunPackagerRunnerResult, Diagnostic | null]> {
|
|
125
|
+
return atlaspackNapiPackage(this._atlaspack_napi, bundleId) as Promise<
|
|
126
|
+
[RunPackagerRunnerResult, Diagnostic | null]
|
|
127
|
+
>;
|
|
116
128
|
}
|
|
117
129
|
|
|
118
130
|
async respondToFsEvents(events: Array<Event>): Promise<boolean> {
|
|
@@ -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, {
|