-
Notifications
You must be signed in to change notification settings - Fork 102
/
Copy pathvan-1.2.5.debug.js
121 lines (101 loc) · 4.51 KB
/
van-1.2.5.debug.js
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
110
111
112
113
114
115
116
117
118
119
120
121
import van from "./van.js"
// If this variable is set to an Array, we will push the error message into the array instead of
// throwing an error. This is useful in testing, to capture the error occurred asynchronous to the initiating
// callstack. e.g.: a state change can trigger a dom update processing when idle (i.e.: dom update
// processing is set via setTimeout function, which is asynchronous to the initiating callstack).
let capturedErrors
const startCapturingErrors = () => capturedErrors = []
const stopCapturingErrors = () => capturedErrors = null
const expect = (cond, msg) => {
if (!cond) {
if (capturedErrors) capturedErrors.push(msg); else throw new Error(msg)
return false
}
return true
}
const protoOf = Object.getPrototypeOf
const stateProto = protoOf(van.state())
const isState = s => protoOf(s ?? 0) === stateProto
const checkStateValValid = v => {
expect(!isState(v), "State couldn't have value to other state")
expect(!(v instanceof Node), "DOM Node is not valid value for state")
return v
}
const state = initVal => new Proxy(van.state(checkStateValValid(initVal)), {
set: (s, prop, val) => (prop === "val" && checkStateValValid(val), Reflect.set(s, prop, val)),
})
const derive = f => {
expect(typeof(f) === "function", "Must pass-in a function to `van.derive`")
return van.derive(f)
}
const isValidPrimitive = v =>
typeof(v) === "string" ||
typeof(v) === "number" ||
typeof(v) === "boolean" ||
typeof(v) === "bigint"
const isDomOrPrimitive = v => v instanceof Node || isValidPrimitive(v)
const validateChild = child => {
expect(
isDomOrPrimitive(child) || child === null || child === undefined,
"Only DOM Node, string, number, boolean, bigint, null, undefined are valid child of a DOM Element",
)
return child
}
const withResultValidation = f => dom => {
const r = validateChild(f(dom))
if (r !== dom && r instanceof Node)
expect(!r.isConnected,
"If the result of complex binding function is not the same as previous one, it shouldn't be already connected to document")
return r
}
const checkChildren = children => children.flat(Infinity).map(c => {
if (isState(c)) return withResultValidation(() => c.val)
if (typeof c === "function") return withResultValidation(c)
expect(!c?.isConnected, "You can't add a DOM Node that is already connected to document")
return validateChild(c)
})
const add = (dom, ...children) => {
expect(dom instanceof Element, "1st argument of `van.add` function must be a DOM Element object")
return van.add(dom, ...checkChildren(children))
}
const _ = f => {
expect(typeof(f) === "function", "Must pass-in a function to `van._`")
return van._(f)
}
const _tagsNS = ns => new Proxy(van.tagsNS(ns), {
get: (vanTags, name) => {
const vanTag = vanTags[name]
return (...args) => {
const [props, ...children] = protoOf(args[0] ?? 0) === Object.prototype ? args : [{}, ...args]
const debugProps = {}
for (const [k, v] of Object.entries(props)) {
const validatePropValue = k.startsWith("on") ?
(k.toLowerCase() === k ?
v => (expect(typeof v === "function" || v === null,
`Invalid property value for ${k}: Only functions and null are allowed for ${k} property`), v) :
v => (expect(typeof v === "string",
`Invalid property value for ${k}: Only strings are allowed for ${k} attribute`), v)
) :
v => (expect(isValidPrimitive(v) || v === null,
`Invalid property value for ${k}: Only string, number, boolean, bigint and null are valid prop value types`), v)
if (isState(v))
debugProps[k] = van._(() => validatePropValue(v.val))
else if (typeof v === "function" && (!k.startsWith("on") || v._isBindingFunc))
debugProps[k] = van._(() => validatePropValue(v()))
else
debugProps[k] = validatePropValue(v)
}
return vanTag(debugProps, ...checkChildren(children))
}
},
})
const tagsNS = ns => {
expect(typeof ns === "string", "Must provide a string for parameter `ns` in `van.tagsNS`")
return _tagsNS(ns)
}
const hydrate = (dom, f) => {
expect(dom instanceof Node, "1st argument of `van.hydrate` function must be a DOM Node object")
expect(typeof(f) === "function", "2nd argument of `van.hydrate` function must be a function")
return van.hydrate(dom, withResultValidation(f))
}
export default {add, _, tags: _tagsNS(), tagsNS, state, val: van.val, oldVal: van.oldVal, derive, hydrate, startCapturingErrors, stopCapturingErrors, get capturedErrors() { return capturedErrors }}