@atlaspack/core 2.31.3 → 2.32.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 +52 -0
- package/dist/Atlaspack.js +4 -3
- package/dist/BundleGraph.js +134 -3
- package/dist/atlaspack-v3/AtlaspackV3.js +7 -0
- package/dist/requests/AtlaspackBuildRequest.js +17 -0
- package/dist/requests/BundleGraphRequest.js +1 -1
- package/dist/requests/PackageRequest.js +37 -10
- package/dist/resolveOptions.js +1 -1
- package/lib/Atlaspack.js +3 -3
- package/lib/BundleGraph.js +148 -3
- package/lib/atlaspack-v3/AtlaspackV3.js +12 -0
- package/lib/requests/AtlaspackBuildRequest.js +20 -0
- package/lib/requests/BundleGraphRequest.js +1 -1
- package/lib/requests/PackageRequest.js +51 -10
- package/lib/resolveOptions.js +1 -1
- package/lib/types/BundleGraph.d.ts +46 -3
- package/lib/types/atlaspack-v3/AtlaspackV3.d.ts +5 -0
- package/package.json +15 -15
- package/src/Atlaspack.ts +11 -4
- package/src/BundleGraph.ts +149 -3
- package/src/atlaspack-v3/AtlaspackV3.ts +26 -1
- package/src/requests/AtlaspackBuildRequest.ts +23 -0
- package/src/requests/BundleGraphRequest.ts +4 -3
- package/src/requests/PackageRequest.ts +32 -3
- package/src/resolveOptions.ts +2 -1
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,57 @@
|
|
|
1
1
|
# @atlaspack/core
|
|
2
2
|
|
|
3
|
+
## 2.32.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#988](https://github.com/atlassian-labs/atlaspack/pull/988) [`a631dcd`](https://github.com/atlassian-labs/atlaspack/commit/a631dcd961112db072b0f8de0831efd178f355a7) Thanks [@marcins](https://github.com/marcins)! - Implement a basic package() method for the native packager
|
|
8
|
+
|
|
9
|
+
- [#990](https://github.com/atlassian-labs/atlaspack/pull/990) [`5755a11`](https://github.com/atlassian-labs/atlaspack/commit/5755a114903bbf660e2ada3ae2e7ff6ceac7565b) Thanks [@vykimnguyen](https://github.com/vykimnguyen)! - changes conditional bundleGraphEdgeType value
|
|
10
|
+
|
|
11
|
+
- [#987](https://github.com/atlassian-labs/atlaspack/pull/987) [`fcaf517`](https://github.com/atlassian-labs/atlaspack/commit/fcaf517010d15c9300393bcad3f9b465689d9d16) Thanks [@vykimnguyen](https://github.com/vykimnguyen)! - add get_bundle_assets
|
|
12
|
+
|
|
13
|
+
- Updated dependencies [[`a631dcd`](https://github.com/atlassian-labs/atlaspack/commit/a631dcd961112db072b0f8de0831efd178f355a7), [`e9dce31`](https://github.com/atlassian-labs/atlaspack/commit/e9dce3168a8e6727a994bf2a6ac6041eb29f6027), [`59e1345`](https://github.com/atlassian-labs/atlaspack/commit/59e1345f84f43e0632d434ab42c06bf748241985), [`783118c`](https://github.com/atlassian-labs/atlaspack/commit/783118c772f45a0cf6a3b6b447fb9a0e225b25a6), [`fcaf517`](https://github.com/atlassian-labs/atlaspack/commit/fcaf517010d15c9300393bcad3f9b465689d9d16)]:
|
|
14
|
+
- @atlaspack/rust@3.21.0
|
|
15
|
+
- @atlaspack/cache@3.2.46
|
|
16
|
+
- @atlaspack/fs@2.15.46
|
|
17
|
+
- @atlaspack/logger@2.14.43
|
|
18
|
+
- @atlaspack/source-map@3.2.6
|
|
19
|
+
- @atlaspack/utils@3.3.3
|
|
20
|
+
- @atlaspack/package-manager@2.14.51
|
|
21
|
+
- @atlaspack/profiler@2.15.12
|
|
22
|
+
- @atlaspack/workers@2.14.51
|
|
23
|
+
- @atlaspack/types@2.15.41
|
|
24
|
+
- @atlaspack/graph@3.6.13
|
|
25
|
+
- @atlaspack/plugin@2.14.51
|
|
26
|
+
|
|
27
|
+
## 2.32.0
|
|
28
|
+
|
|
29
|
+
### Minor Changes
|
|
30
|
+
|
|
31
|
+
- [#976](https://github.com/atlassian-labs/atlaspack/pull/976) [`e8ea59b`](https://github.com/atlassian-labs/atlaspack/commit/e8ea59beabb4b4fef647dc9ebea3519b6d56d7b5) Thanks [@marcins](https://github.com/marcins)! - Initial implementation of loadBundleGraph to deserialise JS -> Rust BundleGraph.
|
|
32
|
+
|
|
33
|
+
- [#970](https://github.com/atlassian-labs/atlaspack/pull/970) [`8826fd0`](https://github.com/atlassian-labs/atlaspack/commit/8826fd02c29c9c67cf0c80da41f424257fbdef93) Thanks [@marcins](https://github.com/marcins)! - Add initial plumbing for native packaging to core and Atlaspack V3 code
|
|
34
|
+
|
|
35
|
+
### Patch Changes
|
|
36
|
+
|
|
37
|
+
- [#984](https://github.com/atlassian-labs/atlaspack/pull/984) [`dbcaabb`](https://github.com/atlassian-labs/atlaspack/commit/dbcaabbf15d4fbc8ecd9c0be58cf7b2317eebfc4) Thanks [@marcins](https://github.com/marcins)! - Serialise to JSON on the JS side before sending bundle graph nodes to Rust for performance.
|
|
38
|
+
|
|
39
|
+
- Updated dependencies [[`e8ea59b`](https://github.com/atlassian-labs/atlaspack/commit/e8ea59beabb4b4fef647dc9ebea3519b6d56d7b5), [`3753cb1`](https://github.com/atlassian-labs/atlaspack/commit/3753cb1bf9155eaf3a1a8f952886864682738647), [`8826fd0`](https://github.com/atlassian-labs/atlaspack/commit/8826fd02c29c9c67cf0c80da41f424257fbdef93), [`225683f`](https://github.com/atlassian-labs/atlaspack/commit/225683f7c59355da53b7004d2b8596701ce3af41), [`43adda0`](https://github.com/atlassian-labs/atlaspack/commit/43adda06bf3b6a404b54f8ba2a3b810d92e61d75), [`dbcaabb`](https://github.com/atlassian-labs/atlaspack/commit/dbcaabbf15d4fbc8ecd9c0be58cf7b2317eebfc4)]:
|
|
40
|
+
- @atlaspack/rust@3.20.0
|
|
41
|
+
- @atlaspack/feature-flags@2.28.0
|
|
42
|
+
- @atlaspack/cache@3.2.45
|
|
43
|
+
- @atlaspack/fs@2.15.45
|
|
44
|
+
- @atlaspack/logger@2.14.42
|
|
45
|
+
- @atlaspack/source-map@3.2.5
|
|
46
|
+
- @atlaspack/utils@3.3.2
|
|
47
|
+
- @atlaspack/build-cache@2.13.9
|
|
48
|
+
- @atlaspack/graph@3.6.12
|
|
49
|
+
- @atlaspack/package-manager@2.14.50
|
|
50
|
+
- @atlaspack/profiler@2.15.11
|
|
51
|
+
- @atlaspack/workers@2.14.50
|
|
52
|
+
- @atlaspack/plugin@2.14.50
|
|
53
|
+
- @atlaspack/types@2.15.40
|
|
54
|
+
|
|
3
55
|
## 2.31.3
|
|
4
56
|
|
|
5
57
|
### Patch Changes
|
package/dist/Atlaspack.js
CHANGED
|
@@ -157,7 +157,8 @@ class Atlaspack {
|
|
|
157
157
|
});
|
|
158
158
|
__classPrivateFieldSet(this, _Atlaspack_resolvedOptions, resolvedOptions, "f");
|
|
159
159
|
let rustAtlaspack;
|
|
160
|
-
if (resolvedOptions.featureFlags.atlaspackV3
|
|
160
|
+
if (resolvedOptions.featureFlags.atlaspackV3 ||
|
|
161
|
+
resolvedOptions.featureFlags.nativePackager) {
|
|
161
162
|
// eslint-disable-next-line no-unused-vars
|
|
162
163
|
let { entries, inputFS, outputFS, ...options } = __classPrivateFieldGet(this, _Atlaspack_initialOptions, "f");
|
|
163
164
|
if (!(resolvedOptions.cache instanceof cache_1.LMDBLiteCache)) {
|
|
@@ -487,7 +488,7 @@ class Atlaspack {
|
|
|
487
488
|
message: `File watch event emitted with ${events.length} events. Sample event: [${events[0]?.type}] ${events[0]?.path}`,
|
|
488
489
|
});
|
|
489
490
|
let nativeInvalid = false;
|
|
490
|
-
if (this.rustAtlaspack) {
|
|
491
|
+
if ((0, feature_flags_1.getFeatureFlag)('atlaspackV3') && this.rustAtlaspack) {
|
|
491
492
|
nativeInvalid = await this.rustAtlaspack.respondToFsEvents(events);
|
|
492
493
|
}
|
|
493
494
|
let { didInvalidate: isInvalid } = await __classPrivateFieldGet(this, _Atlaspack_requestTracker, "f").respondToFSEvents(events, Number.POSITIVE_INFINITY);
|
|
@@ -555,7 +556,7 @@ class Atlaspack {
|
|
|
555
556
|
requestedAssetIds: __classPrivateFieldGet(this, _Atlaspack_requestedAssetIds, "f"),
|
|
556
557
|
};
|
|
557
558
|
const start = Date.now();
|
|
558
|
-
const result = await __classPrivateFieldGet(this, _Atlaspack_requestTracker, "f").runRequest(this.rustAtlaspack != null
|
|
559
|
+
const result = await __classPrivateFieldGet(this, _Atlaspack_requestTracker, "f").runRequest((0, feature_flags_1.getFeatureFlag)('atlaspackV3') && this.rustAtlaspack != null
|
|
559
560
|
? // @ts-expect-error TS2345
|
|
560
561
|
(0, AssetGraphRequestRust_1.createAssetGraphRequestRust)(this.rustAtlaspack)(input)
|
|
561
562
|
: // @ts-expect-error TS2345
|
package/dist/BundleGraph.js
CHANGED
|
@@ -16,6 +16,7 @@ const Environment_1 = require("./public/Environment");
|
|
|
16
16
|
const projectPath_1 = require("./projectPath");
|
|
17
17
|
const constants_1 = require("./constants");
|
|
18
18
|
const feature_flags_1 = require("@atlaspack/feature-flags");
|
|
19
|
+
const logger_1 = __importDefault(require("@atlaspack/logger"));
|
|
19
20
|
const EnvironmentManager_1 = require("./EnvironmentManager");
|
|
20
21
|
exports.bundleGraphEdgeTypes = {
|
|
21
22
|
// A lack of an edge type indicates to follow the edge while traversing
|
|
@@ -42,7 +43,7 @@ exports.bundleGraphEdgeTypes = {
|
|
|
42
43
|
internal_async: 5,
|
|
43
44
|
// This type is used to mark an edge between a bundle and a conditional bundle.
|
|
44
45
|
// This allows efficient discovery of conditional bundles in packaging
|
|
45
|
-
conditional:
|
|
46
|
+
conditional: 6,
|
|
46
47
|
};
|
|
47
48
|
function makeReadOnlySet(set) {
|
|
48
49
|
return new Proxy(set, {
|
|
@@ -380,6 +381,108 @@ class BundleGraph {
|
|
|
380
381
|
conditions: serialized.conditions,
|
|
381
382
|
});
|
|
382
383
|
}
|
|
384
|
+
/**
|
|
385
|
+
* Serialize the bundle graph for efficient transfer to native Rust code.
|
|
386
|
+
* Returns a JSON string of nodes, an array of edges, and a map of asset IDs to public IDs.
|
|
387
|
+
*/
|
|
388
|
+
serializeForNative() {
|
|
389
|
+
const start = performance.now();
|
|
390
|
+
const nodes = this._graph.nodes;
|
|
391
|
+
const edges = [];
|
|
392
|
+
const edgeIterator = this._graph.getAllEdges();
|
|
393
|
+
let next = edgeIterator.next();
|
|
394
|
+
while (!next.done) {
|
|
395
|
+
const edge = next.value;
|
|
396
|
+
edges.push([edge.from, edge.to, edge.type]);
|
|
397
|
+
next = edgeIterator.next();
|
|
398
|
+
}
|
|
399
|
+
// Extract and deduplicate environments
|
|
400
|
+
const environmentMap = new Map();
|
|
401
|
+
const extractEnvironment = (envRef) => {
|
|
402
|
+
const env = (0, EnvironmentManager_1.fromEnvironmentId)(envRef);
|
|
403
|
+
const envId = env.id;
|
|
404
|
+
if (!environmentMap.has(envId)) {
|
|
405
|
+
environmentMap.set(envId, env);
|
|
406
|
+
}
|
|
407
|
+
return envId;
|
|
408
|
+
};
|
|
409
|
+
// Replace env objects with env IDs in nodes
|
|
410
|
+
const processedNodes = nodes.map((node) => {
|
|
411
|
+
const processedNode = { ...node };
|
|
412
|
+
if (node.type === 'asset' && node.value?.env) {
|
|
413
|
+
processedNode.value = {
|
|
414
|
+
...node.value,
|
|
415
|
+
env: extractEnvironment(node.value.env),
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
else if (node.type === 'dependency' && node.value?.env) {
|
|
419
|
+
processedNode.value = {
|
|
420
|
+
...node.value,
|
|
421
|
+
env: extractEnvironment(node.value.env),
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
else if (node.type === 'bundle' && node.value?.env) {
|
|
425
|
+
processedNode.value = {
|
|
426
|
+
...node.value,
|
|
427
|
+
env: extractEnvironment(node.value.env),
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
return processedNode;
|
|
431
|
+
});
|
|
432
|
+
// Optimize nodes by omitting null/undefined values to reduce JSON size
|
|
433
|
+
const optimizedNodes = processedNodes.map((node) => this._omitNulls(node));
|
|
434
|
+
const nodesJson = JSON.stringify(optimizedNodes);
|
|
435
|
+
// Serialize environments as array
|
|
436
|
+
const environments = Array.from(environmentMap.values());
|
|
437
|
+
const environmentsJson = JSON.stringify(environments);
|
|
438
|
+
// Convert Map to plain object for serialization
|
|
439
|
+
const publicIdByAssetId = {};
|
|
440
|
+
for (const [assetId, publicId] of this._publicIdByAssetId) {
|
|
441
|
+
publicIdByAssetId[assetId] = publicId;
|
|
442
|
+
}
|
|
443
|
+
const duration = performance.now() - start;
|
|
444
|
+
const nodesSizeMB = (nodesJson.length / (1024 * 1024)).toFixed(2);
|
|
445
|
+
const envsSizeMB = (environmentsJson.length / (1024 * 1024)).toFixed(2);
|
|
446
|
+
logger_1.default.verbose({
|
|
447
|
+
origin: '@atlaspack/core',
|
|
448
|
+
message: `serializeForNative: ${duration.toFixed(1)}ms, ${nodesSizeMB}MB nodes, ${envsSizeMB}MB envs (${environmentMap.size} unique), ${nodes.length} nodes, ${edges.length} edges`,
|
|
449
|
+
});
|
|
450
|
+
return { nodesJson, edges, publicIdByAssetId, environmentsJson };
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Remove null and undefined values from an object to reduce JSON size.
|
|
454
|
+
* Preserves false, 0, empty strings, and arrays.
|
|
455
|
+
*/
|
|
456
|
+
_omitNulls(obj) {
|
|
457
|
+
if (obj === null || obj === undefined)
|
|
458
|
+
return obj;
|
|
459
|
+
if (typeof obj !== 'object')
|
|
460
|
+
return obj;
|
|
461
|
+
if (Array.isArray(obj)) {
|
|
462
|
+
return obj.map((item) => this._omitNulls(item));
|
|
463
|
+
}
|
|
464
|
+
const result = {};
|
|
465
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
466
|
+
if (value === null || value === undefined) {
|
|
467
|
+
continue;
|
|
468
|
+
}
|
|
469
|
+
if (typeof value === 'object' &&
|
|
470
|
+
!Array.isArray(value) &&
|
|
471
|
+
Object.keys(value).length === 0) {
|
|
472
|
+
continue;
|
|
473
|
+
}
|
|
474
|
+
if (typeof value === 'object') {
|
|
475
|
+
const processed = this._omitNulls(value);
|
|
476
|
+
if (processed !== undefined) {
|
|
477
|
+
result[key] = processed;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
else {
|
|
481
|
+
result[key] = value;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
return result;
|
|
485
|
+
}
|
|
383
486
|
createBundle(opts) {
|
|
384
487
|
// @ts-expect-error TS2339
|
|
385
488
|
let { entryAsset, target } = opts;
|
|
@@ -1103,8 +1206,36 @@ class BundleGraph {
|
|
|
1103
1206
|
});
|
|
1104
1207
|
}
|
|
1105
1208
|
/**
|
|
1106
|
-
*
|
|
1107
|
-
*
|
|
1209
|
+
* Performs a depth-first traversal of all assets and dependencies contained
|
|
1210
|
+
* within a bundle. Only visits nodes that are directly contained in the bundle
|
|
1211
|
+
* (connected via a `contains` edge).
|
|
1212
|
+
*
|
|
1213
|
+
* Entry Asset Ordering:
|
|
1214
|
+
* The traversal guarantees that entry assets are visited in the exact order they
|
|
1215
|
+
* appear in `bundle.entryAssetIds`. This ordering is critical for several reasons:
|
|
1216
|
+
*
|
|
1217
|
+
* 1. **Code Execution Order in Packagers**: Packagers (ScopeHoistingPackager,
|
|
1218
|
+
* DevPackager) use this traversal to concatenate assets into the final bundle.
|
|
1219
|
+
* The traversal order determines the execution order of code in the output.
|
|
1220
|
+
* Entry assets must be processed in their defined order to ensure correct
|
|
1221
|
+
* initialization sequences.
|
|
1222
|
+
*
|
|
1223
|
+
* 2. **Runtime Injection**: Runtime assets (HMR, bundle manifests) are prepended
|
|
1224
|
+
* to `entryAssetIds` via `unshift()` in `applyRuntimes.ts`. By honoring the
|
|
1225
|
+
* array order, runtimes are guaranteed to be visited (and thus output) before
|
|
1226
|
+
* application entry points, ensuring the runtime infrastructure is available
|
|
1227
|
+
* when application code executes.
|
|
1228
|
+
*
|
|
1229
|
+
* 3. **Deterministic Builds**: Consistent traversal order ensures reproducible
|
|
1230
|
+
* bundle output, which is essential for caching and build verification.
|
|
1231
|
+
*
|
|
1232
|
+
* The sorting only applies at the first traversal level (direct children of the
|
|
1233
|
+
* start node). Subsequent levels follow standard DFS order based on the graph's
|
|
1234
|
+
* edge structure.
|
|
1235
|
+
*
|
|
1236
|
+
* @param bundle - The bundle to traverse
|
|
1237
|
+
* @param visit - Visitor callback receiving asset or dependency nodes
|
|
1238
|
+
* @param startAsset - Optional asset to start traversal from (defaults to bundle root)
|
|
1108
1239
|
*/
|
|
1109
1240
|
traverseBundle(bundle, visit, startAsset) {
|
|
1110
1241
|
let entries = !startAsset;
|
|
@@ -51,6 +51,13 @@ class AtlaspackV3 {
|
|
|
51
51
|
buildAssetGraph() {
|
|
52
52
|
return (0, rust_1.atlaspackNapiBuildAssetGraph)(this._atlaspack_napi);
|
|
53
53
|
}
|
|
54
|
+
loadBundleGraph(bundleGraph) {
|
|
55
|
+
const { nodesJson, edges, publicIdByAssetId, environmentsJson } = bundleGraph.serializeForNative();
|
|
56
|
+
return (0, rust_1.atlaspackNapiLoadBundleGraph)(this._atlaspack_napi, nodesJson, edges, publicIdByAssetId, environmentsJson);
|
|
57
|
+
}
|
|
58
|
+
package(bundleId) {
|
|
59
|
+
return (0, rust_1.atlaspackNapiPackage)(this._atlaspack_napi, bundleId);
|
|
60
|
+
}
|
|
54
61
|
async respondToFsEvents(events) {
|
|
55
62
|
// @ts-expect-error TS2488
|
|
56
63
|
let [needsRebuild, error] = await (0, rust_1.atlaspackNapiRespondToFsEvents)(this._atlaspack_napi, events);
|
|
@@ -15,6 +15,8 @@ const Bundle_1 = require("../public/Bundle");
|
|
|
15
15
|
const Asset_1 = require("../public/Asset");
|
|
16
16
|
const profiler_1 = require("@atlaspack/profiler");
|
|
17
17
|
const RequestTracker_1 = require("../RequestTracker");
|
|
18
|
+
const feature_flags_1 = require("@atlaspack/feature-flags");
|
|
19
|
+
const EnvironmentManager_1 = require("../EnvironmentManager");
|
|
18
20
|
function createAtlaspackBuildRequest(input) {
|
|
19
21
|
return {
|
|
20
22
|
type: RequestTracker_1.requestTypes.atlaspack_build_request,
|
|
@@ -34,6 +36,21 @@ async function run({ input, api, options, rustAtlaspack, }) {
|
|
|
34
36
|
force: Boolean(rustAtlaspack) ||
|
|
35
37
|
(options.shouldBuildLazily && requestedAssetIds.size > 0),
|
|
36
38
|
});
|
|
39
|
+
if ((0, feature_flags_1.getFeatureFlag)('nativePackager') &&
|
|
40
|
+
(0, feature_flags_1.getFeatureFlag)('nativePackagerSSRDev') &&
|
|
41
|
+
rustAtlaspack) {
|
|
42
|
+
let hasSupportedTarget = false;
|
|
43
|
+
bundleGraph.traverseBundles((bundle, ctx, actions) => {
|
|
44
|
+
if ((0, EnvironmentManager_1.fromEnvironmentId)(bundle.env).context === 'tesseract' &&
|
|
45
|
+
bundle.type === 'js') {
|
|
46
|
+
hasSupportedTarget = true;
|
|
47
|
+
actions.stop();
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
if (hasSupportedTarget) {
|
|
51
|
+
await rustAtlaspack.loadBundleGraph(bundleGraph);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
37
54
|
// @ts-expect-error TS2345
|
|
38
55
|
(0, dumpGraphToGraphViz_1.default)(bundleGraph._graph, 'BundleGraph', BundleGraph_1.bundleGraphEdgeTypes);
|
|
39
56
|
await (0, ReporterRunner_1.report)({
|
|
@@ -104,7 +104,7 @@ function createBundleGraphRequest(input) {
|
|
|
104
104
|
let { options, api, invalidateReason } = input;
|
|
105
105
|
let { optionsRef, requestedAssetIds, signal } = input.input;
|
|
106
106
|
let measurement = profiler_1.tracer.createMeasurement('building');
|
|
107
|
-
let createAssetGraphRequest = input.rustAtlaspack
|
|
107
|
+
let createAssetGraphRequest = (0, feature_flags_1.getFeatureFlag)('atlaspackV3') && input.rustAtlaspack
|
|
108
108
|
? (0, AssetGraphRequestRust_1.createAssetGraphRequestRust)(input.rustAtlaspack)
|
|
109
109
|
: AssetGraphRequest_1.default;
|
|
110
110
|
let request = createAssetGraphRequest({
|
|
@@ -9,6 +9,10 @@ const nullthrows_1 = __importDefault(require("nullthrows"));
|
|
|
9
9
|
const ConfigRequest_1 = require("./ConfigRequest");
|
|
10
10
|
const DevDepRequest_1 = require("./DevDepRequest");
|
|
11
11
|
const AtlaspackConfigRequest_1 = __importDefault(require("./AtlaspackConfigRequest"));
|
|
12
|
+
const EnvironmentManager_1 = require("../EnvironmentManager");
|
|
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"));
|
|
12
16
|
function createPackageRequest(input) {
|
|
13
17
|
return {
|
|
14
18
|
type: RequestTracker_1.requestTypes.package_request,
|
|
@@ -17,21 +21,44 @@ function createPackageRequest(input) {
|
|
|
17
21
|
input,
|
|
18
22
|
};
|
|
19
23
|
}
|
|
20
|
-
async function run({ input, api, farm }) {
|
|
24
|
+
async function run({ input, api, farm, rustAtlaspack }) {
|
|
21
25
|
let { bundleGraphReference, optionsRef, bundle, useMainThread } = input;
|
|
22
26
|
let runPackage = farm.createHandle('runPackage', useMainThread);
|
|
23
27
|
let start = Date.now();
|
|
24
28
|
let { devDeps, invalidDevDeps } = await (0, DevDepRequest_1.getDevDepRequests)(api);
|
|
25
29
|
let { cachePath } = (0, nullthrows_1.default)(await api.runRequest((0, AtlaspackConfigRequest_1.default)()));
|
|
26
|
-
let
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
let packagingResult;
|
|
31
|
+
if ((0, feature_flags_1.getFeatureFlag)('nativePackager') &&
|
|
32
|
+
(0, feature_flags_1.getFeatureFlag)('nativePackagerSSRDev') &&
|
|
33
|
+
rustAtlaspack &&
|
|
34
|
+
(0, EnvironmentManager_1.fromEnvironmentId)(bundle.env).context === 'tesseract' &&
|
|
35
|
+
bundle.type === 'js') {
|
|
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)
|
|
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
|
+
}));
|
|
60
|
+
}
|
|
61
|
+
let { devDepRequests, configRequests, bundleInfo, invalidations } = packagingResult;
|
|
35
62
|
for (let devDepRequest of devDepRequests) {
|
|
36
63
|
await (0, DevDepRequest_1.runDevDepRequest)(api, devDepRequest);
|
|
37
64
|
}
|
package/dist/resolveOptions.js
CHANGED
|
@@ -132,7 +132,7 @@ async function resolveOptions(initialOptions) {
|
|
|
132
132
|
if (initialOptions.cache) {
|
|
133
133
|
return initialOptions.cache;
|
|
134
134
|
}
|
|
135
|
-
const needsRustLmdbCache = (0, feature_flags_1.getFeatureFlag)('atlaspackV3');
|
|
135
|
+
const needsRustLmdbCache = (0, feature_flags_1.getFeatureFlag)('atlaspackV3') || (0, feature_flags_1.getFeatureFlag)('nativePackager');
|
|
136
136
|
if (!(0, feature_flags_1.getFeatureFlag)('cachePerformanceImprovements')) {
|
|
137
137
|
if (!needsRustLmdbCache && !(outputFS instanceof fs_1.NodeFS)) {
|
|
138
138
|
return new cache_1.FSCache(outputFS, cacheDir);
|
package/lib/Atlaspack.js
CHANGED
|
@@ -197,7 +197,7 @@ class Atlaspack {
|
|
|
197
197
|
});
|
|
198
198
|
this.#resolvedOptions = resolvedOptions;
|
|
199
199
|
let rustAtlaspack;
|
|
200
|
-
if (resolvedOptions.featureFlags.atlaspackV3) {
|
|
200
|
+
if (resolvedOptions.featureFlags.atlaspackV3 || resolvedOptions.featureFlags.nativePackager) {
|
|
201
201
|
// eslint-disable-next-line no-unused-vars
|
|
202
202
|
let {
|
|
203
203
|
entries,
|
|
@@ -553,7 +553,7 @@ class Atlaspack {
|
|
|
553
553
|
message: `File watch event emitted with ${events.length} events. Sample event: [${(_events$ = events[0]) === null || _events$ === void 0 ? void 0 : _events$.type}] ${(_events$2 = events[0]) === null || _events$2 === void 0 ? void 0 : _events$2.path}`
|
|
554
554
|
});
|
|
555
555
|
let nativeInvalid = false;
|
|
556
|
-
if (this.rustAtlaspack) {
|
|
556
|
+
if ((0, _featureFlags().getFeatureFlag)('atlaspackV3') && this.rustAtlaspack) {
|
|
557
557
|
nativeInvalid = await this.rustAtlaspack.respondToFsEvents(events);
|
|
558
558
|
}
|
|
559
559
|
let {
|
|
@@ -634,7 +634,7 @@ class Atlaspack {
|
|
|
634
634
|
requestedAssetIds: this.#requestedAssetIds
|
|
635
635
|
};
|
|
636
636
|
const start = Date.now();
|
|
637
|
-
const result = await this.#requestTracker.runRequest(this.rustAtlaspack != null ?
|
|
637
|
+
const result = await this.#requestTracker.runRequest((0, _featureFlags().getFeatureFlag)('atlaspackV3') && this.rustAtlaspack != null ?
|
|
638
638
|
// @ts-expect-error TS2345
|
|
639
639
|
(0, _AssetGraphRequestRust.createAssetGraphRequestRust)(this.rustAtlaspack)(input) :
|
|
640
640
|
// @ts-expect-error TS2345
|
package/lib/BundleGraph.js
CHANGED
|
@@ -51,6 +51,13 @@ function _featureFlags() {
|
|
|
51
51
|
};
|
|
52
52
|
return data;
|
|
53
53
|
}
|
|
54
|
+
function _logger() {
|
|
55
|
+
const data = _interopRequireDefault(require("@atlaspack/logger"));
|
|
56
|
+
_logger = function () {
|
|
57
|
+
return data;
|
|
58
|
+
};
|
|
59
|
+
return data;
|
|
60
|
+
}
|
|
54
61
|
var _EnvironmentManager = require("./EnvironmentManager");
|
|
55
62
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
56
63
|
const bundleGraphEdgeTypes = exports.bundleGraphEdgeTypes = {
|
|
@@ -78,7 +85,7 @@ const bundleGraphEdgeTypes = exports.bundleGraphEdgeTypes = {
|
|
|
78
85
|
internal_async: 5,
|
|
79
86
|
// This type is used to mark an edge between a bundle and a conditional bundle.
|
|
80
87
|
// This allows efficient discovery of conditional bundles in packaging
|
|
81
|
-
conditional:
|
|
88
|
+
conditional: 6
|
|
82
89
|
};
|
|
83
90
|
function makeReadOnlySet(set) {
|
|
84
91
|
return new Proxy(set, {
|
|
@@ -428,6 +435,116 @@ class BundleGraph {
|
|
|
428
435
|
conditions: serialized.conditions
|
|
429
436
|
});
|
|
430
437
|
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Serialize the bundle graph for efficient transfer to native Rust code.
|
|
441
|
+
* Returns a JSON string of nodes, an array of edges, and a map of asset IDs to public IDs.
|
|
442
|
+
*/
|
|
443
|
+
serializeForNative() {
|
|
444
|
+
const start = performance.now();
|
|
445
|
+
const nodes = this._graph.nodes;
|
|
446
|
+
const edges = [];
|
|
447
|
+
const edgeIterator = this._graph.getAllEdges();
|
|
448
|
+
let next = edgeIterator.next();
|
|
449
|
+
while (!next.done) {
|
|
450
|
+
const edge = next.value;
|
|
451
|
+
edges.push([edge.from, edge.to, edge.type]);
|
|
452
|
+
next = edgeIterator.next();
|
|
453
|
+
}
|
|
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
|
+
|
|
491
|
+
// Optimize nodes by omitting null/undefined values to reduce JSON size
|
|
492
|
+
const optimizedNodes = processedNodes.map(node => this._omitNulls(node));
|
|
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
|
+
}
|
|
504
|
+
const duration = performance.now() - start;
|
|
505
|
+
const nodesSizeMB = (nodesJson.length / (1024 * 1024)).toFixed(2);
|
|
506
|
+
const envsSizeMB = (environmentsJson.length / (1024 * 1024)).toFixed(2);
|
|
507
|
+
_logger().default.verbose({
|
|
508
|
+
origin: '@atlaspack/core',
|
|
509
|
+
message: `serializeForNative: ${duration.toFixed(1)}ms, ${nodesSizeMB}MB nodes, ${envsSizeMB}MB envs (${environmentMap.size} unique), ${nodes.length} nodes, ${edges.length} edges`
|
|
510
|
+
});
|
|
511
|
+
return {
|
|
512
|
+
nodesJson,
|
|
513
|
+
edges,
|
|
514
|
+
publicIdByAssetId,
|
|
515
|
+
environmentsJson
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Remove null and undefined values from an object to reduce JSON size.
|
|
521
|
+
* Preserves false, 0, empty strings, and arrays.
|
|
522
|
+
*/
|
|
523
|
+
_omitNulls(obj) {
|
|
524
|
+
if (obj === null || obj === undefined) return obj;
|
|
525
|
+
if (typeof obj !== 'object') return obj;
|
|
526
|
+
if (Array.isArray(obj)) {
|
|
527
|
+
return obj.map(item => this._omitNulls(item));
|
|
528
|
+
}
|
|
529
|
+
const result = {};
|
|
530
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
531
|
+
if (value === null || value === undefined) {
|
|
532
|
+
continue;
|
|
533
|
+
}
|
|
534
|
+
if (typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length === 0) {
|
|
535
|
+
continue;
|
|
536
|
+
}
|
|
537
|
+
if (typeof value === 'object') {
|
|
538
|
+
const processed = this._omitNulls(value);
|
|
539
|
+
if (processed !== undefined) {
|
|
540
|
+
result[key] = processed;
|
|
541
|
+
}
|
|
542
|
+
} else {
|
|
543
|
+
result[key] = value;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
return result;
|
|
547
|
+
}
|
|
431
548
|
createBundle(opts) {
|
|
432
549
|
// @ts-expect-error TS2339
|
|
433
550
|
let {
|
|
@@ -1084,8 +1201,36 @@ class BundleGraph {
|
|
|
1084
1201
|
}
|
|
1085
1202
|
|
|
1086
1203
|
/**
|
|
1087
|
-
*
|
|
1088
|
-
*
|
|
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)
|
|
1089
1234
|
*/
|
|
1090
1235
|
traverseBundle(bundle, visit, startAsset) {
|
|
1091
1236
|
let entries = !startAsset;
|
|
@@ -72,6 +72,18 @@ class AtlaspackV3 {
|
|
|
72
72
|
buildAssetGraph() {
|
|
73
73
|
return (0, _rust().atlaspackNapiBuildAssetGraph)(this._atlaspack_napi);
|
|
74
74
|
}
|
|
75
|
+
loadBundleGraph(bundleGraph) {
|
|
76
|
+
const {
|
|
77
|
+
nodesJson,
|
|
78
|
+
edges,
|
|
79
|
+
publicIdByAssetId,
|
|
80
|
+
environmentsJson
|
|
81
|
+
} = bundleGraph.serializeForNative();
|
|
82
|
+
return (0, _rust().atlaspackNapiLoadBundleGraph)(this._atlaspack_napi, nodesJson, edges, publicIdByAssetId, environmentsJson);
|
|
83
|
+
}
|
|
84
|
+
package(bundleId) {
|
|
85
|
+
return (0, _rust().atlaspackNapiPackage)(this._atlaspack_napi, bundleId);
|
|
86
|
+
}
|
|
75
87
|
async respondToFsEvents(events) {
|
|
76
88
|
// @ts-expect-error TS2488
|
|
77
89
|
let [needsRebuild, error] = await (0, _rust().atlaspackNapiRespondToFsEvents)(this._atlaspack_napi, events);
|
|
@@ -21,6 +21,14 @@ function _profiler() {
|
|
|
21
21
|
return data;
|
|
22
22
|
}
|
|
23
23
|
var _RequestTracker = require("../RequestTracker");
|
|
24
|
+
function _featureFlags() {
|
|
25
|
+
const data = require("@atlaspack/feature-flags");
|
|
26
|
+
_featureFlags = function () {
|
|
27
|
+
return data;
|
|
28
|
+
};
|
|
29
|
+
return data;
|
|
30
|
+
}
|
|
31
|
+
var _EnvironmentManager = require("../EnvironmentManager");
|
|
24
32
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
25
33
|
function createAtlaspackBuildRequest(input) {
|
|
26
34
|
return {
|
|
@@ -53,6 +61,18 @@ async function run({
|
|
|
53
61
|
} = await api.runRequest(bundleGraphRequest, {
|
|
54
62
|
force: Boolean(rustAtlaspack) || options.shouldBuildLazily && requestedAssetIds.size > 0
|
|
55
63
|
});
|
|
64
|
+
if ((0, _featureFlags().getFeatureFlag)('nativePackager') && (0, _featureFlags().getFeatureFlag)('nativePackagerSSRDev') && rustAtlaspack) {
|
|
65
|
+
let hasSupportedTarget = false;
|
|
66
|
+
bundleGraph.traverseBundles((bundle, ctx, actions) => {
|
|
67
|
+
if ((0, _EnvironmentManager.fromEnvironmentId)(bundle.env).context === 'tesseract' && bundle.type === 'js') {
|
|
68
|
+
hasSupportedTarget = true;
|
|
69
|
+
actions.stop();
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
if (hasSupportedTarget) {
|
|
73
|
+
await rustAtlaspack.loadBundleGraph(bundleGraph);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
56
76
|
|
|
57
77
|
// @ts-expect-error TS2345
|
|
58
78
|
(0, _dumpGraphToGraphViz.default)(bundleGraph._graph, 'BundleGraph', _BundleGraph.bundleGraphEdgeTypes);
|
|
@@ -138,7 +138,7 @@ function createBundleGraphRequest(input) {
|
|
|
138
138
|
signal
|
|
139
139
|
} = input.input;
|
|
140
140
|
let measurement = _profiler().tracer.createMeasurement('building');
|
|
141
|
-
let createAssetGraphRequest = input.rustAtlaspack ? (0, _AssetGraphRequestRust.createAssetGraphRequestRust)(input.rustAtlaspack) : _AssetGraphRequest.default;
|
|
141
|
+
let createAssetGraphRequest = (0, _featureFlags().getFeatureFlag)('atlaspackV3') && input.rustAtlaspack ? (0, _AssetGraphRequestRust.createAssetGraphRequestRust)(input.rustAtlaspack) : _AssetGraphRequest.default;
|
|
142
142
|
let request = createAssetGraphRequest({
|
|
143
143
|
name: 'Main',
|
|
144
144
|
entries: options.entries,
|