@@ -11,6 +11,71 @@ https://github.com/curiousdannii/asyncglk
1111
1212export type ProgressCallback = ( bytes : number ) => void
1313
14+ export type TruthyOption = boolean | number
15+
16+ export interface DownloadOptions {
17+ /** Domains to access directly: should always have both Access-Control-Allow-Origin and compression headers */
18+ direct_domains : string [ ] ,
19+ /** Path to resources */
20+ lib_path : string ,
21+ /** URL of Proxy */
22+ proxy_url : string ,
23+ /** Whether to load embedded resources in single file mode */
24+ single_file ?: TruthyOption ,
25+ /** Use the file proxy; if disabled may mean that some files can't be loaded */
26+ use_proxy ?: boolean | number ,
27+ }
28+
29+ /** Fetch a resource */
30+ const resource_map : Map < string , any > = new Map ( )
31+ export async function fetch_resource ( options : DownloadOptions , path : string , progress_callback ?: ProgressCallback ) {
32+ // Check the cache
33+ const cached = resource_map . get ( path )
34+ if ( cached ) {
35+ return cached
36+ }
37+
38+ const response = fetch_resource_inner ( options , path , progress_callback )
39+ // Fill the cache with the promise, and then when the resource has been obtained, update the cache
40+ resource_map . set ( path , response )
41+ response . then ( ( resource : any ) => {
42+ resource_map . set ( path , resource )
43+ } )
44+ return response
45+ }
46+
47+ /** Actually fetch a resource */
48+ async function fetch_resource_inner ( options : DownloadOptions , path : string , progress_callback ?: ProgressCallback ) {
49+ // Handle embedded resources in single file mode
50+ if ( options . single_file ) {
51+ const data = ( document . getElementById ( path ) as HTMLScriptElement ) . text
52+ if ( path . endsWith ( '.js' ) ) {
53+ return import ( `data:text/javascript,${ encodeURIComponent ( data ) } ` )
54+ }
55+ if ( ! path . endsWith ( '.wasm' ) ) {
56+ throw new Error ( `Can't load ${ path } in single file mode` )
57+ }
58+ return parse_base64 ( data )
59+ }
60+
61+ // Handle when lib_path is a proper URL (such as import.meta.url), as well as the old style path fragment
62+ let url : URL | string
63+ try {
64+ url = new URL ( path , options . lib_path )
65+ }
66+ catch {
67+ url = options . lib_path + path
68+ }
69+
70+ if ( path . endsWith ( '.js' ) ) {
71+ return import ( url + '' )
72+ }
73+
74+ // Something else, like a .wasm
75+ const response = await fetch ( url )
76+ return read_response ( response , progress_callback )
77+ }
78+
1479/** Parse Base 64 into a Uint8Array */
1580export async function parse_base64 ( data : string ) : Promise < Uint8Array > {
1681 // Firefox has a data URL limit of 32MB, so we have to chunk large data
0 commit comments