this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Embed JS stubs directly in library .cma.js files

This change leverages js_of_ocaml's --toplevel --include-runtime flags
(from PR #1509) to embed JS stubs directly into each library's compiled
JavaScript file, rather than requiring them to be bundled in the main
worker/toplevel.

Key changes:
- Add ~import_scripts parameter to Findlibish.require for configurable
JS loading
- Compile library archives with --toplevel --include-runtime --effects=cps
to embed stubs
- Add jsoo_runtime query function to Ocamlfind module
- Update test to use base library and verify stubs work at runtime
- Fix OCaml 5.4/opam 2.5 API compatibility issues

The stubs are now self-contained in each library file and automatically
registered on jsoo_runtime when the library is loaded via importScripts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

+181 -88
+21 -15
bin/jtw.ml
··· 145 145 let archives = List.map (fun x -> Fpath.(dir / x)) archives in 146 146 let d = Fpath.relativize ~root:findlib_dir dir |> Option.get in 147 147 let dest = Fpath.(output_dir / "lib" // d) in 148 - let _ = Bos.OS.Dir.create dest in 149 - let doit archive = 148 + let (_ : (bool, _) result) = Bos.OS.Dir.create dest in 149 + let compile_archive archive = 150 150 let output = Fpath.(dest / (Fpath.filename archive ^ ".js")) in 151 - let cmd = 151 + let js_runtime = Ocamlfind.jsoo_runtime lib in 152 + let js_files = 153 + List.map (fun f -> Fpath.(dir / f |> to_string)) js_runtime 154 + in 155 + let base_cmd = 152 156 match switch with 153 - | None -> 154 - Bos.Cmd.( 155 - v "js_of_ocaml" % "compile" % Fpath.to_string archive % "-o" 156 - % Fpath.to_string output) 157 + | None -> Bos.Cmd.(v "js_of_ocaml") 157 158 | Some s -> 158 - Bos.Cmd.( 159 - v "opam" % "exec" % "--switch" % s % "--" % "js_of_ocaml" 160 - % "compile" % Fpath.to_string archive % "-o" 161 - % Fpath.to_string output) 159 + Bos.Cmd.(v "opam" % "exec" % "--switch" % s % "--" % "js_of_ocaml") 162 160 in 163 - let _ = Util.lines_of_process cmd in 164 - () 161 + let cmd = 162 + Bos.Cmd.( 163 + base_cmd % "compile" % "--toplevel" % "--include-runtime" 164 + % "--effects=cps") 165 + in 166 + let cmd = List.fold_left (fun c f -> Bos.Cmd.(c % f)) cmd js_files in 167 + let cmd = 168 + Bos.Cmd.(cmd % Fpath.to_string archive % "-o" % Fpath.to_string output) 169 + in 170 + ignore (Util.lines_of_process cmd) 165 171 in 166 - List.iter doit archives) 172 + List.iter compile_archive archives) 167 173 libraries; 168 174 169 175 (* Format.eprintf "@[<hov 2>dir: %a [%a]@]\n%!" Fpath.pp dir (Fmt.list ~sep:Fmt.sp Fmt.string) files) cmis; *) ··· 189 195 Format.eprintf "Number of cmis: %d\n%!" (List.length init_cmis); 190 196 191 197 let () = 192 - if no_worker then () else Mk_backend.mk switch libraries output_dir 198 + if no_worker then () else Mk_backend.mk switch output_dir 193 199 in 194 200 195 201 `Ok ()
+8 -20
bin/mk_backend.ml
··· 1 1 (* To make a toplevel backend.js *) 2 2 3 - let mk switch libs dir = 3 + let mk switch dir = 4 4 let txt = {|let _ = Js_top_worker_web.Worker.run ()|} in 5 5 let file = Fpath.(dir / "worker.ml") in 6 6 Util.write_file file [ txt ]; ··· 21 21 Bos.Cmd.(cmd % "-g" % "-o" % Fpath.(dir / "worker.bc" |> to_string)) 22 22 in 23 23 let _ = Util.lines_of_process cmd in 24 - let cmd = 25 - Bos.Cmd.( 26 - ocamlfind_cmd % "query" % "-format" % "%+(jsoo_runtime)" % "-r" 27 - % "js_top_worker-web") 28 - in 29 - let cmd = Util.StringSet.fold (fun lib cmd -> Bos.Cmd.(cmd % lib)) libs cmd in 30 - let js_files = 31 - Util.lines_of_process cmd 32 - |> List.filter (fun x -> String.length x > 0) 33 - |> List.map (fun x -> Astring.String.cuts ~sep:" " x) 34 - |> List.flatten 35 - in 24 + (* No longer query library stubs - they are now linked directly into each library's JS file *) 36 25 let cmd = 37 26 Bos.Cmd.( 38 27 js_of_ocaml_cmd % "--toplevel" % "--no-cmis" % "--linkall" % "--pretty") ··· 40 29 let cmd = 41 30 List.fold_right 42 31 (fun a cmd -> Bos.Cmd.(cmd % a)) 43 - (js_files 44 - @ [ 45 - "+dynlink.js"; 46 - "+toplevel.js"; 47 - "+bigstringaf/runtime.js"; 48 - "+js_top_worker/stubs.js"; 49 - ]) 32 + [ 33 + "+dynlink.js"; 34 + "+toplevel.js"; 35 + "+bigstringaf/runtime.js"; 36 + "+js_top_worker/stubs.js"; 37 + ] 50 38 cmd 51 39 in 52 40 let cmd =
+13
bin/ocamlfind.ml
··· 65 65 let package = Fl_package_base.query pkg in 66 66 let meta = package.Fl_package_base.package_meta in 67 67 meta 68 + 69 + let jsoo_runtime pkg = 70 + init (); 71 + let package = Fl_package_base.query pkg in 72 + try 73 + let runtime = 74 + Fl_metascanner.lookup "jsoo_runtime" [] 75 + package.Fl_package_base.package_defs 76 + in 77 + (* Runtime may be space-separated list of files *) 78 + String.split_on_char ' ' runtime 79 + |> List.filter (fun x -> String.length x > 0) 80 + with _ -> []
+1 -1
bin/opam.ml
··· 58 58 OpamFile.Changes.read_from_string ~filename 59 59 @@ 60 60 (* Field [opam-version] is invalid in [*.changes] files, displaying a warning. *) 61 - if OpamStd.String.starts_with ~prefix:"opam-version" str then 61 + if String.starts_with ~prefix:"opam-version" str then 62 62 match OpamStd.String.cut_at str '\n' with 63 63 | Some (_, str) -> str 64 64 | None -> assert false
+19 -13
lib/findlibish.ml
··· 167 167 metas 168 168 |> flatten_libs |> Lwt.return 169 169 170 - let require sync_get cmi_only v packages = 170 + let require ~import_scripts sync_get cmi_only v packages = 171 171 let rec require dcss package : 172 172 Js_top_worker_rpc.Toplevel_api_gen.dynamic_cmis list = 173 173 match List.find (fun lib -> lib.name = package) v with 174 174 | exception Not_found -> 175 175 Jslib.log "Package %s not found" package; 176 - Jslib.log "Available packages: %s" 177 - (String.concat ", " (List.map (fun lib -> Printf.sprintf "%s (%d)" lib.name (List.length lib.children)) v)); 176 + let available = 177 + v 178 + |> List.map (fun lib -> 179 + Printf.sprintf "%s (%d)" lib.name (List.length lib.children)) 180 + |> String.concat ", " 181 + in 182 + Jslib.log "Available packages: %s" available; 178 183 dcss 179 184 | lib -> 180 185 if lib.loaded then dcss ··· 191 196 Jslib.log "uri: %s" (Uri.to_string uri); 192 197 match fetch_dynamic_cmis sync_get (Uri.to_string uri) with 193 198 | Ok dcs -> 194 - let () = 195 - match lib.archive_name with 196 - | None -> () 197 - | Some archive -> 199 + let should_load = 200 + (not (List.mem lib.name preloaded)) && not cmi_only 201 + in 202 + Option.iter 203 + (fun archive -> 204 + if should_load then begin 198 205 let archive_js = 199 206 Fpath.(dir / (archive ^ ".cma.js") |> to_string) 200 207 in 201 - if List.mem lib.name preloaded || cmi_only then () 202 - else 203 - Js_of_ocaml.Worker.import_scripts 204 - [ Uri.with_path uri archive_js |> Uri.to_string ]; 205 - lib.loaded <- true 206 - in 208 + import_scripts 209 + [ Uri.with_path uri archive_js |> Uri.to_string ] 210 + end) 211 + lib.archive_name; 212 + lib.loaded <- true; 207 213 Jslib.log "Finished loading package %s" lib.name; 208 214 dcs :: dep_dcs 209 215 | Error (`Msg m) ->
+13 -13
lib/impl.ml
··· 416 416 Persistent_env.report_error Format.err_formatter e; 417 417 let err = Format.asprintf "%a" Persistent_env.report_error e in 418 418 failwith ("Error: " ^ err) 419 - | Env.Error e -> 420 - Env.report_error Format.err_formatter e; 421 - let err = Format.asprintf "%a" Env.report_error e in 419 + | Env.Error _ as exn -> 420 + Location.report_exception Format.err_formatter exn; 421 + let err = Format.asprintf "%a" Location.report_exception exn in 422 422 failwith ("Error: " ^ err) 423 423 in 424 424 ··· 478 478 Typemod.type_toplevel_phrase oldenv sstr 479 479 in 480 480 let sg' = Typemod.Signature_names.simplify newenv sn sg in 481 - ignore (Includemod.signatures ~mark:Mark_positive oldenv sg sg'); 481 + ignore (Includemod.signatures ~mark:true oldenv sg sg'); 482 482 Typecore.force_delayed_checks (); 483 483 Printtyped.implementation pp_result str; 484 484 Format.pp_print_flush pp_result (); ··· 535 535 Logs.info (fun m -> m "Typing..."); 536 536 let str, sg, sn, _shape, newenv = 537 537 try Typemod.type_toplevel_phrase oldenv sstr 538 - with Env.Error e -> 539 - Env.report_error Format.err_formatter e; 538 + with Env.Error _ as exn -> 539 + Location.report_exception Format.err_formatter exn; 540 540 (* exit 1 *) 541 - let err = Format.asprintf "%a" Env.report_error e in 541 + let err = Format.asprintf "%a" Location.report_exception exn in 542 542 failwith ("Error: " ^ err) 543 543 in 544 544 Logs.info (fun m -> m "simplify..."); 545 545 let sg' = Typemod.Signature_names.simplify newenv sn sg in 546 - ignore (Includemod.signatures ~mark:Mark_positive oldenv sg sg'); 546 + ignore (Includemod.signatures ~mark:true oldenv sg sg'); 547 547 Typecore.force_delayed_checks (); 548 548 Logs.info (fun m -> m "Translmod..."); 549 549 let lam = Translmod.transl_toplevel_definition str in ··· 590 590 match id with Some id -> `Named id | None -> `Iife 591 591 in 592 592 Js_of_ocaml_compiler.Driver.f' ~standalone:false ~wrap_with_fun 593 - ~link:`No fmt p.debug p.code; 593 + ~link:`No fmt p.code; 594 594 Format.(pp_print_flush std_formatter ()); 595 595 Format.(pp_print_flush err_formatter ()); 596 596 flush stdout; ··· 845 845 Printf.fprintf oc "%s" source; 846 846 close_out oc; 847 847 (try Sys.remove (prefix ^ ".cmi") with Sys_error _ -> ()); 848 - let unit_info = Unit_info.make ~source_file:filename prefix in 848 + let unit_info = Unit_info.make ~source_file:filename Impl prefix in 849 849 try 850 850 let store = Local_store.fresh () in 851 851 Local_store.with_store store (fun () -> ··· 863 863 Logs.info (fun m -> m "file_exists: %s = %b" (prefix ^ ".cmi") b)); 864 864 Ocaml_typing.Cmi_cache.clear () 865 865 with 866 - | Env.Error e -> 867 - Logs.err (fun m -> m "Env.Error: %a" Env.report_error e); 866 + | Env.Error _ as exn -> 867 + Logs.err (fun m -> m "Env.Error: %a" Location.report_exception exn); 868 868 failed_cells := StringSet.add id !failed_cells; 869 869 () 870 870 | exn -> ··· 908 908 wdispatch source query 909 909 |> StdLabels.List.filter_map 910 910 ~f:(fun 911 - (Ocaml_parsing.Location.{ kind; main = _; sub; source } as 911 + (Ocaml_parsing.Location.{ kind; main = _; sub; source; _ } as 912 912 error) 913 913 -> 914 914 let of_sub sub =
+1 -1
lib/worker.ml
··· 63 63 64 64 let require b v = function 65 65 | [] -> [] 66 - | packages -> Findlibish.require sync_get b v packages 66 + | packages -> Findlibish.require ~import_scripts sync_get b v packages 67 67 68 68 let init_function func_name = 69 69 let open Js_of_ocaml in
+11 -9
test/node/dune
··· 39 39 (targets 40 40 (dir _opam)) 41 41 (action 42 - (run jtw opam astring --no-worker -o _opam))) 42 + (run jtw opam base --no-worker -o _opam))) 43 43 44 44 (rule 45 - (with-outputs-to 46 - node_test.out 47 - (run 48 - node 49 - --stack-size=2000 50 - -r 51 - ./%{dep:import_scripts.js} 52 - %{dep:node_test.js}))) 45 + (deps _opam) 46 + (action 47 + (with-outputs-to 48 + node_test.out 49 + (run 50 + node 51 + --stack-size=2000 52 + -r 53 + ./%{dep:import_scripts.js} 54 + %{dep:node_test.js})))) 53 55 54 56 (rule 55 57 (alias runtest)
+83 -13
test/node/node_test.expected
··· 1 1 node_test.js: [INFO] init() 2 2 Initializing findlib 3 3 node_test.js: [INFO] async_get: _opam/findlib_index 4 + node_test.js: [INFO] async_get: _opam/lib/sexplib0/META 5 + node_test.js: [INFO] async_get: _opam/lib/ocaml_intrinsics_kernel/META 4 6 node_test.js: [INFO] async_get: _opam/lib/ocaml/stdlib/META 5 - node_test.js: [INFO] async_get: _opam/lib/astring/META 7 + node_test.js: [INFO] async_get: _opam/lib/base/META 8 + Parsed uri: lib/sexplib0/META 9 + Reading library: sexplib0 10 + Number of children: 0 11 + Parsed uri: lib/ocaml_intrinsics_kernel/META 12 + Reading library: ocaml_intrinsics_kernel 13 + Number of children: 0 6 14 Parsed uri: lib/ocaml/stdlib/META 7 - Parsed uri: lib/astring/META 15 + Reading library: stdlib 16 + Number of children: 0 17 + Parsed uri: lib/base/META 18 + Reading library: base 19 + Number of children: 3 20 + Found child: base_internalhash_types 21 + Reading library: base.base_internalhash_types 22 + Number of children: 0 23 + Found child: md5 24 + Reading library: base.md5 25 + Number of children: 0 26 + Found child: shadow_stdlib 27 + Reading library: base.shadow_stdlib 28 + Number of children: 0 8 29 node_test.js: [INFO] sync_get: _opam/lib/ocaml/dynamic_cmis.json 9 30 node_test.js: [INFO] Adding toplevel modules for dynamic cmis from lib/ocaml/ 10 - node_test.js: [INFO] toplevel modules: CamlinternalOO, Stdlib, CamlinternalFormat, Std_exit, CamlinternalMod, CamlinternalFormatBasics, CamlinternalLazy 11 - node_test.js: [INFO] async_get: _opam/lib/ocaml/camlinternalOO.cmi 12 - node_test.js: [INFO] async_get: _opam/lib/ocaml/stdlib.cmi 31 + node_test.js: [INFO] toplevel modules: CamlinternalFormat, CamlinternalLazy, CamlinternalFormatBasics, CamlinternalMod, Std_exit, Stdlib, CamlinternalOO 13 32 node_test.js: [INFO] async_get: _opam/lib/ocaml/camlinternalFormat.cmi 14 - node_test.js: [INFO] async_get: _opam/lib/ocaml/std_exit.cmi 15 - node_test.js: [INFO] async_get: _opam/lib/ocaml/camlinternalMod.cmi 33 + node_test.js: [INFO] async_get: _opam/lib/ocaml/camlinternalLazy.cmi 16 34 node_test.js: [INFO] async_get: _opam/lib/ocaml/camlinternalFormatBasics.cmi 17 - node_test.js: [INFO] async_get: _opam/lib/ocaml/camlinternalLazy.cmi 35 + node_test.js: [INFO] async_get: _opam/lib/ocaml/camlinternalMod.cmi 36 + node_test.js: [INFO] async_get: _opam/lib/ocaml/std_exit.cmi 37 + node_test.js: [INFO] async_get: _opam/lib/ocaml/stdlib.cmi 38 + node_test.js: [INFO] async_get: _opam/lib/ocaml/camlinternalOO.cmi 18 39 node_test.js: [INFO] init() finished 19 40 node_test.js: [INFO] setup() ... 20 41 node_test.js: [INFO] Fetching stdlib__Format.cmi ··· 26 47 error while evaluating #enable "pretty";; 27 48 error while evaluating #disable "shortvar";; 28 49 node_test.js: [INFO] Setup complete 29 - Package stringext not found 50 + Loading package base 51 + lib.dir: None 52 + Loading package base.base_internalhash_types 53 + lib.dir: base_internalhash_types 54 + uri: lib/base/base_internalhash_types/dynamic_cmis.json 55 + node_test.js: [INFO] sync_get: _opam/lib/base/base_internalhash_types/dynamic_cmis.json 56 + importScripts: lib/base/base_internalhash_types/base_internalhash_types.cma.js 57 + Finished loading package base.base_internalhash_types 58 + Loading package base.shadow_stdlib 59 + lib.dir: shadow_stdlib 60 + uri: lib/base/shadow_stdlib/dynamic_cmis.json 61 + node_test.js: [INFO] sync_get: _opam/lib/base/shadow_stdlib/dynamic_cmis.json 62 + importScripts: lib/base/shadow_stdlib/shadow_stdlib.cma.js 63 + Finished loading package base.shadow_stdlib 64 + Loading package ocaml_intrinsics_kernel 65 + lib.dir: None 66 + uri: lib/ocaml_intrinsics_kernel/dynamic_cmis.json 67 + node_test.js: [INFO] sync_get: _opam/lib/ocaml_intrinsics_kernel/dynamic_cmis.json 68 + importScripts: lib/ocaml_intrinsics_kernel/ocaml_intrinsics_kernel.cma.js 69 + Finished loading package ocaml_intrinsics_kernel 70 + Loading package sexplib0 71 + lib.dir: None 72 + uri: lib/sexplib0/dynamic_cmis.json 73 + node_test.js: [INFO] sync_get: _opam/lib/sexplib0/dynamic_cmis.json 74 + importScripts: lib/sexplib0/sexplib0.cma.js 75 + Finished loading package sexplib0 76 + uri: lib/base/dynamic_cmis.json 77 + node_test.js: [INFO] sync_get: _opam/lib/base/dynamic_cmis.json 78 + importScripts: lib/base/base.cma.js 79 + Finished loading package base 80 + node_test.js: [INFO] Adding toplevel modules for dynamic cmis from lib/base/ 81 + node_test.js: [INFO] toplevel modules: Base 82 + node_test.js: [INFO] async_get: _opam/lib/base/base.cmi 83 + node_test.js: [INFO] Adding toplevel modules for dynamic cmis from lib/sexplib0/ 84 + node_test.js: [INFO] toplevel modules: Sexplib0 85 + node_test.js: [INFO] async_get: _opam/lib/sexplib0/sexplib0.cmi 86 + node_test.js: [INFO] Adding toplevel modules for dynamic cmis from lib/ocaml_intrinsics_kernel/ 87 + node_test.js: [INFO] toplevel modules: Ocaml_intrinsics_kernel 88 + node_test.js: [INFO] async_get: _opam/lib/ocaml_intrinsics_kernel/ocaml_intrinsics_kernel.cmi 89 + node_test.js: [INFO] Adding toplevel modules for dynamic cmis from lib/base/shadow_stdlib/ 90 + node_test.js: [INFO] toplevel modules: Shadow_stdlib 91 + node_test.js: [INFO] async_get: _opam/lib/base/shadow_stdlib/shadow_stdlib.cmi 92 + node_test.js: [INFO] Adding toplevel modules for dynamic cmis from lib/base/base_internalhash_types/ 93 + node_test.js: [INFO] toplevel modules: Base_internalhash_types 94 + node_test.js: [INFO] async_get: _opam/lib/base/base_internalhash_types/base_internalhash_types.cmi 30 95 node_test.js: [INFO] setup() finished 31 - node_test.js: [INFO] setup output: OCaml version 5.2.0 96 + node_test.js: [INFO] setup output: OCaml version 5.4.0 32 97 Unknown directive enable. 33 98 Unknown directive disable. 34 99 node_test.js: [INFO] add_cmi ··· 59 124 node_test.js: [INFO] line1: '' (length: 0) 60 125 node_test.js: [INFO] src: ' let _ = List.' (length: 15) 61 126 node_test.js: [INFO] complete after offset: . 62 - node_test.js: [INFO] Completions for 'List.': 68 entries 63 - node_test.js: [INFO] - (::) (Constructor): 'a * 'a list -> 'a List.t 64 - node_test.js: [INFO] - ([]) (Constructor): 'a List.t 127 + node_test.js: [INFO] Completions for 'List.': 73 entries 128 + node_test.js: [INFO] - (::) (Constructor): 'a0 * 'a0 list -> 'a0 List.t 129 + node_test.js: [INFO] - ([]) (Constructor): 'a0 List.t 65 130 node_test.js: [INFO] - append (Value): 'a list -> 'a list -> 'a list 66 131 node_test.js: [INFO] - assoc (Value): 'a -> ('a * 'b) list -> 'b 67 132 node_test.js: [INFO] - assoc_opt (Value): 'a -> ('a * 'b) list -> 'b option ··· 74 139 node_test.js: [INFO] - concat (Value): 'a list list -> 'a list 75 140 node_test.js: [INFO] - concat_map (Value): ('a -> 'b list) -> 'a list -> 'b list 76 141 node_test.js: [INFO] - cons (Value): 'a -> 'a list -> 'a list 142 + node_test.js: [INFO] - drop (Value): int -> 'a list -> 'a list 143 + node_test.js: [INFO] - drop_while (Value): ('a -> bool) -> 'a list -> 'a list 77 144 node_test.js: [INFO] - equal (Value): ('a -> 'a -> bool) -> 'a list -> 'a list -> bool 78 145 node_test.js: [INFO] - exists (Value): ('a -> bool) -> 'a list -> bool 79 146 node_test.js: [INFO] - exists2 (Value): ('a -> 'b -> bool) -> 'a list -> 'b list -> bool ··· 121 188 node_test.js: [INFO] - rev_append (Value): 'a list -> 'a list -> 'a list 122 189 node_test.js: [INFO] - rev_map (Value): ('a -> 'b) -> 'a list -> 'b list 123 190 node_test.js: [INFO] - rev_map2 (Value): ('a -> 'b -> 'c) -> 'a list -> 'b list -> 'c list 191 + node_test.js: [INFO] - singleton (Value): 'a -> 'a list 124 192 node_test.js: [INFO] - sort (Value): ('a -> 'a -> int) -> 'a list -> 'a list 125 193 node_test.js: [INFO] - sort_uniq (Value): ('a -> 'a -> int) -> 'a list -> 'a list 126 194 node_test.js: [INFO] - split (Value): ('a * 'b) list -> 'a list * 'b list 127 195 node_test.js: [INFO] - stable_sort (Value): ('a -> 'a -> int) -> 'a list -> 'a list 196 + node_test.js: [INFO] - take (Value): int -> 'a list -> 'a list 197 + node_test.js: [INFO] - take_while (Value): ('a -> bool) -> 'a list -> 'a list 128 198 node_test.js: [INFO] - tl (Value): 'a list -> 'a list 129 199 node_test.js: [INFO] - to_seq (Value): 'a list -> 'a Seq.t 130 200 node_test.js: [INFO] - t (Type): type 'a t = 'a list = [] | (::) of 'a * 'a list
+11 -3
test/node/node_test.ml
··· 51 51 let create_file = Js_of_ocaml.Sys_js.create_file 52 52 53 53 let import_scripts urls = 54 - if List.length urls > 0 then failwith "Not implemented" else () 54 + let open Js_of_ocaml.Js in 55 + let import_scripts_fn = Unsafe.get Unsafe.global (string "importScripts") in 56 + List.iter 57 + (fun url -> 58 + let (_ : 'a) = 59 + Unsafe.fun_call import_scripts_fn [| Unsafe.inject (string url) |] 60 + in 61 + ()) 62 + urls 55 63 56 64 let init_function _ () = failwith "Not implemented" 57 65 let findlib_init = Js_top_worker_web.Findlibish.init async_get ··· 62 70 63 71 let require b v = function 64 72 | [] -> [] 65 - | packages -> Js_top_worker_web.Findlibish.require sync_get b v packages 73 + | packages -> Js_top_worker_web.Findlibish.require ~import_scripts sync_get b v packages 66 74 67 75 let path = "/static/cmis" 68 76 end ··· 93 101 let ( let* ) = IdlM.ErrM.bind in 94 102 let init_config = 95 103 Js_top_worker_rpc.Toplevel_api_gen. 96 - { stdlib_dcs = None; findlib_requires = [ "stringext" ]; execute = false } 104 + { stdlib_dcs = None; findlib_requires = [ "base" ]; execute = true } 97 105 in 98 106 let x = 99 107 let open Client in