-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSafeDOMExample.res
More file actions
109 lines (96 loc) · 3.08 KB
/
SafeDOMExample.res
File metadata and controls
109 lines (96 loc) · 3.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// SPDX-License-Identifier: AGPL-3.0-or-later
// Example: Using SafeDOM for formally verified DOM mounting
open SafeDOM
// Example 1: Basic mounting with error handling
let mountApp = () => {
mountSafe(
"#app",
"<div><h1>Hello, World!</h1><p>Mounted safely with proofs.</p></div>",
~onSuccess=el => {
Console.log("✓ App mounted successfully!")
Console.log("Element:", el)
},
~onError=err => {
Console.error("✗ Mount failed:", err)
}
)
}
// Example 2: Wait for DOM ready before mounting
let mountWhenDOMReady = () => {
mountWhenReady(
"#app",
"<div class='container'><h1>App Title</h1></div>",
~onSuccess=_ => Console.log("✓ Mounted after DOM ready"),
~onError=err => Console.error("✗ Failed:", err)
)
}
// Example 3: Batch mounting (atomic - all or nothing)
let mountMultiple = () => {
let specs = [
{selector: "#header", html: "<header><h1>Site Title</h1></header>"},
{selector: "#nav", html: "<nav><a href='/'>Home</a></nav>"},
{selector: "#main", html: "<main><p>Content here</p></main>"},
{selector: "#footer", html: "<footer>© 2026</footer>"}
]
switch mountBatch(specs) {
| Ok(elements) => {
Console.log(`✓ Successfully mounted ${Array.length(elements)} elements`)
elements->Array.forEach(el => Console.log(" -", el))
}
| Error(err) => {
Console.error("✗ Batch mount failed:", err)
Console.error(" (None were mounted - atomic operation)")
}
}
}
// Example 4: Explicit validation before mounting
let mountWithValidation = () => {
// Validate selector first
switch ProvenSelector.validate("#my-app") {
| Error(e) => Console.error(`Invalid selector: ${e}`)
| Ok(validSelector) => {
// Validate HTML
switch ProvenHTML.validate("<div>Content</div>") {
| Error(e) => Console.error(`Invalid HTML: ${e}`)
| Ok(validHtml) => {
// Now mount with proven safety
switch mount(validSelector, validHtml) {
| Mounted(el) => Console.log("✓ Mounted with validated inputs:", el)
| MountPointNotFound(s) => Console.error(`✗ Element not found: ${s}`)
| InvalidSelector(_) => Console.error("Impossible - already validated")
| InvalidHTML(_) => Console.error("Impossible - already validated")
}
}
}
}
}
// Example 5: Integration with TEA
module MyApp = {
type model = {message: string}
type msg = NoOp
let init = () => {message: "Hello from TEA"}
let update = (model, _msg) => model
let view = model => `<div><h1>${model.message}</h1></div>`
}
let mountTEAApp = () => {
let model = MyApp.init()
let html = MyApp.view(model)
mountWhenReady(
"#tea-app",
html,
~onSuccess=el => {
Console.log("✓ TEA app mounted")
// Set up event handlers, subscriptions here
},
~onError=err => Console.error(`✗ TEA mount failed: ${err}`)
)
}
// Entry point
let main = () => {
Console.log("SafeDOM Examples")
Console.log("================\n")
// Choose which example to run
mountWhenDOMReady() // Run on DOM ready
}
// Auto-execute when module loads
main()