66using System . Collections . Generic ;
77using System . Runtime . Serialization ;
88using System . Text . Json ;
9+ using System . Text . Json . Serialization ;
910using ResourceHashesByNameDictionary = System . Collections . Generic . Dictionary < string , string > ;
1011
1112// For test purposes only. Actual build time implementation lives in runtime repository with WasmSDK
@@ -41,7 +42,11 @@ public string entryAssembly
4142 /// and values are SHA-256 hashes formatted in prefixed base-64 style (e.g., 'sha256-abcdefg...')
4243 /// as used for subresource integrity checking.
4344 /// </summary>
44- public ResourcesData resources { get ; set ; } = new ResourcesData ( ) ;
45+ [ JsonIgnore ]
46+ public ResourcesData resources => ( ResourcesData ) resourcesRaw ;
47+
48+ [ JsonPropertyName ( "resources" ) ]
49+ public object resourcesRaw { get ; set ; }
4550
4651 /// <summary>
4752 /// Gets a value that determines whether to enable caching of the <see cref="resources"/>
@@ -148,6 +153,9 @@ public class ResourcesData
148153 [ DataMember ( EmitDefaultValue = false ) ]
149154 public ResourceHashesByNameDictionary jsModuleWorker { get ; set ; }
150155
156+ [ DataMember ( EmitDefaultValue = false ) ]
157+ public ResourceHashesByNameDictionary jsModuleDiagnostics { get ; set ; }
158+
151159 [ DataMember ( EmitDefaultValue = false ) ]
152160 public ResourceHashesByNameDictionary jsModuleNative { get ; set ; }
153161
@@ -158,16 +166,21 @@ public class ResourcesData
158166 public ResourceHashesByNameDictionary wasmNative { get ; set ; }
159167
160168 [ DataMember ( EmitDefaultValue = false ) ]
161- public ResourceHashesByNameDictionary jsSymbols { get ; set ; }
169+ public ResourceHashesByNameDictionary wasmSymbols { get ; set ; }
162170
163171 [ DataMember ( EmitDefaultValue = false ) ]
164172 public ResourceHashesByNameDictionary icu { get ; set ; }
165173
174+ public ResourceHashesByNameDictionary coreAssembly { get ; set ; } = new ResourceHashesByNameDictionary ( ) ;
175+
166176 /// <summary>
167177 /// "assembly" (.dll) resources
168178 /// </summary>
169179 public ResourceHashesByNameDictionary assembly { get ; set ; } = new ResourceHashesByNameDictionary ( ) ;
170180
181+ [ DataMember ( EmitDefaultValue = false ) ]
182+ public ResourceHashesByNameDictionary corePdb { get ; set ; }
183+
171184 /// <summary>
172185 /// "debug" (.pdb) resources
173186 /// </summary>
@@ -212,13 +225,144 @@ public class ResourcesData
212225 [ DataMember ( EmitDefaultValue = false ) ]
213226 public Dictionary < string , AdditionalAsset > runtimeAssets { get ; set ; }
214227
228+ [ DataMember ( EmitDefaultValue = false ) ]
229+ public Dictionary < string , ResourceHashesByNameDictionary > coreVfs { get ; set ; }
230+
215231 [ DataMember ( EmitDefaultValue = false ) ]
216232 public Dictionary < string , ResourceHashesByNameDictionary > vfs { get ; set ; }
217233
218234 [ DataMember ( EmitDefaultValue = false ) ]
219235 public List < string > remoteSources { get ; set ; }
220236}
221237
238+ public class AssetsData
239+ {
240+ /// <summary>
241+ /// Gets a hash of all resources
242+ /// </summary>
243+ public string hash { get ; set ; }
244+
245+ [ DataMember ( EmitDefaultValue = false ) ]
246+ public List < JsAsset > jsModuleWorker { get ; set ; }
247+
248+ [ DataMember ( EmitDefaultValue = false ) ]
249+ public List < JsAsset > jsModuleDiagnostics { get ; set ; }
250+
251+ [ DataMember ( EmitDefaultValue = false ) ]
252+ public List < JsAsset > jsModuleNative { get ; set ; }
253+
254+ [ DataMember ( EmitDefaultValue = false ) ]
255+ public List < JsAsset > jsModuleRuntime { get ; set ; }
256+
257+ [ DataMember ( EmitDefaultValue = false ) ]
258+ public List < WasmAsset > wasmNative { get ; set ; }
259+
260+ [ DataMember ( EmitDefaultValue = false ) ]
261+ public List < SymbolsAsset > wasmSymbols { get ; set ; }
262+
263+ [ DataMember ( EmitDefaultValue = false ) ]
264+ public List < GeneralAsset > icu { get ; set ; }
265+
266+ /// <summary>
267+ /// "assembly" (.dll) resources needed to start MonoVM
268+ /// </summary>
269+ public List < GeneralAsset > coreAssembly { get ; set ; } = new ( ) ;
270+
271+ /// <summary>
272+ /// "assembly" (.dll) resources
273+ /// </summary>
274+ public List < GeneralAsset > assembly { get ; set ; } = new ( ) ;
275+
276+ /// <summary>
277+ /// "debug" (.pdb) resources needed to start MonoVM
278+ /// </summary>
279+ [ DataMember ( EmitDefaultValue = false ) ]
280+ public List < GeneralAsset > corePdb { get ; set ; }
281+
282+ /// <summary>
283+ /// "debug" (.pdb) resources
284+ /// </summary>
285+ [ DataMember ( EmitDefaultValue = false ) ]
286+ public List < GeneralAsset > pdb { get ; set ; }
287+
288+ /// <summary>
289+ /// localization (.satellite resx) resources
290+ /// </summary>
291+ [ DataMember ( EmitDefaultValue = false ) ]
292+ public Dictionary < string , List < GeneralAsset > > satelliteResources { get ; set ; }
293+
294+ /// <summary>
295+ /// Assembly (.dll) resources that are loaded lazily during runtime
296+ /// </summary>
297+ [ DataMember ( EmitDefaultValue = false ) ]
298+ public List < GeneralAsset > lazyAssembly { get ; set ; }
299+
300+ /// <summary>
301+ /// JavaScript module initializers that Blazor will be in charge of loading.
302+ /// Used in .NET < 8
303+ /// </summary>
304+ [ DataMember ( EmitDefaultValue = false ) ]
305+ public List < JsAsset > libraryInitializers { get ; set ; }
306+
307+ [ DataMember ( EmitDefaultValue = false ) ]
308+ public List < JsAsset > modulesAfterConfigLoaded { get ; set ; }
309+
310+ [ DataMember ( EmitDefaultValue = false ) ]
311+ public List < JsAsset > modulesAfterRuntimeReady { get ; set ; }
312+
313+ /// <summary>
314+ /// Extensions created by users customizing the initialization process. The format of the file(s)
315+ /// is up to the user.
316+ /// </summary>
317+ [ DataMember ( EmitDefaultValue = false ) ]
318+ public Dictionary < string , ResourceHashesByNameDictionary > extensions { get ; set ; }
319+
320+ [ DataMember ( EmitDefaultValue = false ) ]
321+ public List < VfsAsset > coreVfs { get ; set ; }
322+
323+ [ DataMember ( EmitDefaultValue = false ) ]
324+ public List < VfsAsset > vfs { get ; set ; }
325+ }
326+
327+ [ DataContract ]
328+ public class JsAsset
329+ {
330+ public string name { get ; set ; }
331+ public string moduleExports { get ; set ; }
332+ }
333+
334+ [ DataContract ]
335+ public class SymbolsAsset
336+ {
337+ public string name { get ; set ; }
338+ }
339+
340+ [ DataContract ]
341+ public class WasmAsset
342+ {
343+ public string name { get ; set ; }
344+ public string integrity { get ; set ; }
345+ public string resolvedUrl { get ; set ; }
346+ }
347+
348+ [ DataContract ]
349+ public class GeneralAsset
350+ {
351+ public string virtualPath { get ; set ; }
352+ public string name { get ; set ; }
353+ public string integrity { get ; set ; }
354+ public string resolvedUrl { get ; set ; }
355+ }
356+
357+ [ DataContract ]
358+ public class VfsAsset
359+ {
360+ public string virtualPath { get ; set ; }
361+ public string name { get ; set ; }
362+ public string integrity { get ; set ; }
363+ public string resolvedUrl { get ; set ; }
364+ }
365+
222366public enum GlobalizationMode : int
223367{
224368 // Note that the numeric values are serialized and used in JS code, so don't change them without also updating the JS code
@@ -261,10 +405,65 @@ public class BootJsonDataLoader
261405 public static BootJsonData ParseBootData ( string bootConfigPath )
262406 {
263407 string jsonContent = GetJsonContent ( bootConfigPath ) ;
264- BootJsonData config = JsonSerializer . Deserialize < BootJsonData > ( jsonContent , new JsonSerializerOptions { PropertyNameCaseInsensitive = true } ) ;
408+ var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true } ;
409+ options . Converters . Add ( new ResourcesConverter ( ) ) ;
410+ BootJsonData config = JsonSerializer . Deserialize < BootJsonData > ( jsonContent , options ) ;
411+ if ( config . resourcesRaw is AssetsData assets )
412+ {
413+ config . resourcesRaw = ConvertAssetsToResources ( assets ) ;
414+ }
415+
265416 return config ;
266417 }
267418
419+ private static ResourcesData ConvertAssetsToResources ( AssetsData assets )
420+ {
421+ static Dictionary < string , ResourceHashesByNameDictionary > ConvertSatelliteResources ( Dictionary < string , List < GeneralAsset > > satelliteResources )
422+ {
423+ if ( satelliteResources == null )
424+ return null ;
425+
426+ var result = new Dictionary < string , ResourceHashesByNameDictionary > ( ) ;
427+ foreach ( var kvp in satelliteResources )
428+ result [ kvp . Key ] = kvp . Value . ToDictionary ( a => a . name , a => a . integrity ) ;
429+
430+ return result ;
431+ }
432+
433+ static Dictionary < string , ResourceHashesByNameDictionary > ConvertVfsAssets ( List < VfsAsset > vfsAssets )
434+ {
435+ return vfsAssets ? . ToDictionary ( a => a . virtualPath , a => new ResourceHashesByNameDictionary
436+ {
437+ { a . name , a . integrity }
438+ } ) ;
439+ }
440+
441+ var resources = new ResourcesData
442+ {
443+ hash = assets . hash ,
444+ jsModuleWorker = assets . jsModuleWorker ? . ToDictionary ( a => a . name , a => ( string ) null ) ,
445+ jsModuleDiagnostics = assets . jsModuleDiagnostics ? . ToDictionary ( a => a . name , a => ( string ) null ) ,
446+ jsModuleNative = assets . jsModuleNative ? . ToDictionary ( a => a . name , a => ( string ) null ) ,
447+ jsModuleRuntime = assets . jsModuleRuntime ? . ToDictionary ( a => a . name , a => ( string ) null ) ,
448+ wasmNative = assets . wasmNative ? . ToDictionary ( a => a . name , a => a . integrity ) ,
449+ wasmSymbols = assets . wasmSymbols ? . ToDictionary ( a => a . name , a => ( string ) null ) ,
450+ icu = assets . icu ? . ToDictionary ( a => a . name , a => a . integrity ) ,
451+ coreAssembly = assets . coreAssembly ? . ToDictionary ( a => a . name , a => a . integrity ) ,
452+ assembly = assets . assembly ? . ToDictionary ( a => a . name , a => a . integrity ) ,
453+ corePdb = assets . corePdb ? . ToDictionary ( a => a . name , a => a . integrity ) ,
454+ pdb = assets . pdb ? . ToDictionary ( a => a . name , a => a . integrity ) ,
455+ satelliteResources = ConvertSatelliteResources ( assets . satelliteResources ) ,
456+ lazyAssembly = assets . lazyAssembly ? . ToDictionary ( a => a . name , a => a . integrity ) ,
457+ libraryInitializers = assets . libraryInitializers ? . ToDictionary ( a => a . name , a => ( string ) null ) ,
458+ modulesAfterConfigLoaded = assets . modulesAfterConfigLoaded ? . ToDictionary ( a => a . name , a => ( string ) null ) ,
459+ modulesAfterRuntimeReady = assets . modulesAfterRuntimeReady ? . ToDictionary ( a => a . name , a => ( string ) null ) ,
460+ extensions = assets . extensions ,
461+ coreVfs = ConvertVfsAssets ( assets . coreVfs ) ,
462+ vfs = ConvertVfsAssets ( assets . vfs )
463+ } ;
464+ return resources ;
465+ }
466+
268467 public static string GetJsonContent ( string bootConfigPath )
269468 {
270469 string startComment = "/*json-start*/" ;
@@ -284,3 +483,32 @@ public static string GetJsonContent(string bootConfigPath)
284483 return moduleContent ;
285484 }
286485}
486+
487+ internal class ResourcesConverter : JsonConverter < object >
488+ {
489+ public override object Read ( ref Utf8JsonReader reader , Type typeToConvert , JsonSerializerOptions options )
490+ {
491+ var nestedOptions = new JsonSerializerOptions ( options ) ;
492+ nestedOptions . Converters . Remove ( this ) ;
493+
494+ if ( reader . TokenType == JsonTokenType . StartObject )
495+ {
496+ try
497+ {
498+
499+ return JsonSerializer . Deserialize < AssetsData > ( ref reader , nestedOptions ) ! ;
500+ }
501+ catch
502+ {
503+ return JsonSerializer . Deserialize < ResourcesData > ( ref reader , nestedOptions ) ! ;
504+ }
505+ }
506+
507+ return JsonSerializer . Deserialize < object > ( ref reader , nestedOptions ) ! ;
508+ }
509+
510+ public override void Write ( Utf8JsonWriter writer , object value , JsonSerializerOptions options )
511+ {
512+ JsonSerializer . Serialize ( writer , value , value . GetType ( ) , options ) ;
513+ }
514+ }
0 commit comments