@atlaspack/core 2.16.2-canary.48 → 2.16.2-canary.481
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 +1324 -0
- package/dist/AssetGraph.js +523 -0
- package/dist/Atlaspack.js +701 -0
- package/dist/AtlaspackConfig.js +324 -0
- package/dist/AtlaspackConfig.schema.js +117 -0
- package/dist/BundleGraph.js +1906 -0
- package/dist/CommittedAsset.js +142 -0
- package/dist/Dependency.js +125 -0
- package/dist/Environment.js +132 -0
- package/dist/EnvironmentManager.js +108 -0
- package/dist/IdentifierRegistry.js +38 -0
- package/dist/InternalConfig.js +37 -0
- package/dist/PackagerRunner.js +470 -0
- package/dist/ReporterRunner.js +151 -0
- package/dist/RequestTracker.js +1297 -0
- package/dist/SymbolPropagation.js +624 -0
- package/dist/TargetDescriptor.schema.js +146 -0
- package/dist/Transformation.js +514 -0
- package/dist/UncommittedAsset.js +310 -0
- package/dist/Validation.js +196 -0
- package/dist/applyRuntimes.js +384 -0
- package/dist/assetUtils.js +169 -0
- package/dist/atlaspack-v3/AtlaspackV3.js +83 -0
- package/dist/atlaspack-v3/NapiWorkerPool.js +114 -0
- package/dist/atlaspack-v3/fs.js +53 -0
- package/dist/atlaspack-v3/index.js +25 -0
- package/dist/atlaspack-v3/jsCallable.js +16 -0
- package/dist/atlaspack-v3/worker/compat/asset-symbols.js +190 -0
- package/dist/atlaspack-v3/worker/compat/bitflags.js +98 -0
- package/dist/atlaspack-v3/worker/compat/dependency.js +43 -0
- package/dist/atlaspack-v3/worker/compat/environment.js +57 -0
- package/dist/atlaspack-v3/worker/compat/index.js +24 -0
- package/dist/atlaspack-v3/worker/compat/mutable-asset.js +152 -0
- package/dist/atlaspack-v3/worker/compat/plugin-config.js +64 -0
- package/dist/atlaspack-v3/worker/compat/plugin-options.js +137 -0
- package/dist/atlaspack-v3/worker/compat/plugin-tracer.js +10 -0
- package/dist/atlaspack-v3/worker/compat/target.js +14 -0
- package/dist/atlaspack-v3/worker/side-effect-detector.js +243 -0
- package/dist/atlaspack-v3/worker/worker.js +398 -0
- package/dist/constants.js +17 -0
- package/dist/dumpGraphToGraphViz.js +281 -0
- package/dist/index.js +62 -0
- package/dist/loadAtlaspackPlugin.js +128 -0
- package/dist/loadDotEnv.js +41 -0
- package/dist/projectPath.js +83 -0
- package/dist/public/Asset.js +279 -0
- package/dist/public/Bundle.js +224 -0
- package/dist/public/BundleGraph.js +371 -0
- package/dist/public/BundleGroup.js +53 -0
- package/dist/public/Config.js +286 -0
- package/dist/public/Dependency.js +138 -0
- package/dist/public/Environment.js +278 -0
- package/dist/public/MutableBundleGraph.js +277 -0
- package/dist/public/PluginOptions.js +80 -0
- package/dist/public/Symbols.js +248 -0
- package/dist/public/Target.js +69 -0
- package/dist/registerCoreWithSerializer.js +38 -0
- package/dist/requests/AssetGraphRequest.js +430 -0
- package/dist/requests/AssetGraphRequestRust.js +471 -0
- package/dist/requests/AssetRequest.js +130 -0
- package/dist/requests/AtlaspackBuildRequest.js +98 -0
- package/dist/requests/AtlaspackConfigRequest.js +493 -0
- package/dist/requests/BundleGraphRequest.js +381 -0
- package/dist/requests/BundleGraphRequestRust.js +324 -0
- package/dist/requests/BundleGraphRequestUtils.js +262 -0
- package/dist/requests/ConfigRequest.js +246 -0
- package/dist/requests/DevDepRequest.js +204 -0
- package/dist/requests/EntryRequest.js +314 -0
- package/dist/requests/PackageRequest.js +89 -0
- package/dist/requests/PathRequest.js +349 -0
- package/dist/requests/TargetRequest.js +1316 -0
- package/dist/requests/ValidationRequest.js +49 -0
- package/dist/requests/WriteBundleRequest.js +522 -0
- package/dist/requests/WriteBundlesRequest.js +190 -0
- package/dist/requests/asset-graph-diff.js +128 -0
- package/dist/requests/asset-graph-dot.js +131 -0
- package/dist/resolveOptions.js +267 -0
- package/dist/rustWorkerThreadDylibHack.js +19 -0
- package/dist/serializerCore.browser.js +43 -0
- package/dist/summarizeRequest.js +39 -0
- package/dist/types.js +31 -0
- package/dist/utils.js +172 -0
- package/dist/worker.js +123 -0
- package/lib/AssetGraph.js +53 -15
- package/lib/Atlaspack.js +140 -56
- package/lib/AtlaspackConfig.js +17 -6
- package/lib/AtlaspackConfig.schema.js +16 -5
- package/lib/BundleGraph.js +390 -43
- package/lib/CommittedAsset.js +8 -2
- package/lib/Dependency.js +9 -3
- package/lib/Environment.js +16 -10
- package/lib/EnvironmentManager.js +143 -0
- package/lib/IdentifierRegistry.js +2 -4
- package/lib/InternalConfig.js +3 -2
- package/lib/PackagerRunner.js +46 -82
- package/lib/ReporterRunner.js +8 -12
- package/lib/RequestTracker.js +191 -152
- package/lib/SymbolPropagation.js +52 -29
- package/lib/TargetDescriptor.schema.js +10 -1
- package/lib/Transformation.js +68 -19
- package/lib/UncommittedAsset.js +17 -24
- package/lib/Validation.js +20 -5
- package/lib/applyRuntimes.js +98 -7
- package/lib/assetUtils.js +16 -6
- package/lib/atlaspack-v3/AtlaspackV3.js +58 -15
- package/lib/atlaspack-v3/NapiWorkerPool.js +63 -2
- package/lib/atlaspack-v3/fs.js +4 -1
- package/lib/atlaspack-v3/index.js +28 -1
- package/lib/atlaspack-v3/jsCallable.js +0 -2
- package/lib/atlaspack-v3/worker/compat/asset-symbols.js +7 -4
- package/lib/atlaspack-v3/worker/compat/bitflags.js +31 -25
- package/lib/atlaspack-v3/worker/compat/dependency.js +4 -1
- package/lib/atlaspack-v3/worker/compat/environment.js +10 -7
- package/lib/atlaspack-v3/worker/compat/index.js +0 -11
- package/lib/atlaspack-v3/worker/compat/mutable-asset.js +16 -11
- package/lib/atlaspack-v3/worker/compat/plugin-config.js +14 -35
- package/lib/atlaspack-v3/worker/compat/plugin-options.js +16 -2
- package/lib/atlaspack-v3/worker/compat/plugin-tracer.js +3 -0
- package/lib/atlaspack-v3/worker/compat/target.js +2 -0
- package/lib/atlaspack-v3/worker/index.js +3 -0
- package/lib/atlaspack-v3/worker/side-effect-detector.js +214 -0
- package/lib/atlaspack-v3/worker/worker.js +231 -79
- package/lib/constants.js +0 -1
- package/lib/dumpGraphToGraphViz.js +72 -17
- package/lib/index.js +46 -3
- package/lib/loadAtlaspackPlugin.js +2 -3
- package/lib/loadDotEnv.js +5 -2
- package/lib/projectPath.js +6 -1
- package/lib/public/Asset.js +22 -12
- package/lib/public/Bundle.js +16 -18
- package/lib/public/BundleGraph.js +27 -25
- package/lib/public/BundleGroup.js +5 -6
- package/lib/public/Config.js +118 -18
- package/lib/public/Dependency.js +9 -7
- package/lib/public/Environment.js +13 -8
- package/lib/public/MutableBundleGraph.js +56 -15
- package/lib/public/PluginOptions.js +2 -2
- package/lib/public/Symbols.js +12 -12
- package/lib/public/Target.js +8 -7
- package/lib/registerCoreWithSerializer.js +7 -4
- package/lib/requests/AssetGraphRequest.js +61 -40
- package/lib/requests/AssetGraphRequestRust.js +314 -82
- package/lib/requests/AssetRequest.js +24 -7
- package/lib/requests/AtlaspackBuildRequest.js +53 -7
- package/lib/requests/AtlaspackConfigRequest.js +29 -19
- package/lib/requests/BundleGraphRequest.js +61 -130
- package/lib/requests/BundleGraphRequestRust.js +381 -0
- package/lib/requests/BundleGraphRequestUtils.js +280 -0
- package/lib/requests/ConfigRequest.js +55 -7
- package/lib/requests/DevDepRequest.js +32 -6
- package/lib/requests/EntryRequest.js +4 -3
- package/lib/requests/PackageRequest.js +56 -12
- package/lib/requests/PathRequest.js +26 -6
- package/lib/requests/TargetRequest.js +129 -60
- package/lib/requests/ValidationRequest.js +6 -2
- package/lib/requests/WriteBundleRequest.js +329 -20
- package/lib/requests/WriteBundlesRequest.js +64 -10
- package/lib/requests/asset-graph-diff.js +13 -8
- package/lib/requests/asset-graph-dot.js +2 -8
- package/lib/resolveOptions.js +37 -14
- package/lib/rustWorkerThreadDylibHack.js +0 -1
- package/lib/serializerCore.browser.js +1 -2
- package/lib/summarizeRequest.js +1 -1
- package/lib/types/AssetGraph.d.ts +55 -0
- package/lib/types/Atlaspack.d.ts +52 -0
- package/lib/types/AtlaspackConfig.d.ts +65 -0
- package/lib/types/AtlaspackConfig.schema.d.ts +53 -0
- package/lib/types/BundleGraph.d.ts +232 -0
- package/lib/types/CommittedAsset.d.ts +23 -0
- package/lib/types/Dependency.d.ts +44 -0
- package/lib/types/Environment.d.ts +11 -0
- package/lib/types/EnvironmentManager.d.ts +37 -0
- package/lib/types/IdentifierRegistry.d.ts +6 -0
- package/lib/types/InternalConfig.d.ts +23 -0
- package/lib/types/PackagerRunner.d.ts +85 -0
- package/lib/types/ReporterRunner.d.ts +25 -0
- package/lib/types/RequestTracker.d.ts +385 -0
- package/lib/types/SymbolPropagation.d.ts +11 -0
- package/lib/types/TargetDescriptor.schema.d.ts +5 -0
- package/lib/types/Transformation.d.ts +72 -0
- package/lib/types/UncommittedAsset.d.ts +61 -0
- package/lib/types/Validation.d.ts +37 -0
- package/lib/types/applyRuntimes.d.ts +25 -0
- package/lib/types/assetUtils.d.ts +42 -0
- package/lib/types/atlaspack-v3/AtlaspackV3.d.ts +35 -0
- package/lib/types/atlaspack-v3/NapiWorkerPool.d.ts +13 -0
- package/lib/types/atlaspack-v3/fs.d.ts +13 -0
- package/lib/types/atlaspack-v3/index.d.ts +6 -0
- package/lib/types/atlaspack-v3/jsCallable.d.ts +1 -0
- package/lib/types/atlaspack-v3/worker/compat/asset-symbols.d.ts +51 -0
- package/lib/types/atlaspack-v3/worker/compat/bitflags.d.ts +14 -0
- package/lib/types/atlaspack-v3/worker/compat/dependency.d.ts +25 -0
- package/lib/types/atlaspack-v3/worker/compat/environment.d.ts +27 -0
- package/{src/atlaspack-v3/worker/compat/index.js → lib/types/atlaspack-v3/worker/compat/index.d.ts} +0 -2
- package/lib/types/atlaspack-v3/worker/compat/mutable-asset.d.ts +49 -0
- package/lib/types/atlaspack-v3/worker/compat/plugin-config.d.ts +29 -0
- package/lib/types/atlaspack-v3/worker/compat/plugin-options.d.ts +23 -0
- package/lib/types/atlaspack-v3/worker/compat/plugin-tracer.d.ts +5 -0
- package/lib/types/atlaspack-v3/worker/compat/target.d.ts +11 -0
- package/lib/types/atlaspack-v3/worker/side-effect-detector.d.ts +76 -0
- package/lib/types/atlaspack-v3/worker/worker.d.ts +81 -0
- package/lib/types/constants.d.ts +13 -0
- package/lib/types/dumpGraphToGraphViz.d.ts +10 -0
- package/lib/types/index.d.ts +8 -0
- package/lib/types/loadAtlaspackPlugin.d.ts +8 -0
- package/lib/types/loadDotEnv.d.ts +3 -0
- package/lib/types/projectPath.d.ts +19 -0
- package/lib/types/public/Asset.d.ts +74 -0
- package/lib/types/public/Bundle.d.ts +45 -0
- package/lib/types/public/BundleGraph.d.ts +72 -0
- package/lib/types/public/BundleGroup.d.ts +12 -0
- package/lib/types/public/Config.d.ts +75 -0
- package/lib/types/public/Dependency.d.ts +32 -0
- package/lib/types/public/Environment.d.ts +34 -0
- package/lib/types/public/MutableBundleGraph.d.ts +26 -0
- package/lib/types/public/PluginOptions.d.ts +25 -0
- package/lib/types/public/Symbols.d.ts +81 -0
- package/lib/types/public/Target.d.ts +16 -0
- package/lib/types/registerCoreWithSerializer.d.ts +2 -0
- package/lib/types/requests/AssetGraphRequest.d.ts +76 -0
- package/lib/types/requests/AssetGraphRequestRust.d.ts +21 -0
- package/lib/types/requests/AssetRequest.d.ts +16 -0
- package/lib/types/requests/AtlaspackBuildRequest.d.ts +33 -0
- package/lib/types/requests/AtlaspackConfigRequest.d.ts +45 -0
- package/lib/types/requests/BundleGraphRequest.d.ts +28 -0
- package/lib/types/requests/BundleGraphRequestRust.d.ts +34 -0
- package/lib/types/requests/BundleGraphRequestUtils.d.ts +38 -0
- package/lib/types/requests/ConfigRequest.d.ts +67 -0
- package/lib/types/requests/DevDepRequest.d.ts +30 -0
- package/lib/types/requests/EntryRequest.d.ts +36 -0
- package/lib/types/requests/PackageRequest.d.ts +27 -0
- package/lib/types/requests/PathRequest.d.ts +48 -0
- package/lib/types/requests/TargetRequest.d.ts +48 -0
- package/lib/types/requests/ValidationRequest.d.ts +20 -0
- package/lib/types/requests/WriteBundleRequest.d.ts +80 -0
- package/lib/types/requests/WriteBundlesRequest.d.ts +32 -0
- package/lib/types/requests/asset-graph-diff.d.ts +1 -0
- package/lib/types/requests/asset-graph-dot.d.ts +9 -0
- package/lib/types/resolveOptions.d.ts +3 -0
- package/lib/types/rustWorkerThreadDylibHack.d.ts +9 -0
- package/lib/types/serializerCore.browser.d.ts +3 -0
- package/lib/types/summarizeRequest.d.ts +10 -0
- package/lib/types/types.d.ts +496 -0
- package/lib/types/utils.d.ts +23 -0
- package/lib/types/worker.d.ts +44 -0
- package/lib/types.js +8 -1
- package/lib/utils.js +18 -3
- package/lib/worker.js +32 -15
- package/package.json +26 -36
- package/src/{AssetGraph.js → AssetGraph.ts} +87 -51
- package/src/{Atlaspack.js → Atlaspack.ts} +181 -72
- package/src/{AtlaspackConfig.schema.js → AtlaspackConfig.schema.ts} +25 -19
- package/src/{AtlaspackConfig.js → AtlaspackConfig.ts} +78 -54
- package/src/{BundleGraph.js → BundleGraph.ts} +575 -145
- package/src/{CommittedAsset.js → CommittedAsset.ts} +15 -13
- package/src/{Dependency.js → Dependency.ts} +59 -42
- package/src/{Environment.js → Environment.ts} +24 -15
- package/src/EnvironmentManager.ts +154 -0
- package/src/{IdentifierRegistry.js → IdentifierRegistry.ts} +1 -4
- package/src/{InternalConfig.js → InternalConfig.ts} +22 -23
- package/src/{PackagerRunner.js → PackagerRunner.ts} +114 -159
- package/src/{ReporterRunner.js → ReporterRunner.ts} +13 -18
- package/src/{RequestTracker.js → RequestTracker.ts} +444 -355
- package/src/{SymbolPropagation.js → SymbolPropagation.ts} +178 -61
- package/src/{TargetDescriptor.schema.js → TargetDescriptor.schema.ts} +10 -1
- package/src/{Transformation.js → Transformation.ts} +110 -65
- package/src/{UncommittedAsset.js → UncommittedAsset.ts} +45 -49
- package/src/{Validation.js → Validation.ts} +32 -17
- package/src/{applyRuntimes.js → applyRuntimes.ts} +135 -26
- package/src/{assetUtils.js → assetUtils.ts} +49 -36
- package/src/atlaspack-v3/AtlaspackV3.ts +183 -0
- package/src/atlaspack-v3/NapiWorkerPool.ts +129 -0
- package/src/atlaspack-v3/{fs.js → fs.ts} +8 -4
- package/src/atlaspack-v3/{index.js → index.ts} +3 -4
- package/src/atlaspack-v3/jsCallable.ts +14 -0
- package/src/atlaspack-v3/worker/compat/{asset-symbols.js → asset-symbols.ts} +40 -30
- package/src/atlaspack-v3/worker/compat/bitflags.ts +102 -0
- package/src/atlaspack-v3/worker/compat/{dependency.js → dependency.ts} +13 -13
- package/src/atlaspack-v3/worker/compat/{environment.js → environment.ts} +13 -9
- package/src/atlaspack-v3/worker/compat/index.ts +8 -0
- package/src/atlaspack-v3/worker/compat/{mutable-asset.js → mutable-asset.ts} +21 -20
- package/src/atlaspack-v3/worker/compat/{plugin-config.js → plugin-config.ts} +25 -56
- package/src/atlaspack-v3/worker/compat/{plugin-options.js → plugin-options.ts} +19 -5
- package/src/atlaspack-v3/worker/compat/{plugin-tracer.js → plugin-tracer.ts} +2 -2
- package/src/atlaspack-v3/worker/compat/{target.js → target.ts} +3 -4
- package/src/atlaspack-v3/worker/index.js +2 -1
- package/src/atlaspack-v3/worker/side-effect-detector.ts +298 -0
- package/src/atlaspack-v3/worker/worker.ts +548 -0
- package/src/{constants.js → constants.ts} +0 -3
- package/src/{dumpGraphToGraphViz.js → dumpGraphToGraphViz.ts} +73 -28
- package/src/index.ts +18 -0
- package/src/{loadAtlaspackPlugin.js → loadAtlaspackPlugin.ts} +8 -9
- package/src/{loadDotEnv.js → loadDotEnv.ts} +2 -2
- package/src/{projectPath.js → projectPath.ts} +20 -9
- package/src/public/{Asset.js → Asset.ts} +41 -28
- package/src/public/{Bundle.js → Bundle.ts} +28 -29
- package/src/public/{BundleGraph.js → BundleGraph.ts} +103 -68
- package/src/public/{BundleGroup.js → BundleGroup.ts} +7 -10
- package/src/public/{Config.js → Config.ts} +171 -33
- package/src/public/{Dependency.js → Dependency.ts} +20 -17
- package/src/public/{Environment.js → Environment.ts} +28 -17
- package/src/public/{MutableBundleGraph.js → MutableBundleGraph.ts} +55 -24
- package/src/public/{PluginOptions.js → PluginOptions.ts} +6 -6
- package/src/public/{Symbols.js → Symbols.ts} +75 -36
- package/src/public/{Target.js → Target.ts} +10 -8
- package/src/{registerCoreWithSerializer.js → registerCoreWithSerializer.ts} +9 -7
- package/src/requests/{AssetGraphRequest.js → AssetGraphRequest.ts} +117 -90
- package/src/requests/AssetGraphRequestRust.ts +557 -0
- package/src/requests/{AssetRequest.js → AssetRequest.ts} +24 -18
- package/src/requests/AtlaspackBuildRequest.ts +168 -0
- package/src/requests/{AtlaspackConfigRequest.js → AtlaspackConfigRequest.ts} +72 -58
- package/src/requests/{BundleGraphRequest.js → BundleGraphRequest.ts} +119 -199
- package/src/requests/BundleGraphRequestRust.ts +470 -0
- package/src/requests/BundleGraphRequestUtils.ts +323 -0
- package/src/requests/{ConfigRequest.js → ConfigRequest.ts} +110 -50
- package/src/requests/{DevDepRequest.js → DevDepRequest.ts} +60 -35
- package/src/requests/{EntryRequest.js → EntryRequest.ts} +36 -31
- package/src/requests/{PackageRequest.js → PackageRequest.ts} +52 -25
- package/src/requests/{PathRequest.js → PathRequest.ts} +47 -37
- package/src/requests/{TargetRequest.js → TargetRequest.ts} +265 -179
- package/src/requests/{ValidationRequest.js → ValidationRequest.ts} +18 -17
- package/src/requests/WriteBundleRequest.ts +734 -0
- package/src/requests/{WriteBundlesRequest.js → WriteBundlesRequest.ts} +134 -50
- package/src/requests/{asset-graph-diff.js → asset-graph-diff.ts} +25 -21
- package/src/requests/{asset-graph-dot.js → asset-graph-dot.ts} +8 -12
- package/src/{resolveOptions.js → resolveOptions.ts} +57 -27
- package/src/{rustWorkerThreadDylibHack.js → rustWorkerThreadDylibHack.ts} +1 -4
- package/src/{serializerCore.browser.js → serializerCore.browser.ts} +2 -3
- package/src/{summarizeRequest.js → summarizeRequest.ts} +17 -5
- package/src/types.ts +651 -0
- package/src/{utils.js → utils.ts} +52 -21
- package/src/{worker.js → worker.ts} +50 -42
- package/test/{AssetGraph.test.js → AssetGraph.test.ts} +5 -8
- package/test/{Atlaspack.test.js → Atlaspack.test.ts} +5 -10
- package/test/{AtlaspackConfig.test.js → AtlaspackConfig.test.ts} +0 -5
- package/test/{AtlaspackConfigRequest.test.js → AtlaspackConfigRequest.test.ts} +76 -16
- package/test/{BundleGraph.test.js → BundleGraph.test.ts} +8 -13
- package/test/{Dependency.test.js → Dependency.test.ts} +2 -3
- package/test/{EntryRequest.test.js → EntryRequest.test.ts} +1 -6
- package/test/Environment.test.ts +153 -0
- package/test/EnvironmentManager.test.ts +188 -0
- package/test/{IdentifierRegistry.test.js → IdentifierRegistry.test.ts} +2 -4
- package/test/{InternalAsset.test.js → InternalAsset.test.ts} +2 -7
- package/test/PackagerRunner.test.ts +0 -0
- package/test/{PublicAsset.test.js → PublicAsset.test.ts} +2 -7
- package/test/{PublicBundle.test.js → PublicBundle.test.ts} +1 -2
- package/test/{PublicDependency.test.js → PublicDependency.test.ts} +0 -2
- package/test/PublicEnvironment.test.ts +49 -0
- package/test/{PublicMutableBundleGraph.test.js → PublicMutableBundleGraph.test.ts} +6 -11
- package/test/{RequestTracker.test.js → RequestTracker.test.ts} +136 -58
- package/test/{SymbolPropagation.test.js → SymbolPropagation.test.ts} +124 -74
- package/test/{TargetRequest.test.js → TargetRequest.test.ts} +91 -92
- package/test/fixtures/config-with-reporters/.parcelrc +7 -0
- package/test/fixtures/custom-targets/package.json +6 -0
- package/test/public/Config.test.ts +104 -0
- package/test/requests/AssetGraphRequestRust.test.ts +443 -0
- package/test/requests/{ConfigRequest.test.js → ConfigRequest.test.ts} +202 -13
- package/test/requests/{DevDepRequest.test.js → DevDepRequest.test.ts} +0 -2
- package/test/requests/WriteBundleRequest.test.ts +602 -0
- package/test/{test-utils.js → test-utils.ts} +3 -4
- package/test/{utils.test.js → utils.test.ts} +1 -3
- package/tsconfig.json +60 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/index.d.ts +0 -30
- package/lib/atlaspack-v3/worker/compat/plugin-logger.js +0 -29
- package/src/atlaspack-v3/AtlaspackV3.js +0 -87
- package/src/atlaspack-v3/NapiWorkerPool.js +0 -53
- package/src/atlaspack-v3/jsCallable.js +0 -18
- package/src/atlaspack-v3/worker/compat/bitflags.js +0 -100
- package/src/atlaspack-v3/worker/compat/plugin-logger.js +0 -47
- package/src/atlaspack-v3/worker/worker.js +0 -369
- package/src/index.js +0 -13
- package/src/requests/AssetGraphRequestRust.js +0 -263
- package/src/requests/AtlaspackBuildRequest.js +0 -111
- package/src/requests/WriteBundleRequest.js +0 -369
- package/src/types.js +0 -600
- package/test/Environment.test.js +0 -119
- package/test/PackagerRunner.test.js +0 -27
- package/test/PublicEnvironment.test.js +0 -27
- package/test/requests/AssetGraphRequestRust.test.js +0 -411
|
@@ -0,0 +1,1906 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.bundleGraphEdgeTypes = void 0;
|
|
7
|
+
const assert_1 = __importDefault(require("assert"));
|
|
8
|
+
const assert_2 = __importDefault(require("assert"));
|
|
9
|
+
const nullthrows_1 = __importDefault(require("nullthrows"));
|
|
10
|
+
const graph_1 = require("@atlaspack/graph");
|
|
11
|
+
const rust_1 = require("@atlaspack/rust");
|
|
12
|
+
const utils_1 = require("@atlaspack/utils");
|
|
13
|
+
const types_1 = require("./types");
|
|
14
|
+
const utils_2 = require("./utils");
|
|
15
|
+
const Environment_1 = require("./public/Environment");
|
|
16
|
+
const projectPath_1 = require("./projectPath");
|
|
17
|
+
const constants_1 = require("./constants");
|
|
18
|
+
const feature_flags_1 = require("@atlaspack/feature-flags");
|
|
19
|
+
const logger_1 = __importDefault(require("@atlaspack/logger"));
|
|
20
|
+
const EnvironmentManager_1 = require("./EnvironmentManager");
|
|
21
|
+
exports.bundleGraphEdgeTypes = {
|
|
22
|
+
// A lack of an edge type indicates to follow the edge while traversing
|
|
23
|
+
// the bundle's contents, e.g. `bundle.traverse()` during packaging.
|
|
24
|
+
null: 1,
|
|
25
|
+
// Used for constant-time checks of presence of a dependency or asset in a bundle,
|
|
26
|
+
// avoiding bundle traversal in cases like `isAssetInAncestors`
|
|
27
|
+
contains: 2,
|
|
28
|
+
// Connections between bundles and bundle groups, for quick traversal of the
|
|
29
|
+
// bundle hierarchy.
|
|
30
|
+
bundle: 3,
|
|
31
|
+
// When dependency -> asset: Indicates that the asset a dependency references
|
|
32
|
+
// is contained in another bundle.
|
|
33
|
+
// When dependency -> bundle: Indicates the bundle is necessary for any bundles
|
|
34
|
+
// with the dependency.
|
|
35
|
+
// When bundle -> bundle: Indicates the target bundle is necessary for the
|
|
36
|
+
// source bundle.
|
|
37
|
+
// This type prevents referenced assets from being traversed from dependencies
|
|
38
|
+
// along the untyped edge, and enables traversal to referenced bundles that are
|
|
39
|
+
// not directly connected to bundle group nodes.
|
|
40
|
+
references: 4,
|
|
41
|
+
// Signals that the dependency is internally resolvable via the bundle's ancestry,
|
|
42
|
+
// and that the bundle connected to the dependency is not necessary for the source bundle.
|
|
43
|
+
internal_async: 5,
|
|
44
|
+
// This type is used to mark an edge between a bundle and a conditional bundle.
|
|
45
|
+
// This allows efficient discovery of conditional bundles in packaging
|
|
46
|
+
conditional: 6,
|
|
47
|
+
};
|
|
48
|
+
function makeReadOnlySet(set) {
|
|
49
|
+
return new Proxy(set, {
|
|
50
|
+
get(target, property) {
|
|
51
|
+
if (property === 'delete' || property === 'add' || property === 'clear') {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
// @ts-expect-error TS7053
|
|
56
|
+
let value = target[property];
|
|
57
|
+
return typeof value === 'function' ? value.bind(target) : value;
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Stores assets, dependencies, bundle groups, bundles, and the relationships between them.
|
|
64
|
+
* The BundleGraph is passed to the bundler plugin wrapped in a MutableBundleGraph,
|
|
65
|
+
* and is passed to packagers and optimizers wrapped in the public BundleGraph object, both
|
|
66
|
+
* of which implement public api for this structure. This is the internal structure.
|
|
67
|
+
*/
|
|
68
|
+
class BundleGraph {
|
|
69
|
+
constructor({ graph, publicIdByAssetId, assetPublicIds, bundleContentHashes, conditions, }) {
|
|
70
|
+
this._targetEntryRoots = new Map();
|
|
71
|
+
this._bundlePublicIds /*: Set<string> */ = new Set();
|
|
72
|
+
this._conditions /*: Map<string, Condition> */ = new Map();
|
|
73
|
+
this._graph = graph;
|
|
74
|
+
this._assetPublicIds = assetPublicIds;
|
|
75
|
+
this._publicIdByAssetId = publicIdByAssetId;
|
|
76
|
+
this._bundleContentHashes = bundleContentHashes;
|
|
77
|
+
this._conditions = conditions;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Produce a BundleGraph from an AssetGraph by removing asset groups and retargeting dependencies
|
|
81
|
+
* based on the symbol data (resolving side-effect free reexports).
|
|
82
|
+
*/
|
|
83
|
+
static fromAssetGraph(assetGraph, isProduction, publicIdByAssetId = new Map(), assetPublicIds = new Set()) {
|
|
84
|
+
let graph = new graph_1.ContentGraph();
|
|
85
|
+
let assetGroupIds = new Map();
|
|
86
|
+
let dependencies = new Map();
|
|
87
|
+
let assetGraphNodeIdToBundleGraphNodeId = new Map();
|
|
88
|
+
let conditions = new Map();
|
|
89
|
+
let placeholderToDependency = new Map();
|
|
90
|
+
let assetGraphRootNode = assetGraph.rootNodeId != null
|
|
91
|
+
? assetGraph.getNode(assetGraph.rootNodeId)
|
|
92
|
+
: null;
|
|
93
|
+
(0, assert_2.default)(assetGraphRootNode != null && assetGraphRootNode.type === 'root');
|
|
94
|
+
assetGraph.dfsFast((nodeId) => {
|
|
95
|
+
let node = assetGraph.getNode(nodeId);
|
|
96
|
+
if (node != null && node.type === 'asset') {
|
|
97
|
+
let { id: assetId } = node.value;
|
|
98
|
+
// Generate a new, short public id for this asset to use.
|
|
99
|
+
// If one already exists, use it.
|
|
100
|
+
let publicId = publicIdByAssetId.get(assetId);
|
|
101
|
+
if (publicId == null) {
|
|
102
|
+
publicId = (0, utils_2.getPublicId)(assetId, (existing) => assetPublicIds.has(existing));
|
|
103
|
+
publicIdByAssetId.set(assetId, publicId);
|
|
104
|
+
assetPublicIds.add(publicId);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else if (node != null && node.type === 'asset_group') {
|
|
108
|
+
assetGroupIds.set(nodeId, assetGraph.getNodeIdsConnectedFrom(nodeId));
|
|
109
|
+
}
|
|
110
|
+
else if ((0, feature_flags_1.getFeatureFlag)('conditionalBundlingApi') &&
|
|
111
|
+
node != null &&
|
|
112
|
+
node.type === 'dependency') {
|
|
113
|
+
// The dependency placeholders in the `importCond` calls that will be in the transformed
|
|
114
|
+
// code need to be mapped to the "real" dependencies, so we need access to a map of placeholders
|
|
115
|
+
// to dependencies
|
|
116
|
+
const dep = node.value;
|
|
117
|
+
// @ts-expect-error TS2322
|
|
118
|
+
const placeholder = dep.meta?.placeholder;
|
|
119
|
+
if (placeholder != null) {
|
|
120
|
+
placeholderToDependency.set(placeholder, dep);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
let walkVisited = new Set();
|
|
125
|
+
function walk(nodeId) {
|
|
126
|
+
if (walkVisited.has(nodeId))
|
|
127
|
+
return;
|
|
128
|
+
walkVisited.add(nodeId);
|
|
129
|
+
let node = (0, nullthrows_1.default)(assetGraph.getNode(nodeId));
|
|
130
|
+
if ((0, feature_flags_1.getFeatureFlag)('conditionalBundlingApi') && node.type === 'asset') {
|
|
131
|
+
const asset = node.value;
|
|
132
|
+
if (Array.isArray(asset.meta.conditions)) {
|
|
133
|
+
for (const condition of asset.meta.conditions) {
|
|
134
|
+
// Resolve the placeholders that were attached to the asset in JSTransformer to dependencies,
|
|
135
|
+
// as well as create a public id for the condition.
|
|
136
|
+
const { key, ifTruePlaceholder, ifFalsePlaceholder, } = condition;
|
|
137
|
+
const condHash = (0, rust_1.hashString)(`${key}:${ifTruePlaceholder}:${ifFalsePlaceholder}`);
|
|
138
|
+
const condPublicId = (0, utils_2.getPublicId)(condHash, (v) => conditions.has(v));
|
|
139
|
+
if (conditions.has(condHash)) {
|
|
140
|
+
throw new Error('Unexpected duplicate asset');
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
conditions.set(condHash, {
|
|
144
|
+
publicId: condPublicId,
|
|
145
|
+
assets: new Set([asset]),
|
|
146
|
+
key,
|
|
147
|
+
ifTrueDependency: (0, nullthrows_1.default)(placeholderToDependency.get(ifTruePlaceholder), 'ifTruePlaceholder was undefined'),
|
|
148
|
+
ifFalseDependency: (0, nullthrows_1.default)(placeholderToDependency.get(ifFalsePlaceholder), 'ifFalsePlaceholder was undefined'),
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (node.type === 'dependency' &&
|
|
155
|
+
node.value.symbols != null &&
|
|
156
|
+
(0, EnvironmentManager_1.fromEnvironmentId)(node.value.env).shouldScopeHoist &&
|
|
157
|
+
// Disable in dev mode because this feature is at odds with safeToIncrementallyBundle
|
|
158
|
+
isProduction) {
|
|
159
|
+
let nodeValueSymbols = node.value.symbols;
|
|
160
|
+
// asset -> symbols that should be imported directly from that asset
|
|
161
|
+
let targets = new utils_1.DefaultMap(() => new Map());
|
|
162
|
+
let externalSymbols = new Set();
|
|
163
|
+
let hasAmbiguousSymbols = false;
|
|
164
|
+
for (let [symbol, resolvedSymbol] of node.usedSymbolsUp) {
|
|
165
|
+
if (resolvedSymbol) {
|
|
166
|
+
targets
|
|
167
|
+
.get(resolvedSymbol.asset)
|
|
168
|
+
.set(symbol, resolvedSymbol.symbol ?? symbol);
|
|
169
|
+
}
|
|
170
|
+
else if (resolvedSymbol === null) {
|
|
171
|
+
externalSymbols.add(symbol);
|
|
172
|
+
}
|
|
173
|
+
else if (resolvedSymbol === undefined) {
|
|
174
|
+
hasAmbiguousSymbols = true;
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (
|
|
179
|
+
// Only perform retargeting when there is an imported symbol
|
|
180
|
+
// - If the target is side-effect-free, the symbols point to the actual target and removing
|
|
181
|
+
// the original dependency resolution is fine
|
|
182
|
+
// - Otherwise, keep this dependency unchanged for its potential side effects
|
|
183
|
+
node.usedSymbolsUp.size > 0 &&
|
|
184
|
+
// Only perform retargeting if the dependency only points to a single asset (e.g. CSS modules)
|
|
185
|
+
!hasAmbiguousSymbols &&
|
|
186
|
+
// It doesn't make sense to retarget dependencies where `*` is used, because the
|
|
187
|
+
// retargeting won't enable any benefits in that case (apart from potentially even more
|
|
188
|
+
// code being generated).
|
|
189
|
+
!node.usedSymbolsUp.has('*') &&
|
|
190
|
+
// TODO We currently can't rename imports in async imports, e.g. from
|
|
191
|
+
// (parcelRequire("...")).then(({ a }) => a);
|
|
192
|
+
// to
|
|
193
|
+
// (parcelRequire("...")).then(({ a: b }) => a);
|
|
194
|
+
// or
|
|
195
|
+
// (parcelRequire("...")).then((a)=>a);
|
|
196
|
+
// if the reexporting asset did `export {a as b}` or `export * as a`
|
|
197
|
+
node.value.priority === types_1.Priority.sync &&
|
|
198
|
+
// For every asset, no symbol is imported multiple times (with a different local name).
|
|
199
|
+
// Don't retarget because this cannot be resolved without also changing the asset symbols
|
|
200
|
+
// (and the asset content itself).
|
|
201
|
+
[...targets].every(([, t]) => new Set([...t.values()]).size === t.size)) {
|
|
202
|
+
let isReexportAll = nodeValueSymbols.get('*')?.local === '*' ||
|
|
203
|
+
node.value.meta?.hasExportStar;
|
|
204
|
+
let reexportAllLoc = isReexportAll
|
|
205
|
+
? (0, nullthrows_1.default)(nodeValueSymbols.get('*')).loc
|
|
206
|
+
: undefined;
|
|
207
|
+
// TODO adjust sourceAssetIdNode.value.dependencies ?
|
|
208
|
+
let deps = [
|
|
209
|
+
// Keep the original dependency
|
|
210
|
+
{
|
|
211
|
+
asset: null,
|
|
212
|
+
dep: graph.addNodeByContentKey(node.id, {
|
|
213
|
+
...node,
|
|
214
|
+
value: {
|
|
215
|
+
...node.value,
|
|
216
|
+
symbols: new Map(
|
|
217
|
+
// @ts-expect-error TS2769
|
|
218
|
+
[...nodeValueSymbols].filter(([k]) => externalSymbols.has(k))),
|
|
219
|
+
},
|
|
220
|
+
usedSymbolsUp: new Map(
|
|
221
|
+
// @ts-expect-error TS2769
|
|
222
|
+
[...node.usedSymbolsUp].filter(([k]) => externalSymbols.has(k))),
|
|
223
|
+
usedSymbolsDown: new Set(),
|
|
224
|
+
excluded: externalSymbols.size === 0,
|
|
225
|
+
}),
|
|
226
|
+
},
|
|
227
|
+
...[...targets].map(([asset, target]) => {
|
|
228
|
+
let newNodeId = (0, rust_1.hashString)(node.id + [...target.keys()].join(','));
|
|
229
|
+
let symbols = new Map();
|
|
230
|
+
for (let [as, from] of target) {
|
|
231
|
+
let existing = nodeValueSymbols.get(as);
|
|
232
|
+
if (existing) {
|
|
233
|
+
symbols.set(from, existing);
|
|
234
|
+
}
|
|
235
|
+
else {
|
|
236
|
+
(0, assert_2.default)(isReexportAll);
|
|
237
|
+
if (as === from) {
|
|
238
|
+
// Keep the export-all for non-renamed reexports, this still correctly models
|
|
239
|
+
// ambiguous resolution with multiple export-alls.
|
|
240
|
+
symbols.set('*', {
|
|
241
|
+
isWeak: true,
|
|
242
|
+
local: '*',
|
|
243
|
+
loc: reexportAllLoc,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
let local = `${node.value.id}$rewrite$${asset}$${from}`;
|
|
248
|
+
symbols.set(from, {
|
|
249
|
+
isWeak: true,
|
|
250
|
+
local,
|
|
251
|
+
loc: reexportAllLoc,
|
|
252
|
+
});
|
|
253
|
+
if (node.value.sourceAssetId != null) {
|
|
254
|
+
let sourceAssetId;
|
|
255
|
+
if ((0, feature_flags_1.getFeatureFlag)('sourceAssetIdBundleGraphFix')) {
|
|
256
|
+
[sourceAssetId] =
|
|
257
|
+
assetGraph.getNodeIdsConnectedTo(nodeId);
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
sourceAssetId = assetGraph.getNodeIdByContentKey(node.value.sourceAssetId);
|
|
261
|
+
}
|
|
262
|
+
let sourceAsset = (0, nullthrows_1.default)(graph.getNode((0, nullthrows_1.default)(assetGraphNodeIdToBundleGraphNodeId.get(sourceAssetId))));
|
|
263
|
+
(0, assert_2.default)(sourceAsset.type === 'asset');
|
|
264
|
+
let sourceAssetSymbols = sourceAsset.value.symbols;
|
|
265
|
+
if (sourceAssetSymbols) {
|
|
266
|
+
// The `as == from` case above should handle multiple export-alls causing
|
|
267
|
+
// ambiguous resolution. So the current symbol is unambiguous and shouldn't
|
|
268
|
+
// already exist on the importer.
|
|
269
|
+
(0, assert_2.default)(!sourceAssetSymbols.has(as));
|
|
270
|
+
sourceAssetSymbols.set(as, {
|
|
271
|
+
loc: reexportAllLoc,
|
|
272
|
+
local: local,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
let usedSymbolsUp = new Map([...node.usedSymbolsUp]
|
|
280
|
+
// @ts-expect-error TS2769
|
|
281
|
+
.filter(([k]) => target.has(k) || k === '*')
|
|
282
|
+
.map(([k, v]) => [target.get(k) ?? k, v]));
|
|
283
|
+
return {
|
|
284
|
+
asset,
|
|
285
|
+
dep: graph.addNodeByContentKey(newNodeId, {
|
|
286
|
+
...node,
|
|
287
|
+
id: newNodeId,
|
|
288
|
+
value: {
|
|
289
|
+
...node.value,
|
|
290
|
+
id: newNodeId,
|
|
291
|
+
symbols,
|
|
292
|
+
},
|
|
293
|
+
usedSymbolsUp,
|
|
294
|
+
// This is only a temporary helper needed during symbol propagation and is never
|
|
295
|
+
// read afterwards (and also not exposed through the public API).
|
|
296
|
+
usedSymbolsDown: new Set(),
|
|
297
|
+
}),
|
|
298
|
+
};
|
|
299
|
+
}),
|
|
300
|
+
];
|
|
301
|
+
dependencies.set(nodeId, deps);
|
|
302
|
+
// Jump to the dependencies that are used in this dependency
|
|
303
|
+
for (let id of targets.keys()) {
|
|
304
|
+
walk(assetGraph.getNodeIdByContentKey(id));
|
|
305
|
+
}
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
// No special handling
|
|
310
|
+
let bundleGraphNodeId = graph.addNodeByContentKey(node.id, node);
|
|
311
|
+
assetGraphNodeIdToBundleGraphNodeId.set(nodeId, bundleGraphNodeId);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
// Don't copy over asset groups into the bundle graph.
|
|
315
|
+
else if (node.type !== 'asset_group') {
|
|
316
|
+
let nodeToAdd = node.type === 'asset'
|
|
317
|
+
? {
|
|
318
|
+
...node,
|
|
319
|
+
value: { ...node.value, symbols: new Map(node.value.symbols) },
|
|
320
|
+
}
|
|
321
|
+
: node;
|
|
322
|
+
let bundleGraphNodeId = graph.addNodeByContentKey(node.id, nodeToAdd);
|
|
323
|
+
if (node.id === assetGraphRootNode?.id) {
|
|
324
|
+
graph.setRootNodeId(bundleGraphNodeId);
|
|
325
|
+
}
|
|
326
|
+
assetGraphNodeIdToBundleGraphNodeId.set(nodeId, bundleGraphNodeId);
|
|
327
|
+
}
|
|
328
|
+
for (let id of assetGraph.getNodeIdsConnectedFrom(nodeId)) {
|
|
329
|
+
walk(id);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
walk((0, nullthrows_1.default)(assetGraph.rootNodeId));
|
|
333
|
+
// @ts-expect-error TS2488
|
|
334
|
+
for (let edge of assetGraph.getAllEdges()) {
|
|
335
|
+
if (assetGroupIds.has(edge.from)) {
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
if (dependencies.has(edge.from)) {
|
|
339
|
+
// Discard previous edge, insert outgoing edges for all split dependencies
|
|
340
|
+
for (let { asset, dep } of (0, nullthrows_1.default)(dependencies.get(edge.from))) {
|
|
341
|
+
if (asset != null) {
|
|
342
|
+
graph.addEdge(dep, (0, nullthrows_1.default)(assetGraphNodeIdToBundleGraphNodeId.get(assetGraph.getNodeIdByContentKey(asset))));
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
if (!assetGraphNodeIdToBundleGraphNodeId.has(edge.from)) {
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
let to = dependencies.get(edge.to)?.map((v) => v.dep) ??
|
|
351
|
+
assetGroupIds
|
|
352
|
+
.get(edge.to)
|
|
353
|
+
?.map((id) => (0, nullthrows_1.default)(assetGraphNodeIdToBundleGraphNodeId.get(id))) ?? [(0, nullthrows_1.default)(assetGraphNodeIdToBundleGraphNodeId.get(edge.to))];
|
|
354
|
+
for (let t of to) {
|
|
355
|
+
graph.addEdge((0, nullthrows_1.default)(assetGraphNodeIdToBundleGraphNodeId.get(edge.from)), t);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
return new BundleGraph({
|
|
359
|
+
graph,
|
|
360
|
+
assetPublicIds,
|
|
361
|
+
bundleContentHashes: new Map(),
|
|
362
|
+
publicIdByAssetId,
|
|
363
|
+
conditions,
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
serialize() {
|
|
367
|
+
return {
|
|
368
|
+
$$raw: true,
|
|
369
|
+
graph: this._graph.serialize(),
|
|
370
|
+
assetPublicIds: this._assetPublicIds,
|
|
371
|
+
bundleContentHashes: this._bundleContentHashes,
|
|
372
|
+
publicIdByAssetId: this._publicIdByAssetId,
|
|
373
|
+
conditions: this._conditions,
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
static deserialize(serialized) {
|
|
377
|
+
return new BundleGraph({
|
|
378
|
+
graph: graph_1.ContentGraph.deserialize(serialized.graph),
|
|
379
|
+
assetPublicIds: serialized.assetPublicIds,
|
|
380
|
+
bundleContentHashes: serialized.bundleContentHashes,
|
|
381
|
+
publicIdByAssetId: serialized.publicIdByAssetId,
|
|
382
|
+
conditions: serialized.conditions,
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Serialize the bundle graph for efficient transfer to native Rust code.
|
|
387
|
+
* Returns a JSON string of nodes, an array of edges, and a map of asset IDs to public IDs.
|
|
388
|
+
*/
|
|
389
|
+
serializeForNative() {
|
|
390
|
+
const start = performance.now();
|
|
391
|
+
const nodes = this._graph.nodes;
|
|
392
|
+
const edges = [];
|
|
393
|
+
const edgeIterator = this._graph.getAllEdges();
|
|
394
|
+
let next = edgeIterator.next();
|
|
395
|
+
while (!next.done) {
|
|
396
|
+
const edge = next.value;
|
|
397
|
+
edges.push([edge.from, edge.to, edge.type]);
|
|
398
|
+
next = edgeIterator.next();
|
|
399
|
+
}
|
|
400
|
+
// Extract and deduplicate environments
|
|
401
|
+
const environmentMap = new Map();
|
|
402
|
+
const extractEnvironment = (envRef) => {
|
|
403
|
+
const env = (0, EnvironmentManager_1.fromEnvironmentId)(envRef);
|
|
404
|
+
const envId = env.id;
|
|
405
|
+
if (!environmentMap.has(envId)) {
|
|
406
|
+
environmentMap.set(envId, env);
|
|
407
|
+
}
|
|
408
|
+
return envId;
|
|
409
|
+
};
|
|
410
|
+
// Replace env objects with env IDs in nodes
|
|
411
|
+
const processedNodes = nodes.map((node) => {
|
|
412
|
+
const processedNode = { ...node };
|
|
413
|
+
if (node.type === 'asset' && node.value?.env) {
|
|
414
|
+
processedNode.value = {
|
|
415
|
+
...node.value,
|
|
416
|
+
env: extractEnvironment(node.value.env),
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
else if (node.type === 'dependency' && node.value?.env) {
|
|
420
|
+
processedNode.value = {
|
|
421
|
+
...node.value,
|
|
422
|
+
env: extractEnvironment(node.value.env),
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
else if (node.type === 'bundle' && node.value?.env) {
|
|
426
|
+
processedNode.value = {
|
|
427
|
+
...node.value,
|
|
428
|
+
env: extractEnvironment(node.value.env),
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
return processedNode;
|
|
432
|
+
});
|
|
433
|
+
// Optimize nodes by omitting null/undefined values to reduce JSON size
|
|
434
|
+
const optimizedNodes = processedNodes.map((node) => this._omitNulls(node));
|
|
435
|
+
const nodesJson = JSON.stringify(optimizedNodes);
|
|
436
|
+
// Serialize environments as array
|
|
437
|
+
const environments = Array.from(environmentMap.values());
|
|
438
|
+
const environmentsJson = JSON.stringify(environments);
|
|
439
|
+
// Convert Map to plain object for serialization
|
|
440
|
+
const publicIdByAssetId = {};
|
|
441
|
+
for (const [assetId, publicId] of this._publicIdByAssetId) {
|
|
442
|
+
publicIdByAssetId[assetId] = publicId;
|
|
443
|
+
}
|
|
444
|
+
const duration = performance.now() - start;
|
|
445
|
+
const nodesSizeMB = (nodesJson.length / (1024 * 1024)).toFixed(2);
|
|
446
|
+
const envsSizeMB = (environmentsJson.length / (1024 * 1024)).toFixed(2);
|
|
447
|
+
logger_1.default.verbose({
|
|
448
|
+
origin: '@atlaspack/core',
|
|
449
|
+
message: `serializeForNative: ${duration.toFixed(1)}ms, ${nodesSizeMB}MB nodes, ${envsSizeMB}MB envs (${environmentMap.size} unique), ${nodes.length} nodes, ${edges.length} edges`,
|
|
450
|
+
});
|
|
451
|
+
return { nodesJson, edges, publicIdByAssetId, environmentsJson };
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Serialize only the given asset nodes for native incremental update.
|
|
455
|
+
* Same node shape and env/omit logic as serializeForNative.
|
|
456
|
+
*/
|
|
457
|
+
serializeAssetNodesForNative(assetIds) {
|
|
458
|
+
const start = performance.now();
|
|
459
|
+
if (assetIds.length === 0) {
|
|
460
|
+
return '[]';
|
|
461
|
+
}
|
|
462
|
+
const nodes = [];
|
|
463
|
+
for (const assetId of assetIds) {
|
|
464
|
+
const node = this._graph.getNodeByContentKey(assetId);
|
|
465
|
+
if (node?.type !== 'asset') {
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
const processedNode = { ...node };
|
|
469
|
+
if (node.value?.env) {
|
|
470
|
+
processedNode.value = {
|
|
471
|
+
...node.value,
|
|
472
|
+
env: (0, EnvironmentManager_1.fromEnvironmentId)(node.value.env).id,
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
nodes.push(processedNode);
|
|
476
|
+
}
|
|
477
|
+
const optimizedNodes = nodes.map((node) => this._omitNulls(node));
|
|
478
|
+
const nodesJson = JSON.stringify(optimizedNodes);
|
|
479
|
+
const duration = performance.now() - start;
|
|
480
|
+
const nodesSizeMB = (nodesJson.length / (1024 * 1024)).toFixed(2);
|
|
481
|
+
logger_1.default.verbose({
|
|
482
|
+
origin: '@atlaspack/core',
|
|
483
|
+
message: `serializeAssetNodesForNative: ${duration.toFixed(1)}ms, ${nodesSizeMB}MB nodes, ${nodes.length} nodes`,
|
|
484
|
+
});
|
|
485
|
+
return nodesJson;
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Remove null and undefined values from an object to reduce JSON size.
|
|
489
|
+
* Preserves false, 0, empty strings, and arrays.
|
|
490
|
+
*/
|
|
491
|
+
_omitNulls(obj) {
|
|
492
|
+
if (obj === null || obj === undefined)
|
|
493
|
+
return obj;
|
|
494
|
+
if (typeof obj !== 'object')
|
|
495
|
+
return obj;
|
|
496
|
+
if (Array.isArray(obj)) {
|
|
497
|
+
return obj.map((item) => this._omitNulls(item));
|
|
498
|
+
}
|
|
499
|
+
const result = {};
|
|
500
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
501
|
+
if (value === null || value === undefined) {
|
|
502
|
+
continue;
|
|
503
|
+
}
|
|
504
|
+
if (typeof value === 'object' &&
|
|
505
|
+
!Array.isArray(value) &&
|
|
506
|
+
Object.keys(value).length === 0) {
|
|
507
|
+
continue;
|
|
508
|
+
}
|
|
509
|
+
if (typeof value === 'object') {
|
|
510
|
+
const processed = this._omitNulls(value);
|
|
511
|
+
if (processed !== undefined) {
|
|
512
|
+
result[key] = processed;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
else {
|
|
516
|
+
result[key] = value;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
return result;
|
|
520
|
+
}
|
|
521
|
+
createBundle(opts) {
|
|
522
|
+
// @ts-expect-error TS2339
|
|
523
|
+
let { entryAsset, target } = opts;
|
|
524
|
+
let bundleId = (0, rust_1.hashString)('bundle:' +
|
|
525
|
+
// @ts-expect-error TS2339
|
|
526
|
+
(opts.entryAsset ? opts.entryAsset.id : opts.uniqueKey) +
|
|
527
|
+
(0, projectPath_1.fromProjectPathRelative)(target.distDir) +
|
|
528
|
+
(opts.bundleBehavior ?? ''));
|
|
529
|
+
let existing = this._graph.getNodeByContentKey(bundleId);
|
|
530
|
+
if (existing != null) {
|
|
531
|
+
(0, assert_2.default)(existing.type === 'bundle');
|
|
532
|
+
return existing.value;
|
|
533
|
+
}
|
|
534
|
+
let publicId = (0, utils_2.getPublicId)(bundleId, (existing) => this._bundlePublicIds.has(existing));
|
|
535
|
+
this._bundlePublicIds.add(publicId);
|
|
536
|
+
let isPlaceholder = false;
|
|
537
|
+
if (entryAsset) {
|
|
538
|
+
let entryAssetNode = this._graph.getNodeByContentKey(entryAsset.id);
|
|
539
|
+
(0, assert_2.default)(entryAssetNode?.type === 'asset', 'Entry asset does not exist');
|
|
540
|
+
isPlaceholder = entryAssetNode.requested === false;
|
|
541
|
+
}
|
|
542
|
+
let bundleNode = {
|
|
543
|
+
type: 'bundle',
|
|
544
|
+
id: bundleId,
|
|
545
|
+
value: {
|
|
546
|
+
id: bundleId,
|
|
547
|
+
hashReference: opts.shouldContentHash
|
|
548
|
+
? constants_1.HASH_REF_PREFIX + bundleId
|
|
549
|
+
: bundleId.slice(-8),
|
|
550
|
+
// @ts-expect-error TS2339
|
|
551
|
+
type: opts.entryAsset ? opts.entryAsset.type : opts.type,
|
|
552
|
+
env: opts.env,
|
|
553
|
+
entryAssetIds: entryAsset ? [entryAsset.id] : [],
|
|
554
|
+
mainEntryId: entryAsset?.id,
|
|
555
|
+
// @ts-expect-error TS2339
|
|
556
|
+
pipeline: opts.entryAsset ? opts.entryAsset.pipeline : opts.pipeline,
|
|
557
|
+
needsStableName: opts.needsStableName,
|
|
558
|
+
bundleBehavior: opts.bundleBehavior != null
|
|
559
|
+
? types_1.BundleBehavior[opts.bundleBehavior]
|
|
560
|
+
: null,
|
|
561
|
+
// @ts-expect-error TS2339
|
|
562
|
+
isSplittable: opts.entryAsset
|
|
563
|
+
? // @ts-expect-error TS2339
|
|
564
|
+
opts.entryAsset.isBundleSplittable
|
|
565
|
+
: // @ts-expect-error TS2339
|
|
566
|
+
opts.isSplittable,
|
|
567
|
+
isPlaceholder,
|
|
568
|
+
target,
|
|
569
|
+
name: null,
|
|
570
|
+
displayName: null,
|
|
571
|
+
publicId,
|
|
572
|
+
},
|
|
573
|
+
};
|
|
574
|
+
let bundleNodeId = this._graph.addNodeByContentKey(bundleId, bundleNode);
|
|
575
|
+
// @ts-expect-error TS2339
|
|
576
|
+
if (opts.entryAsset) {
|
|
577
|
+
this._graph.addEdge(bundleNodeId,
|
|
578
|
+
// @ts-expect-error TS2339
|
|
579
|
+
this._graph.getNodeIdByContentKey(opts.entryAsset.id));
|
|
580
|
+
}
|
|
581
|
+
assert_2.default;
|
|
582
|
+
return bundleNode.value;
|
|
583
|
+
}
|
|
584
|
+
addAssetToBundle(asset, bundle) {
|
|
585
|
+
let bundleNodeId = this._graph.getNodeIdByContentKey(bundle.id);
|
|
586
|
+
this._graph.addEdge(bundleNodeId, this._graph.getNodeIdByContentKey(asset.id), exports.bundleGraphEdgeTypes.contains);
|
|
587
|
+
this._graph.addEdge(bundleNodeId, this._graph.getNodeIdByContentKey(asset.id));
|
|
588
|
+
let dependencies = this.getDependencies(asset);
|
|
589
|
+
for (let dependency of dependencies) {
|
|
590
|
+
let dependencyNodeId = this._graph.getNodeIdByContentKey(dependency.id);
|
|
591
|
+
this._graph.addEdge(bundleNodeId, dependencyNodeId, exports.bundleGraphEdgeTypes.contains);
|
|
592
|
+
for (let [bundleGroupNodeId, bundleGroupNode] of this._graph
|
|
593
|
+
.getNodeIdsConnectedFrom(dependencyNodeId)
|
|
594
|
+
.map((id) => [id, (0, nullthrows_1.default)(this._graph.getNode(id))])
|
|
595
|
+
// @ts-expect-error TS2769
|
|
596
|
+
.filter(([, node]) => node.type === 'bundle_group')) {
|
|
597
|
+
// @ts-expect-error TS2339
|
|
598
|
+
(0, assert_2.default)(bundleGroupNode.type === 'bundle_group');
|
|
599
|
+
this._graph.addEdge(bundleNodeId,
|
|
600
|
+
// @ts-expect-error TS2345
|
|
601
|
+
bundleGroupNodeId, exports.bundleGraphEdgeTypes.bundle);
|
|
602
|
+
}
|
|
603
|
+
// If the dependency references a target bundle, add a reference edge from
|
|
604
|
+
// the source bundle to the dependency for easy traversal.
|
|
605
|
+
// TODO: Consider bundle being created from dependency
|
|
606
|
+
if (this._graph
|
|
607
|
+
.getNodeIdsConnectedFrom(dependencyNodeId, exports.bundleGraphEdgeTypes.references)
|
|
608
|
+
.map((id) => (0, nullthrows_1.default)(this._graph.getNode(id)))
|
|
609
|
+
.some((node) => node.type === 'bundle')) {
|
|
610
|
+
this._graph.addEdge(bundleNodeId, dependencyNodeId, exports.bundleGraphEdgeTypes.references);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
addAssetGraphToBundle(asset, bundle, shouldSkipDependency = (d) => this.isDependencySkipped(d)) {
|
|
615
|
+
let assetNodeId = this._graph.getNodeIdByContentKey(asset.id);
|
|
616
|
+
let bundleNodeId = this._graph.getNodeIdByContentKey(bundle.id);
|
|
617
|
+
// The root asset should be reached directly from the bundle in traversal.
|
|
618
|
+
// Its children will be traversed from there.
|
|
619
|
+
this._graph.addEdge(bundleNodeId, assetNodeId);
|
|
620
|
+
this._graph.traverse((nodeId, _, actions) => {
|
|
621
|
+
let node = (0, nullthrows_1.default)(this._graph.getNode(nodeId));
|
|
622
|
+
if (node.type === 'bundle_group') {
|
|
623
|
+
actions.skipChildren();
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
if (node.type === 'dependency' && shouldSkipDependency(node.value)) {
|
|
627
|
+
actions.skipChildren();
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
if (node.type === 'asset' || node.type === 'dependency') {
|
|
631
|
+
this._graph.addEdge(bundleNodeId, nodeId, exports.bundleGraphEdgeTypes.contains);
|
|
632
|
+
}
|
|
633
|
+
if (node.type === 'dependency') {
|
|
634
|
+
for (let [bundleGroupNodeId, bundleGroupNode] of this._graph
|
|
635
|
+
.getNodeIdsConnectedFrom(nodeId)
|
|
636
|
+
.map((id) => [id, (0, nullthrows_1.default)(this._graph.getNode(id))])
|
|
637
|
+
// @ts-expect-error TS2769
|
|
638
|
+
.filter(([, node]) => node.type === 'bundle_group')) {
|
|
639
|
+
// @ts-expect-error TS2339
|
|
640
|
+
(0, assert_2.default)(bundleGroupNode.type === 'bundle_group');
|
|
641
|
+
this._graph.addEdge(bundleNodeId,
|
|
642
|
+
// @ts-expect-error TS2345
|
|
643
|
+
bundleGroupNodeId, exports.bundleGraphEdgeTypes.bundle);
|
|
644
|
+
}
|
|
645
|
+
// If the dependency references a target bundle, add a reference edge from
|
|
646
|
+
// the source bundle to the dependency for easy traversal.
|
|
647
|
+
if (this._graph
|
|
648
|
+
.getNodeIdsConnectedFrom(nodeId, exports.bundleGraphEdgeTypes.references)
|
|
649
|
+
.map((id) => (0, nullthrows_1.default)(this._graph.getNode(id)))
|
|
650
|
+
.some((node) => node.type === 'bundle')) {
|
|
651
|
+
this._graph.addEdge(bundleNodeId, nodeId, exports.bundleGraphEdgeTypes.references);
|
|
652
|
+
this.markDependencyReferenceable(node.value);
|
|
653
|
+
//all bundles that have this dependency need to have an edge from bundle to that dependency
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
}, assetNodeId);
|
|
657
|
+
this._bundleContentHashes.delete(bundle.id);
|
|
658
|
+
}
|
|
659
|
+
markDependencyReferenceable(dependency) {
|
|
660
|
+
for (let bundle of this.getBundlesWithDependency(dependency)) {
|
|
661
|
+
this._graph.addEdge(this._graph.getNodeIdByContentKey(bundle.id), this._graph.getNodeIdByContentKey(dependency.id), exports.bundleGraphEdgeTypes.references);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
addEntryToBundle(asset, bundle, shouldSkipDependency) {
|
|
665
|
+
this.addAssetGraphToBundle(asset, bundle, shouldSkipDependency);
|
|
666
|
+
if (!bundle.entryAssetIds.includes(asset.id)) {
|
|
667
|
+
bundle.entryAssetIds.push(asset.id);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
internalizeAsyncDependency(bundle, dependency) {
|
|
671
|
+
if (dependency.priority === types_1.Priority.sync) {
|
|
672
|
+
throw new Error('Expected an async dependency');
|
|
673
|
+
}
|
|
674
|
+
// It's possible for internalized async dependencies to not have
|
|
675
|
+
// reference edges and still have untyped edges.
|
|
676
|
+
// TODO: Maybe don't use internalized async edges at all?
|
|
677
|
+
let dependencyNodeId = this._graph.getNodeIdByContentKey(dependency.id);
|
|
678
|
+
let resolved = this.getResolvedAsset(dependency);
|
|
679
|
+
if (resolved) {
|
|
680
|
+
let resolvedNodeId = this._graph.getNodeIdByContentKey(resolved.id);
|
|
681
|
+
if (!this._graph.hasEdge(dependencyNodeId, resolvedNodeId, exports.bundleGraphEdgeTypes.references)) {
|
|
682
|
+
this._graph.addEdge(dependencyNodeId, resolvedNodeId, exports.bundleGraphEdgeTypes.references);
|
|
683
|
+
this._graph.removeEdge(dependencyNodeId, resolvedNodeId);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
this._graph.addEdge(this._graph.getNodeIdByContentKey(bundle.id), this._graph.getNodeIdByContentKey(dependency.id), exports.bundleGraphEdgeTypes.internal_async);
|
|
687
|
+
this._removeExternalDependency(bundle, dependency);
|
|
688
|
+
}
|
|
689
|
+
isDependencySkipped(dependency) {
|
|
690
|
+
let node = this._graph.getNodeByContentKey(dependency.id);
|
|
691
|
+
(0, assert_2.default)(node && node.type === 'dependency');
|
|
692
|
+
return !!node.hasDeferred || node.excluded;
|
|
693
|
+
}
|
|
694
|
+
getParentBundlesOfBundleGroup(bundleGroup) {
|
|
695
|
+
return this._graph
|
|
696
|
+
.getNodeIdsConnectedTo(this._graph.getNodeIdByContentKey((0, utils_2.getBundleGroupId)(bundleGroup)), exports.bundleGraphEdgeTypes.bundle)
|
|
697
|
+
.map((id) => (0, nullthrows_1.default)(this._graph.getNode(id)))
|
|
698
|
+
.filter((node) => node.type === 'bundle')
|
|
699
|
+
.map((node) => {
|
|
700
|
+
(0, assert_2.default)(node.type === 'bundle');
|
|
701
|
+
return node.value;
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
resolveAsyncDependency(dependency, bundle) {
|
|
705
|
+
let depNodeId = this._graph.getNodeIdByContentKey(dependency.id);
|
|
706
|
+
let bundleNodeId = bundle != null ? this._graph.getNodeIdByContentKey(bundle.id) : null;
|
|
707
|
+
if (bundleNodeId != null &&
|
|
708
|
+
this._graph.hasEdge(bundleNodeId, depNodeId, exports.bundleGraphEdgeTypes.internal_async)) {
|
|
709
|
+
let referencedAssetNodeIds = this._graph.getNodeIdsConnectedFrom(depNodeId, exports.bundleGraphEdgeTypes.references);
|
|
710
|
+
let resolved;
|
|
711
|
+
if (referencedAssetNodeIds.length === 0) {
|
|
712
|
+
resolved = this.getResolvedAsset(dependency, bundle);
|
|
713
|
+
}
|
|
714
|
+
else if (referencedAssetNodeIds.length === 1) {
|
|
715
|
+
let referencedAssetNode = this._graph.getNode(referencedAssetNodeIds[0]);
|
|
716
|
+
// If a referenced asset already exists, resolve this dependency to it.
|
|
717
|
+
(0, assert_2.default)(referencedAssetNode?.type === 'asset');
|
|
718
|
+
resolved = referencedAssetNode.value;
|
|
719
|
+
}
|
|
720
|
+
else {
|
|
721
|
+
throw new Error('Dependencies can only reference one asset');
|
|
722
|
+
}
|
|
723
|
+
if (resolved == null) {
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
else {
|
|
727
|
+
return {
|
|
728
|
+
type: 'asset',
|
|
729
|
+
value: resolved,
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
let node = this._graph
|
|
734
|
+
.getNodeIdsConnectedFrom(this._graph.getNodeIdByContentKey(dependency.id))
|
|
735
|
+
.map((id) => (0, nullthrows_1.default)(this._graph.getNode(id)))
|
|
736
|
+
.find((node) => node.type === 'bundle_group');
|
|
737
|
+
if (node == null) {
|
|
738
|
+
return;
|
|
739
|
+
}
|
|
740
|
+
(0, assert_2.default)(node.type === 'bundle_group');
|
|
741
|
+
return {
|
|
742
|
+
type: 'bundle_group',
|
|
743
|
+
value: node.value,
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
// eslint-disable-next-line no-unused-vars
|
|
747
|
+
getReferencedBundle(dependency, fromBundle) {
|
|
748
|
+
let dependencyNodeId = this._graph.getNodeIdByContentKey(dependency.id);
|
|
749
|
+
// Find an attached bundle via a reference edge (e.g. from createAssetReference).
|
|
750
|
+
let bundleNodes = this._graph
|
|
751
|
+
.getNodeIdsConnectedFrom(dependencyNodeId, exports.bundleGraphEdgeTypes.references)
|
|
752
|
+
.map((id) => (0, nullthrows_1.default)(this._graph.getNode(id)))
|
|
753
|
+
.filter((node) => node.type === 'bundle');
|
|
754
|
+
if (bundleNodes.length) {
|
|
755
|
+
let bundleNode = bundleNodes.find((b) => b.type === 'bundle' && b.value.type === fromBundle.type) || bundleNodes[0];
|
|
756
|
+
(0, assert_2.default)(bundleNode.type === 'bundle');
|
|
757
|
+
return bundleNode.value;
|
|
758
|
+
}
|
|
759
|
+
// If this dependency is async, there will be a bundle group attached to it.
|
|
760
|
+
let node = this._graph
|
|
761
|
+
.getNodeIdsConnectedFrom(dependencyNodeId)
|
|
762
|
+
.map((id) => (0, nullthrows_1.default)(this._graph.getNode(id)))
|
|
763
|
+
.find((node) => node.type === 'bundle_group');
|
|
764
|
+
if (node != null) {
|
|
765
|
+
(0, assert_2.default)(node.type === 'bundle_group');
|
|
766
|
+
return this.getBundlesInBundleGroup(node.value, {
|
|
767
|
+
includeInline: true,
|
|
768
|
+
}).find((b) => {
|
|
769
|
+
if ((0, feature_flags_1.getFeatureFlag)('supportWebpackChunkName')) {
|
|
770
|
+
return b.entryAssetIds.some((id) => id === node.value.entryAssetId);
|
|
771
|
+
}
|
|
772
|
+
else {
|
|
773
|
+
let mainEntryId = b.entryAssetIds[b.entryAssetIds.length - 1];
|
|
774
|
+
return mainEntryId != null && node.value.entryAssetId === mainEntryId;
|
|
775
|
+
}
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
removeAssetGraphFromBundle(asset, bundle) {
|
|
780
|
+
let bundleNodeId = this._graph.getNodeIdByContentKey(bundle.id);
|
|
781
|
+
let assetNodeId = this._graph.getNodeIdByContentKey(asset.id);
|
|
782
|
+
// Remove all contains edges from the bundle to the nodes in the asset's
|
|
783
|
+
// subgraph.
|
|
784
|
+
this._graph.traverse((nodeId, context, actions) => {
|
|
785
|
+
let node = (0, nullthrows_1.default)(this._graph.getNode(nodeId));
|
|
786
|
+
if (node.type === 'bundle_group') {
|
|
787
|
+
actions.skipChildren();
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
if (node.type !== 'dependency' && node.type !== 'asset') {
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
if (this._graph.hasEdge(bundleNodeId, nodeId, exports.bundleGraphEdgeTypes.contains)) {
|
|
794
|
+
this._graph.removeEdge(bundleNodeId, nodeId, exports.bundleGraphEdgeTypes.contains,
|
|
795
|
+
// Removing this contains edge should not orphan the connected node. This
|
|
796
|
+
// is disabled for performance reasons as these edges are removed as part
|
|
797
|
+
// of a traversal, and checking for orphans becomes quite expensive in
|
|
798
|
+
// aggregate.
|
|
799
|
+
false /* removeOrphans */);
|
|
800
|
+
}
|
|
801
|
+
else {
|
|
802
|
+
actions.skipChildren();
|
|
803
|
+
}
|
|
804
|
+
if (node.type === 'asset' && this._graph.hasEdge(bundleNodeId, nodeId)) {
|
|
805
|
+
// Remove the untyped edge from the bundle to the node (it's an entry)
|
|
806
|
+
this._graph.removeEdge(bundleNodeId, nodeId);
|
|
807
|
+
let entryIndex = bundle.entryAssetIds.indexOf(node.value.id);
|
|
808
|
+
if (entryIndex >= 0) {
|
|
809
|
+
// Shared bundles have untyped edges to their asset graphs but don't
|
|
810
|
+
// have entry assets. For those that have entry asset ids, remove them.
|
|
811
|
+
bundle.entryAssetIds.splice(entryIndex, 1);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
if (node.type === 'dependency') {
|
|
815
|
+
this._removeExternalDependency(bundle, node.value);
|
|
816
|
+
if (this._graph.hasEdge(bundleNodeId, nodeId, exports.bundleGraphEdgeTypes.references)) {
|
|
817
|
+
this._graph.addEdge(bundleNodeId, nodeId, exports.bundleGraphEdgeTypes.references);
|
|
818
|
+
this.markDependencyReferenceable(node.value);
|
|
819
|
+
}
|
|
820
|
+
if (this._graph.hasEdge(bundleNodeId, nodeId, exports.bundleGraphEdgeTypes.internal_async)) {
|
|
821
|
+
this._graph.removeEdge(bundleNodeId, nodeId, exports.bundleGraphEdgeTypes.internal_async);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
}, assetNodeId);
|
|
825
|
+
// Remove bundle node if it no longer has any entry assets
|
|
826
|
+
if (this._graph.getNodeIdsConnectedFrom(bundleNodeId).length === 0) {
|
|
827
|
+
this.removeBundle(bundle);
|
|
828
|
+
}
|
|
829
|
+
this._bundleContentHashes.delete(bundle.id);
|
|
830
|
+
}
|
|
831
|
+
/**
|
|
832
|
+
* Remove a bundle from the bundle graph. Remove its bundle group if it is
|
|
833
|
+
* the only bundle in the group.
|
|
834
|
+
*/
|
|
835
|
+
removeBundle(bundle) {
|
|
836
|
+
// Remove bundle node if it no longer has any entry assets
|
|
837
|
+
let bundleNodeId = this._graph.getNodeIdByContentKey(bundle.id);
|
|
838
|
+
let bundleGroupNodeIds = this._graph.getNodeIdsConnectedTo(bundleNodeId, exports.bundleGraphEdgeTypes.bundle);
|
|
839
|
+
this._graph.removeNode(bundleNodeId);
|
|
840
|
+
let removedBundleGroups = new Set();
|
|
841
|
+
// Remove bundle group node if it no longer has any bundles
|
|
842
|
+
for (let bundleGroupNodeId of bundleGroupNodeIds) {
|
|
843
|
+
let bundleGroupNode = (0, nullthrows_1.default)(this._graph.getNode(bundleGroupNodeId));
|
|
844
|
+
(0, assert_2.default)(bundleGroupNode.type === 'bundle_group');
|
|
845
|
+
let bundleGroup = bundleGroupNode.value;
|
|
846
|
+
if (
|
|
847
|
+
// If the bundle group's entry asset belongs to this bundle, the group
|
|
848
|
+
// was created because of this bundle. Remove the group.
|
|
849
|
+
bundle.entryAssetIds.includes(bundleGroup.entryAssetId) ||
|
|
850
|
+
// If the bundle group is now empty, remove it.
|
|
851
|
+
this.getBundlesInBundleGroup(bundleGroup, { includeInline: true })
|
|
852
|
+
.length === 0) {
|
|
853
|
+
removedBundleGroups.add(bundleGroup);
|
|
854
|
+
this.removeBundleGroup(bundleGroup);
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
this._bundleContentHashes.delete(bundle.id);
|
|
858
|
+
return removedBundleGroups;
|
|
859
|
+
}
|
|
860
|
+
removeBundleGroup(bundleGroup) {
|
|
861
|
+
let bundleGroupNode = (0, nullthrows_1.default)(this._graph.getNodeByContentKey((0, utils_2.getBundleGroupId)(bundleGroup)));
|
|
862
|
+
(0, assert_2.default)(bundleGroupNode.type === 'bundle_group');
|
|
863
|
+
let bundlesInGroup = this.getBundlesInBundleGroup(bundleGroupNode.value, {
|
|
864
|
+
includeInline: true,
|
|
865
|
+
});
|
|
866
|
+
for (let bundle of bundlesInGroup) {
|
|
867
|
+
if (this.getBundleGroupsContainingBundle(bundle).length === 1) {
|
|
868
|
+
let removedBundleGroups = this.removeBundle(bundle);
|
|
869
|
+
if (removedBundleGroups.has(bundleGroup)) {
|
|
870
|
+
// This function can be reentered through removeBundle above. In the case this
|
|
871
|
+
// bundle group has already been removed, stop.
|
|
872
|
+
return;
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
// This function can be reentered through removeBundle above. In this case,
|
|
877
|
+
// the node may already been removed.
|
|
878
|
+
if (this._graph.hasContentKey(bundleGroupNode.id)) {
|
|
879
|
+
this._graph.removeNode(this._graph.getNodeIdByContentKey(bundleGroupNode.id));
|
|
880
|
+
}
|
|
881
|
+
(0, assert_1.default)(bundlesInGroup.every((bundle) => this.getBundleGroupsContainingBundle(bundle).length > 0));
|
|
882
|
+
}
|
|
883
|
+
_removeExternalDependency(bundle, dependency) {
|
|
884
|
+
let bundleNodeId = this._graph.getNodeIdByContentKey(bundle.id);
|
|
885
|
+
for (let bundleGroupNode of this._graph
|
|
886
|
+
.getNodeIdsConnectedFrom(this._graph.getNodeIdByContentKey(dependency.id))
|
|
887
|
+
.map((id) => (0, nullthrows_1.default)(this._graph.getNode(id)))
|
|
888
|
+
.filter((node) => node.type === 'bundle_group')) {
|
|
889
|
+
let bundleGroupNodeId = this._graph.getNodeIdByContentKey(bundleGroupNode.id);
|
|
890
|
+
if (!this._graph.hasEdge(bundleNodeId, bundleGroupNodeId, exports.bundleGraphEdgeTypes.bundle)) {
|
|
891
|
+
continue;
|
|
892
|
+
}
|
|
893
|
+
let inboundDependencies = this._graph
|
|
894
|
+
.getNodeIdsConnectedTo(bundleGroupNodeId)
|
|
895
|
+
.map((id) => (0, nullthrows_1.default)(this._graph.getNode(id)))
|
|
896
|
+
.filter((node) => node.type === 'dependency')
|
|
897
|
+
.map((node) => {
|
|
898
|
+
(0, assert_2.default)(node.type === 'dependency');
|
|
899
|
+
return node.value;
|
|
900
|
+
});
|
|
901
|
+
// If every inbound dependency to this bundle group does not belong to this bundle,
|
|
902
|
+
// or the dependency is internal to the bundle, then the connection between
|
|
903
|
+
// this bundle and the group is safe to remove.
|
|
904
|
+
if (inboundDependencies.every((dependency) => dependency.specifierType !== types_1.SpecifierType.url &&
|
|
905
|
+
(!this.bundleHasDependency(bundle, dependency) ||
|
|
906
|
+
this._graph.hasEdge(bundleNodeId, this._graph.getNodeIdByContentKey(dependency.id), exports.bundleGraphEdgeTypes.internal_async)))) {
|
|
907
|
+
this._graph.removeEdge(bundleNodeId, bundleGroupNodeId, exports.bundleGraphEdgeTypes.bundle);
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
createAssetReference(dependency, asset, bundle) {
|
|
912
|
+
let dependencyId = this._graph.getNodeIdByContentKey(dependency.id);
|
|
913
|
+
let assetId = this._graph.getNodeIdByContentKey(asset.id);
|
|
914
|
+
let bundleId = this._graph.getNodeIdByContentKey(bundle.id);
|
|
915
|
+
this._graph.addEdge(dependencyId, assetId, exports.bundleGraphEdgeTypes.references);
|
|
916
|
+
this._graph.addEdge(dependencyId, bundleId, exports.bundleGraphEdgeTypes.references);
|
|
917
|
+
this.markDependencyReferenceable(dependency);
|
|
918
|
+
if (this._graph.hasEdge(dependencyId, assetId)) {
|
|
919
|
+
this._graph.removeEdge(dependencyId, assetId);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
createBundleReference(from, to) {
|
|
923
|
+
this._graph.addEdge(this._graph.getNodeIdByContentKey(from.id), this._graph.getNodeIdByContentKey(to.id), exports.bundleGraphEdgeTypes.references);
|
|
924
|
+
}
|
|
925
|
+
createBundleConditionalReference(from, to) {
|
|
926
|
+
this._graph.addEdge(this._graph.getNodeIdByContentKey(from.id), this._graph.getNodeIdByContentKey(to.id), exports.bundleGraphEdgeTypes.conditional);
|
|
927
|
+
}
|
|
928
|
+
getBundlesWithAsset(asset) {
|
|
929
|
+
return this._graph
|
|
930
|
+
.getNodeIdsConnectedTo(this._graph.getNodeIdByContentKey(asset.id), exports.bundleGraphEdgeTypes.contains)
|
|
931
|
+
.map((id) => (0, nullthrows_1.default)(this._graph.getNode(id)))
|
|
932
|
+
.filter((node) => node.type === 'bundle')
|
|
933
|
+
.map((node) => {
|
|
934
|
+
(0, assert_2.default)(node.type === 'bundle');
|
|
935
|
+
return node.value;
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
getBundlesWithDependency(dependency) {
|
|
939
|
+
return this._graph
|
|
940
|
+
.getNodeIdsConnectedTo((0, nullthrows_1.default)(this._graph.getNodeIdByContentKey(dependency.id)), exports.bundleGraphEdgeTypes.contains)
|
|
941
|
+
.map((id) => (0, nullthrows_1.default)(this._graph.getNode(id)))
|
|
942
|
+
.filter((node) => node.type === 'bundle')
|
|
943
|
+
.map((node) => {
|
|
944
|
+
(0, assert_2.default)(node.type === 'bundle');
|
|
945
|
+
return node.value;
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
getDependencyAssets(dependency) {
|
|
949
|
+
return this._graph
|
|
950
|
+
.getNodeIdsConnectedFrom(this._graph.getNodeIdByContentKey(dependency.id))
|
|
951
|
+
.map((id) => (0, nullthrows_1.default)(this._graph.getNode(id)))
|
|
952
|
+
.filter((node) => node.type === 'asset')
|
|
953
|
+
.map((node) => {
|
|
954
|
+
(0, assert_2.default)(node.type === 'asset');
|
|
955
|
+
return node.value;
|
|
956
|
+
});
|
|
957
|
+
}
|
|
958
|
+
getResolvedAsset(dep, bundle) {
|
|
959
|
+
let assets = this.getDependencyAssets(dep);
|
|
960
|
+
let firstAsset = assets[0];
|
|
961
|
+
let resolved =
|
|
962
|
+
// If no bundle is specified, use the first concrete asset.
|
|
963
|
+
bundle == null
|
|
964
|
+
? firstAsset
|
|
965
|
+
: // Otherwise, find the first asset that belongs to this bundle.
|
|
966
|
+
assets.find((asset) => this.bundleHasAsset(bundle, asset)) ||
|
|
967
|
+
assets.find((a) => a.type === bundle.type) ||
|
|
968
|
+
firstAsset;
|
|
969
|
+
// If a resolution still hasn't been found, return the first referenced asset.
|
|
970
|
+
if (resolved == null) {
|
|
971
|
+
let potential = [];
|
|
972
|
+
this._graph.traverse((nodeId, _, traversal) => {
|
|
973
|
+
let node = (0, nullthrows_1.default)(this._graph.getNode(nodeId));
|
|
974
|
+
if (node.type === 'asset') {
|
|
975
|
+
potential.push(node.value);
|
|
976
|
+
}
|
|
977
|
+
else if (node.id !== dep.id) {
|
|
978
|
+
traversal.skipChildren();
|
|
979
|
+
}
|
|
980
|
+
}, this._graph.getNodeIdByContentKey(dep.id), exports.bundleGraphEdgeTypes.references);
|
|
981
|
+
if (bundle) {
|
|
982
|
+
// @ts-expect-error TS2322
|
|
983
|
+
resolved = potential.find((a) => a.type === bundle.type);
|
|
984
|
+
}
|
|
985
|
+
resolved || (resolved = potential[0]);
|
|
986
|
+
}
|
|
987
|
+
return resolved;
|
|
988
|
+
}
|
|
989
|
+
getDependencies(asset) {
|
|
990
|
+
let nodeId = this._graph.getNodeIdByContentKey(asset.id);
|
|
991
|
+
return this._graph.getNodeIdsConnectedFrom(nodeId).map((id) => {
|
|
992
|
+
let node = (0, nullthrows_1.default)(this._graph.getNode(id));
|
|
993
|
+
(0, assert_2.default)(node.type === 'dependency');
|
|
994
|
+
return node.value;
|
|
995
|
+
});
|
|
996
|
+
}
|
|
997
|
+
traverseAssets(bundle, visit, startAsset) {
|
|
998
|
+
return this.traverseBundle(bundle, (0, graph_1.mapVisitor)((node) => (node.type === 'asset' ? node.value : null), visit), startAsset);
|
|
999
|
+
}
|
|
1000
|
+
isAssetReferenced(bundle, asset) {
|
|
1001
|
+
// If the asset is available in multiple bundles in the same target, it's referenced.
|
|
1002
|
+
if (this.getBundlesWithAsset(asset).filter((b) => b.target.name === bundle.target.name &&
|
|
1003
|
+
b.target.distDir === bundle.target.distDir).length > 1) {
|
|
1004
|
+
return true;
|
|
1005
|
+
}
|
|
1006
|
+
let assetNodeId = (0, nullthrows_1.default)(this._graph.getNodeIdByContentKey(asset.id));
|
|
1007
|
+
if (this._graph
|
|
1008
|
+
.getNodeIdsConnectedTo(assetNodeId, exports.bundleGraphEdgeTypes.references)
|
|
1009
|
+
.map((id) => this._graph.getNode(id))
|
|
1010
|
+
.some((node) => node?.type === 'dependency' &&
|
|
1011
|
+
(node.value.priority === types_1.Priority.lazy ||
|
|
1012
|
+
node.value.priority === types_1.Priority.conditional) &&
|
|
1013
|
+
node.value.specifierType !== types_1.SpecifierType.url)) {
|
|
1014
|
+
// If this asset is referenced by any async dependency, it's referenced.
|
|
1015
|
+
return true;
|
|
1016
|
+
}
|
|
1017
|
+
let dependencies = this._graph
|
|
1018
|
+
.getNodeIdsConnectedTo(assetNodeId)
|
|
1019
|
+
.map((id) => (0, nullthrows_1.default)(this._graph.getNode(id)))
|
|
1020
|
+
.filter((node) => node.type === 'dependency')
|
|
1021
|
+
.map((node) => {
|
|
1022
|
+
(0, assert_2.default)(node.type === 'dependency');
|
|
1023
|
+
return node.value;
|
|
1024
|
+
});
|
|
1025
|
+
const bundleHasReference = (bundle) => {
|
|
1026
|
+
return (!this.bundleHasAsset(bundle, asset) &&
|
|
1027
|
+
dependencies.some((dependency) => this.bundleHasDependency(bundle, dependency)));
|
|
1028
|
+
};
|
|
1029
|
+
let visitedBundles = new Set();
|
|
1030
|
+
let siblingBundles = new Set(this.getBundleGroupsContainingBundle(bundle).flatMap((bundleGroup) => this.getBundlesInBundleGroup(bundleGroup, { includeInline: true })));
|
|
1031
|
+
// Check if any of this bundle's descendants, referencers, bundles referenced
|
|
1032
|
+
// by referencers, or descendants of its referencers use the asset without
|
|
1033
|
+
// an explicit reference edge. This can happen if e.g. the asset has been
|
|
1034
|
+
// deduplicated.
|
|
1035
|
+
return [...siblingBundles].some((referencer) => {
|
|
1036
|
+
let isReferenced = false;
|
|
1037
|
+
this.traverseBundles((descendant, _, actions) => {
|
|
1038
|
+
if (descendant.id === bundle.id) {
|
|
1039
|
+
return;
|
|
1040
|
+
}
|
|
1041
|
+
if (visitedBundles.has(descendant)) {
|
|
1042
|
+
actions.skipChildren();
|
|
1043
|
+
return;
|
|
1044
|
+
}
|
|
1045
|
+
visitedBundles.add(descendant);
|
|
1046
|
+
if (descendant.type !== bundle.type ||
|
|
1047
|
+
(0, EnvironmentManager_1.fromEnvironmentId)(descendant.env).context !==
|
|
1048
|
+
(0, EnvironmentManager_1.fromEnvironmentId)(bundle.env).context) {
|
|
1049
|
+
actions.skipChildren();
|
|
1050
|
+
return;
|
|
1051
|
+
}
|
|
1052
|
+
if (bundleHasReference(descendant)) {
|
|
1053
|
+
isReferenced = true;
|
|
1054
|
+
actions.stop();
|
|
1055
|
+
return;
|
|
1056
|
+
}
|
|
1057
|
+
}, referencer);
|
|
1058
|
+
return isReferenced;
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1061
|
+
// New method: Fast checks only (no caching of results)
|
|
1062
|
+
isAssetReferencedFastCheck(bundle, asset) {
|
|
1063
|
+
// Fast Check #1: If asset is in multiple bundles in same target, it's referenced
|
|
1064
|
+
let bundlesWithAsset = this.getBundlesWithAsset(asset).filter((b) => b.target.name === bundle.target.name &&
|
|
1065
|
+
b.target.distDir === bundle.target.distDir);
|
|
1066
|
+
if (bundlesWithAsset.length > 1) {
|
|
1067
|
+
return true;
|
|
1068
|
+
}
|
|
1069
|
+
// Fast Check #2: If asset is referenced by any async/conditional dependency, it's referenced
|
|
1070
|
+
let assetNodeId = (0, nullthrows_1.default)(this._graph.getNodeIdByContentKey(asset.id));
|
|
1071
|
+
if (this._graph
|
|
1072
|
+
.getNodeIdsConnectedTo(assetNodeId, exports.bundleGraphEdgeTypes.references)
|
|
1073
|
+
.map((id) => this._graph.getNode(id))
|
|
1074
|
+
.some((node) => node?.type === 'dependency' &&
|
|
1075
|
+
(node.value.priority === types_1.Priority.lazy ||
|
|
1076
|
+
node.value.priority === types_1.Priority.conditional) &&
|
|
1077
|
+
node.value.specifierType !== types_1.SpecifierType.url)) {
|
|
1078
|
+
return true;
|
|
1079
|
+
}
|
|
1080
|
+
// Fast checks failed - return null to indicate expensive computation needed
|
|
1081
|
+
return null;
|
|
1082
|
+
}
|
|
1083
|
+
getReferencedAssets(bundle) {
|
|
1084
|
+
let referencedAssets = new Set();
|
|
1085
|
+
// Build a map of all assets in this bundle with their dependencies
|
|
1086
|
+
// This allows us to check all assets in a single traversal
|
|
1087
|
+
let assetDependenciesMap = new Map();
|
|
1088
|
+
this.traverseAssets(bundle, (asset) => {
|
|
1089
|
+
// Always do fast checks (no caching)
|
|
1090
|
+
let fastCheckResult = this.isAssetReferencedFastCheck(bundle, asset);
|
|
1091
|
+
if (fastCheckResult === true) {
|
|
1092
|
+
referencedAssets.add(asset);
|
|
1093
|
+
return;
|
|
1094
|
+
}
|
|
1095
|
+
// Fast checks failed (fastCheckResult === null), need expensive computation
|
|
1096
|
+
// Check if it's actually referenced via traversal
|
|
1097
|
+
// Store dependencies for later batch checking
|
|
1098
|
+
let dependencies = this._graph
|
|
1099
|
+
.getNodeIdsConnectedTo((0, nullthrows_1.default)(this._graph.getNodeIdByContentKey(asset.id)))
|
|
1100
|
+
.map((id) => (0, nullthrows_1.default)(this._graph.getNode(id)))
|
|
1101
|
+
.filter((node) => node.type === 'dependency')
|
|
1102
|
+
.map((node) => {
|
|
1103
|
+
(0, assert_2.default)(node.type === 'dependency');
|
|
1104
|
+
return node.value;
|
|
1105
|
+
});
|
|
1106
|
+
if (dependencies.length > 0) {
|
|
1107
|
+
assetDependenciesMap.set(asset, dependencies);
|
|
1108
|
+
}
|
|
1109
|
+
});
|
|
1110
|
+
// If no assets need the expensive check, return early
|
|
1111
|
+
if (assetDependenciesMap.size === 0) {
|
|
1112
|
+
return referencedAssets;
|
|
1113
|
+
}
|
|
1114
|
+
// Get the assets we need to check once
|
|
1115
|
+
let assetsToCheck = Array.from(assetDependenciesMap.keys());
|
|
1116
|
+
// Helper function to check if all assets from assetDependenciesMap are in referencedAssets
|
|
1117
|
+
const allAssetsReferenced = () => assetsToCheck.length <= referencedAssets.size &&
|
|
1118
|
+
assetsToCheck.every((asset) => referencedAssets.has(asset));
|
|
1119
|
+
// Do ONE traversal to check all remaining assets
|
|
1120
|
+
// We can share visitedBundles across all assets because we check every asset
|
|
1121
|
+
// against every visited bundle, which matches the original per-asset behavior
|
|
1122
|
+
let siblingBundles = new Set(this.getBundleGroupsContainingBundle(bundle).flatMap((bundleGroup) => this.getBundlesInBundleGroup(bundleGroup, { includeInline: true })));
|
|
1123
|
+
let visitedBundles = new Set();
|
|
1124
|
+
// Single traversal from all referencers
|
|
1125
|
+
for (let referencer of siblingBundles) {
|
|
1126
|
+
this.traverseBundles((descendant, _, actions) => {
|
|
1127
|
+
if (descendant.id === bundle.id) {
|
|
1128
|
+
return;
|
|
1129
|
+
}
|
|
1130
|
+
if (visitedBundles.has(descendant)) {
|
|
1131
|
+
actions.skipChildren();
|
|
1132
|
+
return;
|
|
1133
|
+
}
|
|
1134
|
+
visitedBundles.add(descendant);
|
|
1135
|
+
if (descendant.type !== bundle.type ||
|
|
1136
|
+
(0, EnvironmentManager_1.fromEnvironmentId)(descendant.env).context !==
|
|
1137
|
+
(0, EnvironmentManager_1.fromEnvironmentId)(bundle.env).context) {
|
|
1138
|
+
// Don't skip children - they might be the right type!
|
|
1139
|
+
return;
|
|
1140
|
+
}
|
|
1141
|
+
// Check ALL assets at once in this descendant bundle
|
|
1142
|
+
for (let [asset, dependencies] of assetDependenciesMap) {
|
|
1143
|
+
// Skip if already marked as referenced
|
|
1144
|
+
if (referencedAssets.has(asset)) {
|
|
1145
|
+
continue;
|
|
1146
|
+
}
|
|
1147
|
+
// Check if this descendant bundle references the asset
|
|
1148
|
+
if (!this.bundleHasAsset(descendant, asset) &&
|
|
1149
|
+
dependencies.some((dependency) => this.bundleHasDependency(descendant, dependency))) {
|
|
1150
|
+
referencedAssets.add(asset);
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
// If all assets from assetDependenciesMap are now marked as referenced, we can stop early
|
|
1154
|
+
if (allAssetsReferenced()) {
|
|
1155
|
+
actions.stop();
|
|
1156
|
+
return;
|
|
1157
|
+
}
|
|
1158
|
+
}, referencer);
|
|
1159
|
+
// If all assets from assetDependenciesMap are referenced, no need to check more sibling bundles
|
|
1160
|
+
if (allAssetsReferenced()) {
|
|
1161
|
+
break;
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
return referencedAssets;
|
|
1165
|
+
}
|
|
1166
|
+
hasParentBundleOfType(bundle, type) {
|
|
1167
|
+
let parents = this.getParentBundles(bundle);
|
|
1168
|
+
return (parents.length > 0 && parents.every((parent) => parent.type === type));
|
|
1169
|
+
}
|
|
1170
|
+
getParentBundles(bundle) {
|
|
1171
|
+
let parentBundles = new Set();
|
|
1172
|
+
for (let bundleGroup of this.getBundleGroupsContainingBundle(bundle)) {
|
|
1173
|
+
for (let parentBundle of this.getParentBundlesOfBundleGroup(bundleGroup)) {
|
|
1174
|
+
parentBundles.add(parentBundle);
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
return [...parentBundles];
|
|
1178
|
+
}
|
|
1179
|
+
isAssetReachableFromBundle(asset, bundle) {
|
|
1180
|
+
// If a bundle's environment is isolated, it can't access assets present
|
|
1181
|
+
// in any ancestor bundles. Don't consider any assets reachable.
|
|
1182
|
+
if (Environment_1.ISOLATED_ENVS.has((0, EnvironmentManager_1.fromEnvironmentId)(bundle.env).context) ||
|
|
1183
|
+
!bundle.isSplittable ||
|
|
1184
|
+
bundle.bundleBehavior === types_1.BundleBehavior.isolated ||
|
|
1185
|
+
bundle.bundleBehavior === types_1.BundleBehavior.inline ||
|
|
1186
|
+
bundle.bundleBehavior === types_1.BundleBehavior.inlineIsolated) {
|
|
1187
|
+
return false;
|
|
1188
|
+
}
|
|
1189
|
+
// For an asset to be reachable from a bundle, it must either exist in a sibling bundle,
|
|
1190
|
+
// or in an ancestor bundle group reachable from all parent bundles.
|
|
1191
|
+
let bundleGroups = this.getBundleGroupsContainingBundle(bundle);
|
|
1192
|
+
return bundleGroups.every((bundleGroup) => {
|
|
1193
|
+
// If the asset is in any sibling bundles of the original bundle, it is reachable.
|
|
1194
|
+
let bundles = this.getBundlesInBundleGroup(bundleGroup);
|
|
1195
|
+
if (bundles.some((b) => b.id !== bundle.id &&
|
|
1196
|
+
b.bundleBehavior !== types_1.BundleBehavior.isolated &&
|
|
1197
|
+
b.bundleBehavior !== types_1.BundleBehavior.inline &&
|
|
1198
|
+
b.bundleBehavior !== types_1.BundleBehavior.inlineIsolated &&
|
|
1199
|
+
this.bundleHasAsset(b, asset))) {
|
|
1200
|
+
return true;
|
|
1201
|
+
}
|
|
1202
|
+
// Get a list of parent bundle nodes pointing to the bundle group
|
|
1203
|
+
let parentBundleNodes = this._graph.getNodeIdsConnectedTo(this._graph.getNodeIdByContentKey((0, utils_2.getBundleGroupId)(bundleGroup)), exports.bundleGraphEdgeTypes.bundle);
|
|
1204
|
+
// Check that every parent bundle has a bundle group in its ancestry that contains the asset.
|
|
1205
|
+
return parentBundleNodes.every((bundleNodeId) => {
|
|
1206
|
+
let bundleNode = (0, nullthrows_1.default)(this._graph.getNode(bundleNodeId));
|
|
1207
|
+
if (bundleNode.type !== 'bundle' ||
|
|
1208
|
+
bundleNode.value.bundleBehavior === types_1.BundleBehavior.isolated ||
|
|
1209
|
+
bundleNode.value.bundleBehavior === types_1.BundleBehavior.inline ||
|
|
1210
|
+
bundleNode.value.bundleBehavior === types_1.BundleBehavior.inlineIsolated) {
|
|
1211
|
+
return false;
|
|
1212
|
+
}
|
|
1213
|
+
let isReachable = true;
|
|
1214
|
+
this._graph.traverseAncestors(bundleNodeId, (nodeId, ctx, actions) => {
|
|
1215
|
+
let node = (0, nullthrows_1.default)(this._graph.getNode(nodeId));
|
|
1216
|
+
// If we've reached the root or a context change without
|
|
1217
|
+
// finding this asset in the ancestry, it is not reachable.
|
|
1218
|
+
if (node.type === 'root' ||
|
|
1219
|
+
(node.type === 'bundle' &&
|
|
1220
|
+
(node.value.id === bundle.id ||
|
|
1221
|
+
(0, EnvironmentManager_1.fromEnvironmentId)(node.value.env).context !==
|
|
1222
|
+
(0, EnvironmentManager_1.fromEnvironmentId)(bundle.env).context))) {
|
|
1223
|
+
isReachable = false;
|
|
1224
|
+
actions.stop();
|
|
1225
|
+
return;
|
|
1226
|
+
}
|
|
1227
|
+
if (node.type === 'bundle_group') {
|
|
1228
|
+
let childBundles = this.getBundlesInBundleGroup(node.value);
|
|
1229
|
+
if (childBundles.some((b) => b.id !== bundle.id &&
|
|
1230
|
+
b.bundleBehavior !== types_1.BundleBehavior.isolated &&
|
|
1231
|
+
b.bundleBehavior !== types_1.BundleBehavior.inline &&
|
|
1232
|
+
b.bundleBehavior !== types_1.BundleBehavior.inlineIsolated &&
|
|
1233
|
+
this.bundleHasAsset(b, asset))) {
|
|
1234
|
+
actions.skipChildren();
|
|
1235
|
+
return;
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
}, [exports.bundleGraphEdgeTypes.references, exports.bundleGraphEdgeTypes.bundle]);
|
|
1239
|
+
return isReachable;
|
|
1240
|
+
});
|
|
1241
|
+
});
|
|
1242
|
+
}
|
|
1243
|
+
/**
|
|
1244
|
+
* Performs a depth-first traversal of all assets and dependencies contained
|
|
1245
|
+
* within a bundle. Only visits nodes that are directly contained in the bundle
|
|
1246
|
+
* (connected via a `contains` edge).
|
|
1247
|
+
*
|
|
1248
|
+
* Entry Asset Ordering:
|
|
1249
|
+
* The traversal guarantees that entry assets are visited in the exact order they
|
|
1250
|
+
* appear in `bundle.entryAssetIds`. This ordering is critical for several reasons:
|
|
1251
|
+
*
|
|
1252
|
+
* 1. **Code Execution Order in Packagers**: Packagers (ScopeHoistingPackager,
|
|
1253
|
+
* DevPackager) use this traversal to concatenate assets into the final bundle.
|
|
1254
|
+
* The traversal order determines the execution order of code in the output.
|
|
1255
|
+
* Entry assets must be processed in their defined order to ensure correct
|
|
1256
|
+
* initialization sequences.
|
|
1257
|
+
*
|
|
1258
|
+
* 2. **Runtime Injection**: Runtime assets (HMR, bundle manifests) are prepended
|
|
1259
|
+
* to `entryAssetIds` via `unshift()` in `applyRuntimes.ts`. By honoring the
|
|
1260
|
+
* array order, runtimes are guaranteed to be visited (and thus output) before
|
|
1261
|
+
* application entry points, ensuring the runtime infrastructure is available
|
|
1262
|
+
* when application code executes.
|
|
1263
|
+
*
|
|
1264
|
+
* 3. **Deterministic Builds**: Consistent traversal order ensures reproducible
|
|
1265
|
+
* bundle output, which is essential for caching and build verification.
|
|
1266
|
+
*
|
|
1267
|
+
* The sorting only applies at the first traversal level (direct children of the
|
|
1268
|
+
* start node). Subsequent levels follow standard DFS order based on the graph's
|
|
1269
|
+
* edge structure.
|
|
1270
|
+
*
|
|
1271
|
+
* @param bundle - The bundle to traverse
|
|
1272
|
+
* @param visit - Visitor callback receiving asset or dependency nodes
|
|
1273
|
+
* @param startAsset - Optional asset to start traversal from (defaults to bundle root)
|
|
1274
|
+
*/
|
|
1275
|
+
traverseBundle(bundle, visit, startAsset) {
|
|
1276
|
+
let entries = !startAsset;
|
|
1277
|
+
let bundleNodeId = this._graph.getNodeIdByContentKey(bundle.id);
|
|
1278
|
+
// A modified DFS traversal which traverses entry assets in the same order
|
|
1279
|
+
// as their ids appear in `bundle.entryAssetIds`.
|
|
1280
|
+
return this._graph.dfs({
|
|
1281
|
+
visit: (0, graph_1.mapVisitor)((nodeId, actions) => {
|
|
1282
|
+
let node = (0, nullthrows_1.default)(this._graph.getNode(nodeId));
|
|
1283
|
+
if (nodeId === bundleNodeId) {
|
|
1284
|
+
return;
|
|
1285
|
+
}
|
|
1286
|
+
if (node.type === 'dependency' || node.type === 'asset') {
|
|
1287
|
+
if (this._graph.hasEdge(bundleNodeId, nodeId, exports.bundleGraphEdgeTypes.contains)) {
|
|
1288
|
+
return node;
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
actions.skipChildren();
|
|
1292
|
+
}, visit),
|
|
1293
|
+
startNodeId: startAsset
|
|
1294
|
+
? this._graph.getNodeIdByContentKey(startAsset.id)
|
|
1295
|
+
: bundleNodeId,
|
|
1296
|
+
getChildren: (nodeId) => {
|
|
1297
|
+
let children = this._graph
|
|
1298
|
+
.getNodeIdsConnectedFrom(nodeId)
|
|
1299
|
+
.map((id) => [id, (0, nullthrows_1.default)(this._graph.getNode(id))]);
|
|
1300
|
+
let sorted = entries && bundle.entryAssetIds.length > 0
|
|
1301
|
+
? // @ts-expect-error TS2345
|
|
1302
|
+
children.sort(([, a], [, b]) => {
|
|
1303
|
+
let aIndex = bundle.entryAssetIds.indexOf(a.id);
|
|
1304
|
+
let bIndex = bundle.entryAssetIds.indexOf(b.id);
|
|
1305
|
+
if (aIndex === bIndex) {
|
|
1306
|
+
// If both don't exist in the entry asset list, or
|
|
1307
|
+
// otherwise have the same index.
|
|
1308
|
+
return 0;
|
|
1309
|
+
}
|
|
1310
|
+
else if (aIndex === -1) {
|
|
1311
|
+
return 1;
|
|
1312
|
+
}
|
|
1313
|
+
else if (bIndex === -1) {
|
|
1314
|
+
return -1;
|
|
1315
|
+
}
|
|
1316
|
+
return aIndex - bIndex;
|
|
1317
|
+
})
|
|
1318
|
+
: children;
|
|
1319
|
+
entries = false;
|
|
1320
|
+
// @ts-expect-error TS2345
|
|
1321
|
+
return sorted.map(([id]) => id);
|
|
1322
|
+
},
|
|
1323
|
+
});
|
|
1324
|
+
}
|
|
1325
|
+
traverse(visit, start) {
|
|
1326
|
+
return this._graph.filteredTraverse((nodeId) => {
|
|
1327
|
+
let node = (0, nullthrows_1.default)(this._graph.getNode(nodeId));
|
|
1328
|
+
if (node.type === 'asset' || node.type === 'dependency') {
|
|
1329
|
+
return node;
|
|
1330
|
+
}
|
|
1331
|
+
}, visit, start ? this._graph.getNodeIdByContentKey(start.id) : undefined, // start with root
|
|
1332
|
+
graph_1.ALL_EDGE_TYPES);
|
|
1333
|
+
}
|
|
1334
|
+
getChildBundles(bundle) {
|
|
1335
|
+
let siblings = new Set(this.getReferencedBundles(bundle));
|
|
1336
|
+
let bundles = [];
|
|
1337
|
+
this.traverseBundles((b, _, actions) => {
|
|
1338
|
+
if (bundle.id === b.id) {
|
|
1339
|
+
return;
|
|
1340
|
+
}
|
|
1341
|
+
if (!siblings.has(b)) {
|
|
1342
|
+
bundles.push(b);
|
|
1343
|
+
}
|
|
1344
|
+
actions.skipChildren();
|
|
1345
|
+
}, bundle);
|
|
1346
|
+
return bundles;
|
|
1347
|
+
}
|
|
1348
|
+
traverseBundles(visit, startBundle) {
|
|
1349
|
+
return this._graph.filteredTraverse((nodeId) => {
|
|
1350
|
+
let node = (0, nullthrows_1.default)(this._graph.getNode(nodeId));
|
|
1351
|
+
return node.type === 'bundle' ? node.value : null;
|
|
1352
|
+
}, visit, startBundle ? this._graph.getNodeIdByContentKey(startBundle.id) : null, [exports.bundleGraphEdgeTypes.bundle, exports.bundleGraphEdgeTypes.references]);
|
|
1353
|
+
}
|
|
1354
|
+
getBundles(opts) {
|
|
1355
|
+
let bundles = [];
|
|
1356
|
+
this.traverseBundles((bundle) => {
|
|
1357
|
+
if (opts?.includeInline ||
|
|
1358
|
+
(bundle.bundleBehavior !== types_1.BundleBehavior.inline &&
|
|
1359
|
+
bundle.bundleBehavior !== types_1.BundleBehavior.inlineIsolated)) {
|
|
1360
|
+
bundles.push(bundle);
|
|
1361
|
+
}
|
|
1362
|
+
});
|
|
1363
|
+
return bundles;
|
|
1364
|
+
}
|
|
1365
|
+
getTotalSize(asset) {
|
|
1366
|
+
let size = 0;
|
|
1367
|
+
this._graph.traverse((nodeId, _, actions) => {
|
|
1368
|
+
let node = (0, nullthrows_1.default)(this._graph.getNode(nodeId));
|
|
1369
|
+
if (node.type === 'bundle_group') {
|
|
1370
|
+
actions.skipChildren();
|
|
1371
|
+
return;
|
|
1372
|
+
}
|
|
1373
|
+
if (node.type === 'asset') {
|
|
1374
|
+
size += node.value.stats.size;
|
|
1375
|
+
}
|
|
1376
|
+
}, this._graph.getNodeIdByContentKey(asset.id));
|
|
1377
|
+
return size;
|
|
1378
|
+
}
|
|
1379
|
+
getReferencingBundles(bundle) {
|
|
1380
|
+
let referencingBundles = new Set();
|
|
1381
|
+
this._graph.traverseAncestors(this._graph.getNodeIdByContentKey(bundle.id), (nodeId) => {
|
|
1382
|
+
let node = (0, nullthrows_1.default)(this._graph.getNode(nodeId));
|
|
1383
|
+
if (node.type === 'bundle' && node.value.id !== bundle.id) {
|
|
1384
|
+
referencingBundles.add(node.value);
|
|
1385
|
+
}
|
|
1386
|
+
}, exports.bundleGraphEdgeTypes.references);
|
|
1387
|
+
return [...referencingBundles];
|
|
1388
|
+
}
|
|
1389
|
+
getBundleGroupsContainingBundle(bundle) {
|
|
1390
|
+
let bundleGroups = new Set();
|
|
1391
|
+
for (let currentBundle of [bundle, ...this.getReferencingBundles(bundle)]) {
|
|
1392
|
+
for (let bundleGroup of this.getDirectParentBundleGroups(currentBundle)) {
|
|
1393
|
+
bundleGroups.add(bundleGroup);
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
return [...bundleGroups];
|
|
1397
|
+
}
|
|
1398
|
+
getDirectParentBundleGroups(bundle) {
|
|
1399
|
+
return this._graph
|
|
1400
|
+
.getNodeIdsConnectedTo((0, nullthrows_1.default)(this._graph.getNodeIdByContentKey(bundle.id)), exports.bundleGraphEdgeTypes.bundle)
|
|
1401
|
+
.map((id) => (0, nullthrows_1.default)(this._graph.getNode(id)))
|
|
1402
|
+
.filter((node) => node.type === 'bundle_group')
|
|
1403
|
+
.map((node) => {
|
|
1404
|
+
(0, assert_2.default)(node.type === 'bundle_group');
|
|
1405
|
+
return node.value;
|
|
1406
|
+
});
|
|
1407
|
+
}
|
|
1408
|
+
getBundlesInBundleGroup(bundleGroup, opts) {
|
|
1409
|
+
let bundles = new Set();
|
|
1410
|
+
for (let bundleNodeId of this._graph.getNodeIdsConnectedFrom(this._graph.getNodeIdByContentKey((0, utils_2.getBundleGroupId)(bundleGroup)), exports.bundleGraphEdgeTypes.bundle)) {
|
|
1411
|
+
let bundleNode = (0, nullthrows_1.default)(this._graph.getNode(bundleNodeId));
|
|
1412
|
+
(0, assert_2.default)(bundleNode.type === 'bundle');
|
|
1413
|
+
let bundle = bundleNode.value;
|
|
1414
|
+
if (opts?.includeInline ||
|
|
1415
|
+
(bundle.bundleBehavior !== types_1.BundleBehavior.inline &&
|
|
1416
|
+
bundle.bundleBehavior !== types_1.BundleBehavior.inlineIsolated)) {
|
|
1417
|
+
bundles.add(bundle);
|
|
1418
|
+
}
|
|
1419
|
+
for (let referencedBundle of this.getReferencedBundles(bundle, {
|
|
1420
|
+
includeInline: opts?.includeInline,
|
|
1421
|
+
})) {
|
|
1422
|
+
bundles.add(referencedBundle);
|
|
1423
|
+
}
|
|
1424
|
+
}
|
|
1425
|
+
return [...bundles];
|
|
1426
|
+
}
|
|
1427
|
+
getReferencedBundles(bundle, opts) {
|
|
1428
|
+
let recursive = opts?.recursive ?? true;
|
|
1429
|
+
let includeInline = opts?.includeInline ?? false;
|
|
1430
|
+
let referencedBundles = new Set();
|
|
1431
|
+
this._graph.dfs({
|
|
1432
|
+
visit: (nodeId, _, actions) => {
|
|
1433
|
+
let node = (0, nullthrows_1.default)(this._graph.getNode(nodeId));
|
|
1434
|
+
if (node.type !== 'bundle') {
|
|
1435
|
+
return;
|
|
1436
|
+
}
|
|
1437
|
+
if (node.value.id === bundle.id) {
|
|
1438
|
+
return;
|
|
1439
|
+
}
|
|
1440
|
+
if (includeInline ||
|
|
1441
|
+
(node.value.bundleBehavior !== types_1.BundleBehavior.inline &&
|
|
1442
|
+
node.value.bundleBehavior !== types_1.BundleBehavior.inlineIsolated)) {
|
|
1443
|
+
referencedBundles.add(node.value);
|
|
1444
|
+
}
|
|
1445
|
+
if (!recursive) {
|
|
1446
|
+
actions.skipChildren();
|
|
1447
|
+
}
|
|
1448
|
+
},
|
|
1449
|
+
startNodeId: this._graph.getNodeIdByContentKey(bundle.id),
|
|
1450
|
+
getChildren: (nodeId) =>
|
|
1451
|
+
// Shared bundles seem to depend on being used in the opposite order
|
|
1452
|
+
// they were added.
|
|
1453
|
+
// TODO: Should this be the case?
|
|
1454
|
+
this._graph.getNodeIdsConnectedFrom(nodeId, exports.bundleGraphEdgeTypes.references),
|
|
1455
|
+
});
|
|
1456
|
+
// @ts-expect-error TS2322
|
|
1457
|
+
return [...referencedBundles];
|
|
1458
|
+
}
|
|
1459
|
+
getIncomingDependencies(asset) {
|
|
1460
|
+
if (!this._graph.hasContentKey(asset.id)) {
|
|
1461
|
+
return [];
|
|
1462
|
+
}
|
|
1463
|
+
// Dependencies can be a a parent node via an untyped edge (like in the AssetGraph but without AssetGroups)
|
|
1464
|
+
// or they can be parent nodes via a 'references' edge
|
|
1465
|
+
return this._graph
|
|
1466
|
+
.getNodeIdsConnectedTo(this._graph.getNodeIdByContentKey(asset.id), graph_1.ALL_EDGE_TYPES)
|
|
1467
|
+
.map((id) => (0, nullthrows_1.default)(this._graph.getNode(id)))
|
|
1468
|
+
.filter((n) => n.type === 'dependency')
|
|
1469
|
+
.map((n) => {
|
|
1470
|
+
(0, assert_2.default)(n.type === 'dependency');
|
|
1471
|
+
return n.value;
|
|
1472
|
+
});
|
|
1473
|
+
}
|
|
1474
|
+
getAssetWithDependency(dep) {
|
|
1475
|
+
if (!this._graph.hasContentKey(dep.id)) {
|
|
1476
|
+
return null;
|
|
1477
|
+
}
|
|
1478
|
+
let res = null;
|
|
1479
|
+
let count = 0;
|
|
1480
|
+
this._graph.forEachNodeIdConnectedTo(this._graph.getNodeIdByContentKey(dep.id),
|
|
1481
|
+
// @ts-expect-error TS2345
|
|
1482
|
+
(node) => {
|
|
1483
|
+
res = node;
|
|
1484
|
+
count += 1;
|
|
1485
|
+
if (count > 1) {
|
|
1486
|
+
throw new Error('Expected a single asset to be connected to a dependency');
|
|
1487
|
+
}
|
|
1488
|
+
}, 1);
|
|
1489
|
+
let resNode = res != null ? this._graph.getNode(res) : null;
|
|
1490
|
+
if (resNode?.type === 'asset') {
|
|
1491
|
+
return resNode.value;
|
|
1492
|
+
}
|
|
1493
|
+
}
|
|
1494
|
+
bundleHasAsset(bundle, asset) {
|
|
1495
|
+
let bundleNodeId = this._graph.getNodeIdByContentKey(bundle.id);
|
|
1496
|
+
let assetNodeId = this._graph.getNodeIdByContentKey(asset.id);
|
|
1497
|
+
return this._graph.hasEdge(bundleNodeId, assetNodeId, exports.bundleGraphEdgeTypes.contains);
|
|
1498
|
+
}
|
|
1499
|
+
bundleHasDependency(bundle, dependency) {
|
|
1500
|
+
let bundleNodeId = this._graph.getNodeIdByContentKey(bundle.id);
|
|
1501
|
+
let dependencyNodeId = this._graph.getNodeIdByContentKey(dependency.id);
|
|
1502
|
+
return this._graph.hasEdge(bundleNodeId, dependencyNodeId, exports.bundleGraphEdgeTypes.contains);
|
|
1503
|
+
}
|
|
1504
|
+
filteredTraverse(bundleNodeId, filter, visit) {
|
|
1505
|
+
return this._graph.filteredTraverse(filter, visit, bundleNodeId);
|
|
1506
|
+
}
|
|
1507
|
+
getSymbolResolution(asset, symbol, boundary) {
|
|
1508
|
+
let assetOutside = boundary && !this.bundleHasAsset(boundary, asset);
|
|
1509
|
+
let identifier = asset.symbols?.get(symbol)?.local;
|
|
1510
|
+
if (symbol === '*') {
|
|
1511
|
+
return {
|
|
1512
|
+
asset,
|
|
1513
|
+
exportSymbol: '*',
|
|
1514
|
+
symbol: identifier ?? null,
|
|
1515
|
+
loc: asset.symbols?.get(symbol)?.loc,
|
|
1516
|
+
};
|
|
1517
|
+
}
|
|
1518
|
+
let found = false;
|
|
1519
|
+
let nonStaticDependency = false;
|
|
1520
|
+
let skipped = false;
|
|
1521
|
+
let deps = this.getDependencies(asset).reverse();
|
|
1522
|
+
let potentialResults = [];
|
|
1523
|
+
for (let dep of deps) {
|
|
1524
|
+
let depSymbols = dep.symbols;
|
|
1525
|
+
if (!depSymbols) {
|
|
1526
|
+
nonStaticDependency = true;
|
|
1527
|
+
continue;
|
|
1528
|
+
}
|
|
1529
|
+
// If this is a re-export, find the original module.
|
|
1530
|
+
let symbolLookup = new Map([...depSymbols].map(([key, val]) => [val.local, key]));
|
|
1531
|
+
let depSymbol = symbolLookup.get(identifier);
|
|
1532
|
+
if (depSymbol != null) {
|
|
1533
|
+
let resolved = this.getResolvedAsset(dep, boundary);
|
|
1534
|
+
if (!resolved || resolved.id === asset.id) {
|
|
1535
|
+
// External module or self-reference
|
|
1536
|
+
return {
|
|
1537
|
+
asset,
|
|
1538
|
+
exportSymbol: symbol,
|
|
1539
|
+
symbol: identifier,
|
|
1540
|
+
loc: asset.symbols?.get(symbol)?.loc,
|
|
1541
|
+
};
|
|
1542
|
+
}
|
|
1543
|
+
if (assetOutside) {
|
|
1544
|
+
// We found the symbol, but `asset` is outside, return `asset` and the original symbol
|
|
1545
|
+
found = true;
|
|
1546
|
+
break;
|
|
1547
|
+
}
|
|
1548
|
+
if (this.isDependencySkipped(dep)) {
|
|
1549
|
+
// We found the symbol and `dep` was skipped
|
|
1550
|
+
skipped = true;
|
|
1551
|
+
break;
|
|
1552
|
+
}
|
|
1553
|
+
let { asset: resolvedAsset, symbol: resolvedSymbol, exportSymbol, loc, } = this.getSymbolResolution(resolved, depSymbol, boundary);
|
|
1554
|
+
if (!loc) {
|
|
1555
|
+
// Remember how we got there
|
|
1556
|
+
loc = asset.symbols?.get(symbol)?.loc;
|
|
1557
|
+
}
|
|
1558
|
+
return {
|
|
1559
|
+
asset: resolvedAsset,
|
|
1560
|
+
symbol: resolvedSymbol,
|
|
1561
|
+
exportSymbol,
|
|
1562
|
+
loc,
|
|
1563
|
+
};
|
|
1564
|
+
}
|
|
1565
|
+
// If this module exports wildcards, resolve the original module.
|
|
1566
|
+
// Default exports are excluded from wildcard exports.
|
|
1567
|
+
// Wildcard reexports are never listed in the reexporting asset's symbols.
|
|
1568
|
+
if (identifier == null &&
|
|
1569
|
+
(depSymbols.get('*')?.local === '*' || dep.meta?.hasExportStar) &&
|
|
1570
|
+
symbol !== 'default') {
|
|
1571
|
+
let resolved = this.getResolvedAsset(dep, boundary);
|
|
1572
|
+
if (!resolved) {
|
|
1573
|
+
continue;
|
|
1574
|
+
}
|
|
1575
|
+
let result = this.getSymbolResolution(resolved, symbol, boundary);
|
|
1576
|
+
// We found the symbol
|
|
1577
|
+
if (result.symbol != undefined) {
|
|
1578
|
+
if (assetOutside) {
|
|
1579
|
+
// ..., but `asset` is outside, return `asset` and the original symbol
|
|
1580
|
+
found = true;
|
|
1581
|
+
break;
|
|
1582
|
+
}
|
|
1583
|
+
if (this.isDependencySkipped(dep)) {
|
|
1584
|
+
// We found the symbol and `dep` was skipped
|
|
1585
|
+
skipped = true;
|
|
1586
|
+
break;
|
|
1587
|
+
}
|
|
1588
|
+
return {
|
|
1589
|
+
asset: result.asset,
|
|
1590
|
+
symbol: result.symbol,
|
|
1591
|
+
exportSymbol: result.exportSymbol,
|
|
1592
|
+
loc: resolved.symbols?.get(symbol)?.loc,
|
|
1593
|
+
};
|
|
1594
|
+
}
|
|
1595
|
+
if (result.symbol === null) {
|
|
1596
|
+
found = true;
|
|
1597
|
+
if (boundary && !this.bundleHasAsset(boundary, result.asset)) {
|
|
1598
|
+
// If the returned asset is outside (and it's the first asset that is outside), return it.
|
|
1599
|
+
if (!assetOutside) {
|
|
1600
|
+
return {
|
|
1601
|
+
asset: result.asset,
|
|
1602
|
+
symbol: result.symbol,
|
|
1603
|
+
exportSymbol: result.exportSymbol,
|
|
1604
|
+
loc: resolved.symbols?.get(symbol)?.loc,
|
|
1605
|
+
};
|
|
1606
|
+
}
|
|
1607
|
+
else {
|
|
1608
|
+
// Otherwise the original asset will be returned at the end.
|
|
1609
|
+
break;
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
else {
|
|
1613
|
+
// We didn't find it in this dependency, but it might still be there: bailout.
|
|
1614
|
+
// Continue searching though, with the assumption that there are no conficting reexports
|
|
1615
|
+
// and there might be a another (re)export (where we might statically find the symbol).
|
|
1616
|
+
potentialResults.push({
|
|
1617
|
+
asset: result.asset,
|
|
1618
|
+
symbol: result.symbol,
|
|
1619
|
+
exportSymbol: result.exportSymbol,
|
|
1620
|
+
loc: resolved.symbols?.get(symbol)?.loc,
|
|
1621
|
+
});
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
// We didn't find the exact symbol...
|
|
1627
|
+
if (potentialResults.length == 1) {
|
|
1628
|
+
// ..., but if it does exist, it has to be behind this one reexport.
|
|
1629
|
+
return potentialResults[0];
|
|
1630
|
+
}
|
|
1631
|
+
else {
|
|
1632
|
+
let result = identifier;
|
|
1633
|
+
if (skipped) {
|
|
1634
|
+
// ... and it was excluded (by symbol propagation) or deferred.
|
|
1635
|
+
// @ts-expect-error TS2322
|
|
1636
|
+
result = false;
|
|
1637
|
+
}
|
|
1638
|
+
else {
|
|
1639
|
+
// ... and there is no single reexport, but it might still be exported:
|
|
1640
|
+
if (found) {
|
|
1641
|
+
// Fallback to namespace access, because of a bundle boundary.
|
|
1642
|
+
// @ts-expect-error TS2322
|
|
1643
|
+
result = null;
|
|
1644
|
+
}
|
|
1645
|
+
else if (result === undefined) {
|
|
1646
|
+
// If not exported explicitly by the asset (= would have to be in * or a reexport-all) ...
|
|
1647
|
+
if (nonStaticDependency || asset.symbols?.has('*')) {
|
|
1648
|
+
// ... and if there are non-statically analyzable dependencies or it's a CJS asset,
|
|
1649
|
+
// fallback to namespace access.
|
|
1650
|
+
// @ts-expect-error TS2322
|
|
1651
|
+
result = null;
|
|
1652
|
+
}
|
|
1653
|
+
// (It shouldn't be possible for the symbol to be in a reexport-all and to end up here).
|
|
1654
|
+
// Otherwise return undefined to report that the symbol wasn't found.
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
return {
|
|
1658
|
+
asset,
|
|
1659
|
+
exportSymbol: symbol,
|
|
1660
|
+
symbol: result,
|
|
1661
|
+
loc: asset.symbols?.get(symbol)?.loc,
|
|
1662
|
+
};
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
getAssetById(contentKey) {
|
|
1666
|
+
let node = this._graph.getNodeByContentKey(contentKey);
|
|
1667
|
+
if (node == null) {
|
|
1668
|
+
throw new Error('Node not found');
|
|
1669
|
+
}
|
|
1670
|
+
else if (node.type !== 'asset') {
|
|
1671
|
+
throw new Error('Node was not an asset');
|
|
1672
|
+
}
|
|
1673
|
+
return node.value;
|
|
1674
|
+
}
|
|
1675
|
+
getAssetPublicId(asset) {
|
|
1676
|
+
let publicId = this._publicIdByAssetId.get(asset.id);
|
|
1677
|
+
if (publicId == null) {
|
|
1678
|
+
throw new Error("Asset or it's public id not found");
|
|
1679
|
+
}
|
|
1680
|
+
return publicId;
|
|
1681
|
+
}
|
|
1682
|
+
getExportedSymbols(asset, boundary) {
|
|
1683
|
+
if (!asset.symbols) {
|
|
1684
|
+
return [];
|
|
1685
|
+
}
|
|
1686
|
+
let symbols = [];
|
|
1687
|
+
for (let symbol of asset.symbols.keys()) {
|
|
1688
|
+
symbols.push({
|
|
1689
|
+
...this.getSymbolResolution(asset, symbol, boundary),
|
|
1690
|
+
exportAs: symbol,
|
|
1691
|
+
});
|
|
1692
|
+
}
|
|
1693
|
+
let deps = this.getDependencies(asset);
|
|
1694
|
+
for (let dep of deps) {
|
|
1695
|
+
let depSymbols = dep.symbols;
|
|
1696
|
+
if (!depSymbols)
|
|
1697
|
+
continue;
|
|
1698
|
+
if (depSymbols.get('*')?.local === '*' || dep.meta?.hasExportStar) {
|
|
1699
|
+
let resolved = this.getResolvedAsset(dep, boundary);
|
|
1700
|
+
if (!resolved)
|
|
1701
|
+
continue;
|
|
1702
|
+
let exported = this.getExportedSymbols(resolved, boundary)
|
|
1703
|
+
.filter((s) => s.exportSymbol !== 'default')
|
|
1704
|
+
.map((s) => s.exportSymbol !== '*' ? { ...s, exportAs: s.exportSymbol } : s);
|
|
1705
|
+
symbols.push(...exported);
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
return symbols;
|
|
1709
|
+
}
|
|
1710
|
+
getContentHash(bundle) {
|
|
1711
|
+
let existingHash = this._bundleContentHashes.get(bundle.id);
|
|
1712
|
+
if (existingHash != null) {
|
|
1713
|
+
return existingHash;
|
|
1714
|
+
}
|
|
1715
|
+
let hash = new rust_1.Hash();
|
|
1716
|
+
// TODO: sort??
|
|
1717
|
+
this.traverseAssets(bundle, (asset) => {
|
|
1718
|
+
{
|
|
1719
|
+
hash.writeString([this.getAssetPublicId(asset), asset.id, asset.outputHash].join(':'));
|
|
1720
|
+
}
|
|
1721
|
+
});
|
|
1722
|
+
let hashHex = hash.finish();
|
|
1723
|
+
this._bundleContentHashes.set(bundle.id, hashHex);
|
|
1724
|
+
return hashHex;
|
|
1725
|
+
}
|
|
1726
|
+
getInlineBundles(bundle) {
|
|
1727
|
+
let bundles = [];
|
|
1728
|
+
let seen = new Set();
|
|
1729
|
+
let addReferencedBundles = (bundle) => {
|
|
1730
|
+
if (seen.has(bundle.id)) {
|
|
1731
|
+
return;
|
|
1732
|
+
}
|
|
1733
|
+
seen.add(bundle.id);
|
|
1734
|
+
let referencedBundles = this.getReferencedBundles(bundle, {
|
|
1735
|
+
includeInline: true,
|
|
1736
|
+
});
|
|
1737
|
+
for (let referenced of referencedBundles) {
|
|
1738
|
+
if (referenced.bundleBehavior === types_1.BundleBehavior.inline ||
|
|
1739
|
+
referenced.bundleBehavior === types_1.BundleBehavior.inlineIsolated) {
|
|
1740
|
+
bundles.push(referenced);
|
|
1741
|
+
addReferencedBundles(referenced);
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
};
|
|
1745
|
+
addReferencedBundles(bundle);
|
|
1746
|
+
this.traverseBundles((childBundle, _, traversal) => {
|
|
1747
|
+
if (childBundle.bundleBehavior === types_1.BundleBehavior.inline ||
|
|
1748
|
+
childBundle.bundleBehavior === types_1.BundleBehavior.inlineIsolated) {
|
|
1749
|
+
bundles.push(childBundle);
|
|
1750
|
+
}
|
|
1751
|
+
else if (childBundle.id !== bundle.id) {
|
|
1752
|
+
traversal.skipChildren();
|
|
1753
|
+
}
|
|
1754
|
+
}, bundle);
|
|
1755
|
+
return bundles;
|
|
1756
|
+
}
|
|
1757
|
+
getHash(bundle) {
|
|
1758
|
+
let hash = new rust_1.Hash();
|
|
1759
|
+
hash.writeString(bundle.id + JSON.stringify(bundle.target) + this.getContentHash(bundle));
|
|
1760
|
+
if (bundle.isPlaceholder) {
|
|
1761
|
+
hash.writeString('placeholder');
|
|
1762
|
+
}
|
|
1763
|
+
let inlineBundles = this.getInlineBundles(bundle);
|
|
1764
|
+
for (let inlineBundle of inlineBundles) {
|
|
1765
|
+
hash.writeString(this.getContentHash(inlineBundle));
|
|
1766
|
+
}
|
|
1767
|
+
for (let referencedBundle of this.getReferencedBundles(bundle)) {
|
|
1768
|
+
hash.writeString(referencedBundle.id);
|
|
1769
|
+
}
|
|
1770
|
+
hash.writeString(JSON.stringify((0, utils_1.objectSortedEntriesDeep)((0, EnvironmentManager_1.fromEnvironmentId)(bundle.env))));
|
|
1771
|
+
return hash.finish();
|
|
1772
|
+
}
|
|
1773
|
+
getBundleGraphHash() {
|
|
1774
|
+
let hashes = '';
|
|
1775
|
+
for (let bundle of this.getBundles()) {
|
|
1776
|
+
hashes += this.getHash(bundle);
|
|
1777
|
+
}
|
|
1778
|
+
return (0, rust_1.hashString)(hashes);
|
|
1779
|
+
}
|
|
1780
|
+
addBundleToBundleGroup(bundle, bundleGroup) {
|
|
1781
|
+
let bundleGroupNodeId = this._graph.getNodeIdByContentKey((0, utils_2.getBundleGroupId)(bundleGroup));
|
|
1782
|
+
let bundleNodeId = this._graph.getNodeIdByContentKey(bundle.id);
|
|
1783
|
+
if (this._graph.hasEdge(bundleGroupNodeId, bundleNodeId, exports.bundleGraphEdgeTypes.bundle)) {
|
|
1784
|
+
// Bundle group already has bundle
|
|
1785
|
+
return;
|
|
1786
|
+
}
|
|
1787
|
+
this._graph.addEdge(bundleGroupNodeId, bundleNodeId);
|
|
1788
|
+
this._graph.addEdge(bundleGroupNodeId, bundleNodeId, exports.bundleGraphEdgeTypes.bundle);
|
|
1789
|
+
for (let entryAssetId of bundle.entryAssetIds) {
|
|
1790
|
+
let entryAssetNodeId = this._graph.getNodeIdByContentKey(entryAssetId);
|
|
1791
|
+
if (this._graph.hasEdge(bundleGroupNodeId, entryAssetNodeId)) {
|
|
1792
|
+
this._graph.removeEdge(bundleGroupNodeId, entryAssetNodeId);
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
getUsedSymbolsAsset(asset) {
|
|
1797
|
+
let node = this._graph.getNodeByContentKey(asset.id);
|
|
1798
|
+
(0, assert_2.default)(node && node.type === 'asset');
|
|
1799
|
+
return node.value.symbols
|
|
1800
|
+
? makeReadOnlySet(new Set(node.usedSymbols.keys()))
|
|
1801
|
+
: null;
|
|
1802
|
+
}
|
|
1803
|
+
getUsedSymbolsDependency(dep) {
|
|
1804
|
+
let node = this._graph.getNodeByContentKey(dep.id);
|
|
1805
|
+
(0, assert_2.default)(node && node.type === 'dependency');
|
|
1806
|
+
return node.value.symbols
|
|
1807
|
+
? makeReadOnlySet(new Set(node.usedSymbolsUp.keys()))
|
|
1808
|
+
: null;
|
|
1809
|
+
}
|
|
1810
|
+
merge(other) {
|
|
1811
|
+
let otherGraphIdToThisNodeId = new Map();
|
|
1812
|
+
for (let [otherNodeId, otherNode] of other._graph.nodes.entries()) {
|
|
1813
|
+
if (!otherNode)
|
|
1814
|
+
continue;
|
|
1815
|
+
if (this._graph.hasContentKey(otherNode.id)) {
|
|
1816
|
+
let existingNodeId = this._graph.getNodeIdByContentKey(otherNode.id);
|
|
1817
|
+
otherGraphIdToThisNodeId.set(otherNodeId, existingNodeId);
|
|
1818
|
+
let existingNode = (0, nullthrows_1.default)(this._graph.getNode(existingNodeId));
|
|
1819
|
+
// Merge symbols, recompute dep.excluded based on that
|
|
1820
|
+
if (existingNode.type === 'asset') {
|
|
1821
|
+
(0, assert_2.default)(otherNode.type === 'asset');
|
|
1822
|
+
existingNode.usedSymbols = new Set([
|
|
1823
|
+
...existingNode.usedSymbols,
|
|
1824
|
+
...otherNode.usedSymbols,
|
|
1825
|
+
]);
|
|
1826
|
+
}
|
|
1827
|
+
else if (existingNode.type === 'dependency') {
|
|
1828
|
+
(0, assert_2.default)(otherNode.type === 'dependency');
|
|
1829
|
+
existingNode.usedSymbolsDown = new Set([
|
|
1830
|
+
...existingNode.usedSymbolsDown,
|
|
1831
|
+
...otherNode.usedSymbolsDown,
|
|
1832
|
+
]);
|
|
1833
|
+
existingNode.usedSymbolsUp = new Map([
|
|
1834
|
+
...existingNode.usedSymbolsUp,
|
|
1835
|
+
...otherNode.usedSymbolsUp,
|
|
1836
|
+
]);
|
|
1837
|
+
existingNode.excluded =
|
|
1838
|
+
(existingNode.excluded || Boolean(existingNode.hasDeferred)) &&
|
|
1839
|
+
(otherNode.excluded || Boolean(otherNode.hasDeferred));
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
else {
|
|
1843
|
+
let updateNodeId = this._graph.addNodeByContentKey(otherNode.id, otherNode);
|
|
1844
|
+
otherGraphIdToThisNodeId.set(otherNodeId, updateNodeId);
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
// @ts-expect-error TS2488
|
|
1848
|
+
for (let edge of other._graph.getAllEdges()) {
|
|
1849
|
+
this._graph.addEdge((0, nullthrows_1.default)(otherGraphIdToThisNodeId.get(edge.from)), (0, nullthrows_1.default)(otherGraphIdToThisNodeId.get(edge.to)), edge.type);
|
|
1850
|
+
}
|
|
1851
|
+
}
|
|
1852
|
+
isEntryBundleGroup(bundleGroup) {
|
|
1853
|
+
return this._graph
|
|
1854
|
+
.getNodeIdsConnectedTo((0, nullthrows_1.default)(this._graph.getNodeIdByContentKey((0, utils_2.getBundleGroupId)(bundleGroup))), exports.bundleGraphEdgeTypes.bundle)
|
|
1855
|
+
.map((id) => (0, nullthrows_1.default)(this._graph.getNode(id)))
|
|
1856
|
+
.some((n) => n.type === 'root');
|
|
1857
|
+
}
|
|
1858
|
+
/**
|
|
1859
|
+
* Update the asset in a Bundle Graph and clear the associated Bundle hash.
|
|
1860
|
+
*/
|
|
1861
|
+
updateAsset(asset) {
|
|
1862
|
+
this._graph.updateNode(this._graph.getNodeIdByContentKey(asset.id), asset);
|
|
1863
|
+
let bundles = this.getBundlesWithAsset(asset.value);
|
|
1864
|
+
for (let bundle of bundles) {
|
|
1865
|
+
// the bundle content will change with a modified asset
|
|
1866
|
+
this._bundleContentHashes.delete(bundle.id);
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
getEntryRoot(projectRoot, target) {
|
|
1870
|
+
let cached = this._targetEntryRoots.get(target.distDir);
|
|
1871
|
+
if (cached != null) {
|
|
1872
|
+
return cached;
|
|
1873
|
+
}
|
|
1874
|
+
let entryBundleGroupIds = this._graph.getNodeIdsConnectedFrom((0, nullthrows_1.default)(this._graph.rootNodeId), exports.bundleGraphEdgeTypes.bundle);
|
|
1875
|
+
let entries = [];
|
|
1876
|
+
for (let bundleGroupId of entryBundleGroupIds) {
|
|
1877
|
+
let bundleGroupNode = this._graph.getNode(bundleGroupId);
|
|
1878
|
+
(0, assert_2.default)(bundleGroupNode?.type === 'bundle_group');
|
|
1879
|
+
if (bundleGroupNode.value.target.distDir === target.distDir) {
|
|
1880
|
+
let entryAssetNode = this._graph.getNodeByContentKey(bundleGroupNode.value.entryAssetId);
|
|
1881
|
+
(0, assert_2.default)(entryAssetNode?.type === 'asset');
|
|
1882
|
+
entries.push((0, projectPath_1.fromProjectPath)(projectRoot, entryAssetNode.value.filePath));
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1885
|
+
let root = (0, utils_1.getRootDir)(entries);
|
|
1886
|
+
this._targetEntryRoots.set(target.distDir, root);
|
|
1887
|
+
return root;
|
|
1888
|
+
}
|
|
1889
|
+
getReferencedConditionalBundles(bundle) {
|
|
1890
|
+
let referencedBundles = new Set();
|
|
1891
|
+
this._graph.dfs({
|
|
1892
|
+
visit: (nodeId) => {
|
|
1893
|
+
let node = (0, nullthrows_1.default)(this._graph.getNode(nodeId));
|
|
1894
|
+
if (node.type !== 'bundle' || node.value.id === bundle.id) {
|
|
1895
|
+
return;
|
|
1896
|
+
}
|
|
1897
|
+
referencedBundles.add(node.value);
|
|
1898
|
+
},
|
|
1899
|
+
startNodeId: this._graph.getNodeIdByContentKey(bundle.id),
|
|
1900
|
+
getChildren: (nodeId) => this._graph.getNodeIdsConnectedFrom(nodeId, exports.bundleGraphEdgeTypes.conditional),
|
|
1901
|
+
});
|
|
1902
|
+
// @ts-expect-error TS2322
|
|
1903
|
+
return [...referencedBundles];
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
exports.default = BundleGraph;
|