@atlaspack/core 2.34.0 → 2.36.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 +70 -0
- package/dist/AssetGraph.js +4 -72
- package/dist/BundleGraph.js +34 -0
- package/dist/PackagerRunner.js +8 -53
- package/dist/RequestTracker.js +17 -80
- package/dist/TargetDescriptor.schema.js +3 -0
- package/dist/UncommittedAsset.js +0 -5
- package/dist/atlaspack-v3/AtlaspackV3.js +6 -2
- package/dist/requests/AssetGraphRequest.js +6 -15
- package/dist/requests/AssetGraphRequestRust.js +51 -7
- package/dist/requests/AtlaspackBuildRequest.js +8 -2
- package/dist/requests/BundleGraphRequest.js +17 -21
- package/dist/requests/BundleGraphRequestRust.js +2 -2
- package/dist/requests/BundleGraphRequestUtils.js +133 -2
- package/dist/requests/PackageRequest.js +1 -1
- package/dist/requests/TargetRequest.js +5 -0
- package/dist/requests/WriteBundleRequest.js +169 -24
- package/dist/resolveOptions.js +2 -4
- package/lib/AssetGraph.js +3 -62
- package/lib/BundleGraph.js +38 -0
- package/lib/PackagerRunner.js +8 -42
- package/lib/RequestTracker.js +15 -69
- package/lib/TargetDescriptor.schema.js +3 -0
- package/lib/UncommittedAsset.js +0 -11
- package/lib/atlaspack-v3/AtlaspackV3.js +6 -2
- package/lib/requests/AssetGraphRequest.js +4 -18
- package/lib/requests/AssetGraphRequestRust.js +51 -7
- package/lib/requests/AtlaspackBuildRequest.js +8 -2
- package/lib/requests/BundleGraphRequest.js +20 -22
- package/lib/requests/BundleGraphRequestRust.js +3 -3
- package/lib/requests/BundleGraphRequestUtils.js +132 -2
- package/lib/requests/PackageRequest.js +3 -1
- package/lib/requests/TargetRequest.js +5 -0
- package/lib/requests/WriteBundleRequest.js +182 -14
- package/lib/resolveOptions.js +2 -4
- package/lib/types/AssetGraph.d.ts +2 -27
- package/lib/types/BundleGraph.d.ts +5 -0
- package/lib/types/atlaspack-v3/AtlaspackV3.d.ts +3 -2
- package/lib/types/requests/BundleGraphRequest.d.ts +1 -1
- package/lib/types/requests/BundleGraphRequestUtils.d.ts +7 -0
- package/lib/types/requests/WriteBundleRequest.d.ts +33 -0
- package/lib/types/types.d.ts +1 -0
- package/package.json +15 -15
- package/src/AssetGraph.ts +4 -72
- package/src/BundleGraph.ts +39 -0
- package/src/PackagerRunner.ts +9 -55
- package/src/RequestTracker.ts +24 -110
- package/src/TargetDescriptor.schema.ts +3 -0
- package/src/UncommittedAsset.ts +1 -11
- package/src/atlaspack-v3/AtlaspackV3.ts +19 -3
- package/src/requests/AssetGraphRequest.ts +8 -20
- package/src/requests/AssetGraphRequestRust.ts +59 -7
- package/src/requests/AtlaspackBuildRequest.ts +16 -8
- package/src/requests/BundleGraphRequest.ts +22 -36
- package/src/requests/BundleGraphRequestRust.ts +4 -2
- package/src/requests/BundleGraphRequestUtils.ts +157 -1
- package/src/requests/PackageRequest.ts +1 -1
- package/src/requests/TargetRequest.ts +5 -0
- package/src/requests/WriteBundleRequest.ts +203 -29
- package/src/resolveOptions.ts +2 -4
- package/src/types.ts +1 -0
- package/test/AssetGraph.test.ts +0 -32
- package/test/RequestTracker.test.ts +0 -165
- package/test/TargetRequest.test.ts +25 -0
- package/test/requests/WriteBundleRequest.test.ts +363 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -36,8 +36,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.SourceMapHashRefRewriteStream = void 0;
|
|
39
40
|
exports.default = createWriteBundleRequest;
|
|
40
41
|
exports.applyReplacementsToSourceMap = applyReplacementsToSourceMap;
|
|
42
|
+
exports.applyReplacementsToVLQMappings = applyReplacementsToVLQMappings;
|
|
41
43
|
exports.computeSourceMapRoot = computeSourceMapRoot;
|
|
42
44
|
const constants_1 = require("../constants");
|
|
43
45
|
const nullthrows_1 = __importDefault(require("nullthrows"));
|
|
@@ -56,10 +58,12 @@ const profiler_1 = require("@atlaspack/profiler");
|
|
|
56
58
|
const RequestTracker_1 = require("../RequestTracker");
|
|
57
59
|
const feature_flags_1 = require("@atlaspack/feature-flags");
|
|
58
60
|
const EnvironmentManager_1 = require("../EnvironmentManager");
|
|
59
|
-
const source_map_1 =
|
|
61
|
+
const source_map_1 = require("@atlaspack/source-map");
|
|
60
62
|
const HASH_REF_PREFIX_LEN = constants_1.HASH_REF_PREFIX.length;
|
|
61
63
|
const BOUNDARY_LENGTH = constants_1.HASH_REF_PREFIX.length + 32 - 1;
|
|
62
64
|
const HASH_REF_PLACEHOLDER_LEN = HASH_REF_PREFIX_LEN + constants_1.HASH_REF_HASH_LEN;
|
|
65
|
+
// The JSON key prefix we scan for in the source map stream.
|
|
66
|
+
const MAPPINGS_KEY_BUF = Buffer.from('"mappings":"');
|
|
63
67
|
/**
|
|
64
68
|
* Writes a bundle to the dist directory, replacing hash references with the final content hashes.
|
|
65
69
|
*/
|
|
@@ -134,36 +138,16 @@ async function run({ input, options, api }) {
|
|
|
134
138
|
? []
|
|
135
139
|
: undefined;
|
|
136
140
|
await writeFiles(contentStream, info, hashRefToNameHash, options, config, outputFS, filePath, writeOptions, devDeps, api, bundleReplacements);
|
|
137
|
-
const hasSourceMap =
|
|
138
|
-
? await options.cache.hasLargeBlob(mapKey)
|
|
139
|
-
: await options.cache.has(mapKey);
|
|
141
|
+
const hasSourceMap = await options.cache.has(mapKey);
|
|
140
142
|
if (mapKey && env.sourceMap && !env.sourceMap.inline && hasSourceMap) {
|
|
143
|
+
const mapEntry = await options.cache.getBlob(mapKey);
|
|
141
144
|
let mapStream;
|
|
142
145
|
if ((0, feature_flags_1.getFeatureFlag)('fixSourceMapHashRefs') &&
|
|
143
146
|
bundleReplacements &&
|
|
144
147
|
bundleReplacements.length > 0) {
|
|
145
|
-
|
|
146
|
-
? await options.cache.getLargeBlob(mapKey)
|
|
147
|
-
: await options.cache.getBlob(mapKey);
|
|
148
|
-
const mapBuffer = Buffer.isBuffer(mapEntry)
|
|
149
|
-
? mapEntry
|
|
150
|
-
: Buffer.from(mapEntry);
|
|
151
|
-
const projectRoot = typeof options.projectRoot === 'string'
|
|
152
|
-
? options.projectRoot
|
|
153
|
-
: String(options.projectRoot);
|
|
154
|
-
const sourceMap = new source_map_1.default(projectRoot, mapBuffer);
|
|
155
|
-
applyReplacementsToSourceMap(sourceMap, bundleReplacements);
|
|
156
|
-
const mapJson = await sourceMap.stringify({
|
|
157
|
-
format: 'string',
|
|
158
|
-
file: name,
|
|
159
|
-
sourceRoot: computeSourceMapRoot(bundle, options),
|
|
160
|
-
});
|
|
161
|
-
mapStream = (0, utils_1.blobToStream)(Buffer.from(typeof mapJson === 'string' ? mapJson : JSON.stringify(mapJson), 'utf8'));
|
|
148
|
+
mapStream = (0, utils_1.blobToStream)(mapEntry).pipe(new SourceMapHashRefRewriteStream(bundleReplacements));
|
|
162
149
|
}
|
|
163
150
|
else {
|
|
164
|
-
const mapEntry = (0, feature_flags_1.getFeatureFlag)('cachePerformanceImprovements')
|
|
165
|
-
? await options.cache.getLargeBlob(mapKey)
|
|
166
|
-
: await options.cache.getBlob(mapKey);
|
|
167
151
|
mapStream = (0, utils_1.blobToStream)(mapEntry);
|
|
168
152
|
}
|
|
169
153
|
await writeFiles(mapStream, info, hashRefToNameHash, options, config, outputFS, (0, projectPath_1.toProjectPathUnsafe)((0, projectPath_1.fromProjectPathRelative)(filePath) + '.map'), writeOptions, devDeps, api);
|
|
@@ -198,6 +182,167 @@ function applyReplacementsToSourceMap(sourceMap, replacements) {
|
|
|
198
182
|
}
|
|
199
183
|
}
|
|
200
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Applies hash-ref replacement column offsets directly to a VLQ mappings
|
|
187
|
+
* string without deserializing the full source map into a native struct.
|
|
188
|
+
*
|
|
189
|
+
* Each replacement r describes a hash-ref that was substituted in the output
|
|
190
|
+
* file. r.column is in the progressively-shifted post-replacement coordinate
|
|
191
|
+
* space (matching the already-shifted source map state after all previous
|
|
192
|
+
* offsetColumns calls), so thresholds are applied sequentially against the
|
|
193
|
+
* running absCol values exactly as the native offsetColumns implementation does.
|
|
194
|
+
*/
|
|
195
|
+
function applyReplacementsToVLQMappings(mappings, replacements) {
|
|
196
|
+
if (replacements.length === 0)
|
|
197
|
+
return mappings;
|
|
198
|
+
// Group replacements by line (0-indexed), sorted by column ascending.
|
|
199
|
+
const byLine = new Map();
|
|
200
|
+
for (const r of replacements) {
|
|
201
|
+
let arr = byLine.get(r.line);
|
|
202
|
+
if (!arr) {
|
|
203
|
+
arr = [];
|
|
204
|
+
byLine.set(r.line, arr);
|
|
205
|
+
}
|
|
206
|
+
arr.push(r);
|
|
207
|
+
}
|
|
208
|
+
for (const arr of byLine.values()) {
|
|
209
|
+
arr.sort((a, b) => a.column - b.column);
|
|
210
|
+
}
|
|
211
|
+
const lines = mappings.split(';');
|
|
212
|
+
const resultLines = [];
|
|
213
|
+
for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {
|
|
214
|
+
const lineReps = byLine.get(lineIdx);
|
|
215
|
+
if (!lineReps || lineReps.length === 0) {
|
|
216
|
+
resultLines.push(lines[lineIdx]);
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
const line = lines[lineIdx];
|
|
220
|
+
if (!line) {
|
|
221
|
+
resultLines.push('');
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
// Decode segment column deltas to absolute columns.
|
|
225
|
+
const segments = line.split(',');
|
|
226
|
+
const colVlqEnds = [];
|
|
227
|
+
const absCols = [];
|
|
228
|
+
let absCol = 0;
|
|
229
|
+
for (const seg of segments) {
|
|
230
|
+
const { value: colDelta, nextPos } = (0, source_map_1.decodeVLQ)(seg, 0);
|
|
231
|
+
absCol += colDelta;
|
|
232
|
+
colVlqEnds.push(nextPos);
|
|
233
|
+
absCols.push(absCol);
|
|
234
|
+
}
|
|
235
|
+
// Apply each replacement's column shift sequentially against the
|
|
236
|
+
// current absCol values (which have already been adjusted by previous
|
|
237
|
+
// replacements on this line), mirroring the sequential offsetColumns calls.
|
|
238
|
+
for (const r of lineReps) {
|
|
239
|
+
const delta = r.newLength - r.originalLength;
|
|
240
|
+
if (delta === 0)
|
|
241
|
+
continue;
|
|
242
|
+
const threshold = r.column + r.originalLength;
|
|
243
|
+
for (let i = 0; i < absCols.length; i++) {
|
|
244
|
+
if (absCols[i] >= threshold) {
|
|
245
|
+
absCols[i] += delta;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// Re-encode with updated absolute columns; only the leading column VLQ
|
|
250
|
+
// field of each segment changes – the tail bytes are sliced unchanged.
|
|
251
|
+
const resultSegments = [];
|
|
252
|
+
let prevAbsCol = 0;
|
|
253
|
+
for (let i = 0; i < segments.length; i++) {
|
|
254
|
+
const newDelta = absCols[i] - prevAbsCol;
|
|
255
|
+
prevAbsCol = absCols[i];
|
|
256
|
+
resultSegments.push((0, source_map_1.encodeVLQ)(newDelta) + segments[i].slice(colVlqEnds[i]));
|
|
257
|
+
}
|
|
258
|
+
resultLines.push(resultSegments.join(','));
|
|
259
|
+
}
|
|
260
|
+
return resultLines.join(';');
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* A Transform stream that rewrites the "mappings" VLQ field of a source map
|
|
264
|
+
* JSON to account for hash-ref replacements, without ever loading the full
|
|
265
|
+
* JSON object or the native Rust SourceMapInner into memory.
|
|
266
|
+
*
|
|
267
|
+
* Field order in cached source maps (from partialVlqMapToSourceMap / toVLQ):
|
|
268
|
+
* mappings → sources → sourcesContent → names → version → file → sourceRoot
|
|
269
|
+
*
|
|
270
|
+
* "mappings" is the very first field, so we scan only a tiny header before
|
|
271
|
+
* switching to zero-copy passthrough for the bulk sourcesContent bytes.
|
|
272
|
+
*/
|
|
273
|
+
class SourceMapHashRefRewriteStream extends stream_1.Transform {
|
|
274
|
+
constructor(replacements) {
|
|
275
|
+
super();
|
|
276
|
+
this.replacements = replacements;
|
|
277
|
+
this.state = 'scanning';
|
|
278
|
+
this.scanBuf = Buffer.alloc(0);
|
|
279
|
+
this.mappingsBufs = [];
|
|
280
|
+
}
|
|
281
|
+
// @ts-expect-error TS7006
|
|
282
|
+
_transform(chunk, _encoding, cb) {
|
|
283
|
+
if (this.state === 'passthrough') {
|
|
284
|
+
this.push(chunk);
|
|
285
|
+
cb();
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
if (this.state === 'scanning') {
|
|
289
|
+
const combined = Buffer.concat([this.scanBuf, chunk]);
|
|
290
|
+
const idx = combined.indexOf(MAPPINGS_KEY_BUF);
|
|
291
|
+
if (idx === -1) {
|
|
292
|
+
// Key not yet found – hold back enough bytes to handle a split key.
|
|
293
|
+
const keepLen = Math.min(combined.length, MAPPINGS_KEY_BUF.length - 1);
|
|
294
|
+
if (combined.length > keepLen) {
|
|
295
|
+
this.push(combined.slice(0, combined.length - keepLen));
|
|
296
|
+
}
|
|
297
|
+
this.scanBuf = combined.slice(combined.length - keepLen);
|
|
298
|
+
cb();
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
// Emit everything up to and including the key.
|
|
302
|
+
const keyEnd = idx + MAPPINGS_KEY_BUF.length;
|
|
303
|
+
this.push(combined.slice(0, keyEnd));
|
|
304
|
+
this.scanBuf = Buffer.alloc(0);
|
|
305
|
+
this.state = 'buffering';
|
|
306
|
+
this._bufferingTransform(combined.slice(keyEnd), cb);
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
// state === 'buffering'
|
|
310
|
+
this._bufferingTransform(chunk, cb);
|
|
311
|
+
}
|
|
312
|
+
// @ts-expect-error TS7006
|
|
313
|
+
_bufferingTransform(chunk, cb) {
|
|
314
|
+
// Mappings values contain only base64 chars, ';', and ',' – no escaping –
|
|
315
|
+
// so scanning for the closing '"' (0x22) is safe.
|
|
316
|
+
const closeIdx = chunk.indexOf(0x22);
|
|
317
|
+
if (closeIdx === -1) {
|
|
318
|
+
this.mappingsBufs.push(chunk);
|
|
319
|
+
cb();
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
this.mappingsBufs.push(chunk.slice(0, closeIdx));
|
|
323
|
+
// VLQ chars are all ASCII (<128), so latin1 round-trips without loss.
|
|
324
|
+
const mappingsStr = Buffer.concat(this.mappingsBufs).toString('latin1');
|
|
325
|
+
const rewritten = applyReplacementsToVLQMappings(mappingsStr, this.replacements);
|
|
326
|
+
this.push(Buffer.from(rewritten, 'latin1'));
|
|
327
|
+
// Emit the closing '"' and everything remaining in one push.
|
|
328
|
+
this.push(chunk.slice(closeIdx));
|
|
329
|
+
this.state = 'passthrough';
|
|
330
|
+
this.mappingsBufs = [];
|
|
331
|
+
cb();
|
|
332
|
+
}
|
|
333
|
+
// @ts-expect-error TS7006
|
|
334
|
+
_flush(cb) {
|
|
335
|
+
if (this.state === 'scanning' && this.scanBuf.length > 0) {
|
|
336
|
+
this.push(this.scanBuf);
|
|
337
|
+
}
|
|
338
|
+
else if (this.state === 'buffering') {
|
|
339
|
+
// Malformed JSON – flush whatever we buffered as-is.
|
|
340
|
+
this.push(Buffer.concat(this.mappingsBufs));
|
|
341
|
+
}
|
|
342
|
+
cb();
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
exports.SourceMapHashRefRewriteStream = SourceMapHashRefRewriteStream;
|
|
201
346
|
/**
|
|
202
347
|
* Computes the sourceRoot for a source map file. This is the relative path from
|
|
203
348
|
* the output directory back to the project root, so that source paths (stored
|
package/dist/resolveOptions.js
CHANGED
|
@@ -133,10 +133,8 @@ async function resolveOptions(initialOptions) {
|
|
|
133
133
|
return initialOptions.cache;
|
|
134
134
|
}
|
|
135
135
|
const needsRustLmdbCache = (0, feature_flags_1.getFeatureFlag)('atlaspackV3') || (0, feature_flags_1.getFeatureFlag)('nativePackager');
|
|
136
|
-
if (!(
|
|
137
|
-
|
|
138
|
-
return new cache_1.FSCache(outputFS, cacheDir);
|
|
139
|
-
}
|
|
136
|
+
if (!needsRustLmdbCache && !(outputFS instanceof fs_1.NodeFS)) {
|
|
137
|
+
return new cache_1.FSCache(outputFS, cacheDir);
|
|
140
138
|
}
|
|
141
139
|
return new cache_1.LMDBLiteCache(cacheDir);
|
|
142
140
|
}
|
package/lib/AssetGraph.js
CHANGED
|
@@ -108,32 +108,16 @@ function nodeFromEntryFile(entry) {
|
|
|
108
108
|
|
|
109
109
|
// @ts-expect-error TS2417
|
|
110
110
|
class AssetGraph extends _graph().ContentGraph {
|
|
111
|
-
/**
|
|
112
|
-
* Incremented when the asset graph is modified such that it requires a bundling pass.
|
|
113
|
-
*/
|
|
114
|
-
#bundlingVersion = 0;
|
|
115
|
-
/**
|
|
116
|
-
* Force incremental bundling to be disabled.
|
|
117
|
-
*/
|
|
118
|
-
#disableIncrementalBundling = false;
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* @deprecated
|
|
122
|
-
*/
|
|
123
111
|
safeToIncrementallyBundle = true;
|
|
124
112
|
constructor(opts) {
|
|
125
113
|
if (opts) {
|
|
126
114
|
let {
|
|
127
115
|
hash,
|
|
128
|
-
bundlingVersion,
|
|
129
|
-
disableIncrementalBundling,
|
|
130
116
|
...rest
|
|
131
117
|
} = opts;
|
|
132
118
|
// @ts-expect-error TS2345
|
|
133
119
|
super(rest);
|
|
134
120
|
this.hash = hash;
|
|
135
|
-
this.#bundlingVersion = bundlingVersion ?? 0;
|
|
136
|
-
this.#disableIncrementalBundling = disableIncrementalBundling ?? false;
|
|
137
121
|
} else {
|
|
138
122
|
super();
|
|
139
123
|
this.setRootNodeId(this.addNode({
|
|
@@ -151,57 +135,16 @@ class AssetGraph extends _graph().ContentGraph {
|
|
|
151
135
|
serialize() {
|
|
152
136
|
return {
|
|
153
137
|
...super.serialize(),
|
|
154
|
-
bundlingVersion: this.#bundlingVersion,
|
|
155
|
-
disableIncrementalBundling: this.#disableIncrementalBundling,
|
|
156
138
|
hash: this.hash
|
|
157
139
|
};
|
|
158
140
|
}
|
|
159
141
|
|
|
160
142
|
/**
|
|
161
|
-
*
|
|
162
|
-
*/
|
|
163
|
-
setDisableIncrementalBundling(disable) {
|
|
164
|
-
this.#disableIncrementalBundling = disable;
|
|
165
|
-
}
|
|
166
|
-
testing_getDisableIncrementalBundling() {
|
|
167
|
-
return this.#disableIncrementalBundling;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Make sure this asset graph is marked as needing a full bundling pass.
|
|
172
|
-
*/
|
|
173
|
-
setNeedsBundling() {
|
|
174
|
-
if (!(0, _featureFlags().getFeatureFlag)('incrementalBundlingVersioning')) {
|
|
175
|
-
// In legacy mode, we rely solely on safeToIncrementallyBundle to
|
|
176
|
-
// invalidate incremental bundling, so we skip bumping the version.
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
this.#bundlingVersion += 1;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Get the current bundling version.
|
|
184
|
-
*
|
|
185
|
-
* Each bundle pass should keep this version around. Whenever an asset graph has a new version,
|
|
186
|
-
* bundling should be re-run.
|
|
187
|
-
*/
|
|
188
|
-
getBundlingVersion() {
|
|
189
|
-
if (!(0, _featureFlags().getFeatureFlag)('incrementalBundlingVersioning')) {
|
|
190
|
-
return 0;
|
|
191
|
-
}
|
|
192
|
-
return this.#bundlingVersion;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* If the `bundlingVersion` has not changed since the last bundling pass,
|
|
197
|
-
* we can incrementally bundle, which will not require a full bundling pass
|
|
143
|
+
* Determine if we can incrementally bundle, which will not require a full bundling pass
|
|
198
144
|
* but just update assets into the bundle graph output.
|
|
199
145
|
*/
|
|
200
|
-
canIncrementallyBundle(
|
|
201
|
-
|
|
202
|
-
return this.safeToIncrementallyBundle && !this.#disableIncrementalBundling;
|
|
203
|
-
}
|
|
204
|
-
return this.safeToIncrementallyBundle && this.#bundlingVersion === lastVersion && !this.#disableIncrementalBundling;
|
|
146
|
+
canIncrementallyBundle() {
|
|
147
|
+
return this.safeToIncrementallyBundle;
|
|
205
148
|
}
|
|
206
149
|
|
|
207
150
|
// Deduplicates Environments by making them referentially equal
|
|
@@ -381,13 +324,11 @@ class AssetGraph extends _graph().ContentGraph {
|
|
|
381
324
|
// @ts-expect-error TS2339
|
|
382
325
|
if (!(ctx !== null && ctx !== void 0 && ctx.hasDeferred)) {
|
|
383
326
|
this.safeToIncrementallyBundle = false;
|
|
384
|
-
this.setNeedsBundling();
|
|
385
327
|
delete traversedNode.hasDeferred;
|
|
386
328
|
}
|
|
387
329
|
actions.skipChildren();
|
|
388
330
|
} else if (traversedNode.type === 'dependency') {
|
|
389
331
|
this.safeToIncrementallyBundle = false;
|
|
390
|
-
this.setNeedsBundling();
|
|
391
332
|
traversedNode.hasDeferred = false;
|
|
392
333
|
} else if (nodeId !== traversedNodeId) {
|
|
393
334
|
actions.skipChildren();
|
package/lib/BundleGraph.js
CHANGED
|
@@ -516,6 +516,44 @@ class BundleGraph {
|
|
|
516
516
|
};
|
|
517
517
|
}
|
|
518
518
|
|
|
519
|
+
/**
|
|
520
|
+
* Serialize only the given asset nodes for native incremental update.
|
|
521
|
+
* Same node shape and env/omit logic as serializeForNative.
|
|
522
|
+
*/
|
|
523
|
+
serializeAssetNodesForNative(assetIds) {
|
|
524
|
+
const start = performance.now();
|
|
525
|
+
if (assetIds.length === 0) {
|
|
526
|
+
return '[]';
|
|
527
|
+
}
|
|
528
|
+
const nodes = [];
|
|
529
|
+
for (const assetId of assetIds) {
|
|
530
|
+
var _node$value4;
|
|
531
|
+
const node = this._graph.getNodeByContentKey(assetId);
|
|
532
|
+
if ((node === null || node === void 0 ? void 0 : node.type) !== 'asset') {
|
|
533
|
+
continue;
|
|
534
|
+
}
|
|
535
|
+
const processedNode = {
|
|
536
|
+
...node
|
|
537
|
+
};
|
|
538
|
+
if ((_node$value4 = node.value) !== null && _node$value4 !== void 0 && _node$value4.env) {
|
|
539
|
+
processedNode.value = {
|
|
540
|
+
...node.value,
|
|
541
|
+
env: (0, _EnvironmentManager.fromEnvironmentId)(node.value.env).id
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
nodes.push(processedNode);
|
|
545
|
+
}
|
|
546
|
+
const optimizedNodes = nodes.map(node => this._omitNulls(node));
|
|
547
|
+
const nodesJson = JSON.stringify(optimizedNodes);
|
|
548
|
+
const duration = performance.now() - start;
|
|
549
|
+
const nodesSizeMB = (nodesJson.length / (1024 * 1024)).toFixed(2);
|
|
550
|
+
_logger().default.verbose({
|
|
551
|
+
origin: '@atlaspack/core',
|
|
552
|
+
message: `serializeAssetNodesForNative: ${duration.toFixed(1)}ms, ${nodesSizeMB}MB nodes, ${nodes.length} nodes`
|
|
553
|
+
});
|
|
554
|
+
return nodesJson;
|
|
555
|
+
}
|
|
556
|
+
|
|
519
557
|
/**
|
|
520
558
|
* Remove null and undefined values from an object to reduce JSON size.
|
|
521
559
|
* Preserves false, 0, empty strings, and arrays.
|
package/lib/PackagerRunner.js
CHANGED
|
@@ -87,13 +87,6 @@ function _profiler() {
|
|
|
87
87
|
return data;
|
|
88
88
|
}
|
|
89
89
|
var _EnvironmentManager = require("./EnvironmentManager");
|
|
90
|
-
function _featureFlags() {
|
|
91
|
-
const data = require("@atlaspack/feature-flags");
|
|
92
|
-
_featureFlags = function () {
|
|
93
|
-
return data;
|
|
94
|
-
};
|
|
95
|
-
return data;
|
|
96
|
-
}
|
|
97
90
|
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); }
|
|
98
91
|
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; }
|
|
99
92
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -437,10 +430,6 @@ class PackagerRunner {
|
|
|
437
430
|
devDepHashes += await this.getDevDepHashes(inlineBundle);
|
|
438
431
|
}
|
|
439
432
|
let invalidationHash = await (0, _assetUtils.getInvalidationHash)(invalidations, this.options);
|
|
440
|
-
if ((0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements')) {
|
|
441
|
-
const hash = (0, _rust().hashString)(_constants.ATLASPACK_VERSION + devDepHashes + invalidationHash + bundle.target.publicUrl + bundleGraph.getHash(bundle) + JSON.stringify(configResults) + JSON.stringify(globalInfoResults) + this.options.mode + (this.options.shouldBuildLazily ? 'lazy' : 'eager'));
|
|
442
|
-
return _path().default.join(bundle.displayName ?? bundle.name ?? bundle.id, hash);
|
|
443
|
-
}
|
|
444
433
|
return (0, _rust().hashString)(_constants.ATLASPACK_VERSION + devDepHashes + invalidationHash + bundle.target.publicUrl + bundleGraph.getHash(bundle) + JSON.stringify(configResults) + JSON.stringify(globalInfoResults) + this.options.mode + (this.options.shouldBuildLazily ? 'lazy' : 'eager'));
|
|
445
434
|
}
|
|
446
435
|
async getDevDepHashes(bundle) {
|
|
@@ -464,14 +453,14 @@ class PackagerRunner {
|
|
|
464
453
|
let contentKey = PackagerRunner.getContentKey(cacheKey);
|
|
465
454
|
let mapKey = PackagerRunner.getMapKey(cacheKey);
|
|
466
455
|
let isLargeBlob = await this.options.cache.hasLargeBlob(contentKey);
|
|
467
|
-
let contentExists =
|
|
456
|
+
let contentExists = isLargeBlob || (await this.options.cache.has(contentKey));
|
|
468
457
|
if (!contentExists) {
|
|
469
458
|
return null;
|
|
470
459
|
}
|
|
471
|
-
let mapExists =
|
|
460
|
+
let mapExists = await this.options.cache.has(mapKey);
|
|
472
461
|
return {
|
|
473
462
|
contents: isLargeBlob ? this.options.cache.getStream(contentKey) : (0, _utils().blobToStream)(await this.options.cache.getBlob(contentKey)),
|
|
474
|
-
map: mapExists ? (0, _utils().blobToStream)(
|
|
463
|
+
map: mapExists ? (0, _utils().blobToStream)(await this.options.cache.getBlob(mapKey)) : null
|
|
475
464
|
};
|
|
476
465
|
}
|
|
477
466
|
async writeToCache(cacheKeys, type, contents, map) {
|
|
@@ -479,13 +468,11 @@ class PackagerRunner {
|
|
|
479
468
|
let hash;
|
|
480
469
|
// @ts-expect-error TS2702
|
|
481
470
|
let hashReferences = [];
|
|
482
|
-
let isLargeBlob =
|
|
471
|
+
let isLargeBlob = false;
|
|
483
472
|
|
|
484
473
|
// TODO: don't replace hash references in binary files??
|
|
485
474
|
if (contents instanceof _stream().Readable) {
|
|
486
|
-
|
|
487
|
-
isLargeBlob = true;
|
|
488
|
-
}
|
|
475
|
+
isLargeBlob = true;
|
|
489
476
|
let boundaryStr = '';
|
|
490
477
|
let h = new (_rust().Hash)();
|
|
491
478
|
await this.options.cache.setStream(cacheKeys.content, (0, _utils().blobToStream)(contents).pipe(
|
|
@@ -503,27 +490,15 @@ class PackagerRunner {
|
|
|
503
490
|
size = buffer.byteLength;
|
|
504
491
|
hash = (0, _rust().hashBuffer)(buffer);
|
|
505
492
|
hashReferences = contents.match(_constants.HASH_REF_REGEX) ?? [];
|
|
506
|
-
|
|
507
|
-
await this.options.cache.setLargeBlob(cacheKeys.content, buffer);
|
|
508
|
-
} else {
|
|
509
|
-
await this.options.cache.setBlob(cacheKeys.content, buffer);
|
|
510
|
-
}
|
|
493
|
+
await this.options.cache.setBlob(cacheKeys.content, buffer);
|
|
511
494
|
} else {
|
|
512
495
|
size = contents.length;
|
|
513
496
|
hash = (0, _rust().hashBuffer)(contents);
|
|
514
497
|
hashReferences = contents.toString().match(_constants.HASH_REF_REGEX) ?? [];
|
|
515
|
-
|
|
516
|
-
await this.options.cache.setLargeBlob(cacheKeys.content, contents);
|
|
517
|
-
} else {
|
|
518
|
-
await this.options.cache.setBlob(cacheKeys.content, contents);
|
|
519
|
-
}
|
|
498
|
+
await this.options.cache.setBlob(cacheKeys.content, contents);
|
|
520
499
|
}
|
|
521
500
|
if (map != null) {
|
|
522
|
-
|
|
523
|
-
await this.options.cache.setLargeBlob(cacheKeys.map, map);
|
|
524
|
-
} else {
|
|
525
|
-
await this.options.cache.setBlob(cacheKeys.map, map);
|
|
526
|
-
}
|
|
501
|
+
await this.options.cache.setBlob(cacheKeys.map, map);
|
|
527
502
|
}
|
|
528
503
|
let info = {
|
|
529
504
|
type,
|
|
@@ -537,21 +512,12 @@ class PackagerRunner {
|
|
|
537
512
|
return info;
|
|
538
513
|
}
|
|
539
514
|
static getContentKey(cacheKey) {
|
|
540
|
-
if ((0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements')) {
|
|
541
|
-
return `PackagerRunner/${_constants.ATLASPACK_VERSION}/${cacheKey}/content`;
|
|
542
|
-
}
|
|
543
515
|
return (0, _rust().hashString)(`${cacheKey}:content`);
|
|
544
516
|
}
|
|
545
517
|
static getMapKey(cacheKey) {
|
|
546
|
-
if ((0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements')) {
|
|
547
|
-
return `PackagerRunner/${_constants.ATLASPACK_VERSION}/${cacheKey}/map`;
|
|
548
|
-
}
|
|
549
518
|
return (0, _rust().hashString)(`${cacheKey}:map`);
|
|
550
519
|
}
|
|
551
520
|
static getInfoKey(cacheKey) {
|
|
552
|
-
if ((0, _featureFlags().getFeatureFlag)('cachePerformanceImprovements')) {
|
|
553
|
-
return `PackagerRunner/${_constants.ATLASPACK_VERSION}/${cacheKey}/info`;
|
|
554
|
-
}
|
|
555
521
|
return (0, _rust().hashString)(`${cacheKey}:info`);
|
|
556
522
|
}
|
|
557
523
|
}
|