@carbonenginejs/runtime-resource 0.9.2 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +3 -2
- package/README.md +47 -6
- package/dist/CjsMotherLode.js +88 -88
- package/dist/CjsMotherLode.js.map +1 -1
- package/dist/CjsResMan.js +717 -228
- package/dist/CjsResMan.js.map +1 -1
- package/dist/CjsResManFetchProvider.js +94 -0
- package/dist/CjsResManFetchProvider.js.map +1 -0
- package/dist/{CjsResManQueue.js → CjsResManWorkQueue.js} +112 -25
- package/dist/CjsResManWorkQueue.js.map +1 -0
- package/dist/format/CjsBlueReader.js +89 -0
- package/dist/format/CjsBlueReader.js.map +1 -1
- package/dist/format/CjsFormat.js +42 -16
- package/dist/format/CjsFormat.js.map +1 -1
- package/dist/format/CjsReader.js +4 -0
- package/dist/format/CjsReader.js.map +1 -1
- package/dist/format/CjsResourceProbe.js +2 -0
- package/dist/format/CjsResourceProbe.js.map +1 -1
- package/dist/format/effect/effectPermutationGraph.js +257 -0
- package/dist/format/effect/effectPermutationGraph.js.map +1 -0
- package/dist/format/effect/effectReflectionPackage.js +636 -0
- package/dist/format/effect/effectReflectionPackage.js.map +1 -0
- package/dist/format/effect/sha256.js +114 -0
- package/dist/format/effect/sha256.js.map +1 -0
- package/dist/format/payloadContract.js +20 -0
- package/dist/format/payloadContract.js.map +1 -1
- package/dist/formats/black/CjsBlackFormat.js +15 -1
- package/dist/formats/black/CjsBlackFormat.js.map +1 -1
- package/dist/formats/black/core/CjsBlackBinaryReader.js +103 -0
- package/dist/formats/black/core/CjsBlackBinaryReader.js.map +1 -1
- package/dist/formats/black/core/CjsBlackPropertyReaders.js +61 -0
- package/dist/formats/black/core/CjsBlackPropertyReaders.js.map +1 -1
- package/dist/formats/black/core/CjsBlackReader.js +125 -0
- package/dist/formats/black/core/CjsBlackReader.js.map +1 -1
- package/dist/formats/black/core/CjsBlackSchemaRegistry.js +103 -0
- package/dist/formats/black/core/CjsBlackSchemaRegistry.js.map +1 -1
- package/dist/formats/black/core/helpers.js +17 -0
- package/dist/formats/black/core/helpers.js.map +1 -1
- package/dist/formats/bnk/CjsBnkFormat.js +8 -0
- package/dist/formats/bnk/CjsBnkFormat.js.map +1 -1
- package/dist/formats/bnk/core/helpers.js +20 -0
- package/dist/formats/bnk/core/helpers.js.map +1 -1
- package/dist/formats/bnk/core/musicNodes.js +40 -3
- package/dist/formats/bnk/core/musicNodes.js.map +1 -1
- package/dist/formats/bnk/core/soundbanksInfo.js +2 -0
- package/dist/formats/bnk/core/soundbanksInfo.js.map +1 -1
- package/dist/formats/cmf/core/binary.js +71 -0
- package/dist/formats/cmf/core/binary.js.map +1 -1
- package/dist/formats/cmf/core/buffers.js +4 -0
- package/dist/formats/cmf/core/buffers.js.map +1 -1
- package/dist/formats/cmf/core/helpers.js +31 -0
- package/dist/formats/cmf/core/helpers.js.map +1 -1
- package/dist/formats/cmf/core/schema.js +10 -0
- package/dist/formats/cmf/core/schema.js.map +1 -1
- package/dist/formats/cmf/core/shared.js +9 -0
- package/dist/formats/cmf/core/shared.js.map +1 -1
- package/dist/formats/cmf/core/writer.js +54 -0
- package/dist/formats/cmf/core/writer.js.map +1 -1
- package/dist/formats/dds/core/bc6h.js +10 -0
- package/dist/formats/dds/core/bc6h.js.map +1 -1
- package/dist/formats/dds/core/bc7.js +16 -0
- package/dist/formats/dds/core/bc7.js.map +1 -1
- package/dist/formats/dds/core/helpers.js +47 -0
- package/dist/formats/dds/core/helpers.js.map +1 -1
- package/dist/formats/dxbc/CjsDxbcFormat.js +142 -0
- package/dist/formats/dxbc/CjsDxbcFormat.js.map +1 -0
- package/dist/formats/dxbc/core/DxbcReader.js +266 -0
- package/dist/formats/dxbc/core/DxbcReader.js.map +1 -0
- package/dist/formats/dxbc/core/container.js +169 -0
- package/dist/formats/dxbc/core/container.js.map +1 -0
- package/dist/formats/dxbc/core/decoder.js +789 -0
- package/dist/formats/dxbc/core/decoder.js.map +1 -0
- package/dist/formats/dxbc/core/errors.js +19 -0
- package/dist/formats/dxbc/core/errors.js.map +1 -0
- package/dist/formats/dxbc/core/helpers.js +220 -0
- package/dist/formats/dxbc/core/helpers.js.map +1 -0
- package/dist/formats/dxbc/core/opcodes.js +45 -0
- package/dist/formats/dxbc/core/opcodes.js.map +1 -0
- package/dist/formats/dxbc/core/program.js +91 -0
- package/dist/formats/dxbc/core/program.js.map +1 -0
- package/dist/formats/dxbc/core/signature.js +172 -0
- package/dist/formats/dxbc/core/signature.js.map +1 -0
- package/dist/formats/dxbc/index.js +2 -0
- package/dist/formats/dxbc/index.js.map +1 -0
- package/dist/formats/fbx/core/helpers.js +21 -0
- package/dist/formats/fbx/core/helpers.js.map +1 -1
- package/dist/formats/flac/CjsFlacFormat.js +49 -0
- package/dist/formats/flac/CjsFlacFormat.js.map +1 -1
- package/dist/formats/flac/core/helpers.js +20 -0
- package/dist/formats/flac/core/helpers.js.map +1 -1
- package/dist/formats/gif/CjsGifFormat.js +49 -0
- package/dist/formats/gif/CjsGifFormat.js.map +1 -1
- package/dist/formats/gif/core/helpers.js +20 -0
- package/dist/formats/gif/core/helpers.js.map +1 -1
- package/dist/formats/gltf/core/helpers.js +15 -0
- package/dist/formats/gltf/core/helpers.js.map +1 -1
- package/dist/formats/gltf/core/parser.js +13 -0
- package/dist/formats/gltf/core/parser.js.map +1 -1
- package/dist/formats/gltf/core/targets.js +10 -0
- package/dist/formats/gltf/core/targets.js.map +1 -1
- package/dist/formats/gr2/core/bitknit2.js +2 -0
- package/dist/formats/gr2/core/bitknit2.js.map +1 -1
- package/dist/formats/gr2/core/helpers.js +20 -0
- package/dist/formats/gr2/core/helpers.js.map +1 -1
- package/dist/formats/gr2/core/targets.js +10 -0
- package/dist/formats/gr2/core/targets.js.map +1 -1
- package/dist/formats/hlsl/CjsHlslFormat.js +254 -0
- package/dist/formats/hlsl/CjsHlslFormat.js.map +1 -0
- package/dist/formats/hlsl/core/HlslBinaryUtils.js +15 -0
- package/dist/formats/hlsl/core/HlslBinaryUtils.js.map +1 -0
- package/dist/formats/hlsl/core/HlslEffectReadError.js +19 -0
- package/dist/formats/hlsl/core/HlslEffectReadError.js.map +1 -0
- package/dist/formats/hlsl/core/HlslEffectStateManager.js +130 -0
- package/dist/formats/hlsl/core/HlslEffectStateManager.js.map +1 -0
- package/dist/formats/hlsl/core/HlslReader.js +266 -0
- package/dist/formats/hlsl/core/HlslReader.js.map +1 -0
- package/dist/formats/hlsl/core/HlslRenderStateSetup.js +37 -0
- package/dist/formats/hlsl/core/HlslRenderStateSetup.js.map +1 -0
- package/dist/formats/hlsl/core/HlslResourceSetDescription.js +94 -0
- package/dist/formats/hlsl/core/HlslResourceSetDescription.js.map +1 -0
- package/dist/formats/hlsl/core/HlslShaderBytecode.js +44 -0
- package/dist/formats/hlsl/core/HlslShaderBytecode.js.map +1 -0
- package/dist/formats/hlsl/core/analysis.js +51 -0
- package/dist/formats/hlsl/core/analysis.js.map +1 -0
- package/dist/formats/hlsl/core/helpers.js +270 -0
- package/dist/formats/hlsl/core/helpers.js.map +1 -0
- package/dist/formats/hlsl/core/json.js +284 -0
- package/dist/formats/hlsl/core/json.js.map +1 -0
- package/dist/formats/hlsl/core/metadata.js +327 -0
- package/dist/formats/hlsl/core/metadata.js.map +1 -0
- package/dist/formats/hlsl/core/portableReflection.js +848 -0
- package/dist/formats/hlsl/core/portableReflection.js.map +1 -0
- package/dist/formats/hlsl/core/render-states.js +280 -0
- package/dist/formats/hlsl/core/render-states.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/HlslRenderContextEnum.js +43 -0
- package/dist/formats/hlsl/core/tr2/HlslRenderContextEnum.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/resources/HlslEffectRes.js +294 -0
- package/dist/formats/hlsl/core/tr2/resources/HlslEffectRes.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/resources/HlslShaderPermutation.js +33 -0
- package/dist/formats/hlsl/core/tr2/resources/HlslShaderPermutation.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectBindingManifest.js +416 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectBindingManifest.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectConstant.js +40 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectConstant.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectDescription.js +742 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectDescription.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectLibrary.js +52 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectLibrary.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectParameterAnnotation.js +38 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectParameterAnnotation.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectResource.js +50 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectResource.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectStageInput.js +86 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectStageInput.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectTechnique.js +31 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslEffectTechnique.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslPass.js +42 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslPass.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslSamplerDescription.js +55 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslSamplerDescription.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslSamplerSetup.js +29 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslSamplerSetup.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslShader.js +220 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslShader.js.map +1 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslShaderOption.js +30 -0
- package/dist/formats/hlsl/core/tr2/shader/HlslShaderOption.js.map +1 -0
- package/dist/formats/hlsl/index.js +2 -0
- package/dist/formats/hlsl/index.js.map +1 -0
- package/dist/formats/hlsl/portable.js +2 -0
- package/dist/formats/hlsl/portable.js.map +1 -0
- package/dist/formats/index.js +4 -0
- package/dist/formats/index.js.map +1 -1
- package/dist/formats/jpeg/core/helpers.js +52 -0
- package/dist/formats/jpeg/core/helpers.js.map +1 -1
- package/dist/formats/jpeg/core/jpeg.js +93 -0
- package/dist/formats/jpeg/core/jpeg.js.map +1 -1
- package/dist/formats/mp3/core/helpers.js +37 -0
- package/dist/formats/mp3/core/helpers.js.map +1 -1
- package/dist/formats/mp4/core/helpers.js +35 -0
- package/dist/formats/mp4/core/helpers.js.map +1 -1
- package/dist/formats/ogg/CjsOggFormat.js +49 -0
- package/dist/formats/ogg/CjsOggFormat.js.map +1 -1
- package/dist/formats/ogg/core/helpers.js +23 -0
- package/dist/formats/ogg/core/helpers.js.map +1 -1
- package/dist/formats/ogg/core/vorbis.js +13 -0
- package/dist/formats/ogg/core/vorbis.js.map +1 -1
- package/dist/formats/png/core/helpers.js +52 -0
- package/dist/formats/png/core/helpers.js.map +1 -1
- package/dist/formats/red/CjsRedFormat.js +2 -0
- package/dist/formats/red/CjsRedFormat.js.map +1 -1
- package/dist/formats/red/core/CjsRedReader.js +52 -0
- package/dist/formats/red/core/CjsRedReader.js.map +1 -1
- package/dist/formats/red/core/helpers.js +19 -0
- package/dist/formats/red/core/helpers.js.map +1 -1
- package/dist/formats/stl/core/stl.js +8 -0
- package/dist/formats/stl/core/stl.js.map +1 -1
- package/dist/formats/stl/core/targets.js +10 -0
- package/dist/formats/stl/core/targets.js.map +1 -1
- package/dist/formats/tga/core/helpers.js +47 -0
- package/dist/formats/tga/core/helpers.js.map +1 -1
- package/dist/formats/wav/core/helpers.js +37 -0
- package/dist/formats/wav/core/helpers.js.map +1 -1
- package/dist/formats/webgl/CjsWebglFormat.js +221 -0
- package/dist/formats/webgl/CjsWebglFormat.js.map +1 -0
- package/dist/formats/webgl/core/cewg/CewgPackage.js +339 -0
- package/dist/formats/webgl/core/cewg/CewgPackage.js.map +1 -0
- package/dist/formats/webgl/core/cewg/CewgPackageBuilder.js +104 -0
- package/dist/formats/webgl/core/cewg/CewgPackageBuilder.js.map +1 -0
- package/dist/formats/webgl/core/cewg/binary.js +101 -0
- package/dist/formats/webgl/core/cewg/binary.js.map +1 -0
- package/dist/formats/webgl/core/cewgCompleteness.js +81 -0
- package/dist/formats/webgl/core/cewgCompleteness.js.map +1 -0
- package/dist/formats/webgl/core/effectPackage.js +789 -0
- package/dist/formats/webgl/core/effectPackage.js.map +1 -0
- package/dist/formats/webgl/core/effectPackageValidation.js +331 -0
- package/dist/formats/webgl/core/effectPackageValidation.js.map +1 -0
- package/dist/formats/webgl/core/errors.js +27 -0
- package/dist/formats/webgl/core/errors.js.map +1 -0
- package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js +2678 -0
- package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js.map +1 -0
- package/dist/formats/webgl/core/glsl/DxbcGlslHelpers.js +89 -0
- package/dist/formats/webgl/core/glsl/DxbcGlslHelpers.js.map +1 -0
- package/dist/formats/webgl/core/glsl/DxbcGlslOperandFormatter.js +428 -0
- package/dist/formats/webgl/core/glsl/DxbcGlslOperandFormatter.js.map +1 -0
- package/dist/formats/webgl/core/helpers.js +306 -0
- package/dist/formats/webgl/core/helpers.js.map +1 -0
- package/dist/formats/webgl/index.js +2 -0
- package/dist/formats/webgl/index.js.map +1 -0
- package/dist/formats/webgpu/CjsWebgpuFormat.js +376 -0
- package/dist/formats/webgpu/CjsWebgpuFormat.js.map +1 -0
- package/dist/formats/webgpu/core/cewgpu/CewgpuPackage.js +415 -0
- package/dist/formats/webgpu/core/cewgpu/CewgpuPackage.js.map +1 -0
- package/dist/formats/webgpu/core/cewgpu/CewgpuPackageBuilder.js +100 -0
- package/dist/formats/webgpu/core/cewgpu/CewgpuPackageBuilder.js.map +1 -0
- package/dist/formats/webgpu/core/cewgpu/binary.js +93 -0
- package/dist/formats/webgpu/core/cewgpu/binary.js.map +1 -0
- package/dist/formats/webgpu/core/cewgpu/tags.js +17 -0
- package/dist/formats/webgpu/core/cewgpu/tags.js.map +1 -0
- package/dist/formats/webgpu/core/effectAnalysis.js +82 -0
- package/dist/formats/webgpu/core/effectAnalysis.js.map +1 -0
- package/dist/formats/webgpu/core/effectBackendBodySet.js +305 -0
- package/dist/formats/webgpu/core/effectBackendBodySet.js.map +1 -0
- package/dist/formats/webgpu/core/effectPackageValidation.js +1078 -0
- package/dist/formats/webgpu/core/effectPackageValidation.js.map +1 -0
- package/dist/formats/webgpu/core/errors.js +20 -0
- package/dist/formats/webgpu/core/errors.js.map +1 -0
- package/dist/formats/webgpu/core/helpers.js +448 -0
- package/dist/formats/webgpu/core/helpers.js.map +1 -0
- package/dist/formats/webgpu/core/ir/analyzeRegisterValues.js +223 -0
- package/dist/formats/webgpu/core/ir/analyzeRegisterValues.js.map +1 -0
- package/dist/formats/webgpu/core/ir/buildControlFlow.js +220 -0
- package/dist/formats/webgpu/core/ir/buildControlFlow.js.map +1 -0
- package/dist/formats/webgpu/core/ir/indexableTemps.js +137 -0
- package/dist/formats/webgpu/core/ir/indexableTemps.js.map +1 -0
- package/dist/formats/webgpu/core/ir/inferValueTypes.js +454 -0
- package/dist/formats/webgpu/core/ir/inferValueTypes.js.map +1 -0
- package/dist/formats/webgpu/core/ir/lowerDxbcToIr.js +494 -0
- package/dist/formats/webgpu/core/ir/lowerDxbcToIr.js.map +1 -0
- package/dist/formats/webgpu/core/ir/resolveRegisterFlow.js +177 -0
- package/dist/formats/webgpu/core/ir/resolveRegisterFlow.js.map +1 -0
- package/dist/formats/webgpu/core/ir/sourceLanes.js +61 -0
- package/dist/formats/webgpu/core/ir/sourceLanes.js.map +1 -0
- package/dist/formats/webgpu/core/packageEffect.js +300 -0
- package/dist/formats/webgpu/core/packageEffect.js.map +1 -0
- package/dist/formats/webgpu/core/packageEffectSelection.js +164 -0
- package/dist/formats/webgpu/core/packageEffectSelection.js.map +1 -0
- package/dist/formats/webgpu/core/packageMetadata.js +8 -0
- package/dist/formats/webgpu/core/packageMetadata.js.map +1 -0
- package/dist/formats/webgpu/core/schema.js +4 -0
- package/dist/formats/webgpu/core/schema.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js +275 -0
- package/dist/formats/webgpu/core/wgsl/buildResourceTransformPlan.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/buildWgslBindingPlan.js +182 -0
- package/dist/formats/webgpu/core/wgsl/buildWgslBindingPlan.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/buildWgslSet.js +324 -0
- package/dist/formats/webgpu/core/wgsl/buildWgslSet.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/emitWgsl.js +356 -0
- package/dist/formats/webgpu/core/wgsl/emitWgsl.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/hoistEscapingValues.js +77 -0
- package/dist/formats/webgpu/core/wgsl/hoistEscapingValues.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerBindingLayout.js +451 -0
- package/dist/formats/webgpu/core/wgsl/lowerBindingLayout.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerComputeProgram.js +754 -0
- package/dist/formats/webgpu/core/wgsl/lowerComputeProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerCreateHistogramsComputeProgram.js +457 -0
- package/dist/formats/webgpu/core/wgsl/lowerCreateHistogramsComputeProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerFragmentProgram.js +1572 -0
- package/dist/formats/webgpu/core/wgsl/lowerFragmentProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerMergeHistogramsComputeProgram.js +659 -0
- package/dist/formats/webgpu/core/wgsl/lowerMergeHistogramsComputeProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerParticleClearComputePrograms.js +734 -0
- package/dist/formats/webgpu/core/wgsl/lowerParticleClearComputePrograms.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerParticleEmitComputeProgram.js +583 -0
- package/dist/formats/webgpu/core/wgsl/lowerParticleEmitComputeProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerSkinVerticesComputeProgram.js +621 -0
- package/dist/formats/webgpu/core/wgsl/lowerSkinVerticesComputeProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerSortComputeProgram.js +824 -0
- package/dist/formats/webgpu/core/wgsl/lowerSortComputeProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerSortInnerComputeProgram.js +697 -0
- package/dist/formats/webgpu/core/wgsl/lowerSortInnerComputeProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerSortStepComputeProgram.js +559 -0
- package/dist/formats/webgpu/core/wgsl/lowerSortStepComputeProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/lowerVertexProgram.js +1328 -0
- package/dist/formats/webgpu/core/wgsl/lowerVertexProgram.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/particleEmitSemanticDigest.js +110 -0
- package/dist/formats/webgpu/core/wgsl/particleEmitSemanticDigest.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/precisionControls.js +55 -0
- package/dist/formats/webgpu/core/wgsl/precisionControls.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/selectionPlans.js +758 -0
- package/dist/formats/webgpu/core/wgsl/selectionPlans.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/uniformity.js +78 -0
- package/dist/formats/webgpu/core/wgsl/uniformity.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/validateExactComputeIr.js +196 -0
- package/dist/formats/webgpu/core/wgsl/validateExactComputeIr.js.map +1 -0
- package/dist/formats/webgpu/core/wgsl/validateHandleOperand.js +37 -0
- package/dist/formats/webgpu/core/wgsl/validateHandleOperand.js.map +1 -0
- package/dist/formats/webgpu/index.js +2 -0
- package/dist/formats/webgpu/index.js.map +1 -0
- package/dist/formats/webm/core/helpers.js +35 -0
- package/dist/formats/webm/core/helpers.js.map +1 -1
- package/dist/formats/webp/CjsWebpFormat.js +49 -0
- package/dist/formats/webp/CjsWebpFormat.js.map +1 -1
- package/dist/formats/webp/core/helpers.js +23 -0
- package/dist/formats/webp/core/helpers.js.map +1 -1
- package/dist/formats/wem/CjsWemFormat.js +8 -0
- package/dist/formats/wem/CjsWemFormat.js.map +1 -1
- package/dist/formats/wem/core/bitStream.js +2 -0
- package/dist/formats/wem/core/bitStream.js.map +1 -1
- package/dist/formats/wem/core/helpers.js +20 -0
- package/dist/formats/wem/core/helpers.js.map +1 -1
- package/dist/formats/yaml/CjsYamlFormat.js +45 -0
- package/dist/formats/yaml/CjsYamlFormat.js.map +1 -1
- package/dist/formats/yaml/core/CjsYamlReader.js +91 -0
- package/dist/formats/yaml/core/CjsYamlReader.js.map +1 -1
- package/dist/formats/yaml/core/helpers.js +10 -0
- package/dist/formats/yaml/core/helpers.js.map +1 -1
- package/dist/index.js +56 -43
- package/dist/index.js.map +1 -1
- package/dist/{CjsResource.js → resource/CjsResource.js} +232 -17
- package/dist/resource/CjsResource.js.map +1 -0
- package/dist/{resources → resource}/Tr2LightProfileRes.js +4 -3
- package/dist/resource/Tr2LightProfileRes.js.map +1 -0
- package/dist/{resources → resource/audio}/AudioGeometryResData.js +1 -1
- package/dist/resource/audio/AudioGeometryResData.js.map +1 -0
- package/dist/resource/audio/CjsAudioBufferRes.js +86 -0
- package/dist/resource/audio/CjsAudioBufferRes.js.map +1 -0
- package/dist/resource/audio/CjsAudioRes.js +213 -0
- package/dist/resource/audio/CjsAudioRes.js.map +1 -0
- package/dist/resource/audio/index.js +4 -0
- package/dist/resource/audio/index.js.map +1 -0
- package/dist/{resources → resource/geometry}/MeshDecalData.js +1 -1
- package/dist/resource/geometry/MeshDecalData.js.map +1 -0
- package/dist/{resources → resource/geometry}/MeshDecalLodData.js +1 -1
- package/dist/resource/geometry/MeshDecalLodData.js.map +1 -0
- package/dist/resource/geometry/TriGeometryRes.js +656 -0
- package/dist/resource/geometry/TriGeometryRes.js.map +1 -0
- package/dist/{resources → resource/geometry}/TriGeometryResAreaData.js +1 -1
- package/dist/resource/geometry/TriGeometryResAreaData.js.map +1 -0
- package/dist/{resources → resource/geometry}/TriGeometryResJointData.js +1 -1
- package/dist/resource/geometry/TriGeometryResJointData.js.map +1 -0
- package/dist/{resources → resource/geometry}/TriGeometryResLodData.js +1 -1
- package/dist/resource/geometry/TriGeometryResLodData.js.map +1 -0
- package/dist/{resources → resource/geometry}/TriGeometryResMeshData.js +1 -1
- package/dist/resource/geometry/TriGeometryResMeshData.js.map +1 -0
- package/dist/{resources → resource/geometry}/TriGeometryResSkeletonData.js +1 -1
- package/dist/resource/geometry/TriGeometryResSkeletonData.js.map +1 -0
- package/dist/{resources → resource/geometry}/TriJointBinding.js +1 -1
- package/dist/resource/geometry/TriJointBinding.js.map +1 -0
- package/dist/{resources → resource/geometry}/TriMorphTargetGeometryConstants.js +1 -1
- package/dist/resource/geometry/TriMorphTargetGeometryConstants.js.map +1 -0
- package/dist/{resources → resource/geometry}/TriRtGeometryConstants.js +1 -1
- package/dist/resource/geometry/TriRtGeometryConstants.js.map +1 -0
- package/dist/{resources → resource/geometry/granny}/GStateBindingCallbackData.js +1 -1
- package/dist/resource/geometry/granny/GStateBindingCallbackData.js.map +1 -0
- package/dist/{resources → resource/geometry/granny}/Tr2GrannyIntersectionResult.js +1 -1
- package/dist/resource/geometry/granny/Tr2GrannyIntersectionResult.js.map +1 -0
- package/dist/{resources → resource/geometry/granny}/Tr2GrannyStateRes.js +6 -5
- package/dist/resource/geometry/granny/Tr2GrannyStateRes.js.map +1 -0
- package/dist/{resources → resource/geometry/granny}/TriGrannyRes.js +6 -5
- package/dist/resource/geometry/granny/TriGrannyRes.js.map +1 -0
- package/dist/{resources → resource/geometry/granny}/enums.js +1 -9
- package/dist/resource/geometry/granny/enums.js.map +1 -0
- package/dist/resource/geometry/granny/index.js +6 -0
- package/dist/resource/geometry/granny/index.js.map +1 -0
- package/dist/resource/geometry/index.js +17 -0
- package/dist/resource/geometry/index.js.map +1 -0
- package/dist/resource/index.js +52 -0
- package/dist/resource/index.js.map +1 -0
- package/dist/resource/resourceBoundary.js +64 -0
- package/dist/resource/resourceBoundary.js.map +1 -0
- package/dist/resource/shader/Tr2EffectRes.js +429 -0
- package/dist/resource/shader/Tr2EffectRes.js.map +1 -0
- package/dist/resource/shader/Tr2MaterialArea.js +34 -0
- package/dist/resource/shader/Tr2MaterialArea.js.map +1 -0
- package/dist/resource/shader/Tr2MaterialMesh.js +30 -0
- package/dist/resource/shader/Tr2MaterialMesh.js.map +1 -0
- package/dist/resource/shader/Tr2MaterialRes.js +35 -0
- package/dist/resource/shader/Tr2MaterialRes.js.map +1 -0
- package/dist/resource/shader/Tr2Shader.js +256 -0
- package/dist/resource/shader/Tr2Shader.js.map +1 -0
- package/dist/resource/shader/Tr2ShaderPermutation.js +47 -0
- package/dist/resource/shader/Tr2ShaderPermutation.js.map +1 -0
- package/dist/resource/shader/index.js +17 -0
- package/dist/resource/shader/index.js.map +1 -0
- package/dist/resource/shader/portable.js +33 -0
- package/dist/resource/shader/portable.js.map +1 -0
- package/dist/resource/shader/reflection/Tr2EffectConstant.js +135 -0
- package/dist/resource/shader/reflection/Tr2EffectConstant.js.map +1 -0
- package/dist/resource/shader/reflection/Tr2EffectDefine.js +28 -0
- package/dist/resource/shader/reflection/Tr2EffectDefine.js.map +1 -0
- package/dist/resource/shader/reflection/Tr2EffectDescription.js +107 -0
- package/dist/resource/shader/reflection/Tr2EffectDescription.js.map +1 -0
- package/dist/resource/shader/reflection/Tr2EffectLibrary.js +145 -0
- package/dist/resource/shader/reflection/Tr2EffectLibrary.js.map +1 -0
- package/dist/resource/shader/reflection/Tr2EffectParameterAnnotation.js +103 -0
- package/dist/resource/shader/reflection/Tr2EffectParameterAnnotation.js.map +1 -0
- package/dist/resource/shader/reflection/Tr2EffectResource.js +84 -0
- package/dist/resource/shader/reflection/Tr2EffectResource.js.map +1 -0
- package/dist/resource/shader/reflection/Tr2EffectStageInput.js +239 -0
- package/dist/resource/shader/reflection/Tr2EffectStageInput.js.map +1 -0
- package/dist/resource/shader/reflection/Tr2EffectTechnique.js +66 -0
- package/dist/resource/shader/reflection/Tr2EffectTechnique.js.map +1 -0
- package/dist/resource/shader/reflection/Tr2Pass.js +109 -0
- package/dist/resource/shader/reflection/Tr2Pass.js.map +1 -0
- package/dist/resource/shader/sampler/Tr2SamplerSetup.js +75 -0
- package/dist/resource/shader/sampler/Tr2SamplerSetup.js.map +1 -0
- package/dist/{texture → resource/texture}/CjsTextureArrayRes.js +83 -6
- package/dist/resource/texture/CjsTextureArrayRes.js.map +1 -0
- package/dist/{texture/CjsTextureParameterProxy.js → resource/texture/CjsTextureArrayResParameterProxy.js} +56 -10
- package/dist/resource/texture/CjsTextureArrayResParameterProxy.js.map +1 -0
- package/dist/{resources → resource/texture}/Tr2ImageRes.js +6 -4
- package/dist/resource/texture/Tr2ImageRes.js.map +1 -0
- package/dist/{resources → resource/texture}/Tr2TextureLodManager.js +3 -1
- package/dist/resource/texture/Tr2TextureLodManager.js.map +1 -0
- package/dist/{resources → resource/texture}/Tr2TextureLodUpdateRequest.js +1 -1
- package/dist/resource/texture/Tr2TextureLodUpdateRequest.js.map +1 -0
- package/dist/{resources → resource/texture}/Tr2TexturePackChannel.js +1 -1
- package/dist/resource/texture/Tr2TexturePackChannel.js.map +1 -0
- package/dist/{resources → resource/texture}/Tr2TexturePipeline.js +6 -4
- package/dist/resource/texture/Tr2TexturePipeline.js.map +1 -0
- package/dist/{resources → resource/texture}/Tr2TexturePipelineParams.js +1 -1
- package/dist/resource/texture/Tr2TexturePipelineParams.js.map +1 -0
- package/dist/{resources → resource/texture}/Tr2TexturePipelineStepCompress.js +1 -1
- package/dist/resource/texture/Tr2TexturePipelineStepCompress.js.map +1 -0
- package/dist/{resources → resource/texture}/Tr2TexturePipelineStepGenerateMips.js +1 -1
- package/dist/resource/texture/Tr2TexturePipelineStepGenerateMips.js.map +1 -0
- package/dist/{resources → resource/texture}/Tr2TexturePipelineStepLimitSize.js +1 -1
- package/dist/resource/texture/Tr2TexturePipelineStepLimitSize.js.map +1 -0
- package/dist/{resources → resource/texture}/Tr2TexturePipelineStepLoad.js +1 -1
- package/dist/resource/texture/Tr2TexturePipelineStepLoad.js.map +1 -0
- package/dist/{resources → resource/texture}/Tr2TexturePipelineStepPack.js +1 -1
- package/dist/resource/texture/Tr2TexturePipelineStepPack.js.map +1 -0
- package/dist/{resources → resource/texture}/TriTextureRes.js +42 -26
- package/dist/resource/texture/TriTextureRes.js.map +1 -0
- package/dist/resource/texture/index.js +15 -0
- package/dist/resource/texture/index.js.map +1 -0
- package/dist/{resources → resource/texture}/texturePipelineBehavior.js +59 -59
- package/dist/resource/texture/texturePipelineBehavior.js.map +1 -0
- package/dist/worker/CjsResManMainThreadLoader.js +87 -0
- package/dist/worker/CjsResManMainThreadLoader.js.map +1 -0
- package/dist/worker/CjsResManWorker.js +217 -0
- package/dist/worker/CjsResManWorker.js.map +1 -0
- package/dist/worker/CjsResManWorkerLoader.js +434 -0
- package/dist/worker/CjsResManWorkerLoader.js.map +1 -0
- package/dist/worker/protocol.js +12 -0
- package/dist/worker/protocol.js.map +1 -0
- package/docs/README.md +16 -3
- package/docs/architecture.md +39 -16
- package/docs/concepts/resource-lifecycle.md +2 -1
- package/docs/formats/README.md +8 -0
- package/docs/formats/provenance.md +11 -3
- package/docs/reference/classes/README.md +6 -4
- package/docs/reference/classes/audio.md +30 -0
- package/docs/reference/classes/core.md +31 -11
- package/docs/reference/classes/formats.md +440 -0
- package/docs/reference/classes/resources.md +151 -41
- package/docs/reference/classes/texture.md +7 -7
- package/docs/reference/motherlode-cache.md +17 -0
- package/docs/reference/queues.md +9 -1
- package/docs/reference/workers.md +135 -0
- package/docs/roadmap.md +27 -1
- package/format-notices/dxbc/LICENSE +21 -0
- package/format-notices/dxbc/NOTICE +20 -0
- package/format-notices/hlsl/LICENSE +21 -0
- package/format-notices/hlsl/NOTICE +25 -0
- package/format-notices/webgl/LICENSE +21 -0
- package/format-notices/webgl/NOTICE +35 -0
- package/format-notices/webgpu/LICENSE +21 -0
- package/format-notices/webgpu/NOTICE +31 -0
- package/package.json +13 -1
- package/dist/CjsResManQueue.js.map +0 -1
- package/dist/CjsResource.js.map +0 -1
- package/dist/CjsResourceSource.js +0 -68
- package/dist/CjsResourceSource.js.map +0 -1
- package/dist/resourcePath.js +0 -18
- package/dist/resourcePath.js.map +0 -1
- package/dist/resourceStates.js +0 -9
- package/dist/resourceStates.js.map +0 -1
- package/dist/resources/AudioGeometryResData.js.map +0 -1
- package/dist/resources/GStateBindingCallbackData.js.map +0 -1
- package/dist/resources/MeshDecalData.js.map +0 -1
- package/dist/resources/MeshDecalLodData.js.map +0 -1
- package/dist/resources/Tr2EffectRes.js +0 -71
- package/dist/resources/Tr2EffectRes.js.map +0 -1
- package/dist/resources/Tr2GrannyIntersectionResult.js.map +0 -1
- package/dist/resources/Tr2GrannyStateRes.js.map +0 -1
- package/dist/resources/Tr2ImageRes.js.map +0 -1
- package/dist/resources/Tr2LightProfileRes.js.map +0 -1
- package/dist/resources/Tr2MaterialArea.js +0 -34
- package/dist/resources/Tr2MaterialArea.js.map +0 -1
- package/dist/resources/Tr2MaterialMesh.js +0 -31
- package/dist/resources/Tr2MaterialMesh.js.map +0 -1
- package/dist/resources/Tr2MaterialRes.js +0 -34
- package/dist/resources/Tr2MaterialRes.js.map +0 -1
- package/dist/resources/Tr2ShaderPermutation.js +0 -43
- package/dist/resources/Tr2ShaderPermutation.js.map +0 -1
- package/dist/resources/Tr2TextureLodManager.js.map +0 -1
- package/dist/resources/Tr2TextureLodUpdateRequest.js.map +0 -1
- package/dist/resources/Tr2TexturePackChannel.js.map +0 -1
- package/dist/resources/Tr2TexturePipeline.js.map +0 -1
- package/dist/resources/Tr2TexturePipelineParams.js.map +0 -1
- package/dist/resources/Tr2TexturePipelineStepCompress.js.map +0 -1
- package/dist/resources/Tr2TexturePipelineStepGenerateMips.js.map +0 -1
- package/dist/resources/Tr2TexturePipelineStepLimitSize.js.map +0 -1
- package/dist/resources/Tr2TexturePipelineStepLoad.js.map +0 -1
- package/dist/resources/Tr2TexturePipelineStepPack.js.map +0 -1
- package/dist/resources/TriGeometryRes.js +0 -239
- package/dist/resources/TriGeometryRes.js.map +0 -1
- package/dist/resources/TriGeometryResAreaData.js.map +0 -1
- package/dist/resources/TriGeometryResJointData.js.map +0 -1
- package/dist/resources/TriGeometryResLodData.js.map +0 -1
- package/dist/resources/TriGeometryResMeshData.js.map +0 -1
- package/dist/resources/TriGeometryResSkeletonData.js.map +0 -1
- package/dist/resources/TriGrannyRes.js.map +0 -1
- package/dist/resources/TriJointBinding.js.map +0 -1
- package/dist/resources/TriMorphTargetGeometryConstants.js.map +0 -1
- package/dist/resources/TriRtGeometryConstants.js.map +0 -1
- package/dist/resources/TriTextureRes.js.map +0 -1
- package/dist/resources/enums.js.map +0 -1
- package/dist/resources/resourceBoundary.js +0 -47
- package/dist/resources/resourceBoundary.js.map +0 -1
- package/dist/resources/texturePipelineBehavior.js.map +0 -1
- package/dist/texture/CjsTextureArrayRes.js.map +0 -1
- package/dist/texture/CjsTextureParameterProxy.js.map +0 -1
package/dist/CjsResMan.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { CjsMotherLode, getMotherLodeKey } from './CjsMotherLode.js';
|
|
2
2
|
import { CjsEventEmitter } from '@carbonenginejs/runtime-utils/model';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { hasOwnThen } from '@carbonenginejs/runtime-utils/object';
|
|
4
|
+
import { normalizeResourcePath, normalizePath, normalizeResourceExtension, getResourceExtension } from '@carbonenginejs/runtime-utils/path';
|
|
5
|
+
import { CjsResource as _CjsResource } from './resource/CjsResource.js';
|
|
6
|
+
import { CjsResManWorkQueue, CjsResManQueue } from './CjsResManWorkQueue.js';
|
|
7
|
+
import { CjsResManMainThreadLoader } from './worker/CjsResManMainThreadLoader.js';
|
|
8
|
+
import { CjsResManWorkerLoader } from './worker/CjsResManWorkerLoader.js';
|
|
6
9
|
|
|
7
10
|
/** @type {WeakMap<object, CjsResourceReadContext>} */
|
|
8
11
|
const READ_CONTEXTS = new WeakMap();
|
|
@@ -30,6 +33,7 @@ let nextLocalValueIdentity = 1;
|
|
|
30
33
|
* @property {CjsResMan} resMan Owning manager.
|
|
31
34
|
* @property {object|Function} source Selected source implementation.
|
|
32
35
|
* @property {string} path Normalized Carbon-style source path.
|
|
36
|
+
* @property {string} sourcePath Resource path or URL passed to the selected source.
|
|
33
37
|
* @property {string|number|undefined} sourceRevision Caller content token.
|
|
34
38
|
* @property {string} revisionKey Type-stable internal form of the content token.
|
|
35
39
|
*/
|
|
@@ -172,6 +176,8 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
172
176
|
super();
|
|
173
177
|
this.motherLode = new CjsMotherLode();
|
|
174
178
|
this.source = null;
|
|
179
|
+
this.paths = new Map();
|
|
180
|
+
this.pathResolver = null;
|
|
175
181
|
this.resourceTypes = new Map();
|
|
176
182
|
this.objectLoaders = new Map();
|
|
177
183
|
this.formats = new Map();
|
|
@@ -179,11 +185,16 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
179
185
|
this.sourceOperations = new WeakMap();
|
|
180
186
|
this.queuedSourceOperations = new WeakMap();
|
|
181
187
|
this.formatOperations = new WeakMap();
|
|
188
|
+
this.mainThreadLoader = new CjsResManMainThreadLoader();
|
|
189
|
+
this.workerLoader = new CjsResManWorkerLoader({
|
|
190
|
+
fallback: this.mainThreadLoader
|
|
191
|
+
});
|
|
192
|
+
this.resourceLoader = this.workerLoader;
|
|
182
193
|
this.maxConcurrentLoads = 8;
|
|
183
194
|
this.maxPrepareTime = 0.005;
|
|
184
195
|
this.maxPrepareItemsPerTick = 0;
|
|
185
196
|
this.autoPumpMainThreadQueue = true;
|
|
186
|
-
this.queueScheduler =
|
|
197
|
+
this.queueScheduler = defaultQueueScheduler;
|
|
187
198
|
this.urgentResourceLoads = false;
|
|
188
199
|
this._backgroundPumpScheduled = false;
|
|
189
200
|
this._mainThreadPumpScheduled = false;
|
|
@@ -213,6 +224,11 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
213
224
|
* @param {object} [options={}] Additive source, registry, queue, format, and resource-type settings.
|
|
214
225
|
* @param {number} [options.cacheSize] Recorded-byte budget immediately installed on the active MotherLode.
|
|
215
226
|
* @param {object} [options.cacheCleanup] Cleanup policy used if a smaller configured budget evicts cached identities.
|
|
227
|
+
* @param {object} [options.mainThreadLoader] Direct execution strategy.
|
|
228
|
+
* @param {object|Map<string,string>} [options.paths] Resource-prefix URL bases.
|
|
229
|
+
* @param {Function|null} [options.pathResolver] Optional complete resource-path-to-URL resolver.
|
|
230
|
+
* @param {object} [options.workerLoader] Worker loader instance or construction options.
|
|
231
|
+
* @param {boolean} [options.useWorkerLoading=true] Whether worker-backed execution is selected.
|
|
216
232
|
* @returns {CjsResMan} This resource manager.
|
|
217
233
|
* @throws {TypeError} If options or any configured component are invalid.
|
|
218
234
|
* @throws {Error|AggregateError} If resource mutations are active or replacing MotherLode cannot clean its resources.
|
|
@@ -221,60 +237,59 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
221
237
|
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
222
238
|
throw new TypeError("CjsResMan.Register options must be an object.");
|
|
223
239
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
if (
|
|
228
|
-
|
|
240
|
+
hasOwnThen(options, {
|
|
241
|
+
motherLode: value => {
|
|
242
|
+
const nextMotherLode = value || new CjsMotherLode();
|
|
243
|
+
if (nextMotherLode !== this.motherLode) {
|
|
244
|
+
if (this.#activeResourceOperations > 0) {
|
|
245
|
+
throw activeResourceOperationsError(this.#activeResourceOperations);
|
|
246
|
+
}
|
|
247
|
+
const previousMotherLode = this.motherLode;
|
|
248
|
+
this.#InvalidateMotherLodeOwnership(previousMotherLode);
|
|
249
|
+
previousMotherLode?.Shutdown?.();
|
|
250
|
+
this.motherLode = nextMotherLode;
|
|
251
|
+
this.motherLode.Startup?.();
|
|
252
|
+
this.#BindMotherLodeResources();
|
|
253
|
+
this.#reloadGenerations.clear();
|
|
254
|
+
this.#lastAutoPurgeTime = null;
|
|
229
255
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
if (Object.prototype.hasOwnProperty.call(options, "queueScheduler")) {
|
|
266
|
-
if (options.queueScheduler !== null && typeof options.queueScheduler !== "function") {
|
|
267
|
-
throw new TypeError("CjsResMan queueScheduler must be a function or null.");
|
|
268
|
-
}
|
|
269
|
-
this.queueScheduler = options.queueScheduler || DefaultQueueScheduler;
|
|
270
|
-
}
|
|
271
|
-
if (Object.prototype.hasOwnProperty.call(options, "urgentResourceLoads")) {
|
|
272
|
-
this.SetUrgentResourceLoads(options.urgentResourceLoads);
|
|
273
|
-
}
|
|
274
|
-
for (const entry of NormalizeRegistrationEntries(options.formats)) {
|
|
256
|
+
},
|
|
257
|
+
cacheSize: value => this.motherLode.SetCacheSize(value, options.cacheCleanup || {}),
|
|
258
|
+
autoPurgePolicy: this.SetAutoPurgePolicy,
|
|
259
|
+
source: this.SetSource,
|
|
260
|
+
paths: this.SetPaths,
|
|
261
|
+
pathResolver: this.SetPathResolver,
|
|
262
|
+
mainThreadLoader: this.SetMainThreadLoader,
|
|
263
|
+
workerLoader: this.SetWorkerLoader,
|
|
264
|
+
useWorkerLoading: this.UseWorkerLoading,
|
|
265
|
+
maxConcurrentLoads: value => {
|
|
266
|
+
assertPositiveInteger(value, "maxConcurrentLoads");
|
|
267
|
+
this.maxConcurrentLoads = value;
|
|
268
|
+
this._loadQueue.SetConcurrency(value);
|
|
269
|
+
},
|
|
270
|
+
maxPrepareTime: value => {
|
|
271
|
+
assertNonNegativeNumber(value, "maxPrepareTime");
|
|
272
|
+
this.maxPrepareTime = value;
|
|
273
|
+
},
|
|
274
|
+
maxPrepareItemsPerTick: value => {
|
|
275
|
+
assertNonNegativeInteger(value, "maxPrepareItemsPerTick");
|
|
276
|
+
this.maxPrepareItemsPerTick = value;
|
|
277
|
+
},
|
|
278
|
+
autoPumpMainThreadQueue: value => {
|
|
279
|
+
this.autoPumpMainThreadQueue = Boolean(value);
|
|
280
|
+
},
|
|
281
|
+
queueScheduler: value => {
|
|
282
|
+
if (value !== null && typeof value !== "function") {
|
|
283
|
+
throw new TypeError("CjsResMan queueScheduler must be a function or null.");
|
|
284
|
+
}
|
|
285
|
+
this.queueScheduler = value || defaultQueueScheduler;
|
|
286
|
+
},
|
|
287
|
+
urgentResourceLoads: this.SetUrgentResourceLoads
|
|
288
|
+
}, this);
|
|
289
|
+
for (const entry of normalizeRegistrationEntries(options.formats)) {
|
|
275
290
|
if (typeof entry === "function") this.RegisterFormat(entry);else this.RegisterFormat(entry.Format || entry.format, entry.defaults || {});
|
|
276
291
|
}
|
|
277
|
-
for (const entry of
|
|
292
|
+
for (const entry of normalizeRegistrationEntries(options.resourceTypes, true)) {
|
|
278
293
|
if (typeof entry === "function") this.RegisterResourceType(entry);else this.RegisterResourceType(entry.requirement || entry.payload || entry.key, entry.Constructor || entry.Resource || entry.resourceType, entry);
|
|
279
294
|
}
|
|
280
295
|
for (const [ext, loader] of Object.entries(options.objectLoaders || {})) {
|
|
@@ -295,6 +310,189 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
295
310
|
this.source = source || null;
|
|
296
311
|
return this;
|
|
297
312
|
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Add or replace one resource-prefix URL base.
|
|
316
|
+
*
|
|
317
|
+
* @param {string} prefix Resource scheme without `:/`.
|
|
318
|
+
* @param {string} urlBase URL base ending at the scheme root.
|
|
319
|
+
* @returns {CjsResMan} This resource manager.
|
|
320
|
+
*/
|
|
321
|
+
SetPath(prefix, urlBase) {
|
|
322
|
+
const key = normalizePathPrefix(prefix);
|
|
323
|
+
const value = normalizeUrlBase(urlBase);
|
|
324
|
+
this.paths.set(key, value);
|
|
325
|
+
return this;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Add or replace resource-prefix URL bases from an object or Map.
|
|
330
|
+
*
|
|
331
|
+
* @param {object|Map<string,string>} paths Prefix/base entries.
|
|
332
|
+
* @returns {CjsResMan} This resource manager.
|
|
333
|
+
*/
|
|
334
|
+
SetPaths(paths) {
|
|
335
|
+
if (!paths || typeof paths !== "object" && !(paths instanceof Map) || Array.isArray(paths)) {
|
|
336
|
+
throw new TypeError("CjsResMan paths must be an object or Map.");
|
|
337
|
+
}
|
|
338
|
+
const entries = paths instanceof Map ? paths.entries() : Object.entries(paths);
|
|
339
|
+
for (const [prefix, urlBase] of entries) {
|
|
340
|
+
this.SetPath(prefix, urlBase);
|
|
341
|
+
}
|
|
342
|
+
return this;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Reports whether a resource-prefix URL base is registered.
|
|
347
|
+
*
|
|
348
|
+
* @param {string} prefix Resource scheme without `:/`.
|
|
349
|
+
* @returns {boolean}
|
|
350
|
+
*/
|
|
351
|
+
HasPath(prefix) {
|
|
352
|
+
return this.paths.has(normalizePathPrefix(prefix));
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Returns one registered resource-prefix URL base.
|
|
357
|
+
*
|
|
358
|
+
* @param {string} prefix Resource scheme without `:/`.
|
|
359
|
+
* @returns {string|null}
|
|
360
|
+
*/
|
|
361
|
+
GetPath(prefix) {
|
|
362
|
+
return this.paths.get(normalizePathPrefix(prefix)) || null;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Replaces the complete resource-path-to-URL resolver.
|
|
367
|
+
*
|
|
368
|
+
* @param {Function|null} resolver Resolver called as `(resourcePath, resMan)`.
|
|
369
|
+
* @returns {CjsResMan} This resource manager.
|
|
370
|
+
*/
|
|
371
|
+
SetPathResolver(resolver) {
|
|
372
|
+
if (resolver !== null && resolver !== undefined && typeof resolver !== "function") {
|
|
373
|
+
throw new TypeError("CjsResMan pathResolver must be a function or null.");
|
|
374
|
+
}
|
|
375
|
+
this.pathResolver = resolver || null;
|
|
376
|
+
return this;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Builds the URL used by URL-backed providers while preserving the resource
|
|
381
|
+
* path as the canonical resource identity.
|
|
382
|
+
*
|
|
383
|
+
* @param {string} path Resource path or direct HTTP(S) URL.
|
|
384
|
+
* @returns {string} Resolved URL.
|
|
385
|
+
*/
|
|
386
|
+
BuildUrl(path) {
|
|
387
|
+
const normalized = normalizeResourcePath(path);
|
|
388
|
+
if (!normalized) {
|
|
389
|
+
throw new TypeError("CjsResMan resource path must be a non-empty string.");
|
|
390
|
+
}
|
|
391
|
+
if (this.pathResolver) {
|
|
392
|
+
return normalizeResolvedUrl(this.pathResolver(normalized, this));
|
|
393
|
+
}
|
|
394
|
+
const prefixIndex = normalized.indexOf(":/");
|
|
395
|
+
if (prefixIndex === -1) {
|
|
396
|
+
return normalizePath(path);
|
|
397
|
+
}
|
|
398
|
+
const prefix = normalized.slice(0, prefixIndex);
|
|
399
|
+
if (prefix === "http" || prefix === "https") {
|
|
400
|
+
return normalizePath(path);
|
|
401
|
+
}
|
|
402
|
+
const urlBase = this.paths.get(prefix);
|
|
403
|
+
if (!urlBase) {
|
|
404
|
+
const error = new Error(`CjsResMan resource path prefix is not registered: ${prefix}`);
|
|
405
|
+
error.code = "CJS_RESMAN_PATH_PREFIX_UNREGISTERED";
|
|
406
|
+
error.path = normalized;
|
|
407
|
+
error.prefix = prefix;
|
|
408
|
+
throw error;
|
|
409
|
+
}
|
|
410
|
+
return `${urlBase}${normalized.slice(prefixIndex + 2)}`;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Replace the direct execution strategy used by unsupported worker
|
|
415
|
+
* operations and whenever worker loading is not selected.
|
|
416
|
+
*
|
|
417
|
+
* @param {object} loader Loader exposing `Read` and `ReadFormat`.
|
|
418
|
+
* @returns {CjsResMan} This resource manager.
|
|
419
|
+
*/
|
|
420
|
+
SetMainThreadLoader(loader) {
|
|
421
|
+
assertResourceLoader(loader, "mainThreadLoader");
|
|
422
|
+
const wasSelected = this.resourceLoader === this.mainThreadLoader;
|
|
423
|
+
this.mainThreadLoader = loader;
|
|
424
|
+
this.workerLoader?.SetFallback?.(loader);
|
|
425
|
+
if (wasSelected || !this.resourceLoader) this.resourceLoader = loader;
|
|
426
|
+
return this;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Install a worker loader instance or construct one from options.
|
|
431
|
+
*
|
|
432
|
+
* Installation does not select worker execution; call
|
|
433
|
+
* `UseWorkerLoading(true)` or pass `useWorkerLoading: true`.
|
|
434
|
+
*
|
|
435
|
+
* @param {object|null} loader Worker loader or CjsResManWorkerLoader options.
|
|
436
|
+
* @returns {CjsResMan} This resource manager.
|
|
437
|
+
*/
|
|
438
|
+
SetWorkerLoader(loader) {
|
|
439
|
+
const wasSelected = this.resourceLoader === this.workerLoader;
|
|
440
|
+
if (loader === null || loader === false) {
|
|
441
|
+
this.workerLoader = null;
|
|
442
|
+
if (wasSelected) this.resourceLoader = this.mainThreadLoader;
|
|
443
|
+
return this;
|
|
444
|
+
}
|
|
445
|
+
const resolved = isResourceLoader(loader) ? loader : new CjsResManWorkerLoader({
|
|
446
|
+
...(loader || {}),
|
|
447
|
+
fallback: loader?.fallback || this.mainThreadLoader
|
|
448
|
+
});
|
|
449
|
+
assertResourceLoader(resolved, "workerLoader");
|
|
450
|
+
this.workerLoader = resolved;
|
|
451
|
+
if (wasSelected) this.resourceLoader = resolved;
|
|
452
|
+
return this;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Select worker-backed execution, lazily creating the default module worker
|
|
457
|
+
* loader when required. Unsupported sources and formats still use the
|
|
458
|
+
* configured main-thread loader.
|
|
459
|
+
*
|
|
460
|
+
* @param {boolean} [value=true] Whether worker execution is selected.
|
|
461
|
+
* @returns {CjsResMan} This resource manager.
|
|
462
|
+
*/
|
|
463
|
+
UseWorkerLoading(value = true) {
|
|
464
|
+
if (!value) {
|
|
465
|
+
this.resourceLoader = this.mainThreadLoader;
|
|
466
|
+
return this;
|
|
467
|
+
}
|
|
468
|
+
if (!this.workerLoader) this.SetWorkerLoader({});
|
|
469
|
+
this.workerLoader.Reset?.();
|
|
470
|
+
this.resourceLoader = this.workerLoader;
|
|
471
|
+
return this;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Report whether worker-backed execution is the selected strategy.
|
|
476
|
+
*
|
|
477
|
+
* @returns {boolean}
|
|
478
|
+
*/
|
|
479
|
+
IsWorkerLoading() {
|
|
480
|
+
return Boolean(this.workerLoader && this.resourceLoader === this.workerLoader);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Return unresolved requests owned by the selected/installed worker loader.
|
|
485
|
+
*
|
|
486
|
+
* @returns {number}
|
|
487
|
+
*/
|
|
488
|
+
GetPendingWorkers() {
|
|
489
|
+
return this.workerLoader?.GetPendingCount?.() || 0;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Enqueues a resource task on the selected execution lane for the resource
|
|
494
|
+
* manager.
|
|
495
|
+
*/
|
|
298
496
|
AddToQueue(queue, callback, context = null, flags = 0) {
|
|
299
497
|
const task = this.QueueTask(queue, callback, context, {
|
|
300
498
|
flags
|
|
@@ -304,12 +502,24 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
304
502
|
});
|
|
305
503
|
return task.id;
|
|
306
504
|
}
|
|
505
|
+
|
|
506
|
+
/** Cancels a queued resource task before it starts for the resource manager. */
|
|
307
507
|
CancelFromQueue(queue, id, reason = "") {
|
|
308
508
|
return this.GetWorkQueue(queue).Cancel(id, reason);
|
|
309
509
|
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Allocates the next task identifier for a selected queue for the resource
|
|
513
|
+
* manager.
|
|
514
|
+
*/
|
|
310
515
|
GetNextIdForQueue(queue) {
|
|
311
516
|
return this.GetWorkQueue(queue).GetNextId();
|
|
312
517
|
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Starts pending preparation work within the main-thread concurrency limit for
|
|
521
|
+
* the resource manager.
|
|
522
|
+
*/
|
|
313
523
|
PumpMainThreadQueue(options = {}) {
|
|
314
524
|
const urgent = options.urgent === true || this.urgentResourceLoads;
|
|
315
525
|
const result = this._prepareQueue.Pump({
|
|
@@ -320,6 +530,11 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
320
530
|
if (result.queued > 0 && result.active === 0) this.ScheduleMainThreadQueue();
|
|
321
531
|
return result.processed > 0;
|
|
322
532
|
}
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* Starts pending load work within the background concurrency limit for the
|
|
536
|
+
* resource manager.
|
|
537
|
+
*/
|
|
323
538
|
PumpBackgroundQueue(options = {}) {
|
|
324
539
|
const result = this._loadQueue.Pump({
|
|
325
540
|
maxItems: options.maxItems ?? 0,
|
|
@@ -328,22 +543,47 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
328
543
|
});
|
|
329
544
|
return result.processed > 0;
|
|
330
545
|
}
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* Prevents the selected queue from starting additional work for the resource
|
|
549
|
+
* manager.
|
|
550
|
+
*/
|
|
331
551
|
PauseQueue(queue) {
|
|
332
552
|
this.GetWorkQueue(queue).Pause();
|
|
333
553
|
return this;
|
|
334
554
|
}
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* Allows the selected queue to start pending work again for the resource
|
|
558
|
+
* manager.
|
|
559
|
+
*/
|
|
335
560
|
ResumeQueue(queue) {
|
|
336
|
-
const name =
|
|
561
|
+
const name = CjsResManWorkQueue.normalizeName(queue);
|
|
337
562
|
this.GetWorkQueue(name).Resume();
|
|
338
563
|
if (name === CjsResManQueue.MAIN) this.ScheduleMainThreadQueue();else this.ScheduleBackgroundQueue();
|
|
339
564
|
return this;
|
|
340
565
|
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Returns the number of load tasks waiting or running for the resource
|
|
569
|
+
* manager.
|
|
570
|
+
*/
|
|
341
571
|
GetPendingLoads() {
|
|
342
572
|
return this._loadQueue.GetPendingCount();
|
|
343
573
|
}
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* Returns the number of preparation tasks waiting or running for the resource
|
|
577
|
+
* manager.
|
|
578
|
+
*/
|
|
344
579
|
GetPendingPrepares() {
|
|
345
580
|
return this._prepareQueue.GetPendingCount();
|
|
346
581
|
}
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* Returns queue counts and concurrency state for diagnostics for the resource
|
|
585
|
+
* manager.
|
|
586
|
+
*/
|
|
347
587
|
GetQueueStats(queue = null) {
|
|
348
588
|
if (queue !== null && queue !== undefined) return this.GetWorkQueue(queue).GetStats();
|
|
349
589
|
return Object.freeze({
|
|
@@ -351,15 +591,30 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
351
591
|
prepares: this._prepareQueue.GetStats()
|
|
352
592
|
});
|
|
353
593
|
}
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* Switches resource loading between normal and urgent concurrency policy for
|
|
597
|
+
* the resource manager.
|
|
598
|
+
*/
|
|
354
599
|
SetUrgentResourceLoads(value) {
|
|
355
600
|
this.urgentResourceLoads = Boolean(value);
|
|
356
601
|
return this;
|
|
357
602
|
}
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Reports whether urgent resource-load scheduling is active for the resource
|
|
606
|
+
* manager.
|
|
607
|
+
*/
|
|
358
608
|
IsUrgentResourceLoads() {
|
|
359
609
|
return this.urgentResourceLoads;
|
|
360
610
|
}
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* Reports whether any resource load or preparation remains pending for the
|
|
614
|
+
* resource manager.
|
|
615
|
+
*/
|
|
361
616
|
IsLoading() {
|
|
362
|
-
return this.GetPendingLoads() + this.GetPendingPrepares() > 0;
|
|
617
|
+
return this.GetPendingLoads() + this.GetPendingPrepares() + this.GetPendingWorkers() > 0;
|
|
363
618
|
}
|
|
364
619
|
|
|
365
620
|
/**
|
|
@@ -443,7 +698,7 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
443
698
|
await fence;
|
|
444
699
|
return this;
|
|
445
700
|
}
|
|
446
|
-
const yieldQueue = options.yield ||
|
|
701
|
+
const yieldQueue = options.yield || defaultQueueYield;
|
|
447
702
|
let settled = false;
|
|
448
703
|
fence.then(() => {
|
|
449
704
|
settled = true;
|
|
@@ -456,8 +711,13 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
456
711
|
await fence;
|
|
457
712
|
return this;
|
|
458
713
|
}
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Returns the execution queue selected by its public lane name for the
|
|
717
|
+
* resource manager.
|
|
718
|
+
*/
|
|
459
719
|
GetWorkQueue(queue) {
|
|
460
|
-
return
|
|
720
|
+
return CjsResManWorkQueue.normalizeName(queue) === CjsResManQueue.MAIN ? this._prepareQueue : this._loadQueue;
|
|
461
721
|
}
|
|
462
722
|
|
|
463
723
|
/**
|
|
@@ -477,6 +737,8 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
477
737
|
QueueTask(queue, callback, context = null, metadata = null) {
|
|
478
738
|
return this.#TrackQueueTask(this.GetWorkQueue(queue).Add(callback, context, metadata));
|
|
479
739
|
}
|
|
740
|
+
|
|
741
|
+
/** Requests a later background-queue scheduling pass for the resource manager. */
|
|
480
742
|
ScheduleBackgroundQueue() {
|
|
481
743
|
if (this._backgroundPumpScheduled || this._loadQueue.IsPaused()) return this;
|
|
482
744
|
this._backgroundPumpScheduled = true;
|
|
@@ -486,6 +748,11 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
486
748
|
});
|
|
487
749
|
return this;
|
|
488
750
|
}
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* Requests a later main-thread preparation scheduling pass for the resource
|
|
754
|
+
* manager.
|
|
755
|
+
*/
|
|
489
756
|
ScheduleMainThreadQueue() {
|
|
490
757
|
if (!this.autoPumpMainThreadQueue || this._mainThreadPumpScheduled || this._prepareQueue.IsPaused()) return this;
|
|
491
758
|
this._mainThreadPumpScheduled = true;
|
|
@@ -520,14 +787,14 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
520
787
|
Constructor = requirement;
|
|
521
788
|
requirement = options.requirement || options.payload || Constructor.payload;
|
|
522
789
|
}
|
|
523
|
-
const key =
|
|
790
|
+
const key = normalizeRequirement(requirement);
|
|
524
791
|
if (!key) throw new TypeError("CjsResMan.RegisterResourceType requires a semantic requirement.");
|
|
525
792
|
if (typeof Constructor !== "function") {
|
|
526
793
|
throw new TypeError("CjsResMan.RegisterResourceType requires a constructor or factory.");
|
|
527
794
|
}
|
|
528
795
|
this.resourceTypes.set(key, Constructor);
|
|
529
796
|
for (const alias of options.aliases || []) {
|
|
530
|
-
const aliasKey =
|
|
797
|
+
const aliasKey = normalizeRequirement(alias);
|
|
531
798
|
if (aliasKey) this.resourceTypes.set(aliasKey, Constructor);
|
|
532
799
|
}
|
|
533
800
|
return this;
|
|
@@ -575,7 +842,7 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
575
842
|
}
|
|
576
843
|
const descriptor = Object.freeze({
|
|
577
844
|
Format,
|
|
578
|
-
defaults:
|
|
845
|
+
defaults: snapshotFormatDefaults(defaults)
|
|
579
846
|
});
|
|
580
847
|
for (const inputType of Format.inputTypes) {
|
|
581
848
|
const key = normalizeResourceExtension(inputType);
|
|
@@ -635,12 +902,12 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
635
902
|
if (options.emit !== undefined) {
|
|
636
903
|
const objectLoader = this.GetObjectLoader(ext);
|
|
637
904
|
if (objectLoader) {
|
|
638
|
-
throw
|
|
905
|
+
throw createObjectLoaderOutputMissingError(ext, options.emit);
|
|
639
906
|
} else {
|
|
640
907
|
const descriptors = this.GetFormatDescriptors(ext);
|
|
641
|
-
const candidates =
|
|
908
|
+
const candidates = filterFormatDescriptors(descriptors, options);
|
|
642
909
|
if (descriptors.length > 0 && candidates.length === 0) {
|
|
643
|
-
throw
|
|
910
|
+
throw createFormatOutputMissingError(ext, options.emit, descriptors);
|
|
644
911
|
}
|
|
645
912
|
}
|
|
646
913
|
}
|
|
@@ -663,7 +930,7 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
663
930
|
this.motherLode.KeepAlive?.(cacheKey);
|
|
664
931
|
const expectedOwnership = this.#RequireResourceOwnership(existing, "reload-candidate:create");
|
|
665
932
|
const generation = this.#nextResourceReloadGeneration++;
|
|
666
|
-
const loaderOptions = Object.freeze(
|
|
933
|
+
const loaderOptions = Object.freeze(getResourceLoaderOptions(options, options.source || this.source));
|
|
667
934
|
const candidate = Object.freeze({
|
|
668
935
|
reloadCandidate: true,
|
|
669
936
|
generation,
|
|
@@ -682,7 +949,7 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
682
949
|
reload: true
|
|
683
950
|
};
|
|
684
951
|
resource.SetObjectLoader(loadOptions => this.#GetReloadCandidateObject(resource, {
|
|
685
|
-
...
|
|
952
|
+
...mergeResourceLoaderOptions(reloadOptions, loadOptions),
|
|
686
953
|
reload: true
|
|
687
954
|
}), reloadOptions);
|
|
688
955
|
}
|
|
@@ -718,7 +985,7 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
718
985
|
*/
|
|
719
986
|
GetObject(path, options = {}) {
|
|
720
987
|
const resource = this.GetResource(path, options);
|
|
721
|
-
const operationOptions =
|
|
988
|
+
const operationOptions = mergeResourceLoaderOptions(resource.GetObjectRequest?.() || {}, options);
|
|
722
989
|
if (this.#reloadCandidates.has(resource)) {
|
|
723
990
|
return this.#GetReloadCandidateObject(resource, operationOptions);
|
|
724
991
|
}
|
|
@@ -729,7 +996,7 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
729
996
|
}
|
|
730
997
|
if (resource.HasPayload?.()) {
|
|
731
998
|
resource.KeepPayloadAlive?.();
|
|
732
|
-
return Promise.resolve(
|
|
999
|
+
return Promise.resolve(getPublishedResourceObject(resource));
|
|
733
1000
|
}
|
|
734
1001
|
const promise = this.QueueResourceObject(resource, operationOptions);
|
|
735
1002
|
const operation = {
|
|
@@ -748,9 +1015,19 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
748
1015
|
});
|
|
749
1016
|
return promise;
|
|
750
1017
|
}
|
|
1018
|
+
|
|
1019
|
+
/**
|
|
1020
|
+
* Loads and hydrates an object graph through the configured resource pipeline
|
|
1021
|
+
* for the resource manager.
|
|
1022
|
+
*/
|
|
751
1023
|
LoadObject(path, options = {}) {
|
|
752
1024
|
return this.GetObject(path, options);
|
|
753
1025
|
}
|
|
1026
|
+
|
|
1027
|
+
/**
|
|
1028
|
+
* Fetches and hydrates an object graph without retaining a resource handle for
|
|
1029
|
+
* the resource manager.
|
|
1030
|
+
*/
|
|
754
1031
|
FetchObject(path, options = {}) {
|
|
755
1032
|
return this.GetObject(path, options);
|
|
756
1033
|
}
|
|
@@ -830,7 +1107,7 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
830
1107
|
#GetReloadCandidateObject(resource, options) {
|
|
831
1108
|
const candidate = this.#reloadCandidates.get(resource) || null;
|
|
832
1109
|
if (!candidate) {
|
|
833
|
-
return Promise.reject(
|
|
1110
|
+
return Promise.reject(reloadCandidateUnavailableError(resource));
|
|
834
1111
|
}
|
|
835
1112
|
const existing = this.#reloadOperations.get(resource);
|
|
836
1113
|
if (existing?.candidate === candidate) return existing.promise;
|
|
@@ -863,7 +1140,7 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
863
1140
|
*/
|
|
864
1141
|
async #RunReloadCandidate(candidate, options) {
|
|
865
1142
|
let committed = false;
|
|
866
|
-
let releaseLock =
|
|
1143
|
+
let releaseLock = noop;
|
|
867
1144
|
const finishOperation = this.#BeginResourceOperation(true);
|
|
868
1145
|
try {
|
|
869
1146
|
this.#AssertReloadCandidate(candidate, "reload:begin");
|
|
@@ -887,7 +1164,7 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
887
1164
|
commitGuard: () => this.#IsReloadCandidateCurrent(candidate)
|
|
888
1165
|
});
|
|
889
1166
|
if (!result.committed) {
|
|
890
|
-
throw
|
|
1167
|
+
throw staleReloadCandidateError(candidate, "reload:commit-compare");
|
|
891
1168
|
}
|
|
892
1169
|
committed = true;
|
|
893
1170
|
this.#FinalizeCommittedReload(candidate);
|
|
@@ -936,7 +1213,7 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
936
1213
|
const errors = [];
|
|
937
1214
|
try {
|
|
938
1215
|
if (typeof candidate.resource.SetObjectLoader === "function") {
|
|
939
|
-
candidate.resource.SetObjectLoader(loadOptions => this.GetObject(candidate.resource.GetPath(),
|
|
1216
|
+
candidate.resource.SetObjectLoader(loadOptions => this.GetObject(candidate.resource.GetPath(), mergeResourceLoaderOptions(candidate.loaderOptions, loadOptions)), candidate.loaderOptions);
|
|
940
1217
|
}
|
|
941
1218
|
} catch (error) {
|
|
942
1219
|
errors.push(error);
|
|
@@ -1022,6 +1299,11 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1022
1299
|
throw new AggregateError(errors, "CjsResMan reload candidate ownership cleanup failed.");
|
|
1023
1300
|
}
|
|
1024
1301
|
}
|
|
1302
|
+
|
|
1303
|
+
/**
|
|
1304
|
+
* Fetches raw source bytes through the configured resource source for the
|
|
1305
|
+
* resource manager.
|
|
1306
|
+
*/
|
|
1025
1307
|
Fetch(path, options = {}) {
|
|
1026
1308
|
return options.resource === true || options.requirement !== undefined || options.payload !== undefined ? this.FetchResource(path, options) : this.FetchObject(path, options);
|
|
1027
1309
|
}
|
|
@@ -1206,16 +1488,25 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1206
1488
|
*/
|
|
1207
1489
|
async #PrepareResourceObjectQueued(resource, bytes, options, ownership) {
|
|
1208
1490
|
let object = bytes;
|
|
1209
|
-
this.#
|
|
1210
|
-
const
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1491
|
+
const resolved = this.#ResolveResourceObjectRead(resource, bytes, options);
|
|
1492
|
+
const formatOptions = resolved.descriptor ? createFormatReadOptions(resolved.descriptor, options) : null;
|
|
1493
|
+
const runInWorker = Boolean(resolved.descriptor && typeof this.resourceLoader?.CanReadFormat === "function" && this.resourceLoader.CanReadFormat(resolved.descriptor, formatOptions));
|
|
1494
|
+
let read;
|
|
1495
|
+
if (runInWorker) {
|
|
1496
|
+
this.#AssertOptionalResourceOwnership(ownership, "worker-stage:read:run");
|
|
1497
|
+
read = await this.#ReadResolvedResourceObjectPayload(resource, bytes, options, resolved);
|
|
1498
|
+
} else {
|
|
1499
|
+
this.#AssertOptionalResourceOwnership(ownership, "queue-stage:read:enqueue");
|
|
1500
|
+
const readTask = this.QueueTask(CjsResManQueue.MAIN, () => {
|
|
1501
|
+
this.#AssertOptionalResourceOwnership(ownership, "queue-stage:read:run");
|
|
1502
|
+
return this.#ReadResolvedResourceObjectPayload(resource, bytes, options, resolved);
|
|
1503
|
+
}, resource, {
|
|
1504
|
+
kind: "prepare",
|
|
1505
|
+
stage: "read",
|
|
1506
|
+
path: resource.GetPath()
|
|
1507
|
+
});
|
|
1508
|
+
read = await readTask.promise;
|
|
1509
|
+
}
|
|
1219
1510
|
this.#AssertOptionalResourceOwnership(ownership, "queue-stage:read:settled");
|
|
1220
1511
|
if (read !== undefined) object = read;
|
|
1221
1512
|
this.#AssertOptionalResourceOwnership(ownership, "queue-stage:publish:enqueue");
|
|
@@ -1245,18 +1536,52 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1245
1536
|
* @throws {Error|TypeError} If no registered reader matches or its read contract fails.
|
|
1246
1537
|
*/
|
|
1247
1538
|
async ReadResourceObjectPayload(resource, bytes, options = {}) {
|
|
1539
|
+
return this.#ReadResolvedResourceObjectPayload(resource, bytes, options, this.#ResolveResourceObjectRead(resource, bytes, options));
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
/**
|
|
1543
|
+
* Resolve the configured direct loader or format descriptor once so queue
|
|
1544
|
+
* selection and execution use the same registration snapshot.
|
|
1545
|
+
*
|
|
1546
|
+
* @param {CjsResource} resource Resource whose CPU outcome is requested.
|
|
1547
|
+
* @param {*} bytes Source input.
|
|
1548
|
+
* @param {object} options Requested output options.
|
|
1549
|
+
* @returns {{loader: Function|null, descriptor: object|null}} Resolved reader.
|
|
1550
|
+
*/
|
|
1551
|
+
#ResolveResourceObjectRead(resource, bytes, options) {
|
|
1248
1552
|
const explicitLoader = this.GetObjectLoader(resource.GetExt());
|
|
1249
1553
|
if (explicitLoader) {
|
|
1250
1554
|
if (options.emit !== undefined) {
|
|
1251
|
-
throw
|
|
1555
|
+
throw createObjectLoaderOutputMissingError(resource.GetExt(), options.emit);
|
|
1252
1556
|
}
|
|
1253
|
-
return
|
|
1557
|
+
return {
|
|
1558
|
+
loader: explicitLoader,
|
|
1559
|
+
descriptor: null
|
|
1560
|
+
};
|
|
1254
1561
|
}
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1562
|
+
return {
|
|
1563
|
+
loader: null,
|
|
1564
|
+
descriptor: this.ResolveFormatDescriptor(resource.GetExt(), {
|
|
1565
|
+
...options,
|
|
1566
|
+
bytes
|
|
1567
|
+
})
|
|
1568
|
+
};
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
/**
|
|
1572
|
+
* Execute one already-resolved reader through its direct or format path.
|
|
1573
|
+
*
|
|
1574
|
+
* @param {CjsResource} resource Resource whose CPU outcome is requested.
|
|
1575
|
+
* @param {*} bytes Source input.
|
|
1576
|
+
* @param {object} options Requested output options.
|
|
1577
|
+
* @param {{loader: Function|null, descriptor: object|null}} resolved Reader selection.
|
|
1578
|
+
* @returns {Promise<*>} Reader result.
|
|
1579
|
+
*/
|
|
1580
|
+
#ReadResolvedResourceObjectPayload(resource, bytes, options, resolved) {
|
|
1581
|
+
if (resolved.loader) {
|
|
1582
|
+
return resolved.loader(bytes, createPrepareContext(this, resource, bytes, options, "read"));
|
|
1583
|
+
}
|
|
1584
|
+
return this.ReadFormatOnce(resource, resolved.descriptor, bytes, options);
|
|
1260
1585
|
}
|
|
1261
1586
|
|
|
1262
1587
|
/**
|
|
@@ -1323,9 +1648,19 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1323
1648
|
resource.SetPayload?.(object, options);
|
|
1324
1649
|
resource.object = object;
|
|
1325
1650
|
}
|
|
1326
|
-
|
|
1651
|
+
// PREPARED, not LOADED: `object` is the reader/converter OUTCOME, so the
|
|
1652
|
+
// bytes have already been turned into whatever they needed to become.
|
|
1653
|
+
// LOADED means raw source data is in hand and still has to be prepared - a
|
|
1654
|
+
// resource in that state is not yet good, and marking it here left IsGood()
|
|
1655
|
+
// permanently false for every resource that does not prepare itself.
|
|
1656
|
+
if (!resource.IsPrepared?.()) resource.MarkPrepared();
|
|
1327
1657
|
return result;
|
|
1328
1658
|
}
|
|
1659
|
+
|
|
1660
|
+
/**
|
|
1661
|
+
* Warms a resource and its discovered dependencies without returning payload
|
|
1662
|
+
* data for the resource manager.
|
|
1663
|
+
*/
|
|
1329
1664
|
async Prefetch(paths, options = {}) {
|
|
1330
1665
|
const entries = Array.isArray(paths) ? paths : [paths];
|
|
1331
1666
|
return Promise.all(entries.map(path => this.LoadObject(path, options)));
|
|
@@ -1364,11 +1699,11 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1364
1699
|
ResolveFormatDescriptor(inputType, options = {}) {
|
|
1365
1700
|
const key = normalizeResourceExtension(inputType);
|
|
1366
1701
|
const descriptors = this.GetFormatDescriptors(key);
|
|
1367
|
-
const candidates =
|
|
1702
|
+
const candidates = filterFormatDescriptors(descriptors, options);
|
|
1368
1703
|
if (descriptors.length > 0 && candidates.length === 0 && options.emit !== undefined) {
|
|
1369
|
-
throw
|
|
1704
|
+
throw createFormatOutputMissingError(key, options.emit, descriptors);
|
|
1370
1705
|
}
|
|
1371
|
-
return
|
|
1706
|
+
return resolveFormatDescriptorCandidates(candidates, key, options);
|
|
1372
1707
|
}
|
|
1373
1708
|
|
|
1374
1709
|
/**
|
|
@@ -1383,32 +1718,7 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1383
1718
|
* @throws {TypeError|Error} If the facade lacks a reader or reading fails.
|
|
1384
1719
|
*/
|
|
1385
1720
|
async ReadFormat(descriptor, bytes, options = {}) {
|
|
1386
|
-
|
|
1387
|
-
Format,
|
|
1388
|
-
defaults
|
|
1389
|
-
} = descriptor;
|
|
1390
|
-
const formatOptions = {
|
|
1391
|
-
...defaults,
|
|
1392
|
-
...(options.formatOptions || {})
|
|
1393
|
-
};
|
|
1394
|
-
if (options.emit !== undefined) {
|
|
1395
|
-
formatOptions.emit = FindDeclaredOutput(GetFormatOutputs(Format), options.emit) ?? options.emit;
|
|
1396
|
-
}
|
|
1397
|
-
if (options.classes !== undefined) formatOptions.classes = options.classes;
|
|
1398
|
-
if (typeof Format.readAsync === "function") {
|
|
1399
|
-
return Format.readAsync(bytes, formatOptions);
|
|
1400
|
-
}
|
|
1401
|
-
if (typeof Format.read === "function") {
|
|
1402
|
-
return Format.read(bytes, formatOptions);
|
|
1403
|
-
}
|
|
1404
|
-
const reader = new Format(formatOptions);
|
|
1405
|
-
if (typeof reader.ReadAsync === "function") {
|
|
1406
|
-
return reader.ReadAsync(bytes, formatOptions);
|
|
1407
|
-
}
|
|
1408
|
-
if (typeof reader.Read === "function") {
|
|
1409
|
-
return reader.Read(bytes, formatOptions);
|
|
1410
|
-
}
|
|
1411
|
-
throw new TypeError(`${Format.name} does not expose a read operation.`);
|
|
1721
|
+
return this.resourceLoader.ReadFormat(descriptor, bytes, createFormatReadOptions(descriptor, options));
|
|
1412
1722
|
}
|
|
1413
1723
|
|
|
1414
1724
|
/**
|
|
@@ -1502,7 +1812,7 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1502
1812
|
* @throws {TypeError} If the policy, threshold, cleanup control, or clock is invalid.
|
|
1503
1813
|
*/
|
|
1504
1814
|
SetAutoPurgePolicy(policy = null) {
|
|
1505
|
-
this.#autoPurgePolicy =
|
|
1815
|
+
this.#autoPurgePolicy = normalizeAutoPurgePolicy(policy);
|
|
1506
1816
|
this.#lastAutoPurgeTime = null;
|
|
1507
1817
|
return this;
|
|
1508
1818
|
}
|
|
@@ -1539,11 +1849,11 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1539
1849
|
* @throws {AggregateError} If a due sweep cannot clean one or more inactive resources.
|
|
1540
1850
|
*/
|
|
1541
1851
|
PumpAutoPurge(options = {}) {
|
|
1542
|
-
const pump =
|
|
1852
|
+
const pump = normalizeAutoPurgePumpOptions(options);
|
|
1543
1853
|
const policy = this.#autoPurgePolicy;
|
|
1544
1854
|
if (!policy) return null;
|
|
1545
1855
|
const time = pump.time === undefined ? policy.now() : pump.time;
|
|
1546
|
-
|
|
1856
|
+
assertNonNegativeNumber(time, "automatic purge time");
|
|
1547
1857
|
if (this.#lastAutoPurgeTime !== null) {
|
|
1548
1858
|
if (time < this.#lastAutoPurgeTime) {
|
|
1549
1859
|
this.#lastAutoPurgeTime = time;
|
|
@@ -1608,8 +1918,8 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1608
1918
|
throw new TypeError("CjsResMan.InvalidateReadCache options must be an object.");
|
|
1609
1919
|
}
|
|
1610
1920
|
const normalizedPath = normalizeResourcePath(path);
|
|
1611
|
-
const hasRevision =
|
|
1612
|
-
const revisionKey = hasRevision ?
|
|
1921
|
+
const hasRevision = hasOwn(options, "sourceRevision");
|
|
1922
|
+
const revisionKey = hasRevision ? normalizeSourceRevision(options.sourceRevision) : null;
|
|
1613
1923
|
const source = options.source || this.source;
|
|
1614
1924
|
if (!source) {
|
|
1615
1925
|
return Object.freeze({
|
|
@@ -1670,9 +1980,9 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1670
1980
|
throw new TypeError("CjsResMan requires a source with Read(path, options) to load objects.");
|
|
1671
1981
|
}
|
|
1672
1982
|
const sourceRevision = options.sourceRevision;
|
|
1673
|
-
const revisionKey =
|
|
1674
|
-
|
|
1675
|
-
|
|
1983
|
+
const revisionKey = normalizeSourceRevision(sourceRevision);
|
|
1984
|
+
normalizeCachePolicy(options.cacheSource, "cacheSource");
|
|
1985
|
+
normalizeCachePolicy(options.cacheFormat, "cacheFormat");
|
|
1676
1986
|
const operationOptions = {
|
|
1677
1987
|
...options
|
|
1678
1988
|
};
|
|
@@ -1680,6 +1990,7 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1680
1990
|
resMan: this,
|
|
1681
1991
|
source,
|
|
1682
1992
|
path: normalizedPath,
|
|
1993
|
+
sourcePath: sourceRequiresUrl(source) ? this.BuildUrl(normalizedPath) : normalizedPath,
|
|
1683
1994
|
sourceRevision,
|
|
1684
1995
|
revisionKey
|
|
1685
1996
|
});
|
|
@@ -1702,15 +2013,15 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1702
2013
|
* @returns {Promise<*>} Promise for source bytes/data.
|
|
1703
2014
|
*/
|
|
1704
2015
|
#QueueReadResource(context, options) {
|
|
1705
|
-
const cachePolicy =
|
|
1706
|
-
const operations =
|
|
1707
|
-
const key =
|
|
2016
|
+
const cachePolicy = normalizeCachePolicy(options.cacheSource, "cacheSource");
|
|
2017
|
+
const operations = getOwnerOperations(this.queuedSourceOperations, context.source, true);
|
|
2018
|
+
const key = getReadOperationKey(context);
|
|
1708
2019
|
const bypassExisting = options.reload === true || cachePolicy === false;
|
|
1709
2020
|
const existing = bypassExisting ? null : operations.get(key);
|
|
1710
2021
|
if (existing) {
|
|
1711
2022
|
if (cachePolicy === true) {
|
|
1712
2023
|
existing.retain = true;
|
|
1713
|
-
const sourceRecord =
|
|
2024
|
+
const sourceRecord = getOwnerOperations(this.sourceOperations, context.source, false)?.get(key);
|
|
1714
2025
|
if (sourceRecord) sourceRecord.retain = true;
|
|
1715
2026
|
}
|
|
1716
2027
|
return existing.promise;
|
|
@@ -1747,9 +2058,9 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1747
2058
|
* @returns {Promise<*>} Promise for source bytes/data.
|
|
1748
2059
|
*/
|
|
1749
2060
|
#ReadResource(context, options, queuedRecord = null) {
|
|
1750
|
-
const cachePolicy =
|
|
1751
|
-
const operations =
|
|
1752
|
-
const key =
|
|
2061
|
+
const cachePolicy = normalizeCachePolicy(options.cacheSource, "cacheSource");
|
|
2062
|
+
const operations = getOwnerOperations(this.sourceOperations, context.source, true);
|
|
2063
|
+
const key = getReadOperationKey(context);
|
|
1753
2064
|
const bypassExisting = options.reload === true || cachePolicy === false;
|
|
1754
2065
|
const existing = bypassExisting ? null : operations.get(key);
|
|
1755
2066
|
if (existing) {
|
|
@@ -1764,7 +2075,10 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1764
2075
|
revisionKey: context.revisionKey,
|
|
1765
2076
|
retain: cachePolicy === true || queuedRecord?.retain === true
|
|
1766
2077
|
};
|
|
1767
|
-
record.promise = Promise.resolve().then(() =>
|
|
2078
|
+
record.promise = Promise.resolve().then(() => this.resourceLoader.Read(context.source, context.sourcePath, {
|
|
2079
|
+
...options,
|
|
2080
|
+
resourcePath: context.path
|
|
2081
|
+
}));
|
|
1768
2082
|
if (cachePolicy !== false) operations.set(key, record);
|
|
1769
2083
|
record.promise.then(() => {
|
|
1770
2084
|
if (cachePolicy !== false && !record.retain && operations.get(key) === record) {
|
|
@@ -1785,8 +2099,8 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1785
2099
|
* @returns {void}
|
|
1786
2100
|
*/
|
|
1787
2101
|
#RetainSourceResult(context, value) {
|
|
1788
|
-
const operations =
|
|
1789
|
-
const key =
|
|
2102
|
+
const operations = getOwnerOperations(this.sourceOperations, context.source, true);
|
|
2103
|
+
const key = getReadOperationKey(context);
|
|
1790
2104
|
const existing = operations.get(key);
|
|
1791
2105
|
if (existing) {
|
|
1792
2106
|
existing.retain = true;
|
|
@@ -1810,13 +2124,13 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1810
2124
|
* @returns {Readonly<{path: string, queuedSource: number, source: number, format: number}>} Frozen detached counts.
|
|
1811
2125
|
*/
|
|
1812
2126
|
#InvalidateReadCache(source, path, revisionKey) {
|
|
1813
|
-
const queuedSource =
|
|
1814
|
-
const sourceCount =
|
|
2127
|
+
const queuedSource = removeOperationRecords(getOwnerOperations(this.queuedSourceOperations, source, false), path, revisionKey);
|
|
2128
|
+
const sourceCount = removeOperationRecords(getOwnerOperations(this.sourceOperations, source, false), path, revisionKey);
|
|
1815
2129
|
let format = 0;
|
|
1816
2130
|
const descriptors = this.formatOperations.get(source);
|
|
1817
2131
|
if (descriptors) {
|
|
1818
2132
|
for (const [descriptor, operations] of descriptors) {
|
|
1819
|
-
format +=
|
|
2133
|
+
format += removeOperationRecords(operations, path, revisionKey);
|
|
1820
2134
|
if (operations.size === 0) descriptors.delete(descriptor);
|
|
1821
2135
|
}
|
|
1822
2136
|
if (descriptors.size === 0) this.formatOperations.delete(source);
|
|
@@ -1847,12 +2161,12 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1847
2161
|
throw new TypeError("Resource constructor must create a CjsResource-compatible object.");
|
|
1848
2162
|
}
|
|
1849
2163
|
if (disallowedAlias && resource === disallowedAlias) {
|
|
1850
|
-
throw
|
|
2164
|
+
throw reloadCandidateAliasError(path, resource);
|
|
1851
2165
|
}
|
|
1852
|
-
resource.Initialize(path, ext,
|
|
2166
|
+
resource.Initialize(path, ext, normalizeRequirement(options.requirement || options.payload || ""));
|
|
1853
2167
|
if (typeof resource.SetObjectLoader === "function") {
|
|
1854
|
-
const loaderOptions =
|
|
1855
|
-
resource.SetObjectLoader(loadOptions => this.GetObject(path,
|
|
2168
|
+
const loaderOptions = getResourceLoaderOptions(options, options.source || this.source);
|
|
2169
|
+
resource.SetObjectLoader(loadOptions => this.GetObject(path, mergeResourceLoaderOptions(loaderOptions, loadOptions)), loaderOptions);
|
|
1856
2170
|
}
|
|
1857
2171
|
return resource;
|
|
1858
2172
|
}
|
|
@@ -1866,9 +2180,9 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1866
2180
|
* @returns {Function} Registered resource constructor or `CjsResource`.
|
|
1867
2181
|
*/
|
|
1868
2182
|
ResolveResourceConstructor(options = {}) {
|
|
1869
|
-
const requested =
|
|
2183
|
+
const requested = normalizeRequirement(options.requirement || options.payload);
|
|
1870
2184
|
if (requested && this.resourceTypes.has(requested)) return this.resourceTypes.get(requested);
|
|
1871
|
-
const emitted =
|
|
2185
|
+
const emitted = normalizeRequirement(options.emit);
|
|
1872
2186
|
if (emitted && this.resourceTypes.has(emitted)) return this.resourceTypes.get(emitted);
|
|
1873
2187
|
return _CjsResource;
|
|
1874
2188
|
}
|
|
@@ -1889,13 +2203,13 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1889
2203
|
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
1890
2204
|
throw new TypeError("CjsResMan resource variant options must be an object.");
|
|
1891
2205
|
}
|
|
1892
|
-
if (
|
|
2206
|
+
if (hasOwn(options, "variant") && options.variant !== undefined) {
|
|
1893
2207
|
if (typeof options.variant !== "string" || options.variant.trim() === "") {
|
|
1894
2208
|
throw new TypeError("CjsResMan explicit resource variant must be a non-empty string.");
|
|
1895
2209
|
}
|
|
1896
|
-
return
|
|
2210
|
+
return normalizeResourceVariant(options.variant);
|
|
1897
2211
|
}
|
|
1898
|
-
return
|
|
2212
|
+
return normalizeResourceVariant(options.emit ?? options.requirement ?? options.payload ?? "");
|
|
1899
2213
|
}
|
|
1900
2214
|
|
|
1901
2215
|
/**
|
|
@@ -1931,7 +2245,7 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1931
2245
|
#BeginResourceOperation(queued) {
|
|
1932
2246
|
this.#activeResourceOperations += 1;
|
|
1933
2247
|
const id = queued ? this.#nextResourceOperationId++ : 0;
|
|
1934
|
-
let resolveDone =
|
|
2248
|
+
let resolveDone = noop;
|
|
1935
2249
|
const done = queued ? new Promise(resolve => {
|
|
1936
2250
|
resolveDone = resolve;
|
|
1937
2251
|
}) : null;
|
|
@@ -1976,7 +2290,7 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
1976
2290
|
#RequireResourceOwnership(resource, phase) {
|
|
1977
2291
|
const ownership = this.#GetResourceOwnership(resource, phase);
|
|
1978
2292
|
if (ownership) return ownership;
|
|
1979
|
-
throw
|
|
2293
|
+
throw resourceNotOwnedError(resource, phase);
|
|
1980
2294
|
}
|
|
1981
2295
|
|
|
1982
2296
|
/**
|
|
@@ -2005,7 +2319,7 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
2005
2319
|
*/
|
|
2006
2320
|
#AssertResourceOwnership(ownership, phase) {
|
|
2007
2321
|
if (!this.#IsResourceOwnershipCurrent(ownership)) {
|
|
2008
|
-
throw
|
|
2322
|
+
throw staleResourceOperationError(ownership, phase);
|
|
2009
2323
|
}
|
|
2010
2324
|
}
|
|
2011
2325
|
|
|
@@ -2052,7 +2366,7 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
2052
2366
|
*/
|
|
2053
2367
|
#AssertReloadCandidate(candidate, phase) {
|
|
2054
2368
|
if (!this.#IsReloadCandidateCurrent(candidate)) {
|
|
2055
|
-
throw
|
|
2369
|
+
throw staleReloadCandidateError(candidate, phase);
|
|
2056
2370
|
}
|
|
2057
2371
|
}
|
|
2058
2372
|
|
|
@@ -2099,7 +2413,7 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
2099
2413
|
key
|
|
2100
2414
|
} = ownership;
|
|
2101
2415
|
if (typeof owner?.Lock !== "function" || typeof owner?.Unlock !== "function") {
|
|
2102
|
-
return
|
|
2416
|
+
return noop;
|
|
2103
2417
|
}
|
|
2104
2418
|
this.#AssertResourceOwnership(ownership, "lock:acquire");
|
|
2105
2419
|
owner.Lock(key);
|
|
@@ -2120,6 +2434,67 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
2120
2434
|
* @param {object|Function} resource Canonical resource handle.
|
|
2121
2435
|
* @returns {object|Function} The supplied resource.
|
|
2122
2436
|
*/
|
|
2437
|
+
/**
|
|
2438
|
+
* Reload a purged handle back into itself.
|
|
2439
|
+
*
|
|
2440
|
+
* Purge deletes the payload and drops the registry entry, so a consumer left
|
|
2441
|
+
* holding the handle has no way to reach a replacement - it cannot discover
|
|
2442
|
+
* one, and nothing hands it over. Recovery therefore has to fill THIS handle
|
|
2443
|
+
* rather than resolve whatever the manager currently caches for the path.
|
|
2444
|
+
*
|
|
2445
|
+
* The handle is re-registered BEFORE loading, so the ordinary load path finds
|
|
2446
|
+
* it as the canonical identity and loads into it instead of minting another.
|
|
2447
|
+
*
|
|
2448
|
+
* Declines rather than guesses in two cases: when another resource has since
|
|
2449
|
+
* claimed the identity - displacing it would kill whoever holds that one, the
|
|
2450
|
+
* very failure being fixed here - and when the retained request no longer
|
|
2451
|
+
* resolves to the same identity, which would re-register the handle under the
|
|
2452
|
+
* wrong key.
|
|
2453
|
+
*
|
|
2454
|
+
* @param {string} key Canonical resolved identity key.
|
|
2455
|
+
* @param {CjsResource} resource The purged handle to restore.
|
|
2456
|
+
* @returns {boolean} Whether a reload was started.
|
|
2457
|
+
*/
|
|
2458
|
+
#ReloadPurgedResource(key, resource) {
|
|
2459
|
+
if (!resource?.IsPurged?.()) return false;
|
|
2460
|
+
try {
|
|
2461
|
+
const current = this.motherLode.Lookup(key);
|
|
2462
|
+
if (current && current !== resource) return false;
|
|
2463
|
+
const request = resource.GetObjectRequest?.() || {};
|
|
2464
|
+
const path = normalizeResourcePath(resource.GetPath());
|
|
2465
|
+
if (getMotherLodeKey(path, this.GetResourceVariant(request)) !== key) return false;
|
|
2466
|
+
|
|
2467
|
+
// Leave PURGED first: ownership is not considered current while purged,
|
|
2468
|
+
// so binding before this would produce a controller that no-ops.
|
|
2469
|
+
resource.MarkRequested();
|
|
2470
|
+
if (!current) this.motherLode.Insert(key, resource, {
|
|
2471
|
+
replace: true
|
|
2472
|
+
});
|
|
2473
|
+
this.#invalidResourceOwnership.delete(resource);
|
|
2474
|
+
this.#BindResourceLifecycle(key, resource);
|
|
2475
|
+
|
|
2476
|
+
// Failure is recorded on the resource and observed through `completed`.
|
|
2477
|
+
this.GetObject(path, request).catch(() => {});
|
|
2478
|
+
return true;
|
|
2479
|
+
} catch {
|
|
2480
|
+
return false;
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
|
|
2484
|
+
/**
|
|
2485
|
+
* Give one resource the liveness callbacks its consumers never manage
|
|
2486
|
+
* themselves: activity renewal, payload renewal, lock counting, and the
|
|
2487
|
+
* reload hook that revives the handle after a purge.
|
|
2488
|
+
*
|
|
2489
|
+
* Ownership is captured by generation, so a late release can never renew or
|
|
2490
|
+
* unlock a rebound owner. The reload hook is bound outside the lifecycle
|
|
2491
|
+
* controller because that controller is detached exactly when canonical
|
|
2492
|
+
* ownership ends, which is precisely when a purged handle needs to come back.
|
|
2493
|
+
*
|
|
2494
|
+
* @param {string} key Canonical resolved key.
|
|
2495
|
+
* @param {object} resource Resource handle to bind.
|
|
2496
|
+
* @returns {object} The same resource handle.
|
|
2497
|
+
*/
|
|
2123
2498
|
#BindResourceLifecycle(key, resource) {
|
|
2124
2499
|
const owner = this.motherLode;
|
|
2125
2500
|
let ownership = this.#resourceOwnership.get(resource) || null;
|
|
@@ -2133,6 +2508,10 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
2133
2508
|
this.#resourceOwnership.set(resource, ownership);
|
|
2134
2509
|
this.#invalidResourceOwnership.delete(resource);
|
|
2135
2510
|
}
|
|
2511
|
+
|
|
2512
|
+
// Bound outside the lifecycle controller, which is detached when canonical
|
|
2513
|
+
// ownership ends - which is precisely when a handle needs to come back.
|
|
2514
|
+
resource?.SetReloadHook?.(() => this.#ReloadPurgedResource(key, resource));
|
|
2136
2515
|
if (typeof resource?.SetLifecycleController !== "function") return resource;
|
|
2137
2516
|
resource.SetLifecycleController(Object.freeze({
|
|
2138
2517
|
isCurrent: () => this.#IsResourceOwnershipCurrent(ownership),
|
|
@@ -2189,10 +2568,10 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
2189
2568
|
*/
|
|
2190
2569
|
ReadFormatOnce(resource, descriptor, bytes, options = {}) {
|
|
2191
2570
|
const read = this.#BeginReadOperation(resource.GetPath(), options);
|
|
2192
|
-
const cachePolicy =
|
|
2193
|
-
const key =
|
|
2571
|
+
const cachePolicy = normalizeCachePolicy(read.options.cacheFormat, "cacheFormat");
|
|
2572
|
+
const key = getFormatOperationKey(read.context, read.options);
|
|
2194
2573
|
const cacheableOptions = key !== null && cachePolicy !== false;
|
|
2195
|
-
const descriptorOperations = cacheableOptions ?
|
|
2574
|
+
const descriptorOperations = cacheableOptions ? getFormatDescriptorOperations(this.formatOperations, read.context.source, descriptor, true) : null;
|
|
2196
2575
|
const bypassExisting = read.options.reload === true || !cacheableOptions;
|
|
2197
2576
|
const existing = bypassExisting ? null : descriptorOperations.get(key);
|
|
2198
2577
|
if (existing) {
|
|
@@ -2232,11 +2611,11 @@ class CjsResMan extends CjsEventEmitter {
|
|
|
2232
2611
|
* @returns {Readonly<object>} Deeply frozen plain defaults snapshot.
|
|
2233
2612
|
* @throws {TypeError} If defaults contain unsupported objects, accessors, symbols, or byte buffers.
|
|
2234
2613
|
*/
|
|
2235
|
-
function
|
|
2614
|
+
function snapshotFormatDefaults(defaults, seen = new WeakMap()) {
|
|
2236
2615
|
if (!defaults || typeof defaults !== "object" || Array.isArray(defaults)) {
|
|
2237
2616
|
throw new TypeError("CjsResMan format defaults must be a plain object.");
|
|
2238
2617
|
}
|
|
2239
|
-
return
|
|
2618
|
+
return snapshotFormatDefaultValue(defaults, seen, "defaults");
|
|
2240
2619
|
}
|
|
2241
2620
|
|
|
2242
2621
|
/**
|
|
@@ -2248,7 +2627,7 @@ function SnapshotFormatDefaults(defaults, seen = new WeakMap()) {
|
|
|
2248
2627
|
* @returns {*} Frozen snapshot value or stable primitive/function leaf.
|
|
2249
2628
|
* @throws {TypeError} If the value cannot be made structurally immutable.
|
|
2250
2629
|
*/
|
|
2251
|
-
function
|
|
2630
|
+
function snapshotFormatDefaultValue(value, seen, path) {
|
|
2252
2631
|
if (value === null || value === undefined) return value;
|
|
2253
2632
|
const type = typeof value;
|
|
2254
2633
|
if (["string", "number", "boolean", "bigint"].includes(type)) return value;
|
|
@@ -2262,10 +2641,10 @@ function SnapshotFormatDefaultValue(value, seen, path) {
|
|
|
2262
2641
|
const snapshot = [];
|
|
2263
2642
|
seen.set(value, snapshot);
|
|
2264
2643
|
for (let index = 0; index < value.length; index += 1) {
|
|
2265
|
-
if (!
|
|
2644
|
+
if (!hasOwn(value, index)) {
|
|
2266
2645
|
throw new TypeError(`CjsResMan format ${path} must not contain sparse arrays.`);
|
|
2267
2646
|
}
|
|
2268
|
-
snapshot.push(
|
|
2647
|
+
snapshot.push(snapshotFormatDefaultValue(value[index], seen, `${path}[${index}]`));
|
|
2269
2648
|
}
|
|
2270
2649
|
return Object.freeze(snapshot);
|
|
2271
2650
|
}
|
|
@@ -2283,7 +2662,7 @@ function SnapshotFormatDefaultValue(value, seen, path) {
|
|
|
2283
2662
|
if (!descriptor.enumerable || !("value" in descriptor)) {
|
|
2284
2663
|
throw new TypeError(`CjsResMan format ${path}.${key} must be an enumerable data property.`);
|
|
2285
2664
|
}
|
|
2286
|
-
snapshot[key] =
|
|
2665
|
+
snapshot[key] = snapshotFormatDefaultValue(descriptor.value, seen, `${path}.${key}`);
|
|
2287
2666
|
}
|
|
2288
2667
|
return Object.freeze(snapshot);
|
|
2289
2668
|
}
|
|
@@ -2297,7 +2676,7 @@ function SnapshotFormatDefaultValue(value, seen, path) {
|
|
|
2297
2676
|
* @returns {string} Type-stable internal revision key.
|
|
2298
2677
|
* @throws {TypeError} If the token is neither a string nor finite number.
|
|
2299
2678
|
*/
|
|
2300
|
-
function
|
|
2679
|
+
function normalizeSourceRevision(value) {
|
|
2301
2680
|
if (value === undefined) return "undefined";
|
|
2302
2681
|
if (typeof value === "string") return `string:${value}`;
|
|
2303
2682
|
if (typeof value === "number" && Number.isFinite(value)) {
|
|
@@ -2314,7 +2693,7 @@ function NormalizeSourceRevision(value) {
|
|
|
2314
2693
|
* @returns {boolean|undefined} The validated policy.
|
|
2315
2694
|
* @throws {TypeError} If the value is not boolean or omitted.
|
|
2316
2695
|
*/
|
|
2317
|
-
function
|
|
2696
|
+
function normalizeCachePolicy(value, name) {
|
|
2318
2697
|
if (value !== undefined && typeof value !== "boolean") {
|
|
2319
2698
|
throw new TypeError(`CjsResMan ${name} must be a boolean when supplied.`);
|
|
2320
2699
|
}
|
|
@@ -2329,7 +2708,7 @@ function NormalizeCachePolicy(value, name) {
|
|
|
2329
2708
|
* @param {boolean} create Whether a missing map should be allocated.
|
|
2330
2709
|
* @returns {Map<string, CjsResourceReadOperationRecord>|null} Owner map or `null`.
|
|
2331
2710
|
*/
|
|
2332
|
-
function
|
|
2711
|
+
function getOwnerOperations(ledger, owner, create) {
|
|
2333
2712
|
let operations = ledger.get(owner);
|
|
2334
2713
|
if (!operations && create) {
|
|
2335
2714
|
operations = new Map();
|
|
@@ -2344,7 +2723,7 @@ function GetOwnerOperations(ledger, owner, create) {
|
|
|
2344
2723
|
* @param {Readonly<CjsResourceReadContext>} context Normalized provenance.
|
|
2345
2724
|
* @returns {string} Internal read-operation key.
|
|
2346
2725
|
*/
|
|
2347
|
-
function
|
|
2726
|
+
function getReadOperationKey(context) {
|
|
2348
2727
|
return `${context.path}\u0000${context.revisionKey}`;
|
|
2349
2728
|
}
|
|
2350
2729
|
|
|
@@ -2358,7 +2737,7 @@ function GetReadOperationKey(context) {
|
|
|
2358
2737
|
* @param {boolean} create Whether missing maps should be allocated.
|
|
2359
2738
|
* @returns {Map<string, CjsResourceReadOperationRecord>|null} Descriptor map or `null`.
|
|
2360
2739
|
*/
|
|
2361
|
-
function
|
|
2740
|
+
function getFormatDescriptorOperations(ledger, source, descriptor, create) {
|
|
2362
2741
|
let descriptors = ledger.get(source);
|
|
2363
2742
|
if (!descriptors && create) {
|
|
2364
2743
|
descriptors = new Map();
|
|
@@ -2383,10 +2762,10 @@ function GetFormatDescriptorOperations(ledger, source, descriptor, create) {
|
|
|
2383
2762
|
* @param {object} options Format request options.
|
|
2384
2763
|
* @returns {string|null} Internal format-operation key, or `null` to bypass caching.
|
|
2385
2764
|
*/
|
|
2386
|
-
function
|
|
2765
|
+
function getFormatOperationKey(context, options) {
|
|
2387
2766
|
const material = [options.emit, options.mediaType, options.classes, options.formatOptions];
|
|
2388
|
-
if (!material.every(value =>
|
|
2389
|
-
return `${
|
|
2767
|
+
if (!material.every(value => isCanonicalFormatCacheValue(value))) return null;
|
|
2768
|
+
return `${getReadOperationKey(context)}\u0000${material.map(value => serializeFormatCacheValue(value)).join("\u0001")}`;
|
|
2390
2769
|
}
|
|
2391
2770
|
|
|
2392
2771
|
/**
|
|
@@ -2399,7 +2778,7 @@ function GetFormatOperationKey(context, options) {
|
|
|
2399
2778
|
* @param {WeakSet<object|Function>} [seen=new WeakSet()] Cycle guard.
|
|
2400
2779
|
* @returns {boolean} Whether deterministic cache serialization is supported.
|
|
2401
2780
|
*/
|
|
2402
|
-
function
|
|
2781
|
+
function isCanonicalFormatCacheValue(value, seen = new WeakSet()) {
|
|
2403
2782
|
if (value === null || value === undefined) return true;
|
|
2404
2783
|
if (["string", "number", "boolean", "bigint"].includes(typeof value)) return true;
|
|
2405
2784
|
if (typeof value === "function") return true;
|
|
@@ -2408,14 +2787,14 @@ function IsCanonicalFormatCacheValue(value, seen = new WeakSet()) {
|
|
|
2408
2787
|
if (seen.has(value)) return true;
|
|
2409
2788
|
seen.add(value);
|
|
2410
2789
|
if (Array.isArray(value)) {
|
|
2411
|
-
return value.every(entry =>
|
|
2790
|
+
return value.every(entry => isCanonicalFormatCacheValue(entry, seen));
|
|
2412
2791
|
}
|
|
2413
2792
|
const prototype = Object.getPrototypeOf(value);
|
|
2414
2793
|
if (prototype !== Object.prototype && prototype !== null) return false;
|
|
2415
2794
|
if (Object.getOwnPropertySymbols(value).length > 0) return false;
|
|
2416
2795
|
return Object.getOwnPropertyNames(value).every(key => {
|
|
2417
2796
|
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
2418
|
-
return descriptor.enumerable && "value" in descriptor &&
|
|
2797
|
+
return descriptor.enumerable && "value" in descriptor && isCanonicalFormatCacheValue(descriptor.value, seen);
|
|
2419
2798
|
});
|
|
2420
2799
|
}
|
|
2421
2800
|
|
|
@@ -2429,7 +2808,7 @@ function IsCanonicalFormatCacheValue(value, seen = new WeakSet()) {
|
|
|
2429
2808
|
* @param {WeakSet<object|Function>} [seen=new WeakSet()] Cycle guard.
|
|
2430
2809
|
* @returns {string} Deterministic cache-local representation.
|
|
2431
2810
|
*/
|
|
2432
|
-
function
|
|
2811
|
+
function serializeFormatCacheValue(value, seen = new WeakSet()) {
|
|
2433
2812
|
if (value === undefined) return "undefined";
|
|
2434
2813
|
if (value === null) return "null";
|
|
2435
2814
|
if (typeof value === "string") return `string:${JSON.stringify(value)}`;
|
|
@@ -2440,8 +2819,8 @@ function SerializeFormatCacheValue(value, seen = new WeakSet()) {
|
|
|
2440
2819
|
}
|
|
2441
2820
|
if (typeof value === "boolean") return `boolean:${value}`;
|
|
2442
2821
|
if (typeof value === "bigint") return `bigint:${value}`;
|
|
2443
|
-
if (typeof value === "function") return `function:${
|
|
2444
|
-
const identity =
|
|
2822
|
+
if (typeof value === "function") return `function:${getLocalValueIdentity(value)}`;
|
|
2823
|
+
const identity = getLocalValueIdentity(value);
|
|
2445
2824
|
if (seen.has(value)) return `reference:${identity}`;
|
|
2446
2825
|
seen.add(value);
|
|
2447
2826
|
if (ArrayBuffer.isView(value)) {
|
|
@@ -2452,9 +2831,9 @@ function SerializeFormatCacheValue(value, seen = new WeakSet()) {
|
|
|
2452
2831
|
return `buffer:${identity}:${[...new Uint8Array(value)].join(",")}`;
|
|
2453
2832
|
}
|
|
2454
2833
|
if (Array.isArray(value)) {
|
|
2455
|
-
return `array:${identity}:[${value.map(entry =>
|
|
2834
|
+
return `array:${identity}:[${value.map(entry => serializeFormatCacheValue(entry, seen)).join(",")}]`;
|
|
2456
2835
|
}
|
|
2457
|
-
return `object:${identity}:{${Object.keys(value).sort().map(key => `${JSON.stringify(key)}:${
|
|
2836
|
+
return `object:${identity}:{${Object.keys(value).sort().map(key => `${JSON.stringify(key)}:${serializeFormatCacheValue(value[key], seen)}`).join(",")}}`;
|
|
2458
2837
|
}
|
|
2459
2838
|
|
|
2460
2839
|
/**
|
|
@@ -2463,7 +2842,7 @@ function SerializeFormatCacheValue(value, seen = new WeakSet()) {
|
|
|
2463
2842
|
* @param {object|Function} value Candidate option identity owner.
|
|
2464
2843
|
* @returns {number} Stable identity for the life of the value.
|
|
2465
2844
|
*/
|
|
2466
|
-
function
|
|
2845
|
+
function getLocalValueIdentity(value) {
|
|
2467
2846
|
let identity = LOCAL_VALUE_IDENTITIES.get(value);
|
|
2468
2847
|
if (!identity) {
|
|
2469
2848
|
identity = nextLocalValueIdentity++;
|
|
@@ -2481,7 +2860,7 @@ function GetLocalValueIdentity(value) {
|
|
|
2481
2860
|
* @param {string|null} revisionKey Exact revision or `null` for all revisions.
|
|
2482
2861
|
* @returns {number} Number of detached records.
|
|
2483
2862
|
*/
|
|
2484
|
-
function
|
|
2863
|
+
function removeOperationRecords(operations, path, revisionKey) {
|
|
2485
2864
|
if (!operations) return 0;
|
|
2486
2865
|
let removed = 0;
|
|
2487
2866
|
for (const [key, record] of operations) {
|
|
@@ -2500,7 +2879,7 @@ function RemoveOperationRecords(operations, path, revisionKey) {
|
|
|
2500
2879
|
* @param {object} [options={}] Original resource request.
|
|
2501
2880
|
* @returns {object} Shallow reconstruction request without cache/reload policy.
|
|
2502
2881
|
*/
|
|
2503
|
-
function
|
|
2882
|
+
function getResourceRequestOptions(options = {}) {
|
|
2504
2883
|
const request = {};
|
|
2505
2884
|
for (const key of RESOURCE_REQUEST_OPTION_KEYS) {
|
|
2506
2885
|
if (options[key] !== undefined) request[key] = options[key];
|
|
@@ -2518,11 +2897,11 @@ function GetResourceRequestOptions(options = {}) {
|
|
|
2518
2897
|
* @param {object|Function|null} [effectiveSource=null] Source selected when the resource was created.
|
|
2519
2898
|
* @returns {object} Detached loader options safe to retain with the resource.
|
|
2520
2899
|
*/
|
|
2521
|
-
function
|
|
2522
|
-
const loaderOptions =
|
|
2900
|
+
function getResourceLoaderOptions(options = {}, effectiveSource = null) {
|
|
2901
|
+
const loaderOptions = getResourceRequestOptions(options);
|
|
2523
2902
|
if (effectiveSource) loaderOptions.source = effectiveSource;
|
|
2524
2903
|
for (const key of ["sourceRevision", "ext"]) {
|
|
2525
|
-
if (
|
|
2904
|
+
if (hasOwn(options, key)) {
|
|
2526
2905
|
loaderOptions[key] = options[key];
|
|
2527
2906
|
}
|
|
2528
2907
|
}
|
|
@@ -2541,15 +2920,15 @@ function GetResourceLoaderOptions(options = {}, effectiveSource = null) {
|
|
|
2541
2920
|
* @param {object} [overrides={}] Per-call operation controls.
|
|
2542
2921
|
* @returns {object} Merged request with stable promised-output fields.
|
|
2543
2922
|
*/
|
|
2544
|
-
function
|
|
2923
|
+
function mergeResourceLoaderOptions(base, overrides = {}) {
|
|
2545
2924
|
const result = {
|
|
2546
2925
|
...base,
|
|
2547
2926
|
...overrides
|
|
2548
2927
|
};
|
|
2549
|
-
const pinsOutput = RESOURCE_OUTPUT_OPTION_KEYS.some(key =>
|
|
2928
|
+
const pinsOutput = RESOURCE_OUTPUT_OPTION_KEYS.some(key => hasOwn(base, key) && base[key] !== undefined);
|
|
2550
2929
|
if (pinsOutput) {
|
|
2551
2930
|
for (const key of RESOURCE_OUTPUT_OPTION_KEYS) {
|
|
2552
|
-
if (
|
|
2931
|
+
if (hasOwn(base, key) && base[key] !== undefined) {
|
|
2553
2932
|
result[key] = base[key];
|
|
2554
2933
|
} else {
|
|
2555
2934
|
delete result[key];
|
|
@@ -2557,7 +2936,7 @@ function MergeResourceLoaderOptions(base, overrides = {}) {
|
|
|
2557
2936
|
}
|
|
2558
2937
|
}
|
|
2559
2938
|
for (const key of RESOURCE_PROVENANCE_OPTION_KEYS) {
|
|
2560
|
-
if (
|
|
2939
|
+
if (hasOwn(base, key)) result[key] = base[key];
|
|
2561
2940
|
}
|
|
2562
2941
|
return result;
|
|
2563
2942
|
}
|
|
@@ -2570,7 +2949,7 @@ function MergeResourceLoaderOptions(base, overrides = {}) {
|
|
|
2570
2949
|
* @param {object} options Format, output, and media selection.
|
|
2571
2950
|
* @returns {object[]} Matching descriptors in registration order.
|
|
2572
2951
|
*/
|
|
2573
|
-
function
|
|
2952
|
+
function filterFormatDescriptors(descriptors, options) {
|
|
2574
2953
|
let candidates = [...descriptors];
|
|
2575
2954
|
if (options.format) {
|
|
2576
2955
|
candidates = candidates.filter(({
|
|
@@ -2580,7 +2959,7 @@ function FilterFormatDescriptors(descriptors, options) {
|
|
|
2580
2959
|
if (options.emit !== undefined) {
|
|
2581
2960
|
candidates = candidates.filter(({
|
|
2582
2961
|
Format
|
|
2583
|
-
}) =>
|
|
2962
|
+
}) => findDeclaredOutput(getFormatOutputs(Format), options.emit) !== null);
|
|
2584
2963
|
}
|
|
2585
2964
|
if (options.mediaType) {
|
|
2586
2965
|
candidates = candidates.filter(({
|
|
@@ -2596,7 +2975,7 @@ function FilterFormatDescriptors(descriptors, options) {
|
|
|
2596
2975
|
* @param {Function} Format Registered format facade.
|
|
2597
2976
|
* @returns {Array<*>} Declared output values in selection order.
|
|
2598
2977
|
*/
|
|
2599
|
-
function
|
|
2978
|
+
function getFormatOutputs(Format) {
|
|
2600
2979
|
return [...(Format.outputTypes || []), ...(Format.debugOutputTypes || [])];
|
|
2601
2980
|
}
|
|
2602
2981
|
|
|
@@ -2609,11 +2988,11 @@ function GetFormatOutputs(Format) {
|
|
|
2609
2988
|
* @param {*} requested Requested output selector.
|
|
2610
2989
|
* @returns {string|null} Canonical declaration, or `null` when unsupported.
|
|
2611
2990
|
*/
|
|
2612
|
-
function
|
|
2613
|
-
const normalized =
|
|
2991
|
+
function findDeclaredOutput(outputs, requested) {
|
|
2992
|
+
const normalized = normalizeResourceVariant(requested);
|
|
2614
2993
|
for (const output of outputs) {
|
|
2615
2994
|
if (typeof output !== "string") continue;
|
|
2616
|
-
if (
|
|
2995
|
+
if (normalizeResourceVariant(output) === normalized) return output;
|
|
2617
2996
|
}
|
|
2618
2997
|
return null;
|
|
2619
2998
|
}
|
|
@@ -2627,7 +3006,7 @@ function FindDeclaredOutput(outputs, requested) {
|
|
|
2627
3006
|
* @param {readonly object[]} descriptors Registered input-format descriptors.
|
|
2628
3007
|
* @returns {Error} Contextual unsupported-output error.
|
|
2629
3008
|
*/
|
|
2630
|
-
function
|
|
3009
|
+
function createFormatOutputMissingError(ext, emit, descriptors) {
|
|
2631
3010
|
const error = new Error(`No format registered for .${ext} emits ${JSON.stringify(emit)}.`);
|
|
2632
3011
|
error.code = "CJS_RESOURCE_FORMAT_OUTPUT_MISSING";
|
|
2633
3012
|
error.ext = ext;
|
|
@@ -2646,7 +3025,7 @@ function CreateFormatOutputMissingError(ext, emit, descriptors) {
|
|
|
2646
3025
|
* @param {*} emit Requested output tag.
|
|
2647
3026
|
* @returns {Error} Contextual unsupported-output error.
|
|
2648
3027
|
*/
|
|
2649
|
-
function
|
|
3028
|
+
function createObjectLoaderOutputMissingError(ext, emit) {
|
|
2650
3029
|
const error = new Error(`Direct loader for .${ext} exposes only its unforced default; it does not emit ${JSON.stringify(emit)}.`);
|
|
2651
3030
|
error.code = "CJS_RESOURCE_FORMAT_OUTPUT_MISSING";
|
|
2652
3031
|
error.ext = ext;
|
|
@@ -2665,7 +3044,7 @@ function CreateObjectLoaderOutputMissingError(ext, emit) {
|
|
|
2665
3044
|
* @returns {object} Selected descriptor.
|
|
2666
3045
|
* @throws {Error} If the candidate set is missing or remains ambiguous.
|
|
2667
3046
|
*/
|
|
2668
|
-
function
|
|
3047
|
+
function resolveFormatDescriptorCandidates(descriptors, ext, options) {
|
|
2669
3048
|
let candidates = [...descriptors];
|
|
2670
3049
|
if (candidates.length > 1 && options.bytes !== undefined) {
|
|
2671
3050
|
const supported = candidates.filter(descriptor => {
|
|
@@ -2700,7 +3079,7 @@ function ResolveFormatDescriptorCandidates(descriptors, ext, options) {
|
|
|
2700
3079
|
}
|
|
2701
3080
|
return candidates[0];
|
|
2702
3081
|
}
|
|
2703
|
-
function
|
|
3082
|
+
function normalizeRequirement(value) {
|
|
2704
3083
|
return value === null || value === undefined ? "" : String(value).trim().toLowerCase();
|
|
2705
3084
|
}
|
|
2706
3085
|
|
|
@@ -2711,7 +3090,7 @@ function NormalizeRequirement(value) {
|
|
|
2711
3090
|
* @returns {string} Trimmed lowercase tag, or an empty string.
|
|
2712
3091
|
* @throws {TypeError} If a non-empty tag is not a string or contains the internal key delimiter.
|
|
2713
3092
|
*/
|
|
2714
|
-
function
|
|
3093
|
+
function normalizeResourceVariant(value) {
|
|
2715
3094
|
if (value === null || value === undefined || value === "") return "";
|
|
2716
3095
|
if (typeof value !== "string") {
|
|
2717
3096
|
throw new TypeError("CjsResMan resource variant must be a string.");
|
|
@@ -2722,7 +3101,7 @@ function NormalizeResourceVariant(value) {
|
|
|
2722
3101
|
}
|
|
2723
3102
|
return normalized;
|
|
2724
3103
|
}
|
|
2725
|
-
function
|
|
3104
|
+
function createPrepareContext(resMan, resource, bytes, options, stage) {
|
|
2726
3105
|
return Object.freeze({
|
|
2727
3106
|
...options,
|
|
2728
3107
|
stage,
|
|
@@ -2742,20 +3121,20 @@ function CreatePrepareContext(resMan, resource, bytes, options, stage) {
|
|
|
2742
3121
|
* @param {CjsResource} resource Resource with an attached CPU payload.
|
|
2743
3122
|
* @returns {*} Resident public object outcome.
|
|
2744
3123
|
*/
|
|
2745
|
-
function
|
|
3124
|
+
function getPublishedResourceObject(resource) {
|
|
2746
3125
|
return resource.constructor !== _CjsResource ? resource : resource.GetPayload();
|
|
2747
3126
|
}
|
|
2748
|
-
function
|
|
3127
|
+
function assertPositiveInteger(value, name) {
|
|
2749
3128
|
if (!Number.isInteger(value) || value < 1) {
|
|
2750
3129
|
throw new TypeError(`CjsResMan ${name} must be a positive integer.`);
|
|
2751
3130
|
}
|
|
2752
3131
|
}
|
|
2753
|
-
function
|
|
3132
|
+
function assertNonNegativeInteger(value, name) {
|
|
2754
3133
|
if (!Number.isInteger(value) || value < 0) {
|
|
2755
3134
|
throw new TypeError(`CjsResMan ${name} must be a non-negative integer.`);
|
|
2756
3135
|
}
|
|
2757
3136
|
}
|
|
2758
|
-
function
|
|
3137
|
+
function assertNonNegativeNumber(value, name) {
|
|
2759
3138
|
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
|
|
2760
3139
|
throw new TypeError(`CjsResMan ${name} must be a non-negative finite number.`);
|
|
2761
3140
|
}
|
|
@@ -2768,7 +3147,7 @@ function AssertNonNegativeNumber(value, name) {
|
|
|
2768
3147
|
* @returns {Readonly<CjsResManAutoPurgePolicy>|null} Frozen normalized policy, or `null` when disabled.
|
|
2769
3148
|
* @throws {TypeError} If fields, limits, cleanup controls, or the cadence clock are invalid.
|
|
2770
3149
|
*/
|
|
2771
|
-
function
|
|
3150
|
+
function normalizeAutoPurgePolicy(policy) {
|
|
2772
3151
|
if (policy === null || policy === undefined || policy === false) return null;
|
|
2773
3152
|
if (!policy || typeof policy !== "object" || Array.isArray(policy)) {
|
|
2774
3153
|
throw new TypeError("CjsResMan autoPurgePolicy must be an object, false, or null.");
|
|
@@ -2779,10 +3158,10 @@ function NormalizeAutoPurgePolicy(policy) {
|
|
|
2779
3158
|
throw new TypeError(`CjsResMan autoPurgePolicy does not support: ${unsupported.join(", ")}.`);
|
|
2780
3159
|
}
|
|
2781
3160
|
const intervalMilliseconds = policy.intervalMilliseconds ?? 1000;
|
|
2782
|
-
|
|
3161
|
+
assertNonNegativeNumber(intervalMilliseconds, "autoPurgePolicy.intervalMilliseconds");
|
|
2783
3162
|
for (const name of ["maxIdleMilliseconds", "payloadMaxIdleMilliseconds"]) {
|
|
2784
3163
|
if (policy[name] !== undefined) {
|
|
2785
|
-
|
|
3164
|
+
assertNonNegativeNumber(policy[name], `autoPurgePolicy.${name}`);
|
|
2786
3165
|
}
|
|
2787
3166
|
}
|
|
2788
3167
|
if (policy.maxIdleMilliseconds === undefined && policy.payloadMaxIdleMilliseconds === undefined) {
|
|
@@ -2808,7 +3187,7 @@ function NormalizeAutoPurgePolicy(policy) {
|
|
|
2808
3187
|
...(policy.cleanup === undefined ? {} : {
|
|
2809
3188
|
cleanup: policy.cleanup
|
|
2810
3189
|
}),
|
|
2811
|
-
now: policy.now ||
|
|
3190
|
+
now: policy.now || defaultAutoPurgeNow
|
|
2812
3191
|
});
|
|
2813
3192
|
}
|
|
2814
3193
|
|
|
@@ -2819,7 +3198,7 @@ function NormalizeAutoPurgePolicy(policy) {
|
|
|
2819
3198
|
* @returns {CjsResManAutoPurgePumpOptions} Validated options.
|
|
2820
3199
|
* @throws {TypeError} If options or an explicit timestamp are invalid.
|
|
2821
3200
|
*/
|
|
2822
|
-
function
|
|
3201
|
+
function normalizeAutoPurgePumpOptions(options) {
|
|
2823
3202
|
if (!options || typeof options !== "object" || Array.isArray(options)) {
|
|
2824
3203
|
throw new TypeError("CjsResMan automatic purge options must be an object.");
|
|
2825
3204
|
}
|
|
@@ -2828,7 +3207,7 @@ function NormalizeAutoPurgePumpOptions(options) {
|
|
|
2828
3207
|
throw new TypeError(`CjsResMan automatic purge options do not support: ${unsupported.join(", ")}.`);
|
|
2829
3208
|
}
|
|
2830
3209
|
if (options.time !== undefined) {
|
|
2831
|
-
|
|
3210
|
+
assertNonNegativeNumber(options.time, "automatic purge time");
|
|
2832
3211
|
}
|
|
2833
3212
|
return options;
|
|
2834
3213
|
}
|
|
@@ -2840,7 +3219,7 @@ function NormalizeAutoPurgePumpOptions(options) {
|
|
|
2840
3219
|
* @param {number} activeOperations Number of queued and direct mutations.
|
|
2841
3220
|
* @returns {Error} Contextual active-operation error.
|
|
2842
3221
|
*/
|
|
2843
|
-
function
|
|
3222
|
+
function activeResourceOperationsError(activeOperations) {
|
|
2844
3223
|
const error = new Error(`CjsResMan cannot replace MotherLode while ${activeOperations} resource operation(s) are active.`);
|
|
2845
3224
|
error.code = "CJS_RESMAN_ACTIVE_RESOURCE_OPERATIONS";
|
|
2846
3225
|
error.activeOperations = activeOperations;
|
|
@@ -2855,8 +3234,8 @@ function ActiveResourceOperationsError(activeOperations) {
|
|
|
2855
3234
|
* @param {string} phase Operation phase.
|
|
2856
3235
|
* @returns {Error} Contextual ownership error.
|
|
2857
3236
|
*/
|
|
2858
|
-
function
|
|
2859
|
-
const path =
|
|
3237
|
+
function resourceNotOwnedError(resource, phase) {
|
|
3238
|
+
const path = getResourceDiagnosticPath(resource);
|
|
2860
3239
|
const error = new Error(`CjsResMan does not own a canonical resource at ${path}.`);
|
|
2861
3240
|
error.code = "CJS_RESMAN_RESOURCE_NOT_OWNED";
|
|
2862
3241
|
error.resource = resource;
|
|
@@ -2873,8 +3252,8 @@ function ResourceNotOwnedError(resource, phase) {
|
|
|
2873
3252
|
* @param {string} phase Operation phase that detected staleness.
|
|
2874
3253
|
* @returns {Error} Contextual stale-operation error.
|
|
2875
3254
|
*/
|
|
2876
|
-
function
|
|
2877
|
-
const path =
|
|
3255
|
+
function staleResourceOperationError(ownership, phase) {
|
|
3256
|
+
const path = getResourceDiagnosticPath(ownership?.resource);
|
|
2878
3257
|
const error = new Error(`CjsResMan resource operation became stale during ${phase}: ${path}.`);
|
|
2879
3258
|
error.code = "CJS_RESMAN_STALE_RESOURCE_OPERATION";
|
|
2880
3259
|
error.resource = ownership?.resource || null;
|
|
@@ -2893,7 +3272,7 @@ function StaleResourceOperationError(ownership, phase) {
|
|
|
2893
3272
|
* @param {object|Function} resource Aliased canonical resource.
|
|
2894
3273
|
* @returns {Error} Stable candidate-alias error.
|
|
2895
3274
|
*/
|
|
2896
|
-
function
|
|
3275
|
+
function reloadCandidateAliasError(path, resource) {
|
|
2897
3276
|
const error = new Error(`CjsResMan reload candidate aliases the canonical resource: ${path}.`);
|
|
2898
3277
|
error.code = "CJS_RESMAN_RELOAD_CANDIDATE_ALIAS";
|
|
2899
3278
|
error.path = path;
|
|
@@ -2908,8 +3287,8 @@ function ReloadCandidateAliasError(path, resource) {
|
|
|
2908
3287
|
* @param {object|Function} resource Candidate resource.
|
|
2909
3288
|
* @returns {Error} Stable unavailable-candidate error.
|
|
2910
3289
|
*/
|
|
2911
|
-
function
|
|
2912
|
-
const path =
|
|
3290
|
+
function reloadCandidateUnavailableError(resource) {
|
|
3291
|
+
const path = getResourceDiagnosticPath(resource);
|
|
2913
3292
|
const error = new Error(`CjsResMan reload candidate is no longer available: ${path}.`);
|
|
2914
3293
|
error.code = "CJS_RESMAN_RELOAD_CANDIDATE_UNAVAILABLE";
|
|
2915
3294
|
error.path = path;
|
|
@@ -2925,8 +3304,8 @@ function ReloadCandidateUnavailableError(resource) {
|
|
|
2925
3304
|
* @param {string} phase Operation phase that detected staleness.
|
|
2926
3305
|
* @returns {Error} Contextual stale-candidate error.
|
|
2927
3306
|
*/
|
|
2928
|
-
function
|
|
2929
|
-
const path =
|
|
3307
|
+
function staleReloadCandidateError(candidate, phase) {
|
|
3308
|
+
const path = getResourceDiagnosticPath(candidate?.resource);
|
|
2930
3309
|
const error = new Error(`CjsResMan reload candidate became stale during ${phase}: ${path}.`);
|
|
2931
3310
|
error.code = "CJS_RESMAN_STALE_RELOAD_CANDIDATE";
|
|
2932
3311
|
error.resource = candidate?.resource || null;
|
|
@@ -2945,7 +3324,7 @@ function StaleReloadCandidateError(candidate, phase) {
|
|
|
2945
3324
|
* @param {*} resource Candidate resource.
|
|
2946
3325
|
* @returns {string} Best-effort resource path label.
|
|
2947
3326
|
*/
|
|
2948
|
-
function
|
|
3327
|
+
function getResourceDiagnosticPath(resource) {
|
|
2949
3328
|
try {
|
|
2950
3329
|
return String(resource?.GetPath?.() || resource?.path || "<unknown>");
|
|
2951
3330
|
} catch {
|
|
@@ -2958,23 +3337,133 @@ function GetResourceDiagnosticPath(resource) {
|
|
|
2958
3337
|
*
|
|
2959
3338
|
* @returns {void}
|
|
2960
3339
|
*/
|
|
2961
|
-
function
|
|
3340
|
+
function noop() {}
|
|
3341
|
+
|
|
3342
|
+
/**
|
|
3343
|
+
* Validate a resource execution strategy.
|
|
3344
|
+
*
|
|
3345
|
+
* @param {*} loader Candidate loader.
|
|
3346
|
+
* @param {string} name Configuration field name.
|
|
3347
|
+
* @returns {void}
|
|
3348
|
+
*/
|
|
3349
|
+
function assertResourceLoader(loader, name) {
|
|
3350
|
+
if (!isResourceLoader(loader)) {
|
|
3351
|
+
throw new TypeError(`CjsResMan ${name} must provide Read and ReadFormat.`);
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
3354
|
+
|
|
3355
|
+
/**
|
|
3356
|
+
* Test the structural resource loader contract.
|
|
3357
|
+
*
|
|
3358
|
+
* @param {*} loader Candidate loader.
|
|
3359
|
+
* @returns {boolean}
|
|
3360
|
+
*/
|
|
3361
|
+
function isResourceLoader(loader) {
|
|
3362
|
+
return Boolean(loader && typeof loader.Read === "function" && typeof loader.ReadFormat === "function");
|
|
3363
|
+
}
|
|
3364
|
+
|
|
3365
|
+
/**
|
|
3366
|
+
* Merge frozen registration defaults with one request's format overrides.
|
|
3367
|
+
*
|
|
3368
|
+
* @param {object} descriptor Registered format descriptor.
|
|
3369
|
+
* @param {object} options Resource read options.
|
|
3370
|
+
* @returns {object} Effective format reader options.
|
|
3371
|
+
*/
|
|
3372
|
+
function createFormatReadOptions(descriptor, options) {
|
|
3373
|
+
const {
|
|
3374
|
+
Format,
|
|
3375
|
+
defaults
|
|
3376
|
+
} = descriptor;
|
|
3377
|
+
const formatOptions = {
|
|
3378
|
+
...defaults,
|
|
3379
|
+
...(options.formatOptions || {})
|
|
3380
|
+
};
|
|
3381
|
+
if (options.emit !== undefined) {
|
|
3382
|
+
formatOptions.emit = findDeclaredOutput(getFormatOutputs(Format), options.emit) ?? options.emit;
|
|
3383
|
+
}
|
|
3384
|
+
if (options.classes !== undefined) formatOptions.classes = options.classes;
|
|
3385
|
+
return formatOptions;
|
|
3386
|
+
}
|
|
3387
|
+
|
|
3388
|
+
/**
|
|
3389
|
+
* Reports whether a source requires CjsResMan to build a URL before reading.
|
|
3390
|
+
*
|
|
3391
|
+
* @param {*} source Selected source/provider.
|
|
3392
|
+
* @returns {boolean}
|
|
3393
|
+
*/
|
|
3394
|
+
function sourceRequiresUrl(source) {
|
|
3395
|
+
return source?.requiresUrl === true || source?.constructor?.requiresUrl === true;
|
|
3396
|
+
}
|
|
3397
|
+
|
|
3398
|
+
/**
|
|
3399
|
+
* Tests whether an object owns one property.
|
|
3400
|
+
*
|
|
3401
|
+
* @param {*} object Candidate object.
|
|
3402
|
+
* @param {string|number|symbol} property Property key.
|
|
3403
|
+
* @returns {boolean}
|
|
3404
|
+
*/
|
|
3405
|
+
function hasOwn(object, property) {
|
|
3406
|
+
return Object.prototype.hasOwnProperty.call(object, property);
|
|
3407
|
+
}
|
|
3408
|
+
|
|
3409
|
+
/**
|
|
3410
|
+
* Normalizes one resource-path scheme key.
|
|
3411
|
+
*
|
|
3412
|
+
* @param {*} value Candidate scheme.
|
|
3413
|
+
* @returns {string}
|
|
3414
|
+
*/
|
|
3415
|
+
function normalizePathPrefix(value) {
|
|
3416
|
+
const prefix = String(value ?? "").trim().replace(/:\/?$/u, "").toLowerCase();
|
|
3417
|
+
if (!/^[a-z][a-z0-9+.-]*$/u.test(prefix)) {
|
|
3418
|
+
throw new TypeError("CjsResMan path prefixes must be URI scheme names.");
|
|
3419
|
+
}
|
|
3420
|
+
return prefix;
|
|
3421
|
+
}
|
|
3422
|
+
|
|
3423
|
+
/**
|
|
3424
|
+
* Normalizes one registered URL base without altering case-sensitive path
|
|
3425
|
+
* content.
|
|
3426
|
+
*
|
|
3427
|
+
* @param {*} value Candidate URL base.
|
|
3428
|
+
* @returns {string}
|
|
3429
|
+
*/
|
|
3430
|
+
function normalizeUrlBase(value) {
|
|
3431
|
+
const url = normalizePath(value);
|
|
3432
|
+
if (!url || url.includes("\0")) {
|
|
3433
|
+
throw new TypeError("CjsResMan path URL bases must be non-empty strings.");
|
|
3434
|
+
}
|
|
3435
|
+
return url.endsWith("/") ? url : `${url}/`;
|
|
3436
|
+
}
|
|
3437
|
+
|
|
3438
|
+
/**
|
|
3439
|
+
* Validates a URL returned by an injected path resolver.
|
|
3440
|
+
*
|
|
3441
|
+
* @param {*} value Resolver output.
|
|
3442
|
+
* @returns {string}
|
|
3443
|
+
*/
|
|
3444
|
+
function normalizeResolvedUrl(value) {
|
|
3445
|
+
const url = normalizePath(value);
|
|
3446
|
+
if (!url || url.includes("\0")) {
|
|
3447
|
+
throw new TypeError("CjsResMan pathResolver must return a non-empty URL string.");
|
|
3448
|
+
}
|
|
3449
|
+
return url;
|
|
3450
|
+
}
|
|
2962
3451
|
|
|
2963
3452
|
/**
|
|
2964
3453
|
* Return the wall-clock timestamp used by default automatic purge cadence.
|
|
2965
3454
|
*
|
|
2966
3455
|
* @returns {number} Milliseconds since the Unix epoch.
|
|
2967
3456
|
*/
|
|
2968
|
-
function
|
|
3457
|
+
function defaultAutoPurgeNow() {
|
|
2969
3458
|
return Date.now();
|
|
2970
3459
|
}
|
|
2971
|
-
function
|
|
3460
|
+
function defaultQueueScheduler(callback) {
|
|
2972
3461
|
return setTimeout(callback, 0);
|
|
2973
3462
|
}
|
|
2974
|
-
function
|
|
3463
|
+
function defaultQueueYield() {
|
|
2975
3464
|
return new Promise(resolve => setTimeout(resolve, 0));
|
|
2976
3465
|
}
|
|
2977
|
-
function
|
|
3466
|
+
function normalizeRegistrationEntries(value, keyed = false) {
|
|
2978
3467
|
if (value === null || value === undefined) return [];
|
|
2979
3468
|
if (Array.isArray(value)) return value;
|
|
2980
3469
|
if (typeof value === "function") return [value];
|