this repo has no description
0
fork

Configure Feed

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

x-ocaml: auto-discover worker URL from findlib_index compiler field

When a findlib_index.json contains a "compiler" field with version
and content_hash, x-ocaml now constructs the worker URL automatically.
This means .mld files only need @x-ocaml.universe — no separate
@x-ocaml.worker tag is required. The explicit x-ocaml-worker meta
tag still takes priority when present.

Uses a synchronous XHR pre-fetch of the findlib_index.json (~200 bytes)
before creating the worker, with browser JSON.parse for extraction.

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

+68 -11
+68 -11
src/x_ocaml.ml
··· 13 13 | None -> "builtin" 14 14 | Some name -> Jstr.to_string name 15 15 16 - let worker_url = 17 - match current_attribute "src-worker" with 18 - | None -> 19 - if backend_name = "builtin" then 20 - failwith "x-ocaml script missing src-worker attribute" 21 - else "" 22 - | Some url -> Jstr.to_string url 23 - 24 16 let read_meta name = 25 17 let doc = Brr.Document.to_jv Brr.G.document in 26 18 let selector = Jstr.of_string ("meta[name=\"" ^ name ^ "\"]") in ··· 39 31 (List.map String.trim (String.split_on_char ',' s)) in 40 32 if pkgs = [] then None else Some pkgs 41 33 42 - let findlib_index = 34 + let resolve_url relative = 35 + let url_ctor = Jv.get Jv.global "URL" in 36 + let loc = Jv.get (Jv.get Jv.global "window") "location" in 37 + let href = Jv.to_string (Jv.get loc "href") in 38 + let url_obj = Jv.new' url_ctor [| Jv.of_string relative; Jv.of_string href |] in 39 + Jv.to_string (Jv.get url_obj "href") 40 + 41 + let findlib_index_url = 43 42 match read_meta "x-ocaml-universe" with 44 43 | None -> None 45 44 | Some base -> 46 45 let base = if String.length base > 0 && base.[String.length base - 1] = '/' 47 46 then base else base ^ "/" in 48 - Some (base ^ "findlib_index.json") 47 + Some (resolve_url (base ^ "findlib_index.json")) 48 + 49 + (** Synchronous XHR fetch of a small text resource. 50 + Used only for the findlib_index.json pre-fetch (~200 bytes) 51 + to extract compiler info before creating the worker. *) 52 + let sync_fetch_text url = 53 + let xhr = Jv.new' (Jv.get Jv.global "XMLHttpRequest") [||] in 54 + Jv.call xhr "open" [| Jv.of_string "GET"; Jv.of_string url; Jv.of_bool false |] |> ignore; 55 + (try Jv.call xhr "send" [||] |> ignore with _ -> ()); 56 + let status = Jv.to_int (Jv.get xhr "status") in 57 + if status = 200 then Some (Jv.to_string (Jv.get xhr "responseText")) 58 + else None 59 + 60 + (** Extract compiler version and content_hash from a findlib_index.json. 61 + Uses browser JSON.parse — no OCaml JSON library needed. *) 62 + let compiler_from_findlib_index = 63 + match findlib_index_url with 64 + | None -> None 65 + | Some url -> 66 + match sync_fetch_text url with 67 + | None -> None 68 + | Some text -> 69 + (try 70 + let json = Jv.call (Jv.get Jv.global "JSON") "parse" [| Jv.of_string text |] in 71 + let compiler = Jv.get json "compiler" in 72 + if Jv.is_none compiler || Jv.is_undefined compiler then None 73 + else 74 + let version = Jv.to_string (Jv.get compiler "version") in 75 + let content_hash = Jv.to_string (Jv.get compiler "content_hash") in 76 + Some (version, content_hash) 77 + with _ -> None) 78 + 79 + let worker_url = 80 + (* Priority: 1) explicit x-ocaml-worker meta tag, 81 + 2) compiler field from findlib_index.json, 82 + 3) src-worker script attribute *) 83 + match read_meta "x-ocaml-worker" with 84 + | Some url -> url 85 + | None -> 86 + match compiler_from_findlib_index with 87 + | Some (version, content_hash) -> 88 + (* Construct worker URL relative to the findlib_index's directory. 89 + findlib_index is at e.g. .../p/yojson/3.0.0/findlib_index.json 90 + We need .../compiler/<ver>/<hash>/worker.js 91 + Relative from the findlib_index dir: ../../../compiler/... *) 92 + let fi_url = Option.get findlib_index_url in 93 + let base_dir = match String.rindex_opt fi_url '/' with 94 + | Some i -> String.sub fi_url 0 (i + 1) 95 + | None -> fi_url 96 + in 97 + base_dir ^ "../../../compiler/" ^ version ^ "/" ^ content_hash ^ "/worker.js" 98 + | None -> 99 + match current_attribute "src-worker" with 100 + | None -> 101 + if backend_name = "builtin" then 102 + failwith "x-ocaml script missing src-worker attribute" 103 + else "" 104 + | Some url -> Jstr.to_string url 49 105 50 - let backend = Backend.make ~backend:backend_name ?extra_load ?findlib_requires ?findlib_index worker_url 106 + let backend = Backend.make ~backend:backend_name ?extra_load ?findlib_requires 107 + ?findlib_index:findlib_index_url worker_url 51 108 52 109 let format_config = 53 110 match current_attribute "x-ocamlformat" with