@carbonenginejs/runtime-resource 0.19.2 → 0.22.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.
Files changed (308) hide show
  1. package/NOTICE +6 -0
  2. package/dist/CjsResMan.js +1374 -1318
  3. package/dist/CjsResMan.js.map +1 -1
  4. package/dist/format/CjsFormat.js +393 -164
  5. package/dist/format/CjsFormat.js.map +1 -1
  6. package/dist/format/CjsFormatStore.js +315 -0
  7. package/dist/format/CjsFormatStore.js.map +1 -0
  8. package/dist/format/CjsResourceProbe.js +66 -234
  9. package/dist/format/CjsResourceProbe.js.map +1 -1
  10. package/dist/format/payloadContract.js +47 -6
  11. package/dist/format/payloadContract.js.map +1 -1
  12. package/dist/formats/black/CjsBlackFormat.js +23 -6
  13. package/dist/formats/black/CjsBlackFormat.js.map +1 -1
  14. package/dist/formats/bnk/CjsBnkFormat.js +122 -120
  15. package/dist/formats/bnk/CjsBnkFormat.js.map +1 -1
  16. package/dist/formats/bnk/core/helpers.js +5 -15
  17. package/dist/formats/bnk/core/helpers.js.map +1 -1
  18. package/dist/formats/cmf/CjsCmfFormat.js +31 -14
  19. package/dist/formats/cmf/CjsCmfFormat.js.map +1 -1
  20. package/dist/formats/dds/CjsDdsFormat.js +29 -19
  21. package/dist/formats/dds/CjsDdsFormat.js.map +1 -1
  22. package/dist/formats/dds/core/helpers.js +4 -5
  23. package/dist/formats/dds/core/helpers.js.map +1 -1
  24. package/dist/formats/dxbc/CjsDxbcFormat.js +15 -13
  25. package/dist/formats/dxbc/CjsDxbcFormat.js.map +1 -1
  26. package/dist/formats/fbx/CjsFbxFormat.js +27 -19
  27. package/dist/formats/fbx/CjsFbxFormat.js.map +1 -1
  28. package/dist/formats/fbx/core/helpers.js +4 -4
  29. package/dist/formats/fbx/core/helpers.js.map +1 -1
  30. package/dist/formats/flac/CjsFlacFormat.js +19 -17
  31. package/dist/formats/flac/CjsFlacFormat.js.map +1 -1
  32. package/dist/formats/flac/core/helpers.js +5 -11
  33. package/dist/formats/flac/core/helpers.js.map +1 -1
  34. package/dist/formats/fsd/32/CjsFsd32Format.js +55 -0
  35. package/dist/formats/fsd/32/CjsFsd32Format.js.map +1 -0
  36. package/dist/formats/fsd/32/index.js +2 -0
  37. package/dist/formats/fsd/32/index.js.map +1 -0
  38. package/dist/formats/fsd/64/CjsFsd64Format.js +119 -0
  39. package/dist/formats/fsd/64/CjsFsd64Format.js.map +1 -0
  40. package/dist/formats/fsd/64/core/CjsFsd64Binary.js +393 -0
  41. package/dist/formats/fsd/64/core/CjsFsd64Binary.js.map +1 -0
  42. package/dist/formats/fsd/64/core/CjsFsd64Reader.js +138 -0
  43. package/dist/formats/fsd/64/core/CjsFsd64Reader.js.map +1 -0
  44. package/dist/formats/fsd/64/core/CjsFsd64SchemaDecoder.js +389 -0
  45. package/dist/formats/fsd/64/core/CjsFsd64SchemaDecoder.js.map +1 -0
  46. package/dist/formats/fsd/64/core/CjsFsd64SchemaReader.js +43 -0
  47. package/dist/formats/fsd/64/core/CjsFsd64SchemaReader.js.map +1 -0
  48. package/dist/formats/fsd/64/core/fsd64Records.js +60 -0
  49. package/dist/formats/fsd/64/core/fsd64Records.js.map +1 -0
  50. package/dist/formats/fsd/64/index.js +7 -0
  51. package/dist/formats/fsd/64/index.js.map +1 -0
  52. package/dist/formats/fsd/64/readers/CjsFsd64ReaderSetCharacterStaticData.js +33 -0
  53. package/dist/formats/fsd/64/readers/CjsFsd64ReaderSetCharacterStaticData.js.map +1 -0
  54. package/dist/formats/fsd/64/readers/CjsFsd64SchemaAgentTypes.js +35 -0
  55. package/dist/formats/fsd/64/readers/CjsFsd64SchemaAgentTypes.js.map +1 -0
  56. package/dist/formats/fsd/64/readers/CjsFsd64SchemaAgentsInSpace.js +50 -0
  57. package/dist/formats/fsd/64/readers/CjsFsd64SchemaAgentsInSpace.js.map +1 -0
  58. package/dist/formats/fsd/64/readers/CjsFsd64SchemaAncestries.js +75 -0
  59. package/dist/formats/fsd/64/readers/CjsFsd64SchemaAncestries.js.map +1 -0
  60. package/dist/formats/fsd/64/readers/CjsFsd64SchemaArchetypes.js +57 -0
  61. package/dist/formats/fsd/64/readers/CjsFsd64SchemaArchetypes.js.map +1 -0
  62. package/dist/formats/fsd/64/readers/CjsFsd64SchemaAudioMetadata.js +201 -0
  63. package/dist/formats/fsd/64/readers/CjsFsd64SchemaAudioMetadata.js.map +1 -0
  64. package/dist/formats/fsd/64/readers/CjsFsd64SchemaBloodlines.js +73 -0
  65. package/dist/formats/fsd/64/readers/CjsFsd64SchemaBloodlines.js.map +1 -0
  66. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCategories.js +53 -0
  67. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCategories.js.map +1 -0
  68. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCharacterAvatarBehaviors.js +44 -0
  69. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCharacterAvatarBehaviors.js.map +1 -0
  70. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCharacterColorLocations.js +38 -0
  71. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCharacterColorLocations.js.map +1 -0
  72. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCharacterColorNames.js +34 -0
  73. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCharacterColorNames.js.map +1 -0
  74. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCharacterModifierLocations.js +34 -0
  75. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCharacterModifierLocations.js.map +1 -0
  76. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCharacterPortraitResources.js +44 -0
  77. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCharacterPortraitResources.js.map +1 -0
  78. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCharacterResources.js +81 -0
  79. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCharacterResources.js.map +1 -0
  80. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCharacterSculptingLocations.js +34 -0
  81. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCharacterSculptingLocations.js.map +1 -0
  82. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCompressibleTypes.js +41 -0
  83. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCompressibleTypes.js.map +1 -0
  84. package/dist/formats/fsd/64/readers/CjsFsd64SchemaContrabandTypes.js +63 -0
  85. package/dist/formats/fsd/64/readers/CjsFsd64SchemaContrabandTypes.js.map +1 -0
  86. package/dist/formats/fsd/64/readers/CjsFsd64SchemaControlTowerResources.js +76 -0
  87. package/dist/formats/fsd/64/readers/CjsFsd64SchemaControlTowerResources.js.map +1 -0
  88. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCorporationActivities.js +38 -0
  89. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCorporationActivities.js.map +1 -0
  90. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCorporationRoleGroups.js +74 -0
  91. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCorporationRoleGroups.js.map +1 -0
  92. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCorporationRoles.js +59 -0
  93. package/dist/formats/fsd/64/readers/CjsFsd64SchemaCorporationRoles.js.map +1 -0
  94. package/dist/formats/fsd/64/readers/CjsFsd64SchemaDogmaAttributeCategories.js +46 -0
  95. package/dist/formats/fsd/64/readers/CjsFsd64SchemaDogmaAttributeCategories.js.map +1 -0
  96. package/dist/formats/fsd/64/readers/CjsFsd64SchemaDogmaAttributes.js +133 -0
  97. package/dist/formats/fsd/64/readers/CjsFsd64SchemaDogmaAttributes.js.map +1 -0
  98. package/dist/formats/fsd/64/readers/CjsFsd64SchemaDogmaEffects.js +236 -0
  99. package/dist/formats/fsd/64/readers/CjsFsd64SchemaDogmaEffects.js.map +1 -0
  100. package/dist/formats/fsd/64/readers/CjsFsd64SchemaDogmaUnits.js +60 -0
  101. package/dist/formats/fsd/64/readers/CjsFsd64SchemaDogmaUnits.js.map +1 -0
  102. package/dist/formats/fsd/64/readers/CjsFsd64SchemaDynamicItemAttributes.js +95 -0
  103. package/dist/formats/fsd/64/readers/CjsFsd64SchemaDynamicItemAttributes.js.map +1 -0
  104. package/dist/formats/fsd/64/readers/CjsFsd64SchemaEpicArcs.js +106 -0
  105. package/dist/formats/fsd/64/readers/CjsFsd64SchemaEpicArcs.js.map +1 -0
  106. package/dist/formats/fsd/64/readers/CjsFsd64SchemaExpertSystems.js +86 -0
  107. package/dist/formats/fsd/64/readers/CjsFsd64SchemaExpertSystems.js.map +1 -0
  108. package/dist/formats/fsd/64/readers/CjsFsd64SchemaFactions.js +117 -0
  109. package/dist/formats/fsd/64/readers/CjsFsd64SchemaFactions.js.map +1 -0
  110. package/dist/formats/fsd/64/readers/CjsFsd64SchemaGraphicIds.js +70 -0
  111. package/dist/formats/fsd/64/readers/CjsFsd64SchemaGraphicIds.js.map +1 -0
  112. package/dist/formats/fsd/64/readers/CjsFsd64SchemaGraphicMaterialSets.js +173 -0
  113. package/dist/formats/fsd/64/readers/CjsFsd64SchemaGraphicMaterialSets.js.map +1 -0
  114. package/dist/formats/fsd/64/readers/CjsFsd64SchemaGroups.js +77 -0
  115. package/dist/formats/fsd/64/readers/CjsFsd64SchemaGroups.js.map +1 -0
  116. package/dist/formats/fsd/64/readers/CjsFsd64SchemaIcons.js +62 -0
  117. package/dist/formats/fsd/64/readers/CjsFsd64SchemaIcons.js.map +1 -0
  118. package/dist/formats/fsd/64/readers/CjsFsd64SchemaMarketGroups.js +63 -0
  119. package/dist/formats/fsd/64/readers/CjsFsd64SchemaMarketGroups.js.map +1 -0
  120. package/dist/formats/fsd/64/readers/CjsFsd64SchemaMetaGroups.js +86 -0
  121. package/dist/formats/fsd/64/readers/CjsFsd64SchemaMetaGroups.js.map +1 -0
  122. package/dist/formats/fsd/64/readers/CjsFsd64SchemaNpcCorporationDivisions.js +72 -0
  123. package/dist/formats/fsd/64/readers/CjsFsd64SchemaNpcCorporationDivisions.js.map +1 -0
  124. package/dist/formats/fsd/64/readers/CjsFsd64SchemaNpcCorporations.js +326 -0
  125. package/dist/formats/fsd/64/readers/CjsFsd64SchemaNpcCorporations.js.map +1 -0
  126. package/dist/formats/fsd/64/readers/CjsFsd64SchemaPaperdolls.js +279 -0
  127. package/dist/formats/fsd/64/readers/CjsFsd64SchemaPaperdolls.js.map +1 -0
  128. package/dist/formats/fsd/64/readers/CjsFsd64SchemaRaces.js +64 -0
  129. package/dist/formats/fsd/64/readers/CjsFsd64SchemaRaces.js.map +1 -0
  130. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSchoolMap.js +40 -0
  131. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSchoolMap.js.map +1 -0
  132. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSchools.js +113 -0
  133. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSchools.js.map +1 -0
  134. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkillPlans.js +130 -0
  135. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkillPlans.js.map +1 -0
  136. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkinrComponentCategories.js +38 -0
  137. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkinrComponentCategories.js.map +1 -0
  138. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkinrComponentPointValues.js +45 -0
  139. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkinrComponentPointValues.js.map +1 -0
  140. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkinrComponentRarities.js +44 -0
  141. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkinrComponentRarities.js.map +1 -0
  142. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkinrComponents.js +163 -0
  143. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkinrComponents.js.map +1 -0
  144. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkinrSlotCategories.js +37 -0
  145. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkinrSlotCategories.js.map +1 -0
  146. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkinrSlotConfigurations.js +77 -0
  147. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkinrSlotConfigurations.js.map +1 -0
  148. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkinrSlotNames.js +37 -0
  149. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkinrSlotNames.js.map +1 -0
  150. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkinrSlots.js +74 -0
  151. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkinrSlots.js.map +1 -0
  152. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkinrTierThresholds.js +44 -0
  153. package/dist/formats/fsd/64/readers/CjsFsd64SchemaSkinrTierThresholds.js.map +1 -0
  154. package/dist/formats/fsd/64/readers/CjsFsd64SchemaStationOperations.js +120 -0
  155. package/dist/formats/fsd/64/readers/CjsFsd64SchemaStationOperations.js.map +1 -0
  156. package/dist/formats/fsd/64/readers/CjsFsd64SchemaStationServices.js +49 -0
  157. package/dist/formats/fsd/64/readers/CjsFsd64SchemaStationServices.js.map +1 -0
  158. package/dist/formats/fsd/64/readers/CjsFsd64SchemaTypeDogma.js +73 -0
  159. package/dist/formats/fsd/64/readers/CjsFsd64SchemaTypeDogma.js.map +1 -0
  160. package/dist/formats/fsd/64/readers/CjsFsd64SchemaTypeLists.js +122 -0
  161. package/dist/formats/fsd/64/readers/CjsFsd64SchemaTypeLists.js.map +1 -0
  162. package/dist/formats/fsd/64/readers/CjsFsd64SchemaTypeMaterials.js +83 -0
  163. package/dist/formats/fsd/64/readers/CjsFsd64SchemaTypeMaterials.js.map +1 -0
  164. package/dist/formats/fsd/64/readers/CjsFsd64SchemaTypes.js +194 -0
  165. package/dist/formats/fsd/64/readers/CjsFsd64SchemaTypes.js.map +1 -0
  166. package/dist/formats/fsd/64/readers/index.js +58 -0
  167. package/dist/formats/fsd/64/readers/index.js.map +1 -0
  168. package/dist/formats/fsd/CjsFsdFormat.js +62 -0
  169. package/dist/formats/fsd/CjsFsdFormat.js.map +1 -0
  170. package/dist/formats/fsd/index.js +9 -0
  171. package/dist/formats/fsd/index.js.map +1 -0
  172. package/dist/formats/gif/CjsGifFormat.js +26 -16
  173. package/dist/formats/gif/CjsGifFormat.js.map +1 -1
  174. package/dist/formats/gif/core/helpers.js +6 -18
  175. package/dist/formats/gif/core/helpers.js.map +1 -1
  176. package/dist/formats/gltf/CjsGltfFormat.js +25 -13
  177. package/dist/formats/gltf/CjsGltfFormat.js.map +1 -1
  178. package/dist/formats/gr2/CjsGr2Format.js +27 -6
  179. package/dist/formats/gr2/CjsGr2Format.js.map +1 -1
  180. package/dist/formats/hlsl/CjsHlslFormat.js +20 -16
  181. package/dist/formats/hlsl/CjsHlslFormat.js.map +1 -1
  182. package/dist/formats/hlsl/core/analysis.js +1 -1
  183. package/dist/formats/index.js +5 -0
  184. package/dist/formats/index.js.map +1 -1
  185. package/dist/formats/jpeg/CjsJpegFormat.js +26 -19
  186. package/dist/formats/jpeg/CjsJpegFormat.js.map +1 -1
  187. package/dist/formats/jpeg/core/helpers.js +6 -15
  188. package/dist/formats/jpeg/core/helpers.js.map +1 -1
  189. package/dist/formats/jpeg/core/jpeg.js +0 -3
  190. package/dist/formats/jpeg/core/jpeg.js.map +1 -1
  191. package/dist/formats/mp3/CjsMp3Format.js +19 -19
  192. package/dist/formats/mp3/CjsMp3Format.js.map +1 -1
  193. package/dist/formats/mp3/core/helpers.js +5 -11
  194. package/dist/formats/mp3/core/helpers.js.map +1 -1
  195. package/dist/formats/mp4/CjsMp4Format.js +20 -19
  196. package/dist/formats/mp4/CjsMp4Format.js.map +1 -1
  197. package/dist/formats/mp4/core/helpers.js +6 -15
  198. package/dist/formats/mp4/core/helpers.js.map +1 -1
  199. package/dist/formats/obj/CjsObjFormat.js +25 -12
  200. package/dist/formats/obj/CjsObjFormat.js.map +1 -1
  201. package/dist/formats/ogg/CjsOggFormat.js +26 -17
  202. package/dist/formats/ogg/CjsOggFormat.js.map +1 -1
  203. package/dist/formats/ogg/core/helpers.js +5 -16
  204. package/dist/formats/ogg/core/helpers.js.map +1 -1
  205. package/dist/formats/pickle/CjsPickleFormat.js +64 -5
  206. package/dist/formats/pickle/CjsPickleFormat.js.map +1 -1
  207. package/dist/formats/png/CjsPngFormat.js +28 -19
  208. package/dist/formats/png/CjsPngFormat.js.map +1 -1
  209. package/dist/formats/png/core/helpers.js +5 -14
  210. package/dist/formats/png/core/helpers.js.map +1 -1
  211. package/dist/formats/red/CjsRedFormat.js +19 -5
  212. package/dist/formats/red/CjsRedFormat.js.map +1 -1
  213. package/dist/formats/schemabound/CjsSchemaBoundFormat.js +48 -38
  214. package/dist/formats/schemabound/CjsSchemaBoundFormat.js.map +1 -1
  215. package/dist/formats/sqlite/CjsSqliteFormat.js +49 -41
  216. package/dist/formats/sqlite/CjsSqliteFormat.js.map +1 -1
  217. package/dist/formats/static/CjsStaticFormat.js +15 -57
  218. package/dist/formats/static/CjsStaticFormat.js.map +1 -1
  219. package/dist/formats/static/staticContainers.js +6 -6
  220. package/dist/formats/static/staticContainers.js.map +1 -1
  221. package/dist/formats/stl/CjsStlFormat.js +25 -12
  222. package/dist/formats/stl/CjsStlFormat.js.map +1 -1
  223. package/dist/formats/tga/CjsTgaFormat.js +26 -19
  224. package/dist/formats/tga/CjsTgaFormat.js.map +1 -1
  225. package/dist/formats/tga/core/helpers.js +7 -22
  226. package/dist/formats/tga/core/helpers.js.map +1 -1
  227. package/dist/formats/wav/CjsWavFormat.js +26 -19
  228. package/dist/formats/wav/CjsWavFormat.js.map +1 -1
  229. package/dist/formats/wav/core/helpers.js +7 -16
  230. package/dist/formats/wav/core/helpers.js.map +1 -1
  231. package/dist/formats/webgl/CjsWebglFormat.js +11 -13
  232. package/dist/formats/webgl/CjsWebglFormat.js.map +1 -1
  233. package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js +90 -12
  234. package/dist/formats/webgl/core/glsl/DxbcGlslEmitter.js.map +1 -1
  235. package/dist/formats/webgl/core/helpers.js +2 -2
  236. package/dist/formats/webgl/core/helpers.js.map +1 -1
  237. package/dist/formats/webgl/core/readGlslEffectContainer.js +8 -8
  238. package/dist/formats/webgl/core/readGlslEffectContainer.js.map +1 -1
  239. package/dist/formats/webgpu/CjsWebgpuFormat.js +11 -5
  240. package/dist/formats/webgpu/CjsWebgpuFormat.js.map +1 -1
  241. package/dist/formats/webm/CjsWebmFormat.js +20 -19
  242. package/dist/formats/webm/CjsWebmFormat.js.map +1 -1
  243. package/dist/formats/webm/core/helpers.js +6 -15
  244. package/dist/formats/webm/core/helpers.js.map +1 -1
  245. package/dist/formats/webp/CjsWebpFormat.js +19 -17
  246. package/dist/formats/webp/CjsWebpFormat.js.map +1 -1
  247. package/dist/formats/webp/core/helpers.js +5 -11
  248. package/dist/formats/webp/core/helpers.js.map +1 -1
  249. package/dist/formats/wem/CjsWemFormat.js +128 -141
  250. package/dist/formats/wem/CjsWemFormat.js.map +1 -1
  251. package/dist/formats/wem/core/helpers.js +1 -114
  252. package/dist/formats/wem/core/helpers.js.map +1 -1
  253. package/dist/formats/wem/core/{resolve.js → probeCodecSupport.js} +11 -18
  254. package/dist/formats/wem/core/probeCodecSupport.js.map +1 -0
  255. package/dist/formats/yaml/CjsYamlFormat.js +20 -5
  256. package/dist/formats/yaml/CjsYamlFormat.js.map +1 -1
  257. package/dist/generated/index.js +2 -0
  258. package/dist/generated/index.js.map +1 -0
  259. package/dist/generated/resources/Tr2RaycastGeometryRes.js +34 -0
  260. package/dist/generated/resources/Tr2RaycastGeometryRes.js.map +1 -0
  261. package/dist/generated/resources/index.js +2 -0
  262. package/dist/generated/resources/index.js.map +1 -0
  263. package/dist/index.js +3 -1
  264. package/dist/index.js.map +1 -1
  265. package/dist/resource/CjsResource.js +134 -0
  266. package/dist/resource/CjsResource.js.map +1 -1
  267. package/dist/resource/ResourceRequirement.js +42 -0
  268. package/dist/resource/ResourceRequirement.js.map +1 -0
  269. package/dist/resource/Tr2LightProfileRes.js +2 -1
  270. package/dist/resource/Tr2LightProfileRes.js.map +1 -1
  271. package/dist/resource/geometry/TriGeometryRes.js +34 -7
  272. package/dist/resource/geometry/TriGeometryRes.js.map +1 -1
  273. package/dist/resource/geometry/granny/Tr2GrannyStateRes.js +184 -7
  274. package/dist/resource/geometry/granny/Tr2GrannyStateRes.js.map +1 -1
  275. package/dist/resource/geometry/granny/TriGrannyRes.js +20 -8
  276. package/dist/resource/geometry/granny/TriGrannyRes.js.map +1 -1
  277. package/dist/resource/index.js +1 -0
  278. package/dist/resource/index.js.map +1 -1
  279. package/dist/resource/resourceBoundary.js +24 -1
  280. package/dist/resource/resourceBoundary.js.map +1 -1
  281. package/dist/resource/shader/Tr2EffectRes.js +2 -1
  282. package/dist/resource/shader/Tr2EffectRes.js.map +1 -1
  283. package/dist/resource/texture/CjsTextureArrayRes.js +2 -1
  284. package/dist/resource/texture/CjsTextureArrayRes.js.map +1 -1
  285. package/dist/resource/texture/Tr2ImageRes.js +2 -1
  286. package/dist/resource/texture/Tr2ImageRes.js.map +1 -1
  287. package/dist/resource/texture/TriTextureRes.js +40 -2
  288. package/dist/resource/texture/TriTextureRes.js.map +1 -1
  289. package/docs/architecture.md +121 -116
  290. package/docs/concepts/format-capabilities.md +90 -0
  291. package/docs/formats/README.md +14 -6
  292. package/docs/formats/fsd.md +104 -0
  293. package/docs/formats/gr2.md +1 -1
  294. package/docs/formats/hlsl/reference/api.md +6 -4
  295. package/docs/formats/provenance.md +18 -0
  296. package/docs/formats/schemabound.md +10 -4
  297. package/docs/formats/static.md +26 -26
  298. package/docs/formats/webgpu/reference/api.md +4 -3
  299. package/docs/reference/classes/core.md +22 -2
  300. package/docs/reference/classes/formats.md +643 -1
  301. package/docs/reference/classes/resources.md +463 -453
  302. package/docs/reference/queues.md +205 -194
  303. package/docs/roadmap.md +14 -18
  304. package/format-notices/fsd/LICENSE +21 -0
  305. package/format-notices/fsd/NOTICE +11 -0
  306. package/package.json +70 -64
  307. package/dist/formats/wem/core/resolve.js.map +0 -1
  308. package/docs/concepts/format-type-resolution.md +0 -79
package/dist/CjsResMan.js CHANGED
@@ -24,136 +24,136 @@ const RESOURCE_PROVENANCE_OPTION_KEYS = Object.freeze(["source", "sourceRevision
24
24
  const LOCAL_VALUE_IDENTITIES = new WeakMap();
25
25
  let nextLocalValueIdentity = 1;
26
26
 
27
- /**
28
- * Immutable source provenance used by one read/format operation chain.
29
- *
30
- * `sourceRevision` is caller/source-provided opaque content identity. It scopes
31
- * read caches only and never becomes part of MotherLode resource identity.
32
- *
33
- * @typedef {object} CjsResourceReadContext
34
- * @property {CjsResMan} resMan Owning manager.
35
- * @property {object|Function} source Selected source implementation.
36
- * @property {string} path Normalized Carbon-style source path.
37
- * @property {string} resFilePath Normalized lowercase Carbon-style source path.
38
- * @property {string} ext Normalized lowercase resource extension.
39
- * @property {string} fileName Normalized lowercase final path component.
40
- * @property {string|null} url Exact URL passed to a URL-backed source, otherwise `null`.
41
- * @property {string} sourcePath Resource path or URL passed to the selected source.
42
- * @property {string|number|undefined} sourceRevision Caller content token.
43
- * @property {string} revisionKey Type-stable internal form of the content token.
27
+ /**
28
+ * Immutable source provenance used by one read/format operation chain.
29
+ *
30
+ * `sourceRevision` is caller/source-provided opaque content identity. It scopes
31
+ * read caches only and never becomes part of MotherLode resource identity.
32
+ *
33
+ * @typedef {object} CjsResourceReadContext
34
+ * @property {CjsResMan} resMan Owning manager.
35
+ * @property {object|Function} source Selected source implementation.
36
+ * @property {string} path Normalized Carbon-style source path.
37
+ * @property {string} resFilePath Normalized lowercase Carbon-style source path.
38
+ * @property {string} ext Normalized lowercase resource extension.
39
+ * @property {string} fileName Normalized lowercase final path component.
40
+ * @property {string|null} url Exact URL passed to a URL-backed source, otherwise `null`.
41
+ * @property {string} sourcePath Resource path or URL passed to the selected source.
42
+ * @property {string|number|undefined} sourceRevision Caller content token.
43
+ * @property {string} revisionKey Type-stable internal form of the content token.
44
44
  */
45
45
 
46
- /**
47
- * Mutable record retained in a source or format operation ledger.
48
- *
49
- * @typedef {object} CjsResourceReadOperationRecord
50
- * @property {Promise<*>} promise Shared operation promise.
51
- * @property {string} path Normalized source path used for explicit invalidation.
52
- * @property {string} revisionKey Type-stable source revision key.
53
- * @property {boolean} retain Whether any joined caller requested settled retention.
46
+ /**
47
+ * Mutable record retained in a source or format operation ledger.
48
+ *
49
+ * @typedef {object} CjsResourceReadOperationRecord
50
+ * @property {Promise<*>} promise Shared operation promise.
51
+ * @property {string} path Normalized source path used for explicit invalidation.
52
+ * @property {string} revisionKey Type-stable source revision key.
53
+ * @property {boolean} retain Whether any joined caller requested settled retention.
54
54
  */
55
55
 
56
- /**
57
- * Source provenance and tri-state read-cache controls.
58
- *
59
- * Omitted cache flags share in-flight or explicitly retained work but do not
60
- * retain a newly completed operation. `true` retains success, while `false`
61
- * bypasses sharing and retention. Failures are never retained.
62
- *
63
- * @typedef {object} CjsResManReadCacheOptions
64
- * @property {object|Function} [source] Source override providing `Read(path, options)`.
65
- * @property {string|number} [sourceRevision] Opaque caller/source content token; finite numbers only.
66
- * @property {boolean} [reload=false] Invalidate this source/path and begin fresh work once.
67
- * @property {boolean} [cacheSource] Source operation sharing/retention policy.
68
- * @property {boolean} [cacheFormat] Parsed-format operation sharing/retention policy.
56
+ /**
57
+ * Source provenance and tri-state read-cache controls.
58
+ *
59
+ * Omitted cache flags share in-flight or explicitly retained work but do not
60
+ * retain a newly completed operation. `true` retains success, while `false`
61
+ * bypasses sharing and retention. Failures are never retained.
62
+ *
63
+ * @typedef {object} CjsResManReadCacheOptions
64
+ * @property {object|Function} [source] Source override providing `Read(path, options)`.
65
+ * @property {string|number} [sourceRevision] Opaque caller/source content token; finite numbers only.
66
+ * @property {boolean} [reload=false] Invalidate this source/path and begin fresh work once.
67
+ * @property {boolean} [cacheSource] Source operation sharing/retention policy.
68
+ * @property {boolean} [cacheFormat] Parsed-format operation sharing/retention policy.
69
69
  */
70
70
 
71
- /**
72
- * Opt-in time-based inactivity policy run by {@link CjsResMan#Update}.
73
- *
74
- * Automatic policy deliberately uses elapsed milliseconds rather than
75
- * MotherLode activity frames: the latter count explicit activity observations
76
- * and are not guaranteed to match renderer frames. At least one identity or
77
- * payload limit is required. The policy is disabled by default.
78
- *
79
- * @typedef {object} CjsResManAutoPurgePolicy
80
- * @property {number} [intervalMilliseconds=1000] Minimum elapsed milliseconds between automatic sweeps; `0` permits every update.
81
- * @property {number} [maxIdleMilliseconds] Elapsed milliseconds after which an unlocked canonical identity is removed and cleaned.
82
- * @property {number} [payloadMaxIdleMilliseconds] Elapsed milliseconds after which an unlocked CPU payload is released.
83
- * @property {boolean} [destroyAdapters=true] Whether identity cleanup destroys adapter allocations.
84
- * @property {boolean} [releasePayload=true] Whether sweeps may release CPU payloads.
85
- * @property {false|Function} [cleanup] `false` retains owned state; a function replaces default identity cleanup.
86
- * @property {() => number} [now=Date.now] Cadence clock. Use the MotherLode activity clock when supplying a custom clock.
71
+ /**
72
+ * Opt-in time-based inactivity policy run by {@link CjsResMan#Update}.
73
+ *
74
+ * Automatic policy deliberately uses elapsed milliseconds rather than
75
+ * MotherLode activity frames: the latter count explicit activity observations
76
+ * and are not guaranteed to match renderer frames. At least one identity or
77
+ * payload limit is required. The policy is disabled by default.
78
+ *
79
+ * @typedef {object} CjsResManAutoPurgePolicy
80
+ * @property {number} [intervalMilliseconds=1000] Minimum elapsed milliseconds between automatic sweeps; `0` permits every update.
81
+ * @property {number} [maxIdleMilliseconds] Elapsed milliseconds after which an unlocked canonical identity is removed and cleaned.
82
+ * @property {number} [payloadMaxIdleMilliseconds] Elapsed milliseconds after which an unlocked CPU payload is released.
83
+ * @property {boolean} [destroyAdapters=true] Whether identity cleanup destroys adapter allocations.
84
+ * @property {boolean} [releasePayload=true] Whether sweeps may release CPU payloads.
85
+ * @property {false|Function} [cleanup] `false` retains owned state; a function replaces default identity cleanup.
86
+ * @property {() => number} [now=Date.now] Cadence clock. Use the MotherLode activity clock when supplying a custom clock.
87
87
  */
88
88
 
89
- /**
90
- * Per-call controls for {@link CjsResMan#PumpAutoPurge}.
91
- *
92
- * @typedef {object} CjsResManAutoPurgePumpOptions
93
- * @property {number} [time] Explicit non-negative timestamp in milliseconds for deterministic pumping and sweeping.
89
+ /**
90
+ * Per-call controls for {@link CjsResMan#PumpAutoPurge}.
91
+ *
92
+ * @typedef {object} CjsResManAutoPurgePumpOptions
93
+ * @property {number} [time] Explicit non-negative timestamp in milliseconds for deterministic pumping and sweeping.
94
94
  */
95
95
 
96
- /**
97
- * Queue and automatic-purge controls accepted by {@link CjsResMan#Update}.
98
- * Top-level queue options remain a compatibility form for the prepare pump.
99
- *
100
- * @typedef {object} CjsResManUpdateOptions
101
- * @property {object} [background] Background queue pump options.
102
- * @property {object} [prepare] Main-thread prepare queue pump options.
103
- * @property {false|object} [cache] `false` skips recorded-byte housekeeping; otherwise supplies cache-cleanup policy.
104
- * @property {false|CjsResManAutoPurgePumpOptions} [purge] `false` skips this update's automatic sweep; otherwise supplies its timestamp.
96
+ /**
97
+ * Queue and automatic-purge controls accepted by {@link CjsResMan#Update}.
98
+ * Top-level queue options remain a compatibility form for the prepare pump.
99
+ *
100
+ * @typedef {object} CjsResManUpdateOptions
101
+ * @property {object} [background] Background queue pump options.
102
+ * @property {object} [prepare] Main-thread prepare queue pump options.
103
+ * @property {false|object} [cache] `false` skips recorded-byte housekeeping; otherwise supplies cache-cleanup policy.
104
+ * @property {false|CjsResManAutoPurgePumpOptions} [purge] `false` skips this update's automatic sweep; otherwise supplies its timestamp.
105
105
  */
106
106
 
107
- /**
108
- * Snapshot-fence controls accepted by {@link CjsResMan#Wait}.
109
- *
110
- * The default pump uses the manager's ordinary queue budgets and honors queue
111
- * pause state. `pump: false` leaves all progress to an external driver. The
112
- * yield callback is used only while this call is pumping and may return either
113
- * a promise or an immediate value.
114
- *
115
- * @typedef {object} CjsResManWaitOptions
116
- * @property {boolean} [pump=true] Whether this call pumps the two queues while awaiting its snapshot.
117
- * @property {object} [background] Options forwarded to `PumpBackgroundQueue`.
118
- * @property {object} [prepare] Options forwarded to `PumpMainThreadQueue`.
119
- * @property {() => (*|Promise<*>)} [yield] Cooperative wait between pump attempts.
107
+ /**
108
+ * Snapshot-fence controls accepted by {@link CjsResMan#Wait}.
109
+ *
110
+ * The default pump uses the manager's ordinary queue budgets and honors queue
111
+ * pause state. `pump: false` leaves all progress to an external driver. The
112
+ * yield callback is used only while this call is pumping and may return either
113
+ * a promise or an immediate value.
114
+ *
115
+ * @typedef {object} CjsResManWaitOptions
116
+ * @property {boolean} [pump=true] Whether this call pumps the two queues while awaiting its snapshot.
117
+ * @property {object} [background] Options forwarded to `PumpBackgroundQueue`.
118
+ * @property {object} [prepare] Options forwarded to `PumpMainThreadQueue`.
119
+ * @property {() => (*|Promise<*>)} [yield] Cooperative wait between pump attempts.
120
120
  */
121
121
 
122
- /**
123
- * Immutable authority captured by asynchronous work that may mutate a
124
- * canonical resource. A generation changes whenever ResMan removes and later
125
- * rebinds the same JavaScript handle, even when owner and key are reused.
126
- *
127
- * @typedef {object} CjsResourceOwnership
128
- * @property {number} generation Manager-local ownership generation.
129
- * @property {CjsMotherLode} owner Exact registry that owns the resource.
130
- * @property {string} key Exact canonical registry identity.
131
- * @property {object|Function} resource Canonical resource handle.
122
+ /**
123
+ * Immutable authority captured by asynchronous work that may mutate a
124
+ * canonical resource. A generation changes whenever ResMan removes and later
125
+ * rebinds the same JavaScript handle, even when owner and key are reused.
126
+ *
127
+ * @typedef {object} CjsResourceOwnership
128
+ * @property {number} generation Manager-local ownership generation.
129
+ * @property {CjsMotherLode} owner Exact registry that owns the resource.
130
+ * @property {string} key Exact canonical registry identity.
131
+ * @property {object|Function} resource Canonical resource handle.
132
132
  */
133
133
 
134
- /**
135
- * Immutable authority for one off-registry reload candidate.
136
- *
137
- * The newest generation for a canonical key is the only candidate permitted
138
- * to commit. `expectedOwnership` keeps the former canonical handle protected
139
- * by the same exact-owner generation checks used by ordinary asynchronous
140
- * resource work.
141
- *
142
- * @typedef {object} CjsResourceReloadCandidate
143
- * @property {true} reloadCandidate Distinguishes staged authority from canonical ownership.
144
- * @property {number} generation Manager-local reload request generation.
145
- * @property {CjsMotherLode} owner Exact registry expected to receive the candidate.
146
- * @property {string} key Exact canonical registry identity.
147
- * @property {object|Function} expected Former canonical resource preserved until commit.
148
- * @property {CjsResourceOwnership} expectedOwnership Captured authority of the former owner.
149
- * @property {object|Function} resource Off-registry candidate resource.
150
- * @property {Readonly<object>} loaderOptions Durable identity/source options restored after commit.
134
+ /**
135
+ * Immutable authority for one off-registry reload candidate.
136
+ *
137
+ * The newest generation for a canonical key is the only candidate permitted
138
+ * to commit. `expectedOwnership` keeps the former canonical handle protected
139
+ * by the same exact-owner generation checks used by ordinary asynchronous
140
+ * resource work.
141
+ *
142
+ * @typedef {object} CjsResourceReloadCandidate
143
+ * @property {true} reloadCandidate Distinguishes staged authority from canonical ownership.
144
+ * @property {number} generation Manager-local reload request generation.
145
+ * @property {CjsMotherLode} owner Exact registry expected to receive the candidate.
146
+ * @property {string} key Exact canonical registry identity.
147
+ * @property {object|Function} expected Former canonical resource preserved until commit.
148
+ * @property {CjsResourceOwnership} expectedOwnership Captured authority of the former owner.
149
+ * @property {object|Function} resource Off-registry candidate resource.
150
+ * @property {Readonly<object>} loaderOptions Durable identity/source options restored after commit.
151
151
  */
152
152
 
153
- /**
154
- * Hidden authority accepted by guarded CPU read/publication helpers.
155
- *
156
- * @typedef {CjsResourceOwnership|CjsResourceReloadCandidate} CjsResourceMutationAuthority
153
+ /**
154
+ * Hidden authority accepted by guarded CPU read/publication helpers.
155
+ *
156
+ * @typedef {CjsResourceOwnership|CjsResourceReloadCandidate} CjsResourceMutationAuthority
157
157
  */
158
158
 
159
159
  class CjsResMan extends CjsEventEmitter {
@@ -173,12 +173,13 @@ class CjsResMan extends CjsEventEmitter {
173
173
  #extensionRoutes = new Map();
174
174
  #resourceExtensionRoutes = new WeakMap();
175
175
  #resourceHandlerModes = new WeakMap();
176
+ #resourceTypeCandidates = new Map();
176
177
 
177
- /**
178
- * Create a GPU-free resource manager and apply its initial registration.
179
- *
180
- * @param {object} [options={}] Configuration forwarded to {@link CjsResMan#Register}.
181
- * @throws {TypeError} If registration, queue, source, or format options are invalid.
178
+ /**
179
+ * Create a GPU-free resource manager and apply its initial registration.
180
+ *
181
+ * @param {object} [options={}] Configuration forwarded to {@link CjsResMan#Register}.
182
+ * @throws {TypeError} If registration, queue, source, or format options are invalid.
182
183
  */
183
184
  constructor(options = {}) {
184
185
  super();
@@ -217,30 +218,30 @@ class CjsResMan extends CjsEventEmitter {
217
218
  this.Register(options);
218
219
  }
219
220
 
220
- /**
221
- * Add or replace resource-manager configuration.
222
- *
223
- * The same options object can be forwarded unchanged by CjsLibrary. Format
224
- * classes continue to own their input extensions; resource types are keyed
225
- * by semantic requirements such as "texture", "image", or "geometry".
226
- * Replacing MotherLode shuts down and cleans the former owner before the new
227
- * registry is activated. Replacement is rejected while queued or direct
228
- * resource mutations are active so a synchronous configuration call cannot
229
- * detach ownership underneath asynchronous publication. Normal `Wait()`
230
- * drains queued roots only; direct callers must await their own promises.
231
- *
232
- * @param {object} [options={}] Additive source, registry, queue, format, and resource-type settings.
233
- * @param {number} [options.cacheSize] Recorded-byte budget immediately installed on the active MotherLode.
234
- * @param {object} [options.cacheCleanup] Cleanup policy used if a smaller configured budget evicts cached identities.
235
- * @param {object} [options.mainThreadLoader] Direct execution strategy.
236
- * @param {object|Map<string,string>} [options.paths] Resource-prefix URL bases.
237
- * @param {object|Map|object[]} [options.extensions] Extension route registrations.
238
- * @param {Function|null} [options.pathResolver] Optional complete resource-path-to-URL resolver.
239
- * @param {object} [options.workerLoader] Worker loader instance or construction options.
240
- * @param {boolean} [options.useWorkerLoading=true] Whether worker-backed execution is selected.
241
- * @returns {CjsResMan} This resource manager.
242
- * @throws {TypeError} If options or any configured component are invalid.
243
- * @throws {Error|AggregateError} If resource mutations are active or replacing MotherLode cannot clean its resources.
221
+ /**
222
+ * Add or replace resource-manager configuration.
223
+ *
224
+ * The same options object can be forwarded unchanged by CjsLibrary. Format
225
+ * classes continue to own their input extensions; resource types are keyed
226
+ * by semantic requirements such as "texture", "image", or "geometry".
227
+ * Replacing MotherLode shuts down and cleans the former owner before the new
228
+ * registry is activated. Replacement is rejected while queued or direct
229
+ * resource mutations are active so a synchronous configuration call cannot
230
+ * detach ownership underneath asynchronous publication. Normal `Wait()`
231
+ * drains queued roots only; direct callers must await their own promises.
232
+ *
233
+ * @param {object} [options={}] Additive source, registry, queue, format, and resource-type settings.
234
+ * @param {number} [options.cacheSize] Recorded-byte budget immediately installed on the active MotherLode.
235
+ * @param {object} [options.cacheCleanup] Cleanup policy used if a smaller configured budget evicts cached identities.
236
+ * @param {object} [options.mainThreadLoader] Direct execution strategy.
237
+ * @param {object|Map<string,string>} [options.paths] Resource-prefix URL bases.
238
+ * @param {object|Map|object[]} [options.extensions] Extension route registrations.
239
+ * @param {Function|null} [options.pathResolver] Optional complete resource-path-to-URL resolver.
240
+ * @param {object} [options.workerLoader] Worker loader instance or construction options.
241
+ * @param {boolean} [options.useWorkerLoading=true] Whether worker-backed execution is selected.
242
+ * @returns {CjsResMan} This resource manager.
243
+ * @throws {TypeError} If options or any configured component are invalid.
244
+ * @throws {Error|AggregateError} If resource mutations are active or replacing MotherLode cannot clean its resources.
244
245
  */
245
246
  Register(options = {}) {
246
247
  if (!options || typeof options !== "object" || Array.isArray(options)) {
@@ -315,25 +316,25 @@ class CjsResMan extends CjsEventEmitter {
315
316
  return this;
316
317
  }
317
318
 
318
- /**
319
- * Replace the default source selected by later resource requests.
320
- * Existing handles retain the effective source captured when they were
321
- * created, so payload reconstruction does not silently move to this source.
322
- *
323
- * @param {object|Function|null} source Source exposing `Read(path, options)`, or a falsey value to clear the default.
324
- * @returns {CjsResMan} This resource manager.
319
+ /**
320
+ * Replace the default source selected by later resource requests.
321
+ * Existing handles retain the effective source captured when they were
322
+ * created, so payload reconstruction does not silently move to this source.
323
+ *
324
+ * @param {object|Function|null} source Source exposing `Read(path, options)`, or a falsey value to clear the default.
325
+ * @returns {CjsResMan} This resource manager.
325
326
  */
326
327
  SetSource(source) {
327
328
  this.source = source || null;
328
329
  return this;
329
330
  }
330
331
 
331
- /**
332
- * Add or replace one resource-prefix URL base.
333
- *
334
- * @param {string} prefix Resource scheme without `:/`.
335
- * @param {string} urlBase URL base ending at the scheme root.
336
- * @returns {CjsResMan} This resource manager.
332
+ /**
333
+ * Add or replace one resource-prefix URL base.
334
+ *
335
+ * @param {string} prefix Resource scheme without `:/`.
336
+ * @param {string} urlBase URL base ending at the scheme root.
337
+ * @returns {CjsResMan} This resource manager.
337
338
  */
338
339
  SetPath(prefix, urlBase) {
339
340
  const key = normalizePathPrefix(prefix);
@@ -342,11 +343,11 @@ class CjsResMan extends CjsEventEmitter {
342
343
  return this;
343
344
  }
344
345
 
345
- /**
346
- * Add or replace resource-prefix URL bases from an object or Map.
347
- *
348
- * @param {object|Map<string,string>} paths Prefix/base entries.
349
- * @returns {CjsResMan} This resource manager.
346
+ /**
347
+ * Add or replace resource-prefix URL bases from an object or Map.
348
+ *
349
+ * @param {object|Map<string,string>} paths Prefix/base entries.
350
+ * @returns {CjsResMan} This resource manager.
350
351
  */
351
352
  SetPaths(paths) {
352
353
  if (!paths || typeof paths !== "object" && !(paths instanceof Map) || Array.isArray(paths)) {
@@ -359,31 +360,31 @@ class CjsResMan extends CjsEventEmitter {
359
360
  return this;
360
361
  }
361
362
 
362
- /**
363
- * Reports whether a resource-prefix URL base is registered.
364
- *
365
- * @param {string} prefix Resource scheme without `:/`.
366
- * @returns {boolean}
363
+ /**
364
+ * Reports whether a resource-prefix URL base is registered.
365
+ *
366
+ * @param {string} prefix Resource scheme without `:/`.
367
+ * @returns {boolean}
367
368
  */
368
369
  HasPath(prefix) {
369
370
  return this.paths.has(normalizePathPrefix(prefix));
370
371
  }
371
372
 
372
- /**
373
- * Returns one registered resource-prefix URL base.
374
- *
375
- * @param {string} prefix Resource scheme without `:/`.
376
- * @returns {string|null}
373
+ /**
374
+ * Returns one registered resource-prefix URL base.
375
+ *
376
+ * @param {string} prefix Resource scheme without `:/`.
377
+ * @returns {string|null}
377
378
  */
378
379
  GetPath(prefix) {
379
380
  return this.paths.get(normalizePathPrefix(prefix)) || null;
380
381
  }
381
382
 
382
- /**
383
- * Replaces the complete resource-path-to-URL resolver.
384
- *
385
- * @param {Function|null} resolver Resolver called as `(resourcePath, resMan)`.
386
- * @returns {CjsResMan} This resource manager.
383
+ /**
384
+ * Replaces the complete resource-path-to-URL resolver.
385
+ *
386
+ * @param {Function|null} resolver Resolver called as `(resourcePath, resMan)`.
387
+ * @returns {CjsResMan} This resource manager.
387
388
  */
388
389
  SetPathResolver(resolver) {
389
390
  if (resolver !== null && resolver !== undefined && typeof resolver !== "function") {
@@ -393,12 +394,12 @@ class CjsResMan extends CjsEventEmitter {
393
394
  return this;
394
395
  }
395
396
 
396
- /**
397
- * Builds the URL used by URL-backed providers while preserving the resource
398
- * path as the canonical resource identity.
399
- *
400
- * @param {string} path Resource path or direct HTTP(S) URL.
401
- * @returns {string} Resolved URL.
397
+ /**
398
+ * Builds the URL used by URL-backed providers while preserving the resource
399
+ * path as the canonical resource identity.
400
+ *
401
+ * @param {string} path Resource path or direct HTTP(S) URL.
402
+ * @returns {string} Resolved URL.
402
403
  */
403
404
  BuildUrl(path) {
404
405
  const normalized = normalizeResourcePath(path);
@@ -427,12 +428,12 @@ class CjsResMan extends CjsEventEmitter {
427
428
  return `${urlBase}${normalized.slice(prefixIndex + 2)}`;
428
429
  }
429
430
 
430
- /**
431
- * Replace the direct execution strategy used by unsupported worker
432
- * operations and whenever worker loading is not selected.
433
- *
434
- * @param {object} loader Loader exposing `Read` and `ReadFormat`.
435
- * @returns {CjsResMan} This resource manager.
431
+ /**
432
+ * Replace the direct execution strategy used by unsupported worker
433
+ * operations and whenever worker loading is not selected.
434
+ *
435
+ * @param {object} loader Loader exposing `Read` and `ReadFormat`.
436
+ * @returns {CjsResMan} This resource manager.
436
437
  */
437
438
  SetMainThreadLoader(loader) {
438
439
  assertResourceLoader(loader, "mainThreadLoader");
@@ -443,14 +444,14 @@ class CjsResMan extends CjsEventEmitter {
443
444
  return this;
444
445
  }
445
446
 
446
- /**
447
- * Install a worker loader instance or construct one from options.
448
- *
449
- * Installation does not select worker execution; call
450
- * `UseWorkerLoading(true)` or pass `useWorkerLoading: true`.
451
- *
452
- * @param {object|null} loader Worker loader or CjsResManWorkerLoader options.
453
- * @returns {CjsResMan} This resource manager.
447
+ /**
448
+ * Install a worker loader instance or construct one from options.
449
+ *
450
+ * Installation does not select worker execution; call
451
+ * `UseWorkerLoading(true)` or pass `useWorkerLoading: true`.
452
+ *
453
+ * @param {object|null} loader Worker loader or CjsResManWorkerLoader options.
454
+ * @returns {CjsResMan} This resource manager.
454
455
  */
455
456
  SetWorkerLoader(loader) {
456
457
  const wasSelected = this.resourceLoader === this.workerLoader;
@@ -469,13 +470,13 @@ class CjsResMan extends CjsEventEmitter {
469
470
  return this;
470
471
  }
471
472
 
472
- /**
473
- * Select worker-backed execution, lazily creating the default module worker
474
- * loader when required. Unsupported sources and formats still use the
475
- * configured main-thread loader.
476
- *
477
- * @param {boolean} [value=true] Whether worker execution is selected.
478
- * @returns {CjsResMan} This resource manager.
473
+ /**
474
+ * Select worker-backed execution, lazily creating the default module worker
475
+ * loader when required. Unsupported sources and formats still use the
476
+ * configured main-thread loader.
477
+ *
478
+ * @param {boolean} [value=true] Whether worker execution is selected.
479
+ * @returns {CjsResMan} This resource manager.
479
480
  */
480
481
  UseWorkerLoading(value = true) {
481
482
  if (!value) {
@@ -488,27 +489,27 @@ class CjsResMan extends CjsEventEmitter {
488
489
  return this;
489
490
  }
490
491
 
491
- /**
492
- * Report whether worker-backed execution is the selected strategy.
493
- *
494
- * @returns {boolean}
492
+ /**
493
+ * Report whether worker-backed execution is the selected strategy.
494
+ *
495
+ * @returns {boolean}
495
496
  */
496
497
  IsWorkerLoading() {
497
498
  return Boolean(this.workerLoader && this.resourceLoader === this.workerLoader);
498
499
  }
499
500
 
500
- /**
501
- * Return unresolved requests owned by the selected/installed worker loader.
502
- *
503
- * @returns {number}
501
+ /**
502
+ * Return unresolved requests owned by the selected/installed worker loader.
503
+ *
504
+ * @returns {number}
504
505
  */
505
506
  GetPendingWorkers() {
506
507
  return this.workerLoader?.GetPendingCount?.() || 0;
507
508
  }
508
509
 
509
- /**
510
- * Enqueues a resource task on the selected execution lane for the resource
511
- * manager.
510
+ /**
511
+ * Enqueues a resource task on the selected execution lane for the resource
512
+ * manager.
512
513
  */
513
514
  AddToQueue(queue, callback, context = null, flags = 0) {
514
515
  const task = this.QueueTask(queue, callback, context, {
@@ -525,17 +526,17 @@ class CjsResMan extends CjsEventEmitter {
525
526
  return this.GetWorkQueue(queue).Cancel(id, reason);
526
527
  }
527
528
 
528
- /**
529
- * Allocates the next task identifier for a selected queue for the resource
530
- * manager.
529
+ /**
530
+ * Allocates the next task identifier for a selected queue for the resource
531
+ * manager.
531
532
  */
532
533
  GetNextIdForQueue(queue) {
533
534
  return this.GetWorkQueue(queue).GetNextId();
534
535
  }
535
536
 
536
- /**
537
- * Starts pending preparation work within the main-thread concurrency limit for
538
- * the resource manager.
537
+ /**
538
+ * Starts pending preparation work within the main-thread concurrency limit for
539
+ * the resource manager.
539
540
  */
540
541
  PumpMainThreadQueue(options = {}) {
541
542
  const urgent = options.urgent === true || this.urgentResourceLoads;
@@ -548,9 +549,9 @@ class CjsResMan extends CjsEventEmitter {
548
549
  return result.processed > 0;
549
550
  }
550
551
 
551
- /**
552
- * Starts pending load work within the background concurrency limit for the
553
- * resource manager.
552
+ /**
553
+ * Starts pending load work within the background concurrency limit for the
554
+ * resource manager.
554
555
  */
555
556
  PumpBackgroundQueue(options = {}) {
556
557
  const result = this._loadQueue.Pump({
@@ -561,18 +562,18 @@ class CjsResMan extends CjsEventEmitter {
561
562
  return result.processed > 0;
562
563
  }
563
564
 
564
- /**
565
- * Prevents the selected queue from starting additional work for the resource
566
- * manager.
565
+ /**
566
+ * Prevents the selected queue from starting additional work for the resource
567
+ * manager.
567
568
  */
568
569
  PauseQueue(queue) {
569
570
  this.GetWorkQueue(queue).Pause();
570
571
  return this;
571
572
  }
572
573
 
573
- /**
574
- * Allows the selected queue to start pending work again for the resource
575
- * manager.
574
+ /**
575
+ * Allows the selected queue to start pending work again for the resource
576
+ * manager.
576
577
  */
577
578
  ResumeQueue(queue) {
578
579
  const name = CjsResManWorkQueue.normalizeName(queue);
@@ -581,25 +582,25 @@ class CjsResMan extends CjsEventEmitter {
581
582
  return this;
582
583
  }
583
584
 
584
- /**
585
- * Returns the number of load tasks waiting or running for the resource
586
- * manager.
585
+ /**
586
+ * Returns the number of load tasks waiting or running for the resource
587
+ * manager.
587
588
  */
588
589
  GetPendingLoads() {
589
590
  return this._loadQueue.GetPendingCount();
590
591
  }
591
592
 
592
- /**
593
- * Returns the number of preparation tasks waiting or running for the resource
594
- * manager.
593
+ /**
594
+ * Returns the number of preparation tasks waiting or running for the resource
595
+ * manager.
595
596
  */
596
597
  GetPendingPrepares() {
597
598
  return this._prepareQueue.GetPendingCount();
598
599
  }
599
600
 
600
- /**
601
- * Returns queue counts and concurrency state for diagnostics for the resource
602
- * manager.
601
+ /**
602
+ * Returns queue counts and concurrency state for diagnostics for the resource
603
+ * manager.
603
604
  */
604
605
  GetQueueStats(queue = null) {
605
606
  if (queue !== null && queue !== undefined) return this.GetWorkQueue(queue).GetStats();
@@ -609,42 +610,42 @@ class CjsResMan extends CjsEventEmitter {
609
610
  });
610
611
  }
611
612
 
612
- /**
613
- * Switches resource loading between normal and urgent concurrency policy for
614
- * the resource manager.
613
+ /**
614
+ * Switches resource loading between normal and urgent concurrency policy for
615
+ * the resource manager.
615
616
  */
616
617
  SetUrgentResourceLoads(value) {
617
618
  this.urgentResourceLoads = Boolean(value);
618
619
  return this;
619
620
  }
620
621
 
621
- /**
622
- * Reports whether urgent resource-load scheduling is active for the resource
623
- * manager.
622
+ /**
623
+ * Reports whether urgent resource-load scheduling is active for the resource
624
+ * manager.
624
625
  */
625
626
  IsUrgentResourceLoads() {
626
627
  return this.urgentResourceLoads;
627
628
  }
628
629
 
629
- /**
630
- * Reports whether any resource load or preparation remains pending for the
631
- * resource manager.
630
+ /**
631
+ * Reports whether any resource load or preparation remains pending for the
632
+ * resource manager.
632
633
  */
633
634
  IsLoading() {
634
635
  return this.GetPendingLoads() + this.GetPendingPrepares() + this.GetPendingWorkers() > 0;
635
636
  }
636
637
 
637
- /**
638
- * Pump background and main-thread work, enforce the recorded-byte cache
639
- * budget, then run a due automatic inactivity sweep when one has been
640
- * explicitly configured. Queue work is processed before housekeeping, and
641
- * manager-owned active loads/prepares hold eviction locks. No housekeeping
642
- * operation fetches, prepares, or reloads source data.
643
- *
644
- * @param {CjsResManUpdateOptions} [options={}] Queue budgets and optional automatic-purge controls.
645
- * @returns {boolean} Whether queue work ran or housekeeping released owned state.
646
- * @throws {TypeError} If queue, cache, purge timing, or MotherLode policy options are invalid.
647
- * @throws {AggregateError} If cache or inactivity housekeeping cannot clean one or more resources.
638
+ /**
639
+ * Pump background and main-thread work, enforce the recorded-byte cache
640
+ * budget, then run a due automatic inactivity sweep when one has been
641
+ * explicitly configured. Queue work is processed before housekeeping, and
642
+ * manager-owned active loads/prepares hold eviction locks. No housekeeping
643
+ * operation fetches, prepares, or reloads source data.
644
+ *
645
+ * @param {CjsResManUpdateOptions} [options={}] Queue budgets and optional automatic-purge controls.
646
+ * @returns {boolean} Whether queue work ran or housekeeping released owned state.
647
+ * @throws {TypeError} If queue, cache, purge timing, or MotherLode policy options are invalid.
648
+ * @throws {AggregateError} If cache or inactivity housekeeping cannot clean one or more resources.
648
649
  */
649
650
  Update(options = {}) {
650
651
  const loaded = this.PumpBackgroundQueue(options.background || {});
@@ -658,45 +659,45 @@ class CjsResMan extends CjsEventEmitter {
658
659
  return loaded || prepared || trimmed || purged;
659
660
  }
660
661
 
661
- /**
662
- * Compatibility alias for {@link CjsResMan#Update}. It uses the same queue
663
- * budgets, byte-cache housekeeping, opt-in purge cadence, return value, and
664
- * error behavior.
665
- *
666
- * @param {CjsResManUpdateOptions} [options={}] Queue budgets and optional automatic-purge controls.
667
- * @returns {boolean} Whether queue work ran or housekeeping released owned state.
668
- * @throws {TypeError|AggregateError} If update options or a due purge fail.
662
+ /**
663
+ * Compatibility alias for {@link CjsResMan#Update}. It uses the same queue
664
+ * budgets, byte-cache housekeeping, opt-in purge cadence, return value, and
665
+ * error behavior.
666
+ *
667
+ * @param {CjsResManUpdateOptions} [options={}] Queue budgets and optional automatic-purge controls.
668
+ * @returns {boolean} Whether queue work ran or housekeeping released owned state.
669
+ * @throws {TypeError|AggregateError} If update options or a due purge fail.
669
670
  */
670
671
  Tick(options = {}) {
671
672
  return this.Update(options);
672
673
  }
673
674
 
674
- /**
675
- * Wait for the manager work that exists when this method is called.
676
- * The snapshot contains active queued resource load roots and direct queue
677
- * tasks. A captured resource root includes every CPU-work descendant it
678
- * enqueues later, while unrelated roots/tasks submitted after the call do
679
- * not postpone this fence. Shared-source joins do not merge distinct roots.
680
- *
681
- * Failure and queued cancellation count as terminal settlement: callers
682
- * observe those errors through the original operation promises, while this
683
- * method resolves after every captured promise settles. By default it pumps
684
- * background and main queues directly, so waiting never triggers automatic
685
- * retention sweeps. Paused queues remain paused. With `pump: false`, an
686
- * external driver must resume/pump queues or the returned promise may remain
687
- * pending.
688
- *
689
- * A standalone canonical `PrepareResourceObjectQueued()` call opens a
690
- * resource root. Direct `LoadResourceObject()`, direct
691
- * `PrepareResourceObject()`, standalone `ReadResource()`, and standalone
692
- * `ReadFormatOnce()` calls bypass the two queues and are not resource roots
693
- * unless they also own a captured queue task. `WaitUrgent()` remains absent
694
- * until per-item priority and urgent membership exist.
695
- *
696
- * @param {CjsResManWaitOptions} [options={}] Snapshot pumping and cooperative-yield controls.
697
- * @returns {Promise<CjsResMan>} This manager after all captured work settles.
698
- * @throws {TypeError} If options, `pump`, or `yield` are invalid.
699
- * @throws {Error} If a queue pump or custom yield callback itself fails.
675
+ /**
676
+ * Wait for the manager work that exists when this method is called.
677
+ * The snapshot contains active queued resource load roots and direct queue
678
+ * tasks. A captured resource root includes every CPU-work descendant it
679
+ * enqueues later, while unrelated roots/tasks submitted after the call do
680
+ * not postpone this fence. Shared-source joins do not merge distinct roots.
681
+ *
682
+ * Failure and queued cancellation count as terminal settlement: callers
683
+ * observe those errors through the original operation promises, while this
684
+ * method resolves after every captured promise settles. By default it pumps
685
+ * background and main queues directly, so waiting never triggers automatic
686
+ * retention sweeps. Paused queues remain paused. With `pump: false`, an
687
+ * external driver must resume/pump queues or the returned promise may remain
688
+ * pending.
689
+ *
690
+ * A standalone canonical `PrepareResourceObjectQueued()` call opens a
691
+ * resource root. Direct `LoadResourceObject()`, direct
692
+ * `PrepareResourceObject()`, standalone `ReadResource()`, and standalone
693
+ * `ReadFormatOnce()` calls bypass the two queues and are not resource roots
694
+ * unless they also own a captured queue task. `WaitUrgent()` remains absent
695
+ * until per-item priority and urgent membership exist.
696
+ *
697
+ * @param {CjsResManWaitOptions} [options={}] Snapshot pumping and cooperative-yield controls.
698
+ * @returns {Promise<CjsResMan>} This manager after all captured work settles.
699
+ * @throws {TypeError} If options, `pump`, or `yield` are invalid.
700
+ * @throws {Error} If a queue pump or custom yield callback itself fails.
700
701
  */
701
702
  async Wait(options = {}) {
702
703
  if (!options || typeof options !== "object" || Array.isArray(options)) {
@@ -729,27 +730,27 @@ class CjsResMan extends CjsEventEmitter {
729
730
  return this;
730
731
  }
731
732
 
732
- /**
733
- * Returns the execution queue selected by its public lane name for the
734
- * resource manager.
733
+ /**
734
+ * Returns the execution queue selected by its public lane name for the
735
+ * resource manager.
735
736
  */
736
737
  GetWorkQueue(queue) {
737
738
  return CjsResManWorkQueue.normalizeName(queue) === CjsResManQueue.MAIN ? this._prepareQueue : this._loadQueue;
738
739
  }
739
740
 
740
- /**
741
- * Add one low-level task to a manager queue and retain its promise only while
742
- * pending so a contemporaneous {@link CjsResMan#Wait} snapshot can include
743
- * it. This does not assign resource lineage to tasks the callback may submit
744
- * later; callers should return/await such work or use a manager resource
745
- * operation.
746
- *
747
- * @param {string} queue Queue name or compatibility alias.
748
- * @param {Function} callback Queue callback receiving immutable task metadata.
749
- * @param {*} [context=null] `this` value used to invoke the callback.
750
- * @param {object|null} [metadata=null] Opaque diagnostics retained on the task.
751
- * @returns {object} Queue task record containing id, queue, state, metadata, and promise.
752
- * @throws {TypeError} If the queue or callback is invalid.
741
+ /**
742
+ * Add one low-level task to a manager queue and retain its promise only while
743
+ * pending so a contemporaneous {@link CjsResMan#Wait} snapshot can include
744
+ * it. This does not assign resource lineage to tasks the callback may submit
745
+ * later; callers should return/await such work or use a manager resource
746
+ * operation.
747
+ *
748
+ * @param {string} queue Queue name or compatibility alias.
749
+ * @param {Function} callback Queue callback receiving immutable task metadata.
750
+ * @param {*} [context=null] `this` value used to invoke the callback.
751
+ * @param {object|null} [metadata=null] Opaque diagnostics retained on the task.
752
+ * @returns {object} Queue task record containing id, queue, state, metadata, and promise.
753
+ * @throws {TypeError} If the queue or callback is invalid.
753
754
  */
754
755
  QueueTask(queue, callback, context = null, metadata = null) {
755
756
  return this.#TrackQueueTask(this.GetWorkQueue(queue).Add(callback, context, metadata));
@@ -766,9 +767,9 @@ class CjsResMan extends CjsEventEmitter {
766
767
  return this;
767
768
  }
768
769
 
769
- /**
770
- * Requests a later main-thread preparation scheduling pass for the resource
771
- * manager.
770
+ /**
771
+ * Requests a later main-thread preparation scheduling pass for the resource
772
+ * manager.
772
773
  */
773
774
  ScheduleMainThreadQueue() {
774
775
  if (!this.autoPumpMainThreadQueue || this._mainThreadPumpScheduled || this._prepareQueue.IsPaused()) return this;
@@ -785,20 +786,23 @@ class CjsResMan extends CjsEventEmitter {
785
786
  return this;
786
787
  }
787
788
 
788
- /**
789
- * Register a resource constructor or factory for one semantic outcome.
790
- * The constructor is selected by `requirement`/`payload`, never by file
791
- * extension. It does not enter resource identity: re-registration affects a
792
- * path/output only after its existing handle is explicitly deleted/cleared.
793
- *
794
- * @param {string|Function} requirement Semantic outcome key, or a constructor declaring its own `payload`.
795
- * @param {Function|object|null} [Constructor=null] Resource constructor/factory, or options when the first argument is the constructor.
796
- * @param {object} [options={}] Registration aliases and optional requirement/payload override.
789
+ /**
790
+ * Register a resource constructor or factory for one semantic outcome.
791
+ * An explicit keyed registration replaces the semantic default. Constructor
792
+ * shorthand is additive: when several classes declare one requirement, a
793
+ * matching extension handler selects the concrete class and an un-routed
794
+ * request fails as ambiguous. Registration does not enter resource identity:
795
+ * changes affect a path/output only after its existing handle is deleted.
796
+ *
797
+ * @param {string|Function} requirement Semantic outcome key, or a constructor declaring its own `payload`.
798
+ * @param {Function|object|null} [Constructor=null] Resource constructor/factory, or options when the first argument is the constructor.
799
+ * @param {object} [options={}] Registration aliases and optional requirement/payload override.
797
800
  * @param {readonly string[]} [options.aliases=[]] Additional semantic keys mapped to the same constructor.
798
- * @returns {CjsResMan} This resource manager.
799
- * @throws {TypeError} If the semantic key or constructor/factory is invalid.
801
+ * @returns {CjsResMan} This resource manager.
802
+ * @throws {TypeError} If the semantic key or constructor/factory is invalid.
800
803
  */
801
804
  RegisterResourceType(requirement, Constructor = null, options = {}) {
805
+ const inferredRequirement = typeof requirement === "function";
802
806
  if (typeof requirement === "function") {
803
807
  options = Constructor && typeof Constructor === "object" ? Constructor : {};
804
808
  Constructor = requirement;
@@ -809,25 +813,31 @@ class CjsResMan extends CjsEventEmitter {
809
813
  if (typeof Constructor !== "function") {
810
814
  throw new TypeError("CjsResMan.RegisterResourceType requires a constructor or factory.");
811
815
  }
816
+ const candidates = inferredRequirement ? this.#resourceTypeCandidates.get(key) || new Set() : new Set();
817
+ candidates.add(Constructor);
818
+ this.#resourceTypeCandidates.set(key, candidates);
812
819
  this.resourceTypes.set(key, Constructor);
813
820
  for (const alias of options.aliases || []) {
814
821
  const aliasKey = normalizeRequirement(alias);
815
- if (aliasKey) this.resourceTypes.set(aliasKey, Constructor);
822
+ if (aliasKey) {
823
+ this.#resourceTypeCandidates.set(aliasKey, new Set([Constructor]));
824
+ this.resourceTypes.set(aliasKey, Constructor);
825
+ }
816
826
  }
817
827
  return this;
818
828
  }
819
829
 
820
- /**
821
- * Register the direct byte-to-object reader for one input extension.
822
- * Direct loaders take precedence over registered format facades and are
823
- * resolved from current setup-time configuration whenever source is read.
824
- * A direct loader represents only the extension's unforced default result;
825
- * multiple named outputs belong on a registered format facade.
826
- *
827
- * @param {string} ext Input extension with or without a leading dot.
828
- * @param {Function} loader Reader receiving source bytes and an immutable preparation context.
829
- * @returns {CjsResMan} This resource manager.
830
- * @throws {TypeError} If the extension or loader is invalid.
830
+ /**
831
+ * Register the direct byte-to-object reader for one input extension.
832
+ * Direct loaders take precedence over registered format facades and are
833
+ * resolved from current setup-time configuration whenever source is read.
834
+ * A direct loader represents only the extension's unforced default result;
835
+ * multiple named outputs belong on a registered format facade.
836
+ *
837
+ * @param {string} ext Input extension with or without a leading dot.
838
+ * @param {Function} loader Reader receiving source bytes and an immutable preparation context.
839
+ * @returns {CjsResMan} This resource manager.
840
+ * @throws {TypeError} If the extension or loader is invalid.
831
841
  */
832
842
  RegisterObjectLoader(ext, loader) {
833
843
  const key = normalizeResourceExtension(ext);
@@ -837,28 +847,28 @@ class CjsResMan extends CjsEventEmitter {
837
847
  return this;
838
848
  }
839
849
 
840
- /**
841
- * Register a reusable format facade for each accepted input extension.
842
- * Multiple candidates may share an extension and are resolved by requested
843
- * output/media type or by their support probes. Defaults are copied into a
844
- * deeply frozen plain-object/array snapshot so later caller mutation cannot
845
- * rewrite the registered configuration. Format methods are read from the
846
- * currently registered facade when an operation runs.
847
- *
848
- * @param {Function} Format Format facade declaring at least one `inputTypes` extension.
849
- * @param {object} [defaults={}] Plain reader-option defaults to snapshot for this registration.
850
- * @returns {CjsResMan} This resource manager.
851
- * @throws {TypeError} If the format declaration or immutable defaults snapshot is invalid.
850
+ /**
851
+ * Register a reusable format facade for each accepted input extension.
852
+ * Multiple candidates may share an extension and are resolved by requested
853
+ * output/media type or by their support probes. Defaults are copied into a
854
+ * deeply frozen plain-object/array snapshot so later caller mutation cannot
855
+ * rewrite the registered configuration. Format methods are read from the
856
+ * currently registered facade when an operation runs.
857
+ *
858
+ * @param {Function} Format Format facade declaring at least one extension.
859
+ * @param {object} [defaults={}] Plain reader-option defaults to snapshot for this registration.
860
+ * @returns {CjsResMan} This resource manager.
861
+ * @throws {TypeError} If the format declaration or immutable defaults snapshot is invalid.
852
862
  */
853
863
  RegisterFormat(Format, defaults = {}) {
854
864
  if (typeof Format !== "function") {
855
865
  throw new TypeError("CjsResMan.RegisterFormat requires a format class.");
856
866
  }
857
- if (!Array.isArray(Format.inputTypes) || Format.inputTypes.length === 0) {
858
- throw new TypeError(`${Format.name || "Format"} must declare non-empty inputTypes.`);
867
+ if (!Array.isArray(Format.extensions) || Format.extensions.length === 0) {
868
+ throw new TypeError(`${Format.name || "Format"} must declare non-empty extensions.`);
859
869
  }
860
870
  const descriptor = createFormatDescriptor(Format, defaults);
861
- for (const inputType of Format.inputTypes) {
871
+ for (const inputType of Format.extensions) {
862
872
  const key = normalizeResourceExtension(inputType);
863
873
  if (!key) continue;
864
874
  const candidates = this.formats.get(key) || [];
@@ -869,19 +879,19 @@ class CjsResMan extends CjsEventEmitter {
869
879
  return this;
870
880
  }
871
881
 
872
- /**
873
- * Register one extension-selected resource or object handler and its reader
874
- * route. A format constructor and an ordered format array are short forms
875
- * for `{ Format }` and `{ Formats }` respectively.
876
- *
877
- * Re-registration replaces the complete route for future uncached handles.
878
- * Existing handles retain the route snapshot captured at construction.
879
- *
880
- * @param {string} extension Input extension with or without a leading dot.
881
- * @param {Function} Handler CjsResource-compatible handler constructor.
882
- * @param {Function|Function[]|object} [formatOrFormatsOrOptions={}] Reader and optional target configuration.
883
- * @returns {CjsResMan} This resource manager.
884
- * @throws {TypeError} If the extension, handler, formats, or target policy is invalid.
882
+ /**
883
+ * Register one extension-selected resource or object handler and its reader
884
+ * route. A format constructor and an ordered format array are short forms
885
+ * for `{ Format }` and `{ Formats }` respectively.
886
+ *
887
+ * Re-registration replaces the complete route for future uncached handles.
888
+ * Existing handles retain the route snapshot captured at construction.
889
+ *
890
+ * @param {string} extension Input extension with or without a leading dot.
891
+ * @param {Function} Handler CjsResource-compatible handler constructor.
892
+ * @param {Function|Function[]|object} [formatOrFormatsOrOptions={}] Reader and optional target configuration.
893
+ * @returns {CjsResMan} This resource manager.
894
+ * @throws {TypeError} If the extension, handler, formats, or target policy is invalid.
885
895
  */
886
896
  RegisterExtension(extension, Handler, formatOrFormatsOrOptions = {}) {
887
897
  const ext = normalizeResourceExtension(extension);
@@ -936,52 +946,52 @@ class CjsResMan extends CjsEventEmitter {
936
946
  return this;
937
947
  }
938
948
 
939
- /**
940
- * Return the current immutable explicit route for one extension.
941
- *
942
- * @param {string} extension Input extension with or without a leading dot.
943
- * @returns {object|null} Captured route descriptor, or `null`.
949
+ /**
950
+ * Return the current immutable explicit route for one extension.
951
+ *
952
+ * @param {string} extension Input extension with or without a leading dot.
953
+ * @returns {object|null} Captured route descriptor, or `null`.
944
954
  */
945
955
  GetExtensionRoute(extension) {
946
956
  return this.#extensionRoutes.get(normalizeResourceExtension(extension)) || null;
947
957
  }
948
958
 
949
- /**
950
- * Return registered format facades for one normalized input extension.
951
- *
952
- * @param {string} inputType Input extension with or without a leading dot.
953
- * @returns {Function[]} Detached format-class list in registration order.
959
+ /**
960
+ * Return registered format facades for one normalized input extension.
961
+ *
962
+ * @param {string} inputType Input extension with or without a leading dot.
963
+ * @returns {Function[]} Detached format-class list in registration order.
954
964
  */
955
965
  GetFormats(inputType) {
956
966
  return this.GetFormatDescriptors(inputType).map(descriptor => descriptor.Format);
957
967
  }
958
968
 
959
- /**
960
- * Select one registered format facade for an input and requested outcome.
961
- *
962
- * @param {string} inputType Input extension with or without a leading dot.
963
- * @param {object} [options={}] Optional format, output, media type, and source-byte selectors.
964
- * @returns {Function} Unambiguous selected format facade.
965
- * @throws {Error} If no candidate matches or multiple candidates remain.
969
+ /**
970
+ * Select one registered format facade for an input and requested outcome.
971
+ *
972
+ * @param {string} inputType Input extension with or without a leading dot.
973
+ * @param {object} [options={}] Optional format, output, media type, and source-byte selectors.
974
+ * @returns {Function} Unambiguous selected format facade.
975
+ * @throws {Error} If no candidate matches or multiple candidates remain.
966
976
  */
967
977
  ResolveFormat(inputType, options = {}) {
968
978
  return this.ResolveFormatDescriptor(inputType, options).Format;
969
979
  }
970
980
 
971
- /**
972
- * Return the immediate canonical resource handle for a source path and
973
- * promised output. Cache hits explicitly renew MotherLode activity. When
974
- * `reload: true` finds an existing owner, this synchronous method returns a
975
- * distinct off-registry candidate and leaves the canonical handle untouched.
976
- * Calling `Ready()` on that candidate, or using `ReloadResource()` /
977
- * `ReloadObject()`, prepares it and conditionally commits it through the
978
- * asynchronous atomic-reload contract.
979
- *
980
- * @param {string} path Carbon-style source resource path.
981
- * @param {object} [options={}] Promised output, semantic resource, source provenance, and reload settings.
982
- * @returns {CjsResource} Canonical handle, or an off-registry reload candidate.
983
- * @throws {TypeError} If the path, identity settings, or resource constructor are invalid.
984
- * @throws {Error} If MotherLode is inactive or displaced-resource cleanup fails.
981
+ /**
982
+ * Return the immediate canonical resource handle for a source path and
983
+ * promised output. Cache hits explicitly renew MotherLode activity. When
984
+ * `reload: true` finds an existing owner, this synchronous method returns a
985
+ * distinct off-registry candidate and leaves the canonical handle untouched.
986
+ * Calling `Ready()` on that candidate, or using `ReloadResource()` /
987
+ * `ReloadObject()`, prepares it and conditionally commits it through the
988
+ * asynchronous atomic-reload contract.
989
+ *
990
+ * @param {string} path Carbon-style source resource path.
991
+ * @param {object} [options={}] Promised output, semantic resource, source provenance, and reload settings.
992
+ * @returns {CjsResource} Canonical handle, or an off-registry reload candidate.
993
+ * @throws {TypeError} If the path, identity settings, or resource constructor are invalid.
994
+ * @throws {Error} If MotherLode is inactive or displaced-resource cleanup fails.
985
995
  */
986
996
  GetResource(path, options = {}) {
987
997
  if (!options || typeof options !== "object" || Array.isArray(options)) {
@@ -1061,19 +1071,19 @@ class CjsResMan extends CjsEventEmitter {
1061
1071
  return canonical;
1062
1072
  }
1063
1073
 
1064
- /**
1065
- * Resolve one object outcome for a canonical resource identity. Concurrent
1066
- * callers share only the active operation. Once settled, a resident payload
1067
- * is returned without rereading source data and its explicit payload lease is
1068
- * renewed. If the payload was released, calling this method explicitly starts
1069
- * reconstruction; liveness queries and purge operations never do so.
1070
- * `sourceRevision` selects read-cache provenance but does not replace a
1071
- * resident payload by itself—use one-shot `reload: true` for replacement.
1072
- *
1073
- * @param {string} path Carbon-style source resource path.
1074
- * @param {object} [options={}] Identity, source, format, loader, and queue options.
1075
- * @returns {Promise<*>} In-flight, resident, or reconstructed object outcome.
1076
- * @throws {TypeError|Error} If path, identity, source, format, or conversion configuration is invalid.
1074
+ /**
1075
+ * Resolve one object outcome for a canonical resource identity. Concurrent
1076
+ * callers share only the active operation. Once settled, a resident payload
1077
+ * is returned without rereading source data and its explicit payload lease is
1078
+ * renewed. If the payload was released, calling this method explicitly starts
1079
+ * reconstruction; liveness queries and purge operations never do so.
1080
+ * `sourceRevision` selects read-cache provenance but does not replace a
1081
+ * resident payload by itself—use one-shot `reload: true` for replacement.
1082
+ *
1083
+ * @param {string} path Carbon-style source resource path.
1084
+ * @param {object} [options={}] Identity, source, format, loader, and queue options.
1085
+ * @returns {Promise<*>} In-flight, resident, or reconstructed object outcome.
1086
+ * @throws {TypeError|Error} If path, identity, source, format, or conversion configuration is invalid.
1077
1087
  */
1078
1088
  GetObject(path, options = {}) {
1079
1089
  const resource = this.GetResource(path, options);
@@ -1108,31 +1118,31 @@ class CjsResMan extends CjsEventEmitter {
1108
1118
  return promise;
1109
1119
  }
1110
1120
 
1111
- /**
1112
- * Loads and hydrates an object graph through the configured resource pipeline
1113
- * for the resource manager.
1121
+ /**
1122
+ * Loads and hydrates an object graph through the configured resource pipeline
1123
+ * for the resource manager.
1114
1124
  */
1115
1125
  LoadObject(path, options = {}) {
1116
1126
  return this.GetObject(path, options);
1117
1127
  }
1118
1128
 
1119
- /**
1120
- * Fetches and hydrates an object graph without retaining a resource handle for
1121
- * the resource manager.
1129
+ /**
1130
+ * Fetches and hydrates an object graph without retaining a resource handle for
1131
+ * the resource manager.
1122
1132
  */
1123
1133
  FetchObject(path, options = {}) {
1124
1134
  return this.GetObject(path, options);
1125
1135
  }
1126
1136
 
1127
- /**
1128
- * Read and atomically publish a distinct replacement object while the
1129
- * former canonical resource remains available. This is the explicit form of
1130
- * `GetObject(path, { reload: true })`.
1131
- *
1132
- * @param {string} path Carbon-style source resource path.
1133
- * @param {object} [options={}] Identity, source, format, and queue settings.
1134
- * @returns {Promise<*>} Published CPU object outcome from the committed candidate.
1135
- * @throws {TypeError|Error|AggregateError} If candidate creation, conversion, conditional publication, or cleanup fails.
1137
+ /**
1138
+ * Read and atomically publish a distinct replacement object while the
1139
+ * former canonical resource remains available. This is the explicit form of
1140
+ * `GetObject(path, { reload: true })`.
1141
+ *
1142
+ * @param {string} path Carbon-style source resource path.
1143
+ * @param {object} [options={}] Identity, source, format, and queue settings.
1144
+ * @returns {Promise<*>} Published CPU object outcome from the committed candidate.
1145
+ * @throws {TypeError|Error|AggregateError} If candidate creation, conversion, conditional publication, or cleanup fails.
1136
1146
  */
1137
1147
  ReloadObject(path, options = {}) {
1138
1148
  if (!options || typeof options !== "object" || Array.isArray(options)) {
@@ -1144,17 +1154,17 @@ class CjsResMan extends CjsEventEmitter {
1144
1154
  });
1145
1155
  }
1146
1156
 
1147
- /**
1148
- * Resolve and load one canonical resource handle. One-shot reload creates
1149
- * a distinct candidate, keeps the former good handle canonical through every
1150
- * asynchronous CPU operation, and returns only after an exact-owner conditional
1151
- * publication succeeds. Readiness receives `reload: false` because the
1152
- * candidate's private loader owns the one-shot freshness request.
1153
- *
1154
- * @param {string} path Carbon-style source resource path.
1155
- * @param {object} [options={}] Resource identity, source provenance, reload, format, and queue options.
1156
- * @returns {Promise<CjsResource>} Loaded canonical resource selected by this operation.
1157
- * @throws {TypeError|Error} If identity, source, format, conversion, or cleanup fails.
1157
+ /**
1158
+ * Resolve and load one canonical resource handle. One-shot reload creates
1159
+ * a distinct candidate, keeps the former good handle canonical through every
1160
+ * asynchronous CPU operation, and returns only after an exact-owner conditional
1161
+ * publication succeeds. Readiness receives `reload: false` because the
1162
+ * candidate's private loader owns the one-shot freshness request.
1163
+ *
1164
+ * @param {string} path Carbon-style source resource path.
1165
+ * @param {object} [options={}] Resource identity, source provenance, reload, format, and queue options.
1166
+ * @returns {Promise<CjsResource>} Loaded canonical resource selected by this operation.
1167
+ * @throws {TypeError|Error} If identity, source, format, conversion, or cleanup fails.
1158
1168
  */
1159
1169
  async FetchResource(path, options = {}) {
1160
1170
  const resource = this.GetResource(path, options);
@@ -1166,15 +1176,15 @@ class CjsResMan extends CjsEventEmitter {
1166
1176
  return resource;
1167
1177
  }
1168
1178
 
1169
- /**
1170
- * Load and atomically publish a distinct replacement resource while the
1171
- * former canonical handle remains available. This is the explicit form of
1172
- * `FetchResource(path, { reload: true })`.
1173
- *
1174
- * @param {string} path Carbon-style source resource path.
1175
- * @param {object} [options={}] Identity, source, format, and queue settings.
1176
- * @returns {Promise<CjsResource>} Fully loaded committed replacement.
1177
- * @throws {TypeError|Error|AggregateError} If candidate creation, conversion, conditional publication, or cleanup fails.
1179
+ /**
1180
+ * Load and atomically publish a distinct replacement resource while the
1181
+ * former canonical handle remains available. This is the explicit form of
1182
+ * `FetchResource(path, { reload: true })`.
1183
+ *
1184
+ * @param {string} path Carbon-style source resource path.
1185
+ * @param {object} [options={}] Identity, source, format, and queue settings.
1186
+ * @returns {Promise<CjsResource>} Fully loaded committed replacement.
1187
+ * @throws {TypeError|Error|AggregateError} If candidate creation, conversion, conditional publication, or cleanup fails.
1178
1188
  */
1179
1189
  ReloadResource(path, options = {}) {
1180
1190
  if (!options || typeof options !== "object" || Array.isArray(options)) {
@@ -1186,15 +1196,15 @@ class CjsResMan extends CjsEventEmitter {
1186
1196
  });
1187
1197
  }
1188
1198
 
1189
- /**
1190
- * Run or join one off-registry candidate operation. The returned promise
1191
- * resolves only after exact-owner publication and displaced-owner cleanup
1192
- * both succeed. A committed cleanup failure rejects with the new candidate
1193
- * still canonical and attached on the MotherLode error result.
1194
- *
1195
- * @param {object|Function} resource Candidate resource returned by `GetResource`.
1196
- * @param {object} options Reload source, format, and queue options.
1197
- * @returns {Promise<*>} Candidate object outcome after conditional publication.
1199
+ /**
1200
+ * Run or join one off-registry candidate operation. The returned promise
1201
+ * resolves only after exact-owner publication and displaced-owner cleanup
1202
+ * both succeed. A committed cleanup failure rejects with the new candidate
1203
+ * still canonical and attached on the MotherLode error result.
1204
+ *
1205
+ * @param {object|Function} resource Candidate resource returned by `GetResource`.
1206
+ * @param {object} options Reload source, format, and queue options.
1207
+ * @returns {Promise<*>} Candidate object outcome after conditional publication.
1198
1208
  */
1199
1209
  #GetReloadCandidateObject(resource, options) {
1200
1210
  const candidate = this.#reloadCandidates.get(resource) || null;
@@ -1220,15 +1230,15 @@ class CjsResMan extends CjsEventEmitter {
1220
1230
  return operation.promise;
1221
1231
  }
1222
1232
 
1223
- /**
1224
- * Queue source/read/publication work against a detached candidate, then commit
1225
- * it only if its former exact owner and newest-request token remain current.
1226
- * Candidate work is a normal queued root visible to `Wait()` and holds one
1227
- * purge lock on the former good owner until settlement.
1228
- *
1229
- * @param {CjsResourceReloadCandidate} candidate Immutable candidate authority.
1230
- * @param {object} options Reload source, format, queue, and prepare options.
1231
- * @returns {Promise<*>} Published object outcome after a successful commit.
1233
+ /**
1234
+ * Queue source/read/publication work against a detached candidate, then commit
1235
+ * it only if its former exact owner and newest-request token remain current.
1236
+ * Candidate work is a normal queued root visible to `Wait()` and holds one
1237
+ * purge lock on the former good owner until settlement.
1238
+ *
1239
+ * @param {CjsResourceReloadCandidate} candidate Immutable candidate authority.
1240
+ * @param {object} options Reload source, format, queue, and prepare options.
1241
+ * @returns {Promise<*>} Published object outcome after a successful commit.
1232
1242
  */
1233
1243
  async #RunReloadCandidate(candidate, options) {
1234
1244
  let committed = false;
@@ -1291,13 +1301,13 @@ class CjsResMan extends CjsEventEmitter {
1291
1301
  }
1292
1302
  }
1293
1303
 
1294
- /**
1295
- * Bind a successfully committed candidate and invalidate only the displaced
1296
- * handle's former publication generation. The resource loader is restored
1297
- * to ordinary canonical reconstruction behavior.
1298
- *
1299
- * @param {CjsResourceReloadCandidate} candidate Committed candidate authority.
1300
- * @returns {void}
1304
+ /**
1305
+ * Bind a successfully committed candidate and invalidate only the displaced
1306
+ * handle's former publication generation. The resource loader is restored
1307
+ * to ordinary canonical reconstruction behavior.
1308
+ *
1309
+ * @param {CjsResourceReloadCandidate} candidate Committed candidate authority.
1310
+ * @returns {void}
1301
1311
  */
1302
1312
  #FinalizeCommittedReload(candidate) {
1303
1313
  this.#InvalidateResourceOwnership(candidate.expected);
@@ -1329,15 +1339,15 @@ class CjsResMan extends CjsEventEmitter {
1329
1339
  }
1330
1340
  }
1331
1341
 
1332
- /**
1333
- * Mark and clean a failed or stale detached candidate. The original
1334
- * load/prepare/stale error remains the rejection when cleanup succeeds;
1335
- * state-publication or cleanup errors are aggregated without touching the
1336
- * preserved canonical owner.
1337
- *
1338
- * @param {CjsResourceReloadCandidate} candidate Failed candidate authority.
1339
- * @param {*} cause Original operation failure.
1340
- * @returns {*} Original error or a contextual AggregateError.
1342
+ /**
1343
+ * Mark and clean a failed or stale detached candidate. The original
1344
+ * load/prepare/stale error remains the rejection when cleanup succeeds;
1345
+ * state-publication or cleanup errors are aggregated without touching the
1346
+ * preserved canonical owner.
1347
+ *
1348
+ * @param {CjsResourceReloadCandidate} candidate Failed candidate authority.
1349
+ * @param {*} cause Original operation failure.
1350
+ * @returns {*} Original error or a contextual AggregateError.
1341
1351
  */
1342
1352
  #CreateReloadCandidateFailure(candidate, cause) {
1343
1353
  const errors = [cause];
@@ -1359,14 +1369,14 @@ class CjsResMan extends CjsEventEmitter {
1359
1369
  return error;
1360
1370
  }
1361
1371
 
1362
- /**
1363
- * Release adapter and CPU-payload ownership accumulated by an off-registry
1364
- * candidate. This cleanup is idempotent for CjsResource-compatible handles
1365
- * and never marks the never-canonical candidate `PURGED`.
1366
- *
1367
- * @param {object|Function} resource Detached reload candidate.
1368
- * @returns {void}
1369
- * @throws {AggregateError} If adapter destruction, payload release, or lifecycle detachment fails.
1372
+ /**
1373
+ * Release adapter and CPU-payload ownership accumulated by an off-registry
1374
+ * candidate. This cleanup is idempotent for CjsResource-compatible handles
1375
+ * and never marks the never-canonical candidate `PURGED`.
1376
+ *
1377
+ * @param {object|Function} resource Detached reload candidate.
1378
+ * @returns {void}
1379
+ * @throws {AggregateError} If adapter destruction, payload release, or lifecycle detachment fails.
1370
1380
  */
1371
1381
  #CleanupReloadCandidate(resource) {
1372
1382
  const errors = [];
@@ -1392,9 +1402,9 @@ class CjsResMan extends CjsEventEmitter {
1392
1402
  }
1393
1403
  }
1394
1404
 
1395
- /**
1396
- * Fetches raw source bytes through the configured resource source for the
1397
- * resource manager.
1405
+ /**
1406
+ * Fetches raw source bytes through the configured resource source for the
1407
+ * resource manager.
1398
1408
  */
1399
1409
  Fetch(path, options = {}) {
1400
1410
  if (options.resource === true || options.requirement !== undefined || options.payload !== undefined) {
@@ -1409,18 +1419,18 @@ class CjsResMan extends CjsEventEmitter {
1409
1419
  return route?.handlerMode === ResourceHandlerMode.RESOURCE ? this.FetchResource(path, options) : this.FetchObject(path, options);
1410
1420
  }
1411
1421
 
1412
- /**
1413
- * Read and prepare an existing resource immediately, outside the manager
1414
- * queues. One balanced purge lock protects the canonical handle for the
1415
- * complete asynchronous operation; any caller-owned locks remain intact.
1416
- * Failure is published to the resource before rejection only while its
1417
- * captured ownership generation remains canonical. A detached operation
1418
- * preserves its original failure without changing the old handle.
1419
- *
1420
- * @param {CjsResource} resource Existing manager-bound resource handle.
1421
- * @param {object} [options={}] Source, format, semantic outcome, and queue options.
1422
- * @returns {Promise<*>} Prepared object, or the semantic resource when it owns the payload.
1423
- * @throws {TypeError|Error} If the resource, source, format, options, or canonical ownership are invalid.
1422
+ /**
1423
+ * Read and prepare an existing resource immediately, outside the manager
1424
+ * queues. One balanced purge lock protects the canonical handle for the
1425
+ * complete asynchronous operation; any caller-owned locks remain intact.
1426
+ * Failure is published to the resource before rejection only while its
1427
+ * captured ownership generation remains canonical. A detached operation
1428
+ * preserves its original failure without changing the old handle.
1429
+ *
1430
+ * @param {CjsResource} resource Existing manager-bound resource handle.
1431
+ * @param {object} [options={}] Source, format, semantic outcome, and queue options.
1432
+ * @returns {Promise<*>} Prepared object, or the semantic resource when it owns the payload.
1433
+ * @throws {TypeError|Error} If the resource, source, format, options, or canonical ownership are invalid.
1424
1434
  */
1425
1435
  async LoadResourceObject(resource, options = {}) {
1426
1436
  const read = this.#BeginReadOperation(resource.GetPath(), options);
@@ -1444,16 +1454,16 @@ class CjsResMan extends CjsEventEmitter {
1444
1454
  }
1445
1455
  }
1446
1456
 
1447
- /**
1448
- * Queue a source read followed by CPU conversion and publication. One balanced
1449
- * purge lock is acquired before request publication and released only after
1450
- * success or failure, preventing inactivity sweeps from detaching an active
1451
- * handle. The lock does not reload data and does not consume caller locks.
1452
- *
1453
- * @param {CjsResource} resource Existing manager-bound resource handle.
1454
- * @param {object} [options={}] Source, format, queue, and semantic outcome options.
1455
- * @returns {Promise<*>} Promise for the loaded object or semantic resource.
1456
- * @throws {TypeError} If the resource cannot be queued or its options are invalid.
1457
+ /**
1458
+ * Queue a source read followed by CPU conversion and publication. One balanced
1459
+ * purge lock is acquired before request publication and released only after
1460
+ * success or failure, preventing inactivity sweeps from detaching an active
1461
+ * handle. The lock does not reload data and does not consume caller locks.
1462
+ *
1463
+ * @param {CjsResource} resource Existing manager-bound resource handle.
1464
+ * @param {object} [options={}] Source, format, queue, and semantic outcome options.
1465
+ * @returns {Promise<*>} Promise for the loaded object or semantic resource.
1466
+ * @throws {TypeError} If the resource cannot be queued or its options are invalid.
1457
1467
  */
1458
1468
  QueueResourceObject(resource, options = {}) {
1459
1469
  const read = this.#BeginReadOperation(resource.GetPath(), options);
@@ -1485,35 +1495,35 @@ class CjsResMan extends CjsEventEmitter {
1485
1495
  return operation;
1486
1496
  }
1487
1497
 
1488
- /**
1489
- * Queue one source read under the selected source/path/revision identity.
1490
- * Cache policy is tri-state: omitted shares an in-flight or explicitly
1491
- * retained record, `true` additionally retains success, and `false` bypasses
1492
- * both sharing and retention. `reload: true` invalidates this source/path
1493
- * before the new task and does not cancel detached existing consumers.
1494
- *
1495
- * @param {string} path Carbon-style source resource path.
1496
- * @param {CjsResManReadCacheOptions} [options={}] Source, revision, reload, and cache controls forwarded to the read.
1497
- * @returns {Promise<*>} Promise for source bytes or source-compatible data.
1498
- * @throws {TypeError} If path, source, revision, or options are invalid.
1498
+ /**
1499
+ * Queue one source read under the selected source/path/revision identity.
1500
+ * Cache policy is tri-state: omitted shares an in-flight or explicitly
1501
+ * retained record, `true` additionally retains success, and `false` bypasses
1502
+ * both sharing and retention. `reload: true` invalidates this source/path
1503
+ * before the new task and does not cancel detached existing consumers.
1504
+ *
1505
+ * @param {string} path Carbon-style source resource path.
1506
+ * @param {CjsResManReadCacheOptions} [options={}] Source, revision, reload, and cache controls forwarded to the read.
1507
+ * @returns {Promise<*>} Promise for source bytes or source-compatible data.
1508
+ * @throws {TypeError} If path, source, revision, or options are invalid.
1499
1509
  */
1500
1510
  QueueReadResource(path, options = {}) {
1501
1511
  const read = this.#BeginReadOperation(path, options);
1502
1512
  return this.#QueueReadResource(read.context, read.options);
1503
1513
  }
1504
1514
 
1505
- /**
1506
- * Immediately read, transform, and publish one resource payload outside the
1507
- * manager queues. Canonical resources capture their current ownership
1508
- * generation and cannot publish after deletion, clearing, or replacement;
1509
- * historically supported detached resource-like objects remain usable
1510
- * without manager ownership guards.
1511
- *
1512
- * @param {object|Function} resource Resource receiving the final payload.
1513
- * @param {*} bytes Source bytes or reader-compatible source data.
1514
- * @param {object} [options={}] Format and semantic outcome options.
1515
- * @returns {Promise<*>} Final plain payload or semantic resource handle.
1516
- * @throws {Error} If reading/preparation fails or canonical ownership becomes stale.
1515
+ /**
1516
+ * Immediately read, transform, and publish one resource payload outside the
1517
+ * manager queues. Canonical resources capture their current ownership
1518
+ * generation and cannot publish after deletion, clearing, or replacement;
1519
+ * historically supported detached resource-like objects remain usable
1520
+ * without manager ownership guards.
1521
+ *
1522
+ * @param {object|Function} resource Resource receiving the final payload.
1523
+ * @param {*} bytes Source bytes or reader-compatible source data.
1524
+ * @param {object} [options={}] Format and semantic outcome options.
1525
+ * @returns {Promise<*>} Final plain payload or semantic resource handle.
1526
+ * @throws {Error} If reading/preparation fails or canonical ownership becomes stale.
1517
1527
  */
1518
1528
  async PrepareResourceObject(resource, bytes, options = {}) {
1519
1529
  const ownership = this.#GetResourceOwnership(resource, "direct-prepare:begin");
@@ -1530,18 +1540,18 @@ class CjsResMan extends CjsEventEmitter {
1530
1540
  }
1531
1541
  }
1532
1542
 
1533
- /**
1534
- * Queue one reader/format conversion and then CPU publication on the main
1535
- * manager queue. A canonical standalone call becomes a queued resource root
1536
- * for `Wait()` and retains one balanced purge lock through settlement.
1537
- * The read and publication items validate the captured canonical generation
1538
- * before dispatch and after asynchronous settlement.
1539
- *
1540
- * @param {object|Function} resource Resource receiving the final payload.
1541
- * @param {*} bytes Source bytes or reader-compatible source data.
1542
- * @param {object} [options={}] Format and semantic outcome options.
1543
- * @returns {Promise<*>} Final plain payload or semantic resource handle.
1544
- * @throws {Error} If queueing/preparation fails or canonical ownership becomes stale.
1543
+ /**
1544
+ * Queue one reader/format conversion and then CPU publication on the main
1545
+ * manager queue. A canonical standalone call becomes a queued resource root
1546
+ * for `Wait()` and retains one balanced purge lock through settlement.
1547
+ * The read and publication items validate the captured canonical generation
1548
+ * before dispatch and after asynchronous settlement.
1549
+ *
1550
+ * @param {object|Function} resource Resource receiving the final payload.
1551
+ * @param {*} bytes Source bytes or reader-compatible source data.
1552
+ * @param {object} [options={}] Format and semantic outcome options.
1553
+ * @returns {Promise<*>} Final plain payload or semantic resource handle.
1554
+ * @throws {Error} If queueing/preparation fails or canonical ownership becomes stale.
1545
1555
  */
1546
1556
  async PrepareResourceObjectQueued(resource, bytes, options = {}) {
1547
1557
  const ownership = this.#GetResourceOwnership(resource, "queued-prepare:begin");
@@ -1558,16 +1568,16 @@ class CjsResMan extends CjsEventEmitter {
1558
1568
  }
1559
1569
  }
1560
1570
 
1561
- /**
1562
- * Read and immediately publish one CPU payload with optional hidden
1563
- * ownership authority. Format classes own every requested conversion;
1564
- * backend realization runs separately after this CPU publication.
1565
- *
1566
- * @param {object|Function} resource Resource receiving the final payload.
1567
- * @param {*} bytes Source bytes or reader-compatible source data.
1568
- * @param {object} options Resolved prepare options.
1569
- * @param {CjsResourceMutationAuthority|null} ownership Captured canonical or reload-candidate authority.
1570
- * @returns {Promise<*>} Final plain payload or semantic resource handle.
1571
+ /**
1572
+ * Read and immediately publish one CPU payload with optional hidden
1573
+ * ownership authority. Format classes own every requested conversion;
1574
+ * backend realization runs separately after this CPU publication.
1575
+ *
1576
+ * @param {object|Function} resource Resource receiving the final payload.
1577
+ * @param {*} bytes Source bytes or reader-compatible source data.
1578
+ * @param {object} options Resolved prepare options.
1579
+ * @param {CjsResourceMutationAuthority|null} ownership Captured canonical or reload-candidate authority.
1580
+ * @returns {Promise<*>} Final plain payload or semantic resource handle.
1571
1581
  */
1572
1582
  async #PrepareResourceObject(resource, bytes, options, ownership) {
1573
1583
  this.#AssertOptionalResourceOwnership(ownership, "prepare:read");
@@ -1578,16 +1588,16 @@ class CjsResMan extends CjsEventEmitter {
1578
1588
  return this.#PublishResourceObject(ownership, resource, object, options);
1579
1589
  }
1580
1590
 
1581
- /**
1582
- * Queue one main-thread reader/format operation followed by guarded CPU
1583
- * publication. Both remain distinct budgeted queue items under one resource
1584
- * root so `Wait()` continues to fence dynamically enqueued publication.
1585
- *
1586
- * @param {object|Function} resource Resource receiving the final payload.
1587
- * @param {*} bytes Source bytes or reader-compatible source data.
1588
- * @param {object} options Resolved prepare options.
1589
- * @param {CjsResourceMutationAuthority|null} ownership Captured canonical or reload-candidate authority.
1590
- * @returns {Promise<*>} Final plain payload or semantic resource handle.
1591
+ /**
1592
+ * Queue one main-thread reader/format operation followed by guarded CPU
1593
+ * publication. Both remain distinct budgeted queue items under one resource
1594
+ * root so `Wait()` continues to fence dynamically enqueued publication.
1595
+ *
1596
+ * @param {object|Function} resource Resource receiving the final payload.
1597
+ * @param {*} bytes Source bytes or reader-compatible source data.
1598
+ * @param {object} options Resolved prepare options.
1599
+ * @param {CjsResourceMutationAuthority|null} ownership Captured canonical or reload-candidate authority.
1600
+ * @returns {Promise<*>} Final plain payload or semantic resource handle.
1591
1601
  */
1592
1602
  async #PrepareResourceObjectQueued(resource, bytes, options, ownership) {
1593
1603
  let object = bytes;
@@ -1629,29 +1639,29 @@ class CjsResMan extends CjsEventEmitter {
1629
1639
  return object;
1630
1640
  }
1631
1641
 
1632
- /**
1633
- * Decode source bytes with the currently registered reader for the resource
1634
- * extension. A direct extension loader wins over registered format candidates;
1635
- * byte support probes may disambiguate those candidates.
1636
- *
1637
- * @param {CjsResource} resource Resource whose reader outcome is requested.
1638
- * @param {*} bytes Source byte payload.
1639
- * @param {object} [options={}] Requested output plus per-operation controls.
1640
- * @returns {Promise<*>} Direct-loader or registered-format reader outcome.
1641
- * @throws {Error|TypeError} If no registered reader matches or its read contract fails.
1642
+ /**
1643
+ * Decode source bytes with the currently registered reader for the resource
1644
+ * extension. A direct extension loader wins over registered format candidates;
1645
+ * byte support probes may disambiguate those candidates.
1646
+ *
1647
+ * @param {CjsResource} resource Resource whose reader outcome is requested.
1648
+ * @param {*} bytes Source byte payload.
1649
+ * @param {object} [options={}] Requested output plus per-operation controls.
1650
+ * @returns {Promise<*>} Direct-loader or registered-format reader outcome.
1651
+ * @throws {Error|TypeError} If no registered reader matches or its read contract fails.
1642
1652
  */
1643
1653
  async ReadResourceObjectPayload(resource, bytes, options = {}) {
1644
1654
  return this.#ReadResolvedResourceObjectPayload(resource, bytes, options, this.#ResolveResourceObjectRead(resource, bytes, options));
1645
1655
  }
1646
1656
 
1647
- /**
1648
- * Resolve the configured direct loader or format descriptor once so queue
1649
- * selection and execution use the same registration snapshot.
1650
- *
1651
- * @param {CjsResource} resource Resource whose CPU outcome is requested.
1652
- * @param {*} bytes Source input.
1653
- * @param {object} options Requested output options.
1654
- * @returns {{loader: Function|null, descriptor: object|null, route: object|null}} Resolved reader.
1657
+ /**
1658
+ * Resolve the configured direct loader or format descriptor once so queue
1659
+ * selection and execution use the same registration snapshot.
1660
+ *
1661
+ * @param {CjsResource} resource Resource whose CPU outcome is requested.
1662
+ * @param {*} bytes Source input.
1663
+ * @param {object} options Requested output options.
1664
+ * @returns {{loader: Function|null, descriptor: object|null, route: object|null}} Resolved reader.
1655
1665
  */
1656
1666
  #ResolveResourceObjectRead(resource, bytes, options) {
1657
1667
  const route = this.#resourceExtensionRoutes.get(resource) || null;
@@ -1679,14 +1689,14 @@ class CjsResMan extends CjsEventEmitter {
1679
1689
  };
1680
1690
  }
1681
1691
 
1682
- /**
1683
- * Execute one already-resolved reader through its direct or format path.
1684
- *
1685
- * @param {CjsResource} resource Resource whose CPU outcome is requested.
1686
- * @param {*} bytes Source input.
1687
- * @param {object} options Requested output options.
1688
- * @param {{loader: Function|null, descriptor: object|null}} resolved Reader selection.
1689
- * @returns {Promise<*>} Reader result.
1692
+ /**
1693
+ * Execute one already-resolved reader through its direct or format path.
1694
+ *
1695
+ * @param {CjsResource} resource Resource whose CPU outcome is requested.
1696
+ * @param {*} bytes Source input.
1697
+ * @param {object} options Requested output options.
1698
+ * @param {{loader: Function|null, descriptor: object|null}} resolved Reader selection.
1699
+ * @returns {Promise<*>} Reader result.
1690
1700
  */
1691
1701
  #ReadResolvedResourceObjectPayload(resource, bytes, options, resolved) {
1692
1702
  if (resolved.loader) {
@@ -1695,16 +1705,16 @@ class CjsResMan extends CjsEventEmitter {
1695
1705
  return this.ReadFormatOnce(resource, resolved.descriptor, bytes, options);
1696
1706
  }
1697
1707
 
1698
- /**
1699
- * Apply a fixed target or dynamic identification policy after format reading
1700
- * and before payload publication. Worker decoding has settled by this point,
1701
- * so constructors and Identify functions remain on the caller thread.
1702
- *
1703
- * @param {CjsResource} resource Route handler receiving the decoded value.
1704
- * @param {*} values Decoded format result.
1705
- * @param {object} options Request options.
1706
- * @param {{descriptor: object|null, route: object|null}} resolved Captured reader route.
1707
- * @returns {*} Original or hydrated object value.
1708
+ /**
1709
+ * Apply a fixed target or dynamic identification policy after format reading
1710
+ * and before payload publication. Worker decoding has settled by this point,
1711
+ * so constructors and Identify functions remain on the caller thread.
1712
+ *
1713
+ * @param {CjsResource} resource Route handler receiving the decoded value.
1714
+ * @param {*} values Decoded format result.
1715
+ * @param {object} options Request options.
1716
+ * @param {{descriptor: object|null, route: object|null}} resolved Captured reader route.
1717
+ * @returns {*} Original or hydrated object value.
1708
1718
  */
1709
1719
  #HydrateExtensionObject(resource, values, options, resolved) {
1710
1720
  const route = resolved.route;
@@ -1745,19 +1755,19 @@ class CjsResMan extends CjsEventEmitter {
1745
1755
  }
1746
1756
  }
1747
1757
 
1748
- /**
1749
- * Publish the final CPU object outcome and loaded state. Every
1750
- * CjsResource-compatible handle owns the reader/converter result through
1751
- * `SetPayload`, making CPU payloads visible to MotherLode retention policy.
1752
- * Base resources also expose the payload through the compatibility `object`
1753
- * alias; semantic subclasses continue to return and alias the resource while
1754
- * retaining their validated payload privately.
1755
- *
1756
- * @param {CjsResource} resource Target canonical resource handle.
1757
- * @param {*} object Final reader or format-converter outcome.
1758
- * @param {object} [options={}] Semantic resource validation/publication options.
1759
- * @returns {*} Plain payload for a base resource, or the semantic resource handle.
1760
- * @throws {TypeError|Error} If ownership, semantic payload validation, or loaded-state publication fails.
1758
+ /**
1759
+ * Publish the final CPU object outcome and loaded state. Every
1760
+ * CjsResource-compatible handle owns the reader/converter result through
1761
+ * `SetPayload`, making CPU payloads visible to MotherLode retention policy.
1762
+ * Base resources also expose the payload through the compatibility `object`
1763
+ * alias; semantic subclasses continue to return and alias the resource while
1764
+ * retaining their validated payload privately.
1765
+ *
1766
+ * @param {CjsResource} resource Target canonical resource handle.
1767
+ * @param {*} object Final reader or format-converter outcome.
1768
+ * @param {object} [options={}] Semantic resource validation/publication options.
1769
+ * @returns {*} Plain payload for a base resource, or the semantic resource handle.
1770
+ * @throws {TypeError|Error} If ownership, semantic payload validation, or loaded-state publication fails.
1761
1771
  */
1762
1772
  PublishResourceObject(resource, object, options = {}) {
1763
1773
  const ownership = this.#GetResourceOwnership(resource, "publish:begin");
@@ -1772,16 +1782,16 @@ class CjsResMan extends CjsEventEmitter {
1772
1782
  }
1773
1783
  }
1774
1784
 
1775
- /**
1776
- * Publish only while the captured resource authority remains canonical.
1777
- * The post-publication check catches synchronous reentrant ownership changes
1778
- * from state listeners before the caller can treat obsolete work as success.
1779
- *
1780
- * @param {CjsResourceMutationAuthority|null} ownership Captured canonical or reload-candidate authority.
1781
- * @param {object|Function} resource Resource receiving the final payload.
1782
- * @param {*} object Final reader/converter outcome.
1783
- * @param {object} options Semantic resource publication options.
1784
- * @returns {*} Plain payload or semantic resource handle.
1785
+ /**
1786
+ * Publish only while the captured resource authority remains canonical.
1787
+ * The post-publication check catches synchronous reentrant ownership changes
1788
+ * from state listeners before the caller can treat obsolete work as success.
1789
+ *
1790
+ * @param {CjsResourceMutationAuthority|null} ownership Captured canonical or reload-candidate authority.
1791
+ * @param {object|Function} resource Resource receiving the final payload.
1792
+ * @param {*} object Final reader/converter outcome.
1793
+ * @param {object} options Semantic resource publication options.
1794
+ * @returns {*} Plain payload or semantic resource handle.
1785
1795
  */
1786
1796
  #PublishResourceObject(ownership, resource, object, options) {
1787
1797
  this.#AssertOptionalResourceOwnership(ownership, "publish");
@@ -1790,81 +1800,70 @@ class CjsResMan extends CjsEventEmitter {
1790
1800
  return result;
1791
1801
  }
1792
1802
 
1793
- /**
1794
- * Apply the unguarded synchronous payload/state mutation after the caller
1795
- * has established any required canonical authority.
1796
- *
1797
- * @param {object|Function} resource Resource receiving the final payload.
1798
- * @param {*} object Final reader/converter outcome.
1799
- * @param {object} options Semantic resource publication options.
1800
- * @returns {*} Plain payload or semantic resource handle.
1803
+ /**
1804
+ * Apply the unguarded synchronous payload/state mutation after the caller
1805
+ * has established any required canonical authority.
1806
+ *
1807
+ * @param {object|Function} resource Resource receiving the final payload.
1808
+ * @param {*} object Final reader/converter outcome.
1809
+ * @param {object} options Semantic resource publication options.
1810
+ * @returns {*} Plain payload or semantic resource handle.
1801
1811
  */
1802
1812
  #PublishResourceObjectValue(resource, object, options) {
1803
- let result = object;
1804
- const route = this.#resourceExtensionRoutes.get(resource) || null;
1805
- const handlerMode = route ? this.#resourceHandlerModes.get(resource) : null;
1806
- if (handlerMode === ResourceHandlerMode.RESOURCE) {
1807
- resource.SetPayload?.(object, options);
1808
- resource.object = resource;
1809
- result = resource;
1810
- } else if (handlerMode === ResourceHandlerMode.OBJECT) {
1811
- resource.SetPayload?.(object, options);
1812
- resource.object = object;
1813
- } else if (resource.constructor !== CjsResource && typeof resource.SetPayload === "function") {
1814
- resource.SetPayload(object, options);
1815
- resource.object = resource;
1816
- result = resource;
1817
- } else {
1818
- resource.SetPayload?.(object, options);
1819
- resource.object = object;
1820
- }
1813
+ const mode = resolveResourceHandlerMode(resource, this.#resourceExtensionRoutes.get(resource) ? this.#resourceHandlerModes.get(resource) : null);
1814
+ resource.SetPayload?.(object, options);
1815
+ // The two modes differ in one thing only: what `object` names and what the
1816
+ // caller is handed back. RESOURCE publishes the stable handle, so both
1817
+ // point at the resource; OBJECT publishes the reader outcome.
1818
+ const published = mode === ResourceHandlerMode.RESOURCE ? resource : object;
1819
+ resource.object = published;
1821
1820
  // PREPARED, not LOADED: `object` is the reader/converter OUTCOME, so the
1822
1821
  // bytes have already been turned into whatever they needed to become.
1823
1822
  // LOADED means raw source data is in hand and still has to be prepared - a
1824
1823
  // resource in that state is not yet good, and marking it here left IsGood()
1825
1824
  // permanently false for every resource that does not prepare itself.
1826
1825
  if (!resource.IsPrepared?.()) resource.MarkPrepared();
1827
- return result;
1826
+ return published;
1828
1827
  }
1829
1828
 
1830
- /**
1831
- * Warms a resource and its discovered dependencies without returning payload
1832
- * data for the resource manager.
1829
+ /**
1830
+ * Warms a resource and its discovered dependencies without returning payload
1831
+ * data for the resource manager.
1833
1832
  */
1834
1833
  async Prefetch(paths, options = {}) {
1835
1834
  const entries = Array.isArray(paths) ? paths : [paths];
1836
1835
  return Promise.all(entries.map(path => this.LoadObject(path, options)));
1837
1836
  }
1838
1837
 
1839
- /**
1840
- * Return the currently registered direct reader for an input extension.
1841
- *
1842
- * @param {string} ext Input extension with or without a leading dot.
1843
- * @returns {Function|null} Registered loader or `null`.
1838
+ /**
1839
+ * Return the currently registered direct reader for an input extension.
1840
+ *
1841
+ * @param {string} ext Input extension with or without a leading dot.
1842
+ * @returns {Function|null} Registered loader or `null`.
1844
1843
  */
1845
1844
  GetObjectLoader(ext) {
1846
1845
  return this.objectLoaders.get(normalizeResourceExtension(ext)) || null;
1847
1846
  }
1848
1847
 
1849
- /**
1850
- * Return detached references to the current format descriptors for one input
1851
- * extension. Each descriptor contains its facade and frozen defaults.
1852
- *
1853
- * @param {string} inputType Input extension with or without a leading dot.
1854
- * @returns {object[]} Descriptor list in registration order.
1848
+ /**
1849
+ * Return detached references to the current format descriptors for one input
1850
+ * extension. Each descriptor contains its facade and frozen defaults.
1851
+ *
1852
+ * @param {string} inputType Input extension with or without a leading dot.
1853
+ * @returns {object[]} Descriptor list in registration order.
1855
1854
  */
1856
1855
  GetFormatDescriptors(inputType) {
1857
1856
  return [...(this.formats.get(normalizeResourceExtension(inputType)) || [])];
1858
1857
  }
1859
1858
 
1860
- /**
1861
- * Resolve one current format registration descriptor. Output/media filters
1862
- * run first; optional source bytes may then run support probes to disambiguate.
1863
- *
1864
- * @param {string} inputType Input extension with or without a leading dot.
1865
- * @param {object} [options={}] Format, output, media type, and optional byte selectors.
1866
- * @returns {object} Selected immutable registration descriptor.
1867
- * @throws {Error} If no candidate matches or multiple candidates remain.
1859
+ /**
1860
+ * Resolve one current format registration descriptor. Output/media filters
1861
+ * run first; optional source bytes may then run support probes to disambiguate.
1862
+ *
1863
+ * @param {string} inputType Input extension with or without a leading dot.
1864
+ * @param {object} [options={}] Format, output, media type, and optional byte selectors.
1865
+ * @returns {object} Selected immutable registration descriptor.
1866
+ * @throws {Error} If no candidate matches or multiple candidates remain.
1868
1867
  */
1869
1868
  ResolveFormatDescriptor(inputType, options = {}) {
1870
1869
  const key = normalizeResourceExtension(inputType);
@@ -1876,19 +1875,19 @@ class CjsResMan extends CjsEventEmitter {
1876
1875
  return resolveFormatDescriptorCandidates(candidates, key, options);
1877
1876
  }
1878
1877
 
1879
- /**
1880
- * Invoke one format descriptor using its frozen registration defaults and
1881
- * the request's explicit format options. Static async/sync readers take
1882
- * precedence over instance `ReadAsync`/`Read` compatibility methods.
1883
- *
1884
- * @param {object} descriptor Selected immutable registration descriptor.
1885
- * @param {*} bytes Source bytes supplied to the format facade.
1886
- * @param {object} [options={}] Output, class, and `formatOptions` overrides.
1887
- * @returns {Promise<*>} Parsed format outcome.
1888
- * @throws {TypeError|Error} If the facade lacks a reader or reading fails.
1889
- * @remarks Resource-backed calls pass normalized path context as the
1890
- * reader's third argument; direct descriptor reads without a resource pass
1891
- * `null`.
1878
+ /**
1879
+ * Invoke one format descriptor using its frozen registration defaults and
1880
+ * the request's explicit format options. Static async/sync readers take
1881
+ * precedence over instance `ReadAsync`/`Read` compatibility methods.
1882
+ *
1883
+ * @param {object} descriptor Selected immutable registration descriptor.
1884
+ * @param {*} bytes Source bytes supplied to the format facade.
1885
+ * @param {object} [options={}] Output, class, and `formatOptions` overrides.
1886
+ * @returns {Promise<*>} Parsed format outcome.
1887
+ * @throws {TypeError|Error} If the facade lacks a reader or reading fails.
1888
+ * @remarks Resource-backed calls pass normalized path context as the
1889
+ * reader's third argument; direct descriptor reads without a resource pass
1890
+ * `null`.
1892
1891
  */
1893
1892
  async ReadFormat(descriptor, bytes, options = {}) {
1894
1893
  const readContext = READ_CONTEXTS.get(options);
@@ -1896,14 +1895,14 @@ class CjsResMan extends CjsEventEmitter {
1896
1895
  return this.resourceLoader.ReadFormat(descriptor, bytes, createFormatReadOptions(descriptor, options), context);
1897
1896
  }
1898
1897
 
1899
- /**
1900
- * Look up and explicitly renew an existing canonical resource without
1901
- * creating, loading, or preparing a new handle.
1902
- *
1903
- * @param {string} path Carbon-style source resource path.
1904
- * @param {object} [options={}] Identity-defining resource outcome settings.
1905
- * @returns {CjsResource|null} Existing canonical handle, or `null` when absent.
1906
- * @throws {TypeError} If the path or identity settings cannot be normalized.
1898
+ /**
1899
+ * Look up and explicitly renew an existing canonical resource without
1900
+ * creating, loading, or preparing a new handle.
1901
+ *
1902
+ * @param {string} path Carbon-style source resource path.
1903
+ * @param {object} [options={}] Identity-defining resource outcome settings.
1904
+ * @returns {CjsResource|null} Existing canonical handle, or `null` when absent.
1905
+ * @throws {TypeError} If the path or identity settings cannot be normalized.
1907
1906
  */
1908
1907
  Lookup(path, options = {}) {
1909
1908
  const normalizedPath = normalizeResourcePath(path);
@@ -1916,18 +1915,18 @@ class CjsResMan extends CjsEventEmitter {
1916
1915
  return resource;
1917
1916
  }
1918
1917
 
1919
- /**
1920
- * Forget and clean canonical resources for a source path. Omitting options
1921
- * removes every resolved variant; supplying options removes only the exact
1922
- * identity derived from those outcome settings. Explicitly retained source
1923
- * and format records are independent and remain available; call
1924
- * {@link CjsResMan#InvalidateReadCache} when they must also be forgotten.
1925
- *
1926
- * @param {string} path Carbon-style source resource path.
1927
- * @param {object|null} [options=null] Exact identity settings, or `null` for all variants.
1928
- * @returns {boolean} Whether at least one canonical resource was removed.
1929
- * @throws {TypeError} If the path or identity settings cannot be normalized.
1930
- * @throws {Error|AggregateError} If cleanup fails after identities are forgotten.
1918
+ /**
1919
+ * Forget and clean canonical resources for a source path. Omitting options
1920
+ * removes every resolved variant; supplying options removes only the exact
1921
+ * identity derived from those outcome settings. Explicitly retained source
1922
+ * and format records are independent and remain available; call
1923
+ * {@link CjsResMan#InvalidateReadCache} when they must also be forgotten.
1924
+ *
1925
+ * @param {string} path Carbon-style source resource path.
1926
+ * @param {object|null} [options=null] Exact identity settings, or `null` for all variants.
1927
+ * @returns {boolean} Whether at least one canonical resource was removed.
1928
+ * @throws {TypeError} If the path or identity settings cannot be normalized.
1929
+ * @throws {Error|AggregateError} If cleanup fails after identities are forgotten.
1931
1930
  */
1932
1931
  Delete(path, options = null) {
1933
1932
  if (options !== null && options !== undefined) {
@@ -1958,15 +1957,15 @@ class CjsResMan extends CjsEventEmitter {
1958
1957
  }
1959
1958
  }
1960
1959
 
1961
- /**
1962
- * Run one explicit deterministic identity/payload inactivity sweep.
1963
- * This delegates policy and cleanup to MotherLode; it never fetches or
1964
- * reloads a purged resource.
1965
- *
1966
- * @param {object} [options={}] MotherLode frame/time limits and cleanup policy.
1967
- * @returns {object} Immutable purge counts and affected canonical keys.
1968
- * @throws {TypeError} If the configured MotherLode lacks purge support or policy is invalid.
1969
- * @throws {AggregateError} If one or more candidate resources fail cleanup.
1960
+ /**
1961
+ * Run one explicit deterministic identity/payload inactivity sweep.
1962
+ * This delegates policy and cleanup to MotherLode; it never fetches or
1963
+ * reloads a purged resource.
1964
+ *
1965
+ * @param {object} [options={}] MotherLode frame/time limits and cleanup policy.
1966
+ * @returns {object} Immutable purge counts and affected canonical keys.
1967
+ * @throws {TypeError} If the configured MotherLode lacks purge support or policy is invalid.
1968
+ * @throws {AggregateError} If one or more candidate resources fail cleanup.
1970
1969
  */
1971
1970
  PurgeInactive(options = {}) {
1972
1971
  if (typeof this.motherLode?.PurgeInactive !== "function") {
@@ -1975,16 +1974,16 @@ class CjsResMan extends CjsEventEmitter {
1975
1974
  return this.motherLode.PurgeInactive(options);
1976
1975
  }
1977
1976
 
1978
- /**
1979
- * Replace or disable the opt-in automatic inactivity policy. Configuration
1980
- * resets cadence, so the first subsequent pump performs a sweep immediately.
1981
- * Frame-based limits are rejected because manager updates are not a reliable
1982
- * renderer-frame clock. The normalized policy is frozen and never reloads
1983
- * resources.
1984
- *
1985
- * @param {CjsResManAutoPurgePolicy|false|null} [policy=null] Time-based policy, or `false`/`null` to disable automatic sweeping.
1986
- * @returns {CjsResMan} This resource manager.
1987
- * @throws {TypeError} If the policy, threshold, cleanup control, or clock is invalid.
1977
+ /**
1978
+ * Replace or disable the opt-in automatic inactivity policy. Configuration
1979
+ * resets cadence, so the first subsequent pump performs a sweep immediately.
1980
+ * Frame-based limits are rejected because manager updates are not a reliable
1981
+ * renderer-frame clock. The normalized policy is frozen and never reloads
1982
+ * resources.
1983
+ *
1984
+ * @param {CjsResManAutoPurgePolicy|false|null} [policy=null] Time-based policy, or `false`/`null` to disable automatic sweeping.
1985
+ * @returns {CjsResMan} This resource manager.
1986
+ * @throws {TypeError} If the policy, threshold, cleanup control, or clock is invalid.
1988
1987
  */
1989
1988
  SetAutoPurgePolicy(policy = null) {
1990
1989
  this.#autoPurgePolicy = normalizeAutoPurgePolicy(policy);
@@ -1992,36 +1991,36 @@ class CjsResMan extends CjsEventEmitter {
1992
1991
  return this;
1993
1992
  }
1994
1993
 
1995
- /**
1996
- * Return the immutable normalized automatic inactivity policy.
1997
- *
1998
- * @returns {Readonly<CjsResManAutoPurgePolicy>|null} Active policy, or `null` when automatic sweeping is disabled.
1994
+ /**
1995
+ * Return the immutable normalized automatic inactivity policy.
1996
+ *
1997
+ * @returns {Readonly<CjsResManAutoPurgePolicy>|null} Active policy, or `null` when automatic sweeping is disabled.
1999
1998
  */
2000
1999
  GetAutoPurgePolicy() {
2001
2000
  return this.#autoPurgePolicy;
2002
2001
  }
2003
2002
 
2004
- /**
2005
- * Report whether {@link CjsResMan#Update} may run automatic inactivity
2006
- * sweeps. This is a pure query and does not advance cadence or activity.
2007
- *
2008
- * @returns {boolean} Whether an automatic purge policy is configured.
2003
+ /**
2004
+ * Report whether {@link CjsResMan#Update} may run automatic inactivity
2005
+ * sweeps. This is a pure query and does not advance cadence or activity.
2006
+ *
2007
+ * @returns {boolean} Whether an automatic purge policy is configured.
2009
2008
  */
2010
2009
  IsAutoPurgeEnabled() {
2011
2010
  return this.#autoPurgePolicy !== null;
2012
2011
  }
2013
2012
 
2014
- /**
2015
- * Run the configured automatic sweep when its minimum time interval has
2016
- * elapsed. The first pump after configuration runs immediately. A regressing
2017
- * clock rebases cadence and skips that pump; failures consume the interval so
2018
- * repeated updates cannot form a cleanup-error storm. This method never
2019
- * creates, fetches, prepares, or reloads a resource.
2020
- *
2021
- * @param {CjsResManAutoPurgePumpOptions} [options={}] Optional deterministic timestamp.
2022
- * @returns {object|null} Immutable MotherLode purge result when due, otherwise `null`.
2023
- * @throws {TypeError} If options, the clock result, or MotherLode purge policy are invalid.
2024
- * @throws {AggregateError} If a due sweep cannot clean one or more inactive resources.
2013
+ /**
2014
+ * Run the configured automatic sweep when its minimum time interval has
2015
+ * elapsed. The first pump after configuration runs immediately. A regressing
2016
+ * clock rebases cadence and skips that pump; failures consume the interval so
2017
+ * repeated updates cannot form a cleanup-error storm. This method never
2018
+ * creates, fetches, prepares, or reloads a resource.
2019
+ *
2020
+ * @param {CjsResManAutoPurgePumpOptions} [options={}] Optional deterministic timestamp.
2021
+ * @returns {object|null} Immutable MotherLode purge result when due, otherwise `null`.
2022
+ * @throws {TypeError} If options, the clock result, or MotherLode purge policy are invalid.
2023
+ * @throws {AggregateError} If a due sweep cannot clean one or more inactive resources.
2025
2024
  */
2026
2025
  PumpAutoPurge(options = {}) {
2027
2026
  const pump = normalizeAutoPurgePumpOptions(options);
@@ -2051,12 +2050,12 @@ class CjsResMan extends CjsEventEmitter {
2051
2050
  });
2052
2051
  }
2053
2052
 
2054
- /**
2055
- * Cancel queued-but-not-started work, remove every canonical resource through
2056
- * MotherLode cleanup, and reset all in-flight deduplication ledgers.
2057
- *
2058
- * @returns {CjsResMan} This empty resource manager.
2059
- * @throws {AggregateError} If one or more canonical resources fail cleanup.
2053
+ /**
2054
+ * Cancel queued-but-not-started work, remove every canonical resource through
2055
+ * MotherLode cleanup, and reset all in-flight deduplication ledgers.
2056
+ *
2057
+ * @returns {CjsResMan} This empty resource manager.
2058
+ * @throws {AggregateError} If one or more canonical resources fail cleanup.
2060
2059
  */
2061
2060
  Clear() {
2062
2061
  this.#InvalidateMotherLodeOwnership(this.motherLode);
@@ -2072,21 +2071,21 @@ class CjsResMan extends CjsEventEmitter {
2072
2071
  return this;
2073
2072
  }
2074
2073
 
2075
- /**
2076
- * Detach reusable source and parsed-format records for one source path.
2077
- * Omitting `sourceRevision` removes every revision for the selected source;
2078
- * supplying it removes only that string/finite-number revision. Existing
2079
- * consumers keep their promises: invalidation does not abort, reject, touch
2080
- * MotherLode/payload ownership, or perform source work.
2081
- *
2082
- * `Delete()` deliberately remains resource-identity-only. Use this method
2083
- * when explicitly retained read caches must also be forgotten; `Clear()`
2084
- * resets every read ledger.
2085
- *
2086
- * @param {string} path Carbon-style source resource path.
2087
- * @param {CjsResManReadCacheOptions} [options={}] Optional `source` and exact `sourceRevision` selection.
2088
- * @returns {Readonly<{path: string, queuedSource: number, source: number, format: number}>} Frozen detached-record counts.
2089
- * @throws {TypeError} If path, source, revision, or options are invalid.
2074
+ /**
2075
+ * Detach reusable source and parsed-format records for one source path.
2076
+ * Omitting `sourceRevision` removes every revision for the selected source;
2077
+ * supplying it removes only that string/finite-number revision. Existing
2078
+ * consumers keep their promises: invalidation does not abort, reject, touch
2079
+ * MotherLode/payload ownership, or perform source work.
2080
+ *
2081
+ * `Delete()` deliberately remains resource-identity-only. Use this method
2082
+ * when explicitly retained read caches must also be forgotten; `Clear()`
2083
+ * resets every read ledger.
2084
+ *
2085
+ * @param {string} path Carbon-style source resource path.
2086
+ * @param {CjsResManReadCacheOptions} [options={}] Optional `source` and exact `sourceRevision` selection.
2087
+ * @returns {Readonly<{path: string, queuedSource: number, source: number, format: number}>} Frozen detached-record counts.
2088
+ * @throws {TypeError} If path, source, revision, or options are invalid.
2090
2089
  */
2091
2090
  InvalidateReadCache(path, options = {}) {
2092
2091
  if (!options || typeof options !== "object" || Array.isArray(options)) {
@@ -2110,33 +2109,33 @@ class CjsResMan extends CjsEventEmitter {
2110
2109
  return this.#InvalidateReadCache(source, normalizedPath, revisionKey);
2111
2110
  }
2112
2111
 
2113
- /**
2114
- * Read source data under source/path/revision cache identity. Cache policy is
2115
- * tri-state: omitted shares in-flight or explicitly retained work, `true`
2116
- * retains success, and `false` bypasses sharing and retention. Failures are
2117
- * never retained. A joining `true` request upgrades the shared record.
2118
- *
2119
- * `reload: true` invalidates the selected source/path synchronously before
2120
- * beginning fresh work; it does not cancel already detached consumers.
2121
- *
2122
- * @param {string} path Carbon-style source resource path.
2123
- * @param {CjsResManReadCacheOptions} [options={}] Source, revision, reload, and cache controls forwarded to the source.
2124
- * @returns {Promise<*>} Promise for bytes or source-compatible data.
2125
- * @throws {TypeError} If path, source, revision, cache policy, or options are invalid.
2112
+ /**
2113
+ * Read source data under source/path/revision cache identity. Cache policy is
2114
+ * tri-state: omitted shares in-flight or explicitly retained work, `true`
2115
+ * retains success, and `false` bypasses sharing and retention. Failures are
2116
+ * never retained. A joining `true` request upgrades the shared record.
2117
+ *
2118
+ * `reload: true` invalidates the selected source/path synchronously before
2119
+ * beginning fresh work; it does not cancel already detached consumers.
2120
+ *
2121
+ * @param {string} path Carbon-style source resource path.
2122
+ * @param {CjsResManReadCacheOptions} [options={}] Source, revision, reload, and cache controls forwarded to the source.
2123
+ * @returns {Promise<*>} Promise for bytes or source-compatible data.
2124
+ * @throws {TypeError} If path, source, revision, cache policy, or options are invalid.
2126
2125
  */
2127
2126
  ReadResource(path, options = {}) {
2128
2127
  const read = this.#BeginReadOperation(path, options);
2129
2128
  return this.#ReadResource(read.context, read.options);
2130
2129
  }
2131
2130
 
2132
- /**
2133
- * Normalize one source provenance context and invalidate stale path records
2134
- * once at the outermost reload boundary.
2135
- *
2136
- * @param {string} path Source path.
2137
- * @param {object} options Read options.
2138
- * @returns {{context: Readonly<CjsResourceReadContext>, options: object}} Context and detached operation options.
2139
- * @throws {TypeError} If source provenance or options are invalid.
2131
+ /**
2132
+ * Normalize one source provenance context and invalidate stale path records
2133
+ * once at the outermost reload boundary.
2134
+ *
2135
+ * @param {string} path Source path.
2136
+ * @param {object} options Read options.
2137
+ * @returns {{context: Readonly<CjsResourceReadContext>, options: object}} Context and detached operation options.
2138
+ * @throws {TypeError} If source provenance or options are invalid.
2140
2139
  */
2141
2140
  #BeginReadOperation(path, options) {
2142
2141
  if (!options || typeof options !== "object" || Array.isArray(options)) {
@@ -2187,13 +2186,13 @@ class CjsResMan extends CjsEventEmitter {
2187
2186
  };
2188
2187
  }
2189
2188
 
2190
- /**
2191
- * Queue one normalized source operation and deduplicate according to the
2192
- * caller's cache policy.
2193
- *
2194
- * @param {Readonly<CjsResourceReadContext>} context Normalized provenance.
2195
- * @param {object} options Detached read options.
2196
- * @returns {Promise<*>} Promise for source bytes/data.
2189
+ /**
2190
+ * Queue one normalized source operation and deduplicate according to the
2191
+ * caller's cache policy.
2192
+ *
2193
+ * @param {Readonly<CjsResourceReadContext>} context Normalized provenance.
2194
+ * @param {object} options Detached read options.
2195
+ * @returns {Promise<*>} Promise for source bytes/data.
2197
2196
  */
2198
2197
  #QueueReadResource(context, options) {
2199
2198
  const cachePolicy = normalizeCachePolicy(options.cacheSource, "cacheSource");
@@ -2232,13 +2231,13 @@ class CjsResMan extends CjsEventEmitter {
2232
2231
  return record.promise;
2233
2232
  }
2234
2233
 
2235
- /**
2236
- * Run or join one normalized direct source operation.
2237
- *
2238
- * @param {Readonly<CjsResourceReadContext>} context Normalized provenance.
2239
- * @param {object} options Detached read options.
2240
- * @param {CjsResourceReadOperationRecord|null} [queuedRecord=null] Parent queued record whose retention may be promoted by a later join.
2241
- * @returns {Promise<*>} Promise for source bytes/data.
2234
+ /**
2235
+ * Run or join one normalized direct source operation.
2236
+ *
2237
+ * @param {Readonly<CjsResourceReadContext>} context Normalized provenance.
2238
+ * @param {object} options Detached read options.
2239
+ * @param {CjsResourceReadOperationRecord|null} [queuedRecord=null] Parent queued record whose retention may be promoted by a later join.
2240
+ * @returns {Promise<*>} Promise for source bytes/data.
2242
2241
  */
2243
2242
  #ReadResource(context, options, queuedRecord = null) {
2244
2243
  const cachePolicy = normalizeCachePolicy(options.cacheSource, "cacheSource");
@@ -2273,13 +2272,13 @@ class CjsResMan extends CjsEventEmitter {
2273
2272
  return record.promise;
2274
2273
  }
2275
2274
 
2276
- /**
2277
- * Retain a settled source result when a queued caller upgraded cache policy
2278
- * after the direct source promise had already completed its cleanup reaction.
2279
- *
2280
- * @param {Readonly<CjsResourceReadContext>} context Normalized provenance.
2281
- * @param {*} value Settled source result.
2282
- * @returns {void}
2275
+ /**
2276
+ * Retain a settled source result when a queued caller upgraded cache policy
2277
+ * after the direct source promise had already completed its cleanup reaction.
2278
+ *
2279
+ * @param {Readonly<CjsResourceReadContext>} context Normalized provenance.
2280
+ * @param {*} value Settled source result.
2281
+ * @returns {void}
2283
2282
  */
2284
2283
  #RetainSourceResult(context, value) {
2285
2284
  const operations = getOwnerOperations(this.sourceOperations, context.source, true);
@@ -2297,14 +2296,14 @@ class CjsResMan extends CjsEventEmitter {
2297
2296
  });
2298
2297
  }
2299
2298
 
2300
- /**
2301
- * Remove future-reuse records matching one selected source and path.
2302
- * A null revision removes all revisions.
2303
- *
2304
- * @param {object|Function} source Selected source.
2305
- * @param {string} path Normalized source path.
2306
- * @param {string|null} revisionKey Exact revision key or `null` for all.
2307
- * @returns {Readonly<{path: string, queuedSource: number, source: number, format: number}>} Frozen detached counts.
2299
+ /**
2300
+ * Remove future-reuse records matching one selected source and path.
2301
+ * A null revision removes all revisions.
2302
+ *
2303
+ * @param {object|Function} source Selected source.
2304
+ * @param {string} path Normalized source path.
2305
+ * @param {string|null} revisionKey Exact revision key or `null` for all.
2306
+ * @returns {Readonly<{path: string, queuedSource: number, source: number, format: number}>} Frozen detached counts.
2308
2307
  */
2309
2308
  #InvalidateReadCache(source, path, revisionKey) {
2310
2309
  const queuedSource = removeOperationRecords(getOwnerOperations(this.queuedSourceOperations, source, false), path, revisionKey);
@@ -2326,18 +2325,18 @@ class CjsResMan extends CjsEventEmitter {
2326
2325
  });
2327
2326
  }
2328
2327
 
2329
- /**
2330
- * Construct and initialize one resource handle, optionally rejecting a
2331
- * singleton alias before `Initialize()` can mutate the protected owner.
2332
- *
2333
- * @param {Function} Constructor Resource constructor selected for the outcome.
2334
- * @param {string} path Normalized Carbon-style resource path.
2335
- * @param {string} ext Normalized resource extension.
2336
- * @param {object} [options={}] Constructor values, requested output, semantic requirement, and source provenance.
2337
- * @param {object|Function|null} [disallowedAlias=null] Existing owner that a staged candidate must not reuse.
2338
- * @param {object|null} [extensionRoute=null] Immutable explicit extension route captured for this handle.
2339
- * @returns {CjsResource} Initialized resource-compatible handle.
2340
- * @throws {TypeError|Error} If construction, candidate identity, or initialization is invalid.
2328
+ /**
2329
+ * Construct and initialize one resource handle, optionally rejecting a
2330
+ * singleton alias before `Initialize()` can mutate the protected owner.
2331
+ *
2332
+ * @param {Function} Constructor Resource constructor selected for the outcome.
2333
+ * @param {string} path Normalized Carbon-style resource path.
2334
+ * @param {string} ext Normalized resource extension.
2335
+ * @param {object} [options={}] Constructor values, requested output, semantic requirement, and source provenance.
2336
+ * @param {object|Function|null} [disallowedAlias=null] Existing owner that a staged candidate must not reuse.
2337
+ * @param {object|null} [extensionRoute=null] Immutable explicit extension route captured for this handle.
2338
+ * @returns {CjsResource} Initialized resource-compatible handle.
2339
+ * @throws {TypeError|Error} If construction, candidate identity, or initialization is invalid.
2341
2340
  */
2342
2341
  CreateResource(Constructor, path, ext, options = {}, disallowedAlias = null, extensionRoute = null) {
2343
2342
  const resource = new Constructor(options.values);
@@ -2360,35 +2359,46 @@ class CjsResMan extends CjsEventEmitter {
2360
2359
  return resource;
2361
2360
  }
2362
2361
 
2363
- /**
2364
- * Resolve the current resource constructor for a semantic request. Explicit
2365
- * requirement/payload selection precedes an emitted-output registration;
2366
- * otherwise the generic `CjsResource` handle is used.
2367
- *
2368
- * @param {object} [options={}] Semantic requirement, payload, and emit request.
2369
- * @param {object|null} [extensionRoute=null] Captured extension-selected default handler.
2370
- * @returns {Function} Registered resource constructor or `CjsResource`.
2362
+ /**
2363
+ * Resolve the current resource constructor for a semantic request. Explicit
2364
+ * requirement/payload selection normally precedes an emitted-output
2365
+ * registration. When an extension handler declares the same requirement it
2366
+ * wins, because the route is what distinguishes concrete resource classes
2367
+ * sharing one semantic key. Otherwise the generic `CjsResource` is used.
2368
+ *
2369
+ * @param {object} [options={}] Semantic requirement, payload, and emit request.
2370
+ * @param {object|null} [extensionRoute=null] Captured extension-selected default handler.
2371
+ * @returns {Function} Registered resource constructor or `CjsResource`.
2371
2372
  */
2372
2373
  ResolveResourceConstructor(options = {}, extensionRoute = null) {
2373
2374
  const requested = normalizeRequirement(options.requirement || options.payload);
2374
- if (requested && this.resourceTypes.has(requested)) return this.resourceTypes.get(requested);
2375
+ if (requested) {
2376
+ if (extensionRoute && normalizeRequirement(extensionRoute.Handler?.payload) === requested) {
2377
+ return extensionRoute.Handler;
2378
+ }
2379
+ const candidates = this.#resourceTypeCandidates.get(requested);
2380
+ if (candidates?.size > 1) {
2381
+ throw createAmbiguousResourceTypeError(requested, candidates);
2382
+ }
2383
+ if (this.resourceTypes.has(requested)) return this.resourceTypes.get(requested);
2384
+ }
2375
2385
  const emitted = normalizeRequirement(options.emit);
2376
2386
  if (emitted && this.resourceTypes.has(emitted)) return this.resourceTypes.get(emitted);
2377
2387
  if (extensionRoute) return extensionRoute.Handler;
2378
2388
  return CjsResource;
2379
2389
  }
2380
2390
 
2381
- /**
2382
- * Resolve the promised output tag used with the normalized source path.
2383
- *
2384
- * An explicit `variant` wins. Otherwise the requested emitted output is the
2385
- * promise, followed by the semantic requirement/payload for resource-only
2386
- * requests. Reader classes, constructors, and format options
2387
- * are execution details and never enter this identity.
2388
- *
2389
- * @param {object} [options={}] Resource request containing an optional output tag.
2390
- * @returns {string} Normalized promised output tag, or an empty string for the default outcome.
2391
- * @throws {TypeError} If options or its selected tag is invalid.
2391
+ /**
2392
+ * Resolve the promised output tag used with the normalized source path.
2393
+ *
2394
+ * An explicit `variant` wins. Otherwise the requested emitted output is the
2395
+ * promise, followed by the semantic requirement/payload for resource-only
2396
+ * requests. Reader classes, constructors, and format options
2397
+ * are execution details and never enter this identity.
2398
+ *
2399
+ * @param {object} [options={}] Resource request containing an optional output tag.
2400
+ * @returns {string} Normalized promised output tag, or an empty string for the default outcome.
2401
+ * @throws {TypeError} If options or its selected tag is invalid.
2392
2402
  */
2393
2403
  GetResourceVariant(options = {}) {
2394
2404
  if (!options || typeof options !== "object" || Array.isArray(options)) {
@@ -2403,12 +2413,12 @@ class CjsResMan extends CjsEventEmitter {
2403
2413
  return normalizeResourceVariant(options.emit ?? options.requirement ?? options.payload ?? "");
2404
2414
  }
2405
2415
 
2406
- /**
2407
- * Retain a low-level queue task only until settlement so `Wait()` can take a
2408
- * synchronous snapshot without making completed values long-lived.
2409
- *
2410
- * @param {object} task Queue task returned by `CjsResManWorkQueue.Add()`.
2411
- * @returns {object} The supplied task.
2416
+ /**
2417
+ * Retain a low-level queue task only until settlement so `Wait()` can take a
2418
+ * synchronous snapshot without making completed values long-lived.
2419
+ *
2420
+ * @param {object} task Queue task returned by `CjsResManWorkQueue.Add()`.
2421
+ * @returns {object} The supplied task.
2412
2422
  */
2413
2423
  #TrackQueueTask(task) {
2414
2424
  this.#queueOperations.set(task, task.promise);
@@ -2424,14 +2434,14 @@ class CjsResMan extends CjsEventEmitter {
2424
2434
  return task;
2425
2435
  }
2426
2436
 
2427
- /**
2428
- * Open one active resource-mutation record. Queued records additionally own
2429
- * a settlement promise visible to contemporaneous `Wait()` snapshots;
2430
- * direct records block unsafe MotherLode replacement but remain outside that
2431
- * two-queue fence.
2432
- *
2433
- * @param {boolean} queued Whether the operation belongs to the queued fence.
2434
- * @returns {() => void} Idempotent record completion callback.
2437
+ /**
2438
+ * Open one active resource-mutation record. Queued records additionally own
2439
+ * a settlement promise visible to contemporaneous `Wait()` snapshots;
2440
+ * direct records block unsafe MotherLode replacement but remain outside that
2441
+ * two-queue fence.
2442
+ *
2443
+ * @param {boolean} queued Whether the operation belongs to the queued fence.
2444
+ * @returns {() => void} Idempotent record completion callback.
2435
2445
  */
2436
2446
  #BeginResourceOperation(queued) {
2437
2447
  this.#activeResourceOperations += 1;
@@ -2453,15 +2463,15 @@ class CjsResMan extends CjsEventEmitter {
2453
2463
  };
2454
2464
  }
2455
2465
 
2456
- /**
2457
- * Return the known canonical authority for a resource and reject a known
2458
- * stale generation. A never-bound resource returns `null` so historical
2459
- * detached prepare/publication helpers remain compatible.
2460
- *
2461
- * @param {object|Function} resource Candidate resource handle.
2462
- * @param {string} phase Operation phase used for stale diagnostics.
2463
- * @returns {CjsResourceOwnership|null} Current authority or `null` when never bound.
2464
- * @throws {Error} If a previously bound resource is no longer canonical.
2466
+ /**
2467
+ * Return the known canonical authority for a resource and reject a known
2468
+ * stale generation. A never-bound resource returns `null` so historical
2469
+ * detached prepare/publication helpers remain compatible.
2470
+ *
2471
+ * @param {object|Function} resource Candidate resource handle.
2472
+ * @param {string} phase Operation phase used for stale diagnostics.
2473
+ * @returns {CjsResourceOwnership|null} Current authority or `null` when never bound.
2474
+ * @throws {Error} If a previously bound resource is no longer canonical.
2465
2475
  */
2466
2476
  #GetResourceOwnership(resource, phase) {
2467
2477
  const ownership = this.#resourceOwnership.get(resource) || null;
@@ -2470,13 +2480,13 @@ class CjsResMan extends CjsEventEmitter {
2470
2480
  return ownership;
2471
2481
  }
2472
2482
 
2473
- /**
2474
- * Require a current manager-owned canonical resource authority.
2475
- *
2476
- * @param {object|Function} resource Candidate resource handle.
2477
- * @param {string} phase Operation phase used for diagnostics.
2478
- * @returns {CjsResourceOwnership} Current canonical authority.
2479
- * @throws {Error} If the resource is unknown or no longer canonical.
2483
+ /**
2484
+ * Require a current manager-owned canonical resource authority.
2485
+ *
2486
+ * @param {object|Function} resource Candidate resource handle.
2487
+ * @param {string} phase Operation phase used for diagnostics.
2488
+ * @returns {CjsResourceOwnership} Current canonical authority.
2489
+ * @throws {Error} If the resource is unknown or no longer canonical.
2480
2490
  */
2481
2491
  #RequireResourceOwnership(resource, phase) {
2482
2492
  const ownership = this.#GetResourceOwnership(resource, phase);
@@ -2484,13 +2494,13 @@ class CjsResMan extends CjsEventEmitter {
2484
2494
  throw resourceNotOwnedError(resource, phase);
2485
2495
  }
2486
2496
 
2487
- /**
2488
- * Test whether an asynchronous operation still owns publication authority.
2489
- * Registry lookup failures are treated as stale ownership so they cannot
2490
- * replace an operation's more useful underlying source/stage rejection.
2491
- *
2492
- * @param {CjsResourceOwnership} ownership Captured authority.
2493
- * @returns {boolean} Whether the exact generation remains canonical.
2497
+ /**
2498
+ * Test whether an asynchronous operation still owns publication authority.
2499
+ * Registry lookup failures are treated as stale ownership so they cannot
2500
+ * replace an operation's more useful underlying source/stage rejection.
2501
+ *
2502
+ * @param {CjsResourceOwnership} ownership Captured authority.
2503
+ * @returns {boolean} Whether the exact generation remains canonical.
2494
2504
  */
2495
2505
  #IsResourceOwnershipCurrent(ownership) {
2496
2506
  try {
@@ -2500,13 +2510,13 @@ class CjsResMan extends CjsEventEmitter {
2500
2510
  }
2501
2511
  }
2502
2512
 
2503
- /**
2504
- * Assert exact canonical publication authority for one operation phase.
2505
- *
2506
- * @param {CjsResourceOwnership} ownership Captured authority.
2507
- * @param {string} phase Human-readable operation phase.
2508
- * @returns {void}
2509
- * @throws {Error} Stable stale-operation error when ownership changed.
2513
+ /**
2514
+ * Assert exact canonical publication authority for one operation phase.
2515
+ *
2516
+ * @param {CjsResourceOwnership} ownership Captured authority.
2517
+ * @param {string} phase Human-readable operation phase.
2518
+ * @returns {void}
2519
+ * @throws {Error} Stable stale-operation error when ownership changed.
2510
2520
  */
2511
2521
  #AssertResourceOwnership(ownership, phase) {
2512
2522
  if (!this.#IsResourceOwnershipCurrent(ownership)) {
@@ -2514,12 +2524,12 @@ class CjsResMan extends CjsEventEmitter {
2514
2524
  }
2515
2525
  }
2516
2526
 
2517
- /**
2518
- * Assert a captured authority when a compatibility path supplied one.
2519
- *
2520
- * @param {CjsResourceMutationAuthority|null} ownership Optional canonical or reload-candidate authority.
2521
- * @param {string} phase Human-readable operation phase.
2522
- * @returns {void}
2527
+ /**
2528
+ * Assert a captured authority when a compatibility path supplied one.
2529
+ *
2530
+ * @param {CjsResourceMutationAuthority|null} ownership Optional canonical or reload-candidate authority.
2531
+ * @param {string} phase Human-readable operation phase.
2532
+ * @returns {void}
2523
2533
  */
2524
2534
  #AssertOptionalResourceOwnership(ownership, phase) {
2525
2535
  if (!ownership) return;
@@ -2530,13 +2540,13 @@ class CjsResMan extends CjsEventEmitter {
2530
2540
  this.#AssertResourceOwnership(ownership, phase);
2531
2541
  }
2532
2542
 
2533
- /**
2534
- * Test the exact former owner plus newest-request token for an off-registry
2535
- * candidate. Lookup failures are treated as stale so detached work cannot
2536
- * resurrect a deleted, cleared, replaced, or superseded identity.
2537
- *
2538
- * @param {CjsResourceReloadCandidate} candidate Candidate authority.
2539
- * @returns {boolean} Whether this candidate alone may still commit.
2543
+ /**
2544
+ * Test the exact former owner plus newest-request token for an off-registry
2545
+ * candidate. Lookup failures are treated as stale so detached work cannot
2546
+ * resurrect a deleted, cleared, replaced, or superseded identity.
2547
+ *
2548
+ * @param {CjsResourceReloadCandidate} candidate Candidate authority.
2549
+ * @returns {boolean} Whether this candidate alone may still commit.
2540
2550
  */
2541
2551
  #IsReloadCandidateCurrent(candidate) {
2542
2552
  try {
@@ -2546,14 +2556,14 @@ class CjsResMan extends CjsEventEmitter {
2546
2556
  }
2547
2557
  }
2548
2558
 
2549
- /**
2550
- * Assert that a staged candidate still owns newest-request publication
2551
- * authority for one operation phase.
2552
- *
2553
- * @param {CjsResourceReloadCandidate} candidate Candidate authority.
2554
- * @param {string} phase Human-readable operation phase.
2555
- * @returns {void}
2556
- * @throws {Error} Stable stale-candidate error when authority changed.
2559
+ /**
2560
+ * Assert that a staged candidate still owns newest-request publication
2561
+ * authority for one operation phase.
2562
+ *
2563
+ * @param {CjsResourceReloadCandidate} candidate Candidate authority.
2564
+ * @param {string} phase Human-readable operation phase.
2565
+ * @returns {void}
2566
+ * @throws {Error} Stable stale-candidate error when authority changed.
2557
2567
  */
2558
2568
  #AssertReloadCandidate(candidate, phase) {
2559
2569
  if (!this.#IsReloadCandidateCurrent(candidate)) {
@@ -2561,11 +2571,11 @@ class CjsResMan extends CjsEventEmitter {
2561
2571
  }
2562
2572
  }
2563
2573
 
2564
- /**
2565
- * Invalidate the currently recorded generation for a removed resource.
2566
- *
2567
- * @param {object|Function} resource Removed or displaced resource.
2568
- * @returns {void}
2574
+ /**
2575
+ * Invalidate the currently recorded generation for a removed resource.
2576
+ *
2577
+ * @param {object|Function} resource Removed or displaced resource.
2578
+ * @returns {void}
2569
2579
  */
2570
2580
  #InvalidateResourceOwnership(resource) {
2571
2581
  if (resource && (typeof resource === "object" || typeof resource === "function")) {
@@ -2573,13 +2583,13 @@ class CjsResMan extends CjsEventEmitter {
2573
2583
  }
2574
2584
  }
2575
2585
 
2576
- /**
2577
- * Invalidate every generation currently owned by one registry. This runs
2578
- * before Clear cancellation/cleanup so reentrant observers cannot retain
2579
- * authority after canonical ownership removal begins.
2580
- *
2581
- * @param {CjsMotherLode|null|undefined} owner Registry losing ownership.
2582
- * @returns {void}
2586
+ /**
2587
+ * Invalidate every generation currently owned by one registry. This runs
2588
+ * before Clear cancellation/cleanup so reentrant observers cannot retain
2589
+ * authority after canonical ownership removal begins.
2590
+ *
2591
+ * @param {CjsMotherLode|null|undefined} owner Registry losing ownership.
2592
+ * @returns {void}
2583
2593
  */
2584
2594
  #InvalidateMotherLodeOwnership(owner) {
2585
2595
  if (typeof owner?.Entries !== "function") return;
@@ -2589,14 +2599,14 @@ class CjsResMan extends CjsEventEmitter {
2589
2599
  }
2590
2600
  }
2591
2601
 
2592
- /**
2593
- * Add one operation-owned purge lock and release it only while the exact
2594
- * captured canonical record still exists. If removal/replacement made the
2595
- * operation stale, its former MotherLode record (and lock count) no longer
2596
- * exists, so releasing through a rebound resource would corrupt a new owner.
2597
- *
2598
- * @param {CjsResourceOwnership} ownership Captured canonical authority.
2599
- * @returns {() => void} Idempotent balanced release callback.
2602
+ /**
2603
+ * Add one operation-owned purge lock and release it only while the exact
2604
+ * captured canonical record still exists. If removal/replacement made the
2605
+ * operation stale, its former MotherLode record (and lock count) no longer
2606
+ * exists, so releasing through a rebound resource would corrupt a new owner.
2607
+ *
2608
+ * @param {CjsResourceOwnership} ownership Captured canonical authority.
2609
+ * @returns {() => void} Idempotent balanced release callback.
2600
2610
  */
2601
2611
  #AcquireResourcePurgeLock(ownership) {
2602
2612
  const {
@@ -2616,35 +2626,35 @@ class CjsResMan extends CjsEventEmitter {
2616
2626
  };
2617
2627
  }
2618
2628
 
2619
- /**
2620
- * Bind resource-facing liveness methods to one canonical MotherLode key.
2621
- * The controller contains no loader/reload callback, so touching a detached
2622
- * or purged handle cannot start browser/network work.
2623
- *
2624
- * @param {string} key Canonical MotherLode identity.
2625
- * @param {object|Function} resource Canonical resource handle.
2626
- * @returns {object|Function} The supplied resource.
2627
- */
2628
- /**
2629
- * Reload a purged handle back into itself.
2630
- *
2631
- * Purge deletes the payload and drops the registry entry, so a consumer left
2632
- * holding the handle has no way to reach a replacement - it cannot discover
2633
- * one, and nothing hands it over. Recovery therefore has to fill THIS handle
2634
- * rather than resolve whatever the manager currently caches for the path.
2635
- *
2636
- * The handle is re-registered BEFORE loading, so the ordinary load path finds
2637
- * it as the canonical identity and loads into it instead of minting another.
2638
- *
2639
- * Declines rather than guesses in two cases: when another resource has since
2640
- * claimed the identity - displacing it would kill whoever holds that one, the
2641
- * very failure being fixed here - and when the retained request no longer
2642
- * resolves to the same identity, which would re-register the handle under the
2643
- * wrong key.
2644
- *
2645
- * @param {string} key Canonical resolved identity key.
2646
- * @param {CjsResource} resource The purged handle to restore.
2647
- * @returns {boolean} Whether a reload was started.
2629
+ /**
2630
+ * Bind resource-facing liveness methods to one canonical MotherLode key.
2631
+ * The controller contains no loader/reload callback, so touching a detached
2632
+ * or purged handle cannot start browser/network work.
2633
+ *
2634
+ * @param {string} key Canonical MotherLode identity.
2635
+ * @param {object|Function} resource Canonical resource handle.
2636
+ * @returns {object|Function} The supplied resource.
2637
+ */
2638
+ /**
2639
+ * Reload a purged handle back into itself.
2640
+ *
2641
+ * Purge deletes the payload and drops the registry entry, so a consumer left
2642
+ * holding the handle has no way to reach a replacement - it cannot discover
2643
+ * one, and nothing hands it over. Recovery therefore has to fill THIS handle
2644
+ * rather than resolve whatever the manager currently caches for the path.
2645
+ *
2646
+ * The handle is re-registered BEFORE loading, so the ordinary load path finds
2647
+ * it as the canonical identity and loads into it instead of minting another.
2648
+ *
2649
+ * Declines rather than guesses in two cases: when another resource has since
2650
+ * claimed the identity - displacing it would kill whoever holds that one, the
2651
+ * very failure being fixed here - and when the retained request no longer
2652
+ * resolves to the same identity, which would re-register the handle under the
2653
+ * wrong key.
2654
+ *
2655
+ * @param {string} key Canonical resolved identity key.
2656
+ * @param {CjsResource} resource The purged handle to restore.
2657
+ * @returns {boolean} Whether a reload was started.
2648
2658
  */
2649
2659
  #ReloadPurgedResource(key, resource) {
2650
2660
  if (!resource?.IsPurged?.()) return false;
@@ -2672,19 +2682,19 @@ class CjsResMan extends CjsEventEmitter {
2672
2682
  }
2673
2683
  }
2674
2684
 
2675
- /**
2676
- * Give one resource the liveness callbacks its consumers never manage
2677
- * themselves: activity renewal, payload renewal, lock counting, and the
2678
- * reload hook that revives the handle after a purge.
2679
- *
2680
- * Ownership is captured by generation, so a late release can never renew or
2681
- * unlock a rebound owner. The reload hook is bound outside the lifecycle
2682
- * controller because that controller is detached exactly when canonical
2683
- * ownership ends, which is precisely when a purged handle needs to come back.
2684
- *
2685
- * @param {string} key Canonical resolved key.
2686
- * @param {object} resource Resource handle to bind.
2687
- * @returns {object} The same resource handle.
2685
+ /**
2686
+ * Give one resource the liveness callbacks its consumers never manage
2687
+ * themselves: activity renewal, payload renewal, lock counting, and the
2688
+ * reload hook that revives the handle after a purge.
2689
+ *
2690
+ * Ownership is captured by generation, so a late release can never renew or
2691
+ * unlock a rebound owner. The reload hook is bound outside the lifecycle
2692
+ * controller because that controller is detached exactly when canonical
2693
+ * ownership ends, which is precisely when a purged handle needs to come back.
2694
+ *
2695
+ * @param {string} key Canonical resolved key.
2696
+ * @param {object} resource Resource handle to bind.
2697
+ * @returns {object} The same resource handle.
2688
2698
  */
2689
2699
  #BindResourceLifecycle(key, resource) {
2690
2700
  const owner = this.motherLode;
@@ -2723,11 +2733,11 @@ class CjsResMan extends CjsEventEmitter {
2723
2733
  return resource;
2724
2734
  }
2725
2735
 
2726
- /**
2727
- * Bind lifecycle callbacks for resources supplied by a configured custom
2728
- * MotherLode before CjsResMan begins serving them.
2729
- *
2730
- * @returns {CjsResMan} This resource manager.
2736
+ /**
2737
+ * Bind lifecycle callbacks for resources supplied by a configured custom
2738
+ * MotherLode before CjsResMan begins serving them.
2739
+ *
2740
+ * @returns {CjsResMan} This resource manager.
2731
2741
  */
2732
2742
  #BindMotherLodeResources() {
2733
2743
  if (typeof this.motherLode?.Entries !== "function") return this;
@@ -2737,25 +2747,25 @@ class CjsResMan extends CjsEventEmitter {
2737
2747
  return this;
2738
2748
  }
2739
2749
 
2740
- /**
2741
- * Run or join one format read under source/path/revision, frozen descriptor,
2742
- * and effective output-option identity. Descriptor identity prevents a
2743
- * re-registration with different defaults from reusing an old parse, while
2744
- * source identity prevents same-path reads from different sources colliding.
2745
- *
2746
- * `cacheFormat` uses the same tri-state policy as source caching: omitted is
2747
- * in-flight by default, `true` retains success, and `false` bypasses sharing
2748
- * and retention. `reload: true` never joins a prior parse. Failures are never
2749
- * retained, and a joining `true` request upgrades a shared record. Requests
2750
- * with option instances that cannot be represented safely bypass format
2751
- * sharing regardless of cache policy.
2752
- *
2753
- * @param {CjsResource} resource Resource whose normalized path identifies the source data.
2754
- * @param {object} descriptor Frozen registered format descriptor.
2755
- * @param {*} bytes Source bytes or source-compatible reader input.
2756
- * @param {object} [options={}] Source provenance, reload, cacheFormat, emit, classes, and format options.
2757
- * @returns {Promise<*>} Promise for the parsed or converted format result.
2758
- * @throws {TypeError|Error} If resource, source, revision, descriptor, cache policy, or format execution is invalid.
2750
+ /**
2751
+ * Run or join one format read under source/path/revision, frozen descriptor,
2752
+ * and effective output-option identity. Descriptor identity prevents a
2753
+ * re-registration with different defaults from reusing an old parse, while
2754
+ * source identity prevents same-path reads from different sources colliding.
2755
+ *
2756
+ * `cacheFormat` uses the same tri-state policy as source caching: omitted is
2757
+ * in-flight by default, `true` retains success, and `false` bypasses sharing
2758
+ * and retention. `reload: true` never joins a prior parse. Failures are never
2759
+ * retained, and a joining `true` request upgrades a shared record. Requests
2760
+ * with option instances that cannot be represented safely bypass format
2761
+ * sharing regardless of cache policy.
2762
+ *
2763
+ * @param {CjsResource} resource Resource whose normalized path identifies the source data.
2764
+ * @param {object} descriptor Frozen registered format descriptor.
2765
+ * @param {*} bytes Source bytes or source-compatible reader input.
2766
+ * @param {object} [options={}] Source provenance, reload, cacheFormat, emit, classes, and format options.
2767
+ * @returns {Promise<*>} Promise for the parsed or converted format result.
2768
+ * @throws {TypeError|Error} If resource, source, revision, descriptor, cache policy, or format execution is invalid.
2759
2769
  */
2760
2770
  ReadFormatOnce(resource, descriptor, bytes, options = {}) {
2761
2771
  const read = this.#BeginReadOperation(resource.GetPath(), options);
@@ -2791,16 +2801,16 @@ class CjsResMan extends CjsEventEmitter {
2791
2801
  }
2792
2802
  }
2793
2803
 
2794
- /**
2795
- * Copy supported registered format defaults into a deeply frozen snapshot.
2796
- * Plain objects and arrays may be cyclic. Functions and primitives are stable
2797
- * leaves; values with hidden mutable state are rejected because freezing their
2798
- * wrapper would not make the represented behavior immutable.
2799
- *
2800
- * @param {object} defaults Registered format defaults.
2801
- * @param {WeakMap<object, object>} [seen=new WeakMap()] Source-to-snapshot cycle map.
2802
- * @returns {Readonly<object>} Deeply frozen plain defaults snapshot.
2803
- * @throws {TypeError} If defaults contain unsupported objects, accessors, symbols, or byte buffers.
2804
+ /**
2805
+ * Copy supported registered format defaults into a deeply frozen snapshot.
2806
+ * Plain objects and arrays may be cyclic. Functions and primitives are stable
2807
+ * leaves; values with hidden mutable state are rejected because freezing their
2808
+ * wrapper would not make the represented behavior immutable.
2809
+ *
2810
+ * @param {object} defaults Registered format defaults.
2811
+ * @param {WeakMap<object, object>} [seen=new WeakMap()] Source-to-snapshot cycle map.
2812
+ * @returns {Readonly<object>} Deeply frozen plain defaults snapshot.
2813
+ * @throws {TypeError} If defaults contain unsupported objects, accessors, symbols, or byte buffers.
2804
2814
  */
2805
2815
  function snapshotFormatDefaults(defaults, seen = new WeakMap()) {
2806
2816
  if (!defaults || typeof defaults !== "object" || Array.isArray(defaults)) {
@@ -2809,14 +2819,14 @@ function snapshotFormatDefaults(defaults, seen = new WeakMap()) {
2809
2819
  return snapshotFormatDefaultValue(defaults, seen, "defaults");
2810
2820
  }
2811
2821
 
2812
- /**
2813
- * Snapshot one value in a registered format-default tree.
2814
- *
2815
- * @param {*} value Source value.
2816
- * @param {WeakMap<object, object>} seen Source-to-snapshot cycle map.
2817
- * @param {string} path Diagnostic property path.
2818
- * @returns {*} Frozen snapshot value or stable primitive/function leaf.
2819
- * @throws {TypeError} If the value cannot be made structurally immutable.
2822
+ /**
2823
+ * Snapshot one value in a registered format-default tree.
2824
+ *
2825
+ * @param {*} value Source value.
2826
+ * @param {WeakMap<object, object>} seen Source-to-snapshot cycle map.
2827
+ * @param {string} path Diagnostic property path.
2828
+ * @returns {*} Frozen snapshot value or stable primitive/function leaf.
2829
+ * @throws {TypeError} If the value cannot be made structurally immutable.
2820
2830
  */
2821
2831
  function snapshotFormatDefaultValue(value, seen, path) {
2822
2832
  if (value === null || value === undefined) return value;
@@ -2858,14 +2868,14 @@ function snapshotFormatDefaultValue(value, seen, path) {
2858
2868
  return Object.freeze(snapshot);
2859
2869
  }
2860
2870
 
2861
- /**
2862
- * Normalize an opaque caller/source revision without interpreting content.
2863
- * String and number tokens remain type-distinct; finite numeric `-0` and `0`
2864
- * intentionally identify the same revision.
2865
- *
2866
- * @param {string|number|undefined} value Caller-provided source content token.
2867
- * @returns {string} Type-stable internal revision key.
2868
- * @throws {TypeError} If the token is neither a string nor finite number.
2871
+ /**
2872
+ * Normalize an opaque caller/source revision without interpreting content.
2873
+ * String and number tokens remain type-distinct; finite numeric `-0` and `0`
2874
+ * intentionally identify the same revision.
2875
+ *
2876
+ * @param {string|number|undefined} value Caller-provided source content token.
2877
+ * @returns {string} Type-stable internal revision key.
2878
+ * @throws {TypeError} If the token is neither a string nor finite number.
2869
2879
  */
2870
2880
  function normalizeSourceRevision(value) {
2871
2881
  if (value === undefined) return "undefined";
@@ -2876,13 +2886,13 @@ function normalizeSourceRevision(value) {
2876
2886
  throw new TypeError("CjsResMan sourceRevision must be a string or finite number.");
2877
2887
  }
2878
2888
 
2879
- /**
2880
- * Validate tri-state source/format cache policy.
2881
- *
2882
- * @param {boolean|undefined} value Cache policy value.
2883
- * @param {string} name Option name used in failures.
2884
- * @returns {boolean|undefined} The validated policy.
2885
- * @throws {TypeError} If the value is not boolean or omitted.
2889
+ /**
2890
+ * Validate tri-state source/format cache policy.
2891
+ *
2892
+ * @param {boolean|undefined} value Cache policy value.
2893
+ * @param {string} name Option name used in failures.
2894
+ * @returns {boolean|undefined} The validated policy.
2895
+ * @throws {TypeError} If the value is not boolean or omitted.
2886
2896
  */
2887
2897
  function normalizeCachePolicy(value, name) {
2888
2898
  if (value !== undefined && typeof value !== "boolean") {
@@ -2891,13 +2901,13 @@ function normalizeCachePolicy(value, name) {
2891
2901
  return value;
2892
2902
  }
2893
2903
 
2894
- /**
2895
- * Get the operation map owned by one source object.
2896
- *
2897
- * @param {WeakMap<object|Function, Map<string, CjsResourceReadOperationRecord>>} ledger Source-keyed ledger.
2898
- * @param {object|Function} owner Source owner.
2899
- * @param {boolean} create Whether a missing map should be allocated.
2900
- * @returns {Map<string, CjsResourceReadOperationRecord>|null} Owner map or `null`.
2904
+ /**
2905
+ * Get the operation map owned by one source object.
2906
+ *
2907
+ * @param {WeakMap<object|Function, Map<string, CjsResourceReadOperationRecord>>} ledger Source-keyed ledger.
2908
+ * @param {object|Function} owner Source owner.
2909
+ * @param {boolean} create Whether a missing map should be allocated.
2910
+ * @returns {Map<string, CjsResourceReadOperationRecord>|null} Owner map or `null`.
2901
2911
  */
2902
2912
  function getOwnerOperations(ledger, owner, create) {
2903
2913
  let operations = ledger.get(owner);
@@ -2908,25 +2918,25 @@ function getOwnerOperations(ledger, owner, create) {
2908
2918
  return operations || null;
2909
2919
  }
2910
2920
 
2911
- /**
2912
- * Get the source/path/revision operation key for one normalized read context.
2913
- *
2914
- * @param {Readonly<CjsResourceReadContext>} context Normalized provenance.
2915
- * @returns {string} Internal read-operation key.
2921
+ /**
2922
+ * Get the source/path/revision operation key for one normalized read context.
2923
+ *
2924
+ * @param {Readonly<CjsResourceReadContext>} context Normalized provenance.
2925
+ * @returns {string} Internal read-operation key.
2916
2926
  */
2917
2927
  function getReadOperationKey(context) {
2918
2928
  return `${context.path}\u0000${context.revisionKey}`;
2919
2929
  }
2920
2930
 
2921
- /**
2922
- * Get the descriptor-specific format operation map for a selected source.
2923
- * Frozen descriptor identity isolates changed registration defaults.
2924
- *
2925
- * @param {WeakMap<object|Function, Map<object, Map<string, CjsResourceReadOperationRecord>>>} ledger Format ledger.
2926
- * @param {object|Function} source Selected source owner.
2927
- * @param {object} descriptor Frozen registered descriptor.
2928
- * @param {boolean} create Whether missing maps should be allocated.
2929
- * @returns {Map<string, CjsResourceReadOperationRecord>|null} Descriptor map or `null`.
2931
+ /**
2932
+ * Get the descriptor-specific format operation map for a selected source.
2933
+ * Frozen descriptor identity isolates changed registration defaults.
2934
+ *
2935
+ * @param {WeakMap<object|Function, Map<object, Map<string, CjsResourceReadOperationRecord>>>} ledger Format ledger.
2936
+ * @param {object|Function} source Selected source owner.
2937
+ * @param {object} descriptor Frozen registered descriptor.
2938
+ * @param {boolean} create Whether missing maps should be allocated.
2939
+ * @returns {Map<string, CjsResourceReadOperationRecord>|null} Descriptor map or `null`.
2930
2940
  */
2931
2941
  function getFormatDescriptorOperations(ledger, source, descriptor, create) {
2932
2942
  let descriptors = ledger.get(source);
@@ -2943,15 +2953,15 @@ function getFormatDescriptorOperations(ledger, source, descriptor, create) {
2943
2953
  return operations || null;
2944
2954
  }
2945
2955
 
2946
- /**
2947
- * Build a descriptor-local format cache key from source provenance and the
2948
- * output options that materially affect the format reader result.
2949
- * Requests containing non-canonical mutable option objects bypass format-cache
2950
- * sharing instead of risking a false key match.
2951
- *
2952
- * @param {Readonly<CjsResourceReadContext>} context Normalized provenance.
2953
- * @param {object} options Format request options.
2954
- * @returns {string|null} Internal format-operation key, or `null` to bypass caching.
2956
+ /**
2957
+ * Build a descriptor-local format cache key from source provenance and the
2958
+ * output options that materially affect the format reader result.
2959
+ * Requests containing non-canonical mutable option objects bypass format-cache
2960
+ * sharing instead of risking a false key match.
2961
+ *
2962
+ * @param {Readonly<CjsResourceReadContext>} context Normalized provenance.
2963
+ * @param {object} options Format request options.
2964
+ * @returns {string|null} Internal format-operation key, or `null` to bypass caching.
2955
2965
  */
2956
2966
  function getFormatOperationKey(context, options) {
2957
2967
  const material = [options.emit, options.mediaType, options.classes, options.formatOptions];
@@ -2959,15 +2969,15 @@ function getFormatOperationKey(context, options) {
2959
2969
  return `${getReadOperationKey(context)}\u0000${material.map(value => serializeFormatCacheValue(value)).join("\u0001")}`;
2960
2970
  }
2961
2971
 
2962
- /**
2963
- * Return true when a format cache option can be represented without guessing
2964
- * hidden mutable state. Plain objects/arrays, functions by identity, and
2965
- * byte-addressable buffers/views are supported. Other class instances bypass
2966
- * format-cache sharing.
2967
- *
2968
- * @param {*} value Candidate material format option.
2969
- * @param {WeakSet<object|Function>} [seen=new WeakSet()] Cycle guard.
2970
- * @returns {boolean} Whether deterministic cache serialization is supported.
2972
+ /**
2973
+ * Return true when a format cache option can be represented without guessing
2974
+ * hidden mutable state. Plain objects/arrays, functions by identity, and
2975
+ * byte-addressable buffers/views are supported. Other class instances bypass
2976
+ * format-cache sharing.
2977
+ *
2978
+ * @param {*} value Candidate material format option.
2979
+ * @param {WeakSet<object|Function>} [seen=new WeakSet()] Cycle guard.
2980
+ * @returns {boolean} Whether deterministic cache serialization is supported.
2971
2981
  */
2972
2982
  function isCanonicalFormatCacheValue(value, seen = new WeakSet()) {
2973
2983
  if (value === null || value === undefined) return true;
@@ -2989,15 +2999,15 @@ function isCanonicalFormatCacheValue(value, seen = new WeakSet()) {
2989
2999
  });
2990
3000
  }
2991
3001
 
2992
- /**
2993
- * Serialize one supported material format option with process-local identity
2994
- * for objects and functions. Identity prevents same-named constructors and
2995
- * separate option graphs from colliding; visible plain-object/array/buffer
2996
- * contents ensure mutation changes the next operation key.
2997
- *
2998
- * @param {*} value Canonically supported format option.
2999
- * @param {WeakSet<object|Function>} [seen=new WeakSet()] Cycle guard.
3000
- * @returns {string} Deterministic cache-local representation.
3002
+ /**
3003
+ * Serialize one supported material format option with process-local identity
3004
+ * for objects and functions. Identity prevents same-named constructors and
3005
+ * separate option graphs from colliding; visible plain-object/array/buffer
3006
+ * contents ensure mutation changes the next operation key.
3007
+ *
3008
+ * @param {*} value Canonically supported format option.
3009
+ * @param {WeakSet<object|Function>} [seen=new WeakSet()] Cycle guard.
3010
+ * @returns {string} Deterministic cache-local representation.
3001
3011
  */
3002
3012
  function serializeFormatCacheValue(value, seen = new WeakSet()) {
3003
3013
  if (value === undefined) return "undefined";
@@ -3027,11 +3037,11 @@ function serializeFormatCacheValue(value, seen = new WeakSet()) {
3027
3037
  return `object:${identity}:{${Object.keys(value).sort().map(key => `${JSON.stringify(key)}:${serializeFormatCacheValue(value[key], seen)}`).join(",")}}`;
3028
3038
  }
3029
3039
 
3030
- /**
3031
- * Return a process-local identity for a parsed-format cache object or function.
3032
- *
3033
- * @param {object|Function} value Candidate option identity owner.
3034
- * @returns {number} Stable identity for the life of the value.
3040
+ /**
3041
+ * Return a process-local identity for a parsed-format cache object or function.
3042
+ *
3043
+ * @param {object|Function} value Candidate option identity owner.
3044
+ * @returns {number} Stable identity for the life of the value.
3035
3045
  */
3036
3046
  function getLocalValueIdentity(value) {
3037
3047
  let identity = LOCAL_VALUE_IDENTITIES.get(value);
@@ -3042,14 +3052,14 @@ function getLocalValueIdentity(value) {
3042
3052
  return identity;
3043
3053
  }
3044
3054
 
3045
- /**
3046
- * Remove operation records matching a normalized path and optional revision.
3047
- * Detached promises continue for their existing consumers.
3048
- *
3049
- * @param {Map<string, CjsResourceReadOperationRecord>|null} operations Candidate operation map.
3050
- * @param {string} path Normalized source path.
3051
- * @param {string|null} revisionKey Exact revision or `null` for all revisions.
3052
- * @returns {number} Number of detached records.
3055
+ /**
3056
+ * Remove operation records matching a normalized path and optional revision.
3057
+ * Detached promises continue for their existing consumers.
3058
+ *
3059
+ * @param {Map<string, CjsResourceReadOperationRecord>|null} operations Candidate operation map.
3060
+ * @param {string} path Normalized source path.
3061
+ * @param {string|null} revisionKey Exact revision or `null` for all revisions.
3062
+ * @returns {number} Number of detached records.
3053
3063
  */
3054
3064
  function removeOperationRecords(operations, path, revisionKey) {
3055
3065
  if (!operations) return 0;
@@ -3062,13 +3072,13 @@ function removeOperationRecords(operations, path, revisionKey) {
3062
3072
  return removed;
3063
3073
  }
3064
3074
 
3065
- /**
3066
- * Copy the compact requested-output fields needed for explicit payload
3067
- * reconstruction. This request is retained with the handle but never enters
3068
- * MotherLode identity beyond its `variant`/`emit` output tag.
3069
- *
3070
- * @param {object} [options={}] Original resource request.
3071
- * @returns {object} Shallow reconstruction request without cache/reload policy.
3075
+ /**
3076
+ * Copy the compact requested-output fields needed for explicit payload
3077
+ * reconstruction. This request is retained with the handle but never enters
3078
+ * MotherLode identity beyond its `variant`/`emit` output tag.
3079
+ *
3080
+ * @param {object} [options={}] Original resource request.
3081
+ * @returns {object} Shallow reconstruction request without cache/reload policy.
3072
3082
  */
3073
3083
  function getResourceRequestOptions(options = {}) {
3074
3084
  const request = {};
@@ -3078,15 +3088,15 @@ function getResourceRequestOptions(options = {}) {
3078
3088
  return request;
3079
3089
  }
3080
3090
 
3081
- /**
3082
- * Capture the compact output request plus effective source provenance needed
3083
- * to reconstruct a released resource payload. Cache policy and one-shot reload
3084
- * are intentionally not retained. Retaining the effective source prevents an
3085
- * old revision token from being applied to a later manager default source.
3086
- *
3087
- * @param {object} [options={}] Requested output and source provenance options.
3088
- * @param {object|Function|null} [effectiveSource=null] Source selected when the resource was created.
3089
- * @returns {object} Detached loader options safe to retain with the resource.
3091
+ /**
3092
+ * Capture the compact output request plus effective source provenance needed
3093
+ * to reconstruct a released resource payload. Cache policy and one-shot reload
3094
+ * are intentionally not retained. Retaining the effective source prevents an
3095
+ * old revision token from being applied to a later manager default source.
3096
+ *
3097
+ * @param {object} [options={}] Requested output and source provenance options.
3098
+ * @param {object|Function|null} [effectiveSource=null] Source selected when the resource was created.
3099
+ * @returns {object} Detached loader options safe to retain with the resource.
3090
3100
  */
3091
3101
  function getResourceLoaderOptions(options = {}, effectiveSource = null) {
3092
3102
  const loaderOptions = getResourceRequestOptions(options);
@@ -3099,17 +3109,17 @@ function getResourceLoaderOptions(options = {}, effectiveSource = null) {
3099
3109
  return loaderOptions;
3100
3110
  }
3101
3111
 
3102
- /**
3103
- * Merge per-operation controls with a resource's compact reconstruction
3104
- * request. Once the handle has a promised-output field, all output selectors
3105
- * remain pinned to the retained request so `Ready()` cannot publish a
3106
- * different result under the existing MotherLode identity. Retained source
3107
- * provenance is pinned as well; cache/reload controls remain explicit per-call
3108
- * overrides.
3109
- *
3110
- * @param {object} base Retained reconstruction request.
3111
- * @param {object} [overrides={}] Per-call operation controls.
3112
- * @returns {object} Merged request with stable promised-output fields.
3112
+ /**
3113
+ * Merge per-operation controls with a resource's compact reconstruction
3114
+ * request. Once the handle has a promised-output field, all output selectors
3115
+ * remain pinned to the retained request so `Ready()` cannot publish a
3116
+ * different result under the existing MotherLode identity. Retained source
3117
+ * provenance is pinned as well; cache/reload controls remain explicit per-call
3118
+ * overrides.
3119
+ *
3120
+ * @param {object} base Retained reconstruction request.
3121
+ * @param {object} [overrides={}] Per-call operation controls.
3122
+ * @returns {object} Merged request with stable promised-output fields.
3113
3123
  */
3114
3124
  function mergeResourceLoaderOptions(base, overrides = {}) {
3115
3125
  const result = {
@@ -3132,13 +3142,13 @@ function mergeResourceLoaderOptions(base, overrides = {}) {
3132
3142
  return result;
3133
3143
  }
3134
3144
 
3135
- /**
3136
- * Filter current format descriptors using request material available before
3137
- * source bytes are read. Byte-dependent support probes are deferred.
3138
- *
3139
- * @param {readonly object[]} descriptors Registered descriptors for one extension.
3140
- * @param {object} options Format, output, and media selection.
3141
- * @returns {object[]} Matching descriptors in registration order.
3145
+ /**
3146
+ * Filter current format descriptors using request material available before
3147
+ * source bytes are read. Byte-dependent support probes are deferred.
3148
+ *
3149
+ * @param {readonly object[]} descriptors Registered descriptors for one extension.
3150
+ * @param {object} options Format, output, and media selection.
3151
+ * @returns {object[]} Matching descriptors in registration order.
3142
3152
  */
3143
3153
  function filterFormatDescriptors(descriptors, options) {
3144
3154
  let candidates = [...descriptors];
@@ -3160,16 +3170,16 @@ function filterFormatDescriptors(descriptors, options) {
3160
3170
  return candidates;
3161
3171
  }
3162
3172
 
3163
- /**
3164
- * Resolve an ordered explicit extension route. Probes are evaluated in route
3165
- * order and the sole unprobed final descriptor is the fallback. Selection is
3166
- * final: reader failures are never interpreted as a reason to try another
3167
- * format.
3168
- *
3169
- * @param {readonly object[]} descriptors Captured ordered route descriptors.
3170
- * @param {string} ext Normalized resource extension.
3171
- * @param {object} options Output filters and source bytes.
3172
- * @returns {object} Selected immutable format descriptor.
3173
+ /**
3174
+ * Resolve an ordered explicit extension route. Probes are evaluated in route
3175
+ * order and the sole unprobed final descriptor is the fallback. Selection is
3176
+ * final: reader failures are never interpreted as a reason to try another
3177
+ * format.
3178
+ *
3179
+ * @param {readonly object[]} descriptors Captured ordered route descriptors.
3180
+ * @param {string} ext Normalized resource extension.
3181
+ * @param {object} options Output filters and source bytes.
3182
+ * @returns {object} Selected immutable format descriptor.
3173
3183
  */
3174
3184
  function resolveOrderedExtensionFormatDescriptor(descriptors, ext, options) {
3175
3185
  const candidates = filterFormatDescriptors(descriptors, options);
@@ -3187,8 +3197,8 @@ function resolveOrderedExtensionFormatDescriptor(descriptors, ext, options) {
3187
3197
  Format,
3188
3198
  defaults
3189
3199
  } = descriptor;
3190
- if (typeof Format.isSupported !== "function") return descriptor;
3191
- const report = Format.isSupported(options.bytes, {
3200
+ if (typeof Format.is !== "function") return descriptor;
3201
+ const report = Format.is(options.bytes, {
3192
3202
  ...defaults,
3193
3203
  ...(options.formatOptions || {})
3194
3204
  });
@@ -3210,24 +3220,24 @@ function isPositiveFormatProbe(report) {
3210
3220
  return report.supported === true || report.supported === "full" || report.supported === "partial";
3211
3221
  }
3212
3222
 
3213
- /**
3214
- * Return one format facade's normal and diagnostic output declarations.
3215
- *
3216
- * @param {Function} Format Registered format facade.
3217
- * @returns {Array<*>} Declared output values in selection order.
3223
+ /**
3224
+ * Return one format facade's normal and diagnostic output declarations.
3225
+ *
3226
+ * @param {Function} Format Registered format facade.
3227
+ * @returns {Array<*>} Declared output values in selection order.
3218
3228
  */
3219
3229
  function getFormatOutputs(Format) {
3220
- return [...(Format.outputTypes || []), ...(Format.debugOutputTypes || [])];
3230
+ return Object.keys(Format.outputs || {});
3221
3231
  }
3222
3232
 
3223
- /**
3224
- * Resolve a case-insensitive output selector to its canonical declared
3225
- * spelling. MotherLode tags stay lowercase while readers receive declarations
3226
- * such as `cmfJson` or `gr2Json` exactly as authored.
3227
- *
3228
- * @param {readonly *[]} outputs Declared output values.
3229
- * @param {*} requested Requested output selector.
3230
- * @returns {string|null} Canonical declaration, or `null` when unsupported.
3233
+ /**
3234
+ * Resolve a case-insensitive output selector to its canonical declared
3235
+ * spelling. MotherLode tags stay lowercase while readers receive declarations
3236
+ * such as `cmfJson` or `gr2Json` exactly as authored.
3237
+ *
3238
+ * @param {readonly *[]} outputs Declared output values.
3239
+ * @param {*} requested Requested output selector.
3240
+ * @returns {string|null} Canonical declaration, or `null` when unsupported.
3231
3241
  */
3232
3242
  function findDeclaredOutput(outputs, requested) {
3233
3243
  const normalized = normalizeResourceVariant(requested);
@@ -3238,14 +3248,14 @@ function findDeclaredOutput(outputs, requested) {
3238
3248
  return null;
3239
3249
  }
3240
3250
 
3241
- /**
3242
- * Create the stable failure used when a registered input format cannot emit a
3243
- * requested output tag.
3244
- *
3245
- * @param {string} ext Normalized source extension.
3246
- * @param {*} emit Requested output tag.
3247
- * @param {readonly object[]} descriptors Registered input-format descriptors.
3248
- * @returns {Error} Contextual unsupported-output error.
3251
+ /**
3252
+ * Create the stable failure used when a registered input format cannot emit a
3253
+ * requested output tag.
3254
+ *
3255
+ * @param {string} ext Normalized source extension.
3256
+ * @param {*} emit Requested output tag.
3257
+ * @param {readonly object[]} descriptors Registered input-format descriptors.
3258
+ * @returns {Error} Contextual unsupported-output error.
3249
3259
  */
3250
3260
  function createFormatOutputMissingError(ext, emit, descriptors) {
3251
3261
  const error = new Error(`No format registered for .${ext} emits ${JSON.stringify(emit)}.`);
@@ -3258,13 +3268,13 @@ function createFormatOutputMissingError(ext, emit, descriptors) {
3258
3268
  return error;
3259
3269
  }
3260
3270
 
3261
- /**
3262
- * Create the stable failure used when a direct object loader cannot satisfy a
3263
- * forced output request.
3264
- *
3265
- * @param {string} ext Normalized source extension.
3266
- * @param {*} emit Requested output tag.
3267
- * @returns {Error} Contextual unsupported-output error.
3271
+ /**
3272
+ * Create the stable failure used when a direct object loader cannot satisfy a
3273
+ * forced output request.
3274
+ *
3275
+ * @param {string} ext Normalized source extension.
3276
+ * @param {*} emit Requested output tag.
3277
+ * @returns {Error} Contextual unsupported-output error.
3268
3278
  */
3269
3279
  function createObjectLoaderOutputMissingError(ext, emit) {
3270
3280
  const error = new Error(`Direct loader for .${ext} exposes only its unforced default; it does not emit ${JSON.stringify(emit)}.`);
@@ -3275,15 +3285,15 @@ function createObjectLoaderOutputMissingError(ext, emit) {
3275
3285
  return error;
3276
3286
  }
3277
3287
 
3278
- /**
3279
- * Resolve one descriptor from the current candidate set. When bytes are
3280
- * present, support probes may disambiguate candidates.
3281
- *
3282
- * @param {readonly object[]} descriptors Candidate descriptors from current registration.
3283
- * @param {string} ext Normalized resource extension.
3284
- * @param {object} options Effective format options and optional source bytes.
3285
- * @returns {object} Selected descriptor.
3286
- * @throws {Error} If the candidate set is missing or remains ambiguous.
3288
+ /**
3289
+ * Resolve one descriptor from the current candidate set. When bytes are
3290
+ * present, support probes may disambiguate candidates.
3291
+ *
3292
+ * @param {readonly object[]} descriptors Candidate descriptors from current registration.
3293
+ * @param {string} ext Normalized resource extension.
3294
+ * @param {object} options Effective format options and optional source bytes.
3295
+ * @returns {object} Selected descriptor.
3296
+ * @throws {Error} If the candidate set is missing or remains ambiguous.
3287
3297
  */
3288
3298
  function resolveFormatDescriptorCandidates(descriptors, ext, options) {
3289
3299
  let candidates = [...descriptors];
@@ -3293,9 +3303,9 @@ function resolveFormatDescriptorCandidates(descriptors, ext, options) {
3293
3303
  Format,
3294
3304
  defaults
3295
3305
  } = descriptor;
3296
- const isSupported = Format.isSupported;
3297
- if (typeof isSupported !== "function") return false;
3298
- const report = isSupported.call(Format, options.bytes, {
3306
+ const isFormat = Format.is;
3307
+ if (typeof isFormat !== "function") return false;
3308
+ const report = isFormat.call(Format, options.bytes, {
3299
3309
  ...defaults,
3300
3310
  ...(options.formatOptions || {})
3301
3311
  });
@@ -3320,16 +3330,33 @@ function resolveFormatDescriptorCandidates(descriptors, ext, options) {
3320
3330
  }
3321
3331
  return candidates[0];
3322
3332
  }
3333
+
3334
+ /**
3335
+ * Report shorthand resource registrations that need an extension route or an
3336
+ * explicit keyed default to choose between them.
3337
+ *
3338
+ * @param {string} requirement Normalized semantic requirement.
3339
+ * @param {Set<Function>} candidates Registered constructors.
3340
+ * @returns {Error} Contextual ambiguity error.
3341
+ */
3342
+ function createAmbiguousResourceTypeError(requirement, candidates) {
3343
+ const names = [...candidates].map(Constructor => Constructor.name || "resource");
3344
+ const error = new Error(`Ambiguous resource types registered for requirement ${JSON.stringify(requirement)}: ` + `${names.join(", ")}. Register an extension handler to select the concrete ` + "resource for that file, or register one explicit keyed default.");
3345
+ error.code = "CJS_RESOURCE_TYPE_AMBIGUOUS";
3346
+ error.requirement = requirement;
3347
+ error.resourceTypes = names;
3348
+ return error;
3349
+ }
3323
3350
  function normalizeRequirement(value) {
3324
3351
  return value === null || value === undefined ? "" : String(value).trim().toLowerCase();
3325
3352
  }
3326
3353
 
3327
- /**
3328
- * Normalize one human-readable promised output tag.
3329
- *
3330
- * @param {*} value Candidate `variant`, `emit`, requirement, or payload tag.
3331
- * @returns {string} Trimmed lowercase tag, or an empty string.
3332
- * @throws {TypeError} If a non-empty tag is not a string or contains the internal key delimiter.
3354
+ /**
3355
+ * Normalize one human-readable promised output tag.
3356
+ *
3357
+ * @param {*} value Candidate `variant`, `emit`, requirement, or payload tag.
3358
+ * @returns {string} Trimmed lowercase tag, or an empty string.
3359
+ * @throws {TypeError} If a non-empty tag is not a string or contains the internal key delimiter.
3333
3360
  */
3334
3361
  function normalizeResourceVariant(value) {
3335
3362
  if (value === null || value === undefined || value === "") return "";
@@ -3353,13 +3380,13 @@ function createPrepareContext(resMan, resource, bytes, options, stage) {
3353
3380
  });
3354
3381
  }
3355
3382
 
3356
- /**
3357
- * Create the immutable, source-neutral path context shared by format readers,
3358
- * direct object loaders, target identification, and target hydration.
3359
- *
3360
- * @param {string} path Normalized or caller-supplied resource path.
3361
- * @param {CjsResourceReadContext|null|undefined} [readContext] Active source read context.
3362
- * @returns {Readonly<{path: string, resFilePath: string, ext: string, fileName: string, url: string|null}>}
3383
+ /**
3384
+ * Create the immutable, source-neutral path context shared by format readers,
3385
+ * direct object loaders, target identification, and target hydration.
3386
+ *
3387
+ * @param {string} path Normalized or caller-supplied resource path.
3388
+ * @param {CjsResourceReadContext|null|undefined} [readContext] Active source read context.
3389
+ * @returns {Readonly<{path: string, resFilePath: string, ext: string, fileName: string, url: string|null}>}
3363
3390
  */
3364
3391
  function createResourcePathContext(path, readContext = null) {
3365
3392
  const resFilePath = normalizeResourcePath(path);
@@ -3372,12 +3399,12 @@ function createResourcePathContext(path, readContext = null) {
3372
3399
  });
3373
3400
  }
3374
3401
 
3375
- /**
3376
- * Return the normalized final component of a resource path without query or
3377
- * fragment material.
3378
- *
3379
- * @param {string} path Resource path.
3380
- * @returns {string} Lowercase normalized filename, or an empty string.
3402
+ /**
3403
+ * Return the normalized final component of a resource path without query or
3404
+ * fragment material.
3405
+ *
3406
+ * @param {string} path Resource path.
3407
+ * @returns {string} Lowercase normalized filename, or an empty string.
3381
3408
  */
3382
3409
  function getResourceFileName(path) {
3383
3410
  const normalized = normalizeResourcePath(path);
@@ -3387,20 +3414,49 @@ function getResourceFileName(path) {
3387
3414
  return cleanPath.slice(slashIndex + 1);
3388
3415
  }
3389
3416
 
3390
- /**
3391
- * Recover the public object result represented by a resident resource payload.
3392
- * The publication contract returns semantic subclasses as their resource
3393
- * handle and base resources as their plain payload.
3394
- *
3395
- * @param {CjsResource} resource Resource with an attached CPU payload.
3396
- * @param {object|null} route Captured explicit extension route.
3397
- * @param {string|null} handlerMode Captured effective handler mode.
3398
- * @returns {*} Resident public object outcome.
3417
+ /**
3418
+ * The mode this resource publishes under.
3419
+ *
3420
+ * There are two modes and there have only ever been two - RESOURCE hands back
3421
+ * the stable handle, OBJECT hands back the reader outcome - but the question
3422
+ * was answered in four branches at each of two call sites, because a resource
3423
+ * reached without a registered route has no captured mode to read. Both sites
3424
+ * then re-derived the same rule inline, and both had to be kept in agreement by
3425
+ * hand.
3426
+ *
3427
+ * The route's captured mode wins when there is one, since that is what the
3428
+ * registration declared. Otherwise the class answers for itself: anything
3429
+ * deriving from `CjsResource` carries a `handlerMode`, and a bare `CjsResource`
3430
+ * is a carrier rather than a semantic resource, so it publishes its payload.
3431
+ * That last case is why the class static cannot simply be trusted - the base
3432
+ * declares RESOURCE for the subclasses that inherit it, not for itself.
3433
+ *
3434
+ * @param {object} resource Resource being published or read back.
3435
+ * @param {string|null} [routedMode] Mode captured at registration, when routed.
3436
+ * @returns {string} A `ResourceHandlerMode` value.
3437
+ */
3438
+ function resolveResourceHandlerMode(resource, routedMode = null) {
3439
+ if (routedMode === ResourceHandlerMode.RESOURCE) return ResourceHandlerMode.RESOURCE;
3440
+ if (routedMode === ResourceHandlerMode.OBJECT) return ResourceHandlerMode.OBJECT;
3441
+ if (resource?.constructor === CjsResource) return ResourceHandlerMode.OBJECT;
3442
+ return typeof resource?.SetPayload === "function" ? ResourceHandlerMode.RESOURCE : ResourceHandlerMode.OBJECT;
3443
+ }
3444
+
3445
+ /**
3446
+ * Recover the public object result represented by a resident resource payload.
3447
+ *
3448
+ * The read-back counterpart of publication, and it must agree with it exactly:
3449
+ * a resource published as its handle has to be recovered as its handle, or a
3450
+ * cache hit answers differently from the load that filled it.
3451
+ *
3452
+ * @param {CjsResource} resource Resource with an attached CPU payload.
3453
+ * @param {object|null} route Captured explicit extension route.
3454
+ * @param {string|null} handlerMode Captured effective handler mode.
3455
+ * @returns {*} Resident public object outcome.
3399
3456
  */
3400
3457
  function getPublishedResourceObject(resource, route = null, handlerMode = null) {
3401
- if (route && handlerMode === ResourceHandlerMode.RESOURCE) return resource;
3402
- if (route && handlerMode === ResourceHandlerMode.OBJECT) return resource.GetPayload();
3403
- return resource.constructor !== CjsResource ? resource : resource.GetPayload();
3458
+ const mode = resolveResourceHandlerMode(resource, route ? handlerMode : null);
3459
+ return mode === ResourceHandlerMode.RESOURCE ? resource : resource.GetPayload();
3404
3460
  }
3405
3461
  function assertPositiveInteger(value, name) {
3406
3462
  if (!Number.isInteger(value) || value < 1) {
@@ -3418,12 +3474,12 @@ function assertNonNegativeNumber(value, name) {
3418
3474
  }
3419
3475
  }
3420
3476
 
3421
- /**
3422
- * Normalize and freeze an opt-in time-based automatic purge policy.
3423
- *
3424
- * @param {CjsResManAutoPurgePolicy|false|null} policy Caller policy or disable marker.
3425
- * @returns {Readonly<CjsResManAutoPurgePolicy>|null} Frozen normalized policy, or `null` when disabled.
3426
- * @throws {TypeError} If fields, limits, cleanup controls, or the cadence clock are invalid.
3477
+ /**
3478
+ * Normalize and freeze an opt-in time-based automatic purge policy.
3479
+ *
3480
+ * @param {CjsResManAutoPurgePolicy|false|null} policy Caller policy or disable marker.
3481
+ * @returns {Readonly<CjsResManAutoPurgePolicy>|null} Frozen normalized policy, or `null` when disabled.
3482
+ * @throws {TypeError} If fields, limits, cleanup controls, or the cadence clock are invalid.
3427
3483
  */
3428
3484
  function normalizeAutoPurgePolicy(policy) {
3429
3485
  if (policy === null || policy === undefined || policy === false) return null;
@@ -3469,12 +3525,12 @@ function normalizeAutoPurgePolicy(policy) {
3469
3525
  });
3470
3526
  }
3471
3527
 
3472
- /**
3473
- * Validate one automatic-purge pump request without advancing cadence.
3474
- *
3475
- * @param {CjsResManAutoPurgePumpOptions} options Per-call pump options.
3476
- * @returns {CjsResManAutoPurgePumpOptions} Validated options.
3477
- * @throws {TypeError} If options or an explicit timestamp are invalid.
3528
+ /**
3529
+ * Validate one automatic-purge pump request without advancing cadence.
3530
+ *
3531
+ * @param {CjsResManAutoPurgePumpOptions} options Per-call pump options.
3532
+ * @returns {CjsResManAutoPurgePumpOptions} Validated options.
3533
+ * @throws {TypeError} If options or an explicit timestamp are invalid.
3478
3534
  */
3479
3535
  function normalizeAutoPurgePumpOptions(options) {
3480
3536
  if (!options || typeof options !== "object" || Array.isArray(options)) {
@@ -3490,12 +3546,12 @@ function normalizeAutoPurgePumpOptions(options) {
3490
3546
  return options;
3491
3547
  }
3492
3548
 
3493
- /**
3494
- * Create the stable failure used when synchronous MotherLode replacement
3495
- * would detach ownership beneath active asynchronous resource mutation.
3496
- *
3497
- * @param {number} activeOperations Number of queued and direct mutations.
3498
- * @returns {Error} Contextual active-operation error.
3549
+ /**
3550
+ * Create the stable failure used when synchronous MotherLode replacement
3551
+ * would detach ownership beneath active asynchronous resource mutation.
3552
+ *
3553
+ * @param {number} activeOperations Number of queued and direct mutations.
3554
+ * @returns {Error} Contextual active-operation error.
3499
3555
  */
3500
3556
  function activeResourceOperationsError(activeOperations) {
3501
3557
  const error = new Error(`CjsResMan cannot replace MotherLode while ${activeOperations} resource operation(s) are active.`);
@@ -3504,13 +3560,13 @@ function activeResourceOperationsError(activeOperations) {
3504
3560
  return error;
3505
3561
  }
3506
3562
 
3507
- /**
3508
- * Create the stable failure used when a manager-only load API receives a
3509
- * resource that was never bound to this manager.
3510
- *
3511
- * @param {*} resource Candidate resource.
3512
- * @param {string} phase Operation phase.
3513
- * @returns {Error} Contextual ownership error.
3563
+ /**
3564
+ * Create the stable failure used when a manager-only load API receives a
3565
+ * resource that was never bound to this manager.
3566
+ *
3567
+ * @param {*} resource Candidate resource.
3568
+ * @param {string} phase Operation phase.
3569
+ * @returns {Error} Contextual ownership error.
3514
3570
  */
3515
3571
  function resourceNotOwnedError(resource, phase) {
3516
3572
  const path = getResourceDiagnosticPath(resource);
@@ -3522,13 +3578,13 @@ function resourceNotOwnedError(resource, phase) {
3522
3578
  return error;
3523
3579
  }
3524
3580
 
3525
- /**
3526
- * Create the stable failure used when otherwise-successful obsolete work
3527
- * reaches a canonical mutation boundary.
3528
- *
3529
- * @param {CjsResourceOwnership} ownership Captured stale authority.
3530
- * @param {string} phase Operation phase that detected staleness.
3531
- * @returns {Error} Contextual stale-operation error.
3581
+ /**
3582
+ * Create the stable failure used when otherwise-successful obsolete work
3583
+ * reaches a canonical mutation boundary.
3584
+ *
3585
+ * @param {CjsResourceOwnership} ownership Captured stale authority.
3586
+ * @param {string} phase Operation phase that detected staleness.
3587
+ * @returns {Error} Contextual stale-operation error.
3532
3588
  */
3533
3589
  function staleResourceOperationError(ownership, phase) {
3534
3590
  const path = getResourceDiagnosticPath(ownership?.resource);
@@ -3542,13 +3598,13 @@ function staleResourceOperationError(ownership, phase) {
3542
3598
  return error;
3543
3599
  }
3544
3600
 
3545
- /**
3546
- * Reject a resource constructor that returns the protected canonical singleton
3547
- * when a distinct reload candidate is required.
3548
- *
3549
- * @param {string} path Requested resource path.
3550
- * @param {object|Function} resource Aliased canonical resource.
3551
- * @returns {Error} Stable candidate-alias error.
3601
+ /**
3602
+ * Reject a resource constructor that returns the protected canonical singleton
3603
+ * when a distinct reload candidate is required.
3604
+ *
3605
+ * @param {string} path Requested resource path.
3606
+ * @param {object|Function} resource Aliased canonical resource.
3607
+ * @returns {Error} Stable candidate-alias error.
3552
3608
  */
3553
3609
  function reloadCandidateAliasError(path, resource) {
3554
3610
  const error = new Error(`CjsResMan reload candidate aliases the canonical resource: ${path}.`);
@@ -3558,12 +3614,12 @@ function reloadCandidateAliasError(path, resource) {
3558
3614
  return error;
3559
3615
  }
3560
3616
 
3561
- /**
3562
- * Create the stable failure used when a candidate loader no longer has a
3563
- * staged authority record.
3564
- *
3565
- * @param {object|Function} resource Candidate resource.
3566
- * @returns {Error} Stable unavailable-candidate error.
3617
+ /**
3618
+ * Create the stable failure used when a candidate loader no longer has a
3619
+ * staged authority record.
3620
+ *
3621
+ * @param {object|Function} resource Candidate resource.
3622
+ * @returns {Error} Stable unavailable-candidate error.
3567
3623
  */
3568
3624
  function reloadCandidateUnavailableError(resource) {
3569
3625
  const path = getResourceDiagnosticPath(resource);
@@ -3574,13 +3630,13 @@ function reloadCandidateUnavailableError(resource) {
3574
3630
  return error;
3575
3631
  }
3576
3632
 
3577
- /**
3578
- * Create the stable failure used when a deleted, cleared, replaced, or
3579
- * superseded reload candidate reaches a mutation or commit boundary.
3580
- *
3581
- * @param {CjsResourceReloadCandidate} candidate Captured candidate authority.
3582
- * @param {string} phase Operation phase that detected staleness.
3583
- * @returns {Error} Contextual stale-candidate error.
3633
+ /**
3634
+ * Create the stable failure used when a deleted, cleared, replaced, or
3635
+ * superseded reload candidate reaches a mutation or commit boundary.
3636
+ *
3637
+ * @param {CjsResourceReloadCandidate} candidate Captured candidate authority.
3638
+ * @param {string} phase Operation phase that detected staleness.
3639
+ * @returns {Error} Contextual stale-candidate error.
3584
3640
  */
3585
3641
  function staleReloadCandidateError(candidate, phase) {
3586
3642
  const path = getResourceDiagnosticPath(candidate?.resource);
@@ -3595,12 +3651,12 @@ function staleReloadCandidateError(candidate, phase) {
3595
3651
  return error;
3596
3652
  }
3597
3653
 
3598
- /**
3599
- * Read a resource path for diagnostics without allowing an unusual custom
3600
- * resource getter to hide the primary ownership error.
3601
- *
3602
- * @param {*} resource Candidate resource.
3603
- * @returns {string} Best-effort resource path label.
3654
+ /**
3655
+ * Read a resource path for diagnostics without allowing an unusual custom
3656
+ * resource getter to hide the primary ownership error.
3657
+ *
3658
+ * @param {*} resource Candidate resource.
3659
+ * @returns {string} Best-effort resource path label.
3604
3660
  */
3605
3661
  function getResourceDiagnosticPath(resource) {
3606
3662
  try {
@@ -3610,19 +3666,19 @@ function getResourceDiagnosticPath(resource) {
3610
3666
  }
3611
3667
  }
3612
3668
 
3613
- /**
3614
- * Perform no action for lifecycle-compatible optional operations.
3615
- *
3616
- * @returns {void}
3669
+ /**
3670
+ * Perform no action for lifecycle-compatible optional operations.
3671
+ *
3672
+ * @returns {void}
3617
3673
  */
3618
3674
  function noop() {}
3619
3675
 
3620
- /**
3621
- * Validate a resource execution strategy.
3622
- *
3623
- * @param {*} loader Candidate loader.
3624
- * @param {string} name Configuration field name.
3625
- * @returns {void}
3676
+ /**
3677
+ * Validate a resource execution strategy.
3678
+ *
3679
+ * @param {*} loader Candidate loader.
3680
+ * @param {string} name Configuration field name.
3681
+ * @returns {void}
3626
3682
  */
3627
3683
  function assertResourceLoader(loader, name) {
3628
3684
  if (!isResourceLoader(loader)) {
@@ -3630,22 +3686,22 @@ function assertResourceLoader(loader, name) {
3630
3686
  }
3631
3687
  }
3632
3688
 
3633
- /**
3634
- * Test the structural resource loader contract.
3635
- *
3636
- * @param {*} loader Candidate loader.
3637
- * @returns {boolean}
3689
+ /**
3690
+ * Test the structural resource loader contract.
3691
+ *
3692
+ * @param {*} loader Candidate loader.
3693
+ * @returns {boolean}
3638
3694
  */
3639
3695
  function isResourceLoader(loader) {
3640
3696
  return Boolean(loader && typeof loader.Read === "function" && typeof loader.ReadFormat === "function");
3641
3697
  }
3642
3698
 
3643
- /**
3644
- * Merge frozen registration defaults with one request's format overrides.
3645
- *
3646
- * @param {object} descriptor Registered format descriptor.
3647
- * @param {object} options Resource read options.
3648
- * @returns {object} Effective format reader options.
3699
+ /**
3700
+ * Merge frozen registration defaults with one request's format overrides.
3701
+ *
3702
+ * @param {object} descriptor Registered format descriptor.
3703
+ * @param {object} options Resource read options.
3704
+ * @returns {object} Effective format reader options.
3649
3705
  */
3650
3706
  function createFormatReadOptions(descriptor, options) {
3651
3707
  const {
@@ -3663,32 +3719,32 @@ function createFormatReadOptions(descriptor, options) {
3663
3719
  return formatOptions;
3664
3720
  }
3665
3721
 
3666
- /**
3667
- * Reports whether a source requires CjsResMan to build a URL before reading.
3668
- *
3669
- * @param {*} source Selected source/provider.
3670
- * @returns {boolean}
3722
+ /**
3723
+ * Reports whether a source requires CjsResMan to build a URL before reading.
3724
+ *
3725
+ * @param {*} source Selected source/provider.
3726
+ * @returns {boolean}
3671
3727
  */
3672
3728
  function sourceRequiresUrl(source) {
3673
3729
  return source?.requiresUrl === true || source?.constructor?.requiresUrl === true;
3674
3730
  }
3675
3731
 
3676
- /**
3677
- * Tests whether an object owns one property.
3678
- *
3679
- * @param {*} object Candidate object.
3680
- * @param {string|number|symbol} property Property key.
3681
- * @returns {boolean}
3732
+ /**
3733
+ * Tests whether an object owns one property.
3734
+ *
3735
+ * @param {*} object Candidate object.
3736
+ * @param {string|number|symbol} property Property key.
3737
+ * @returns {boolean}
3682
3738
  */
3683
3739
  function hasOwn(object, property) {
3684
3740
  return Object.prototype.hasOwnProperty.call(object, property);
3685
3741
  }
3686
3742
 
3687
- /**
3688
- * Normalizes one resource-path scheme key.
3689
- *
3690
- * @param {*} value Candidate scheme.
3691
- * @returns {string}
3743
+ /**
3744
+ * Normalizes one resource-path scheme key.
3745
+ *
3746
+ * @param {*} value Candidate scheme.
3747
+ * @returns {string}
3692
3748
  */
3693
3749
  function normalizePathPrefix(value) {
3694
3750
  const prefix = String(value ?? "").trim().replace(/:\/?$/u, "").toLowerCase();
@@ -3698,12 +3754,12 @@ function normalizePathPrefix(value) {
3698
3754
  return prefix;
3699
3755
  }
3700
3756
 
3701
- /**
3702
- * Normalizes one registered URL base without altering case-sensitive path
3703
- * content.
3704
- *
3705
- * @param {*} value Candidate URL base.
3706
- * @returns {string}
3757
+ /**
3758
+ * Normalizes one registered URL base without altering case-sensitive path
3759
+ * content.
3760
+ *
3761
+ * @param {*} value Candidate URL base.
3762
+ * @returns {string}
3707
3763
  */
3708
3764
  function normalizeUrlBase(value) {
3709
3765
  const url = normalizePath(value);
@@ -3713,11 +3769,11 @@ function normalizeUrlBase(value) {
3713
3769
  return url.endsWith("/") ? url : `${url}/`;
3714
3770
  }
3715
3771
 
3716
- /**
3717
- * Validates a URL returned by an injected path resolver.
3718
- *
3719
- * @param {*} value Resolver output.
3720
- * @returns {string}
3772
+ /**
3773
+ * Validates a URL returned by an injected path resolver.
3774
+ *
3775
+ * @param {*} value Resolver output.
3776
+ * @returns {string}
3721
3777
  */
3722
3778
  function normalizeResolvedUrl(value) {
3723
3779
  const url = normalizePath(value);
@@ -3727,10 +3783,10 @@ function normalizeResolvedUrl(value) {
3727
3783
  return url;
3728
3784
  }
3729
3785
 
3730
- /**
3731
- * Return the wall-clock timestamp used by default automatic purge cadence.
3732
- *
3733
- * @returns {number} Milliseconds since the Unix epoch.
3786
+ /**
3787
+ * Return the wall-clock timestamp used by default automatic purge cadence.
3788
+ *
3789
+ * @returns {number} Milliseconds since the Unix epoch.
3734
3790
  */
3735
3791
  function defaultAutoPurgeNow() {
3736
3792
  return Date.now();
@@ -3833,7 +3889,7 @@ function createExtensionFormatDescriptor(entry, defaults, label) {
3833
3889
  function validateOrderedExtensionFormats(descriptors, ext) {
3834
3890
  for (let index = 0; index < descriptors.length - 1; index++) {
3835
3891
  const Format = descriptors[index].Format;
3836
- if (typeof Format.isSupported !== "function") {
3892
+ if (typeof Format.is !== "function") {
3837
3893
  throw new TypeError(`CjsResMan extension .${ext} format ${Format.name || index} has no support probe and must be last.`);
3838
3894
  }
3839
3895
  }