this repo has no description
at main 128 lines 5.5 kB view raw
1(** Page-level orchestration for x-ocaml cells. 2 3 A page contains a collection of {!Cell.t} values arranged in document 4 order. This module manages: 5 6 - {b Cell registry}: looking up cells by numeric id or by [data-id]. 7 - {b Execution chain}: linking cells into a linear predecessor chain so 8 that running a cell automatically runs its prerequisites. 9 - {b Test linking}: connecting {!Cell.Test} cells to their target 10 {!Cell.Exercise} cells, either positionally (nearest preceding exercise) 11 or explicitly via [data-for] / [data-id] attributes. After an exercise 12 cell completes, its linked test cells run automatically. 13 - {b Auto-run}: triggering cells whose [run-on] is ["load"] once all 14 cells have been registered. 15 - {b Backend message routing}: dispatching responses from the backend to 16 the correct cell. 17 18 {2 Typical lifecycle} 19 20 {[ 21 let page = Page.create ~backend () in 22 (* WebComponent connectedCallback fires for each <x-ocaml>: *) 23 let _cell = Page.register page element in 24 (* After all cells registered, auto-run triggers. *) 25 ]} 26 27 {2 Test linking} 28 29 When a {!Cell.Test} cell is registered, the page links it to an exercise: 30 31 - If the test has [data-for="some-id"], it links to the exercise cell 32 whose [data-id="some-id"]. 33 - Otherwise it links to the nearest preceding {!Cell.Exercise}. 34 35 After an exercise cell's run completes, all test cells linked to it are 36 triggered automatically. If a test cell is registered after its linked 37 exercise has already completed, the test is triggered immediately upon 38 registration. 39 40 {2 Universe discovery} 41 42 During creation, the page reads 43 [<meta name="x-ocaml-packages" content="pkg1,pkg2,...">] from the document 44 head. If present, each package name is used to register dynamic CMIs with 45 the merlin worker so that type information (completions, type-on-hover, 46 error checking) is available for those packages. 47 48 For each package [pkg], CMIs are expected at [{base_url}/{pkg}/] where 49 [base_url] defaults to ["./cmis/"] and can be overridden with 50 [<meta name="x-ocaml-cmis-url" content="...">]. The toplevel module is 51 assumed to be [{Pkg}] (capitalised) with sub-modules prefixed [{pkg}__]. 52 53 {b Note:} For the toplevel {e evaluator} to have access to the packages, 54 their JavaScript bundles must be loaded separately via the [src-load] 55 attribute on the [<script>] tag. Universe discovery only configures merlin. *) 56 57type t 58(** Mutable page-level state: cell registry, backend handle, and page-wide 59 configuration. *) 60 61val create : 62 backend:Backend.t -> 63 ?extra_style:Jstr.t -> 64 ?inline_style:Jstr.t -> 65 ?default_run_on:string -> 66 ?format_config:string -> 67 unit -> 68 t 69(** Create a new page and initialise the backend. 70 71 Sends [Setup] to the backend, registers a message handler that routes 72 responses to the appropriate cell, and reads 73 [<meta name="x-ocaml-packages">] and [<meta name="x-ocaml-cmis-url">] 74 from the document to configure merlin's dynamic CMI loading. 75 76 @param backend The evaluation/formatting backend. 77 @param extra_style Default stylesheet URL applied to every cell. 78 @param inline_style Default inline CSS for every cell's [:host] selector. 79 @param default_run_on Default [run-on] value for cells that don't specify 80 their own (["load"] or ["click"]). Defaults to ["load"]. 81 @param format_config OCamlformat configuration string. If provided, 82 sent to the backend as [Format_config]. *) 83 84(** {1 Cell registration} *) 85 86val register : t -> Webcomponent.t -> Cell.t 87(** [register page element] creates and registers a new cell from the 88 given custom element. 89 90 Reads the following attributes from [element]: 91 92 - [mode]: cell mode (["interactive"], ["exercise"], ["test"], ["hidden"]). 93 Defaults to ["interactive"]. 94 - [data-id]: makes this cell addressable by name for test linking. 95 - [data-for]: links a test cell to an exercise cell by [data-id]. 96 - [data-env]: reserved for future environment scoping. 97 - [data-filename]: filename for merlin and error reporting. 98 - [data-merlin]: ["false"] to disable merlin for this cell. 99 - [run-on]: per-cell override of the default run-on behaviour. 100 101 After creation, the cell is: 102 + Added to the registry. 103 + Linked into the execution chain (predecessor set to the previous cell). 104 + If it is a {!Cell.Test}, linked to its target exercise cell. If the 105 target exercise has already completed, the test is triggered immediately. 106 + Started (initial source loaded from element [textContent]). 107 + If all cells so far are loadable, the last cell is auto-run. *) 108 109(** {1 Reset} *) 110 111val reset_all : t -> unit 112(** [reset_all page] terminates the current worker, creates a fresh one, 113 replays initialisation messages (Setup, Format_config, Add_cmis), and 114 resets every cell to {!Cell.Not_run}. The user must re-run cells from 115 the top since the new worker has no accumulated state. *) 116 117(** {1 Lookups} *) 118 119val find_by_id : t -> int -> Cell.t 120(** [find_by_id page id] returns the cell with numeric id [id]. 121 @raise Not_found if no such cell exists. *) 122 123val find_by_cell_id : t -> string -> Cell.t option 124(** [find_by_cell_id page name] returns the cell whose [data-id] is [name], 125 if any. *) 126 127val cells : t -> Cell.t list 128(** All registered cells in document order (first cell at the head). *)