ajo 0.0.12 → 0.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs +97 -75
- package/index.js +107 -75
- package/index.min.js +1 -1
- package/license +15 -0
- package/package.json +3 -3
- package/readme.md +8 -5
package/index.cjs
CHANGED
|
@@ -35,14 +35,21 @@ module.exports = __toCommonJS(ajo_exports);
|
|
|
35
35
|
const Fragment = ({ children }) => children, h = (nodeName, props, ...children) => {
|
|
36
36
|
children = children.length == 0 ? null : children.length == 1 ? children[0] : children;
|
|
37
37
|
return { children, ...props, nodeName };
|
|
38
|
-
}, component = (setup) => ({ is, key,
|
|
38
|
+
}, component = (setup) => ({ nodeName, is, key, block, ref: ref2, host, ...props }) => h(is ?? setup.is ?? "div", {
|
|
39
39
|
key,
|
|
40
|
-
...setup.host,
|
|
41
|
-
...host,
|
|
42
40
|
skip: true,
|
|
43
|
-
ref: (
|
|
41
|
+
ref: (node) => {
|
|
42
|
+
node.$params = { ...setup.props, ...props };
|
|
43
|
+
node.$render ??= setup(node.$params, node);
|
|
44
|
+
if (!(block != null && every(node.$deps, node.$deps = block))) {
|
|
45
|
+
update({ ...setup.host, ...host }, node);
|
|
46
|
+
refresh(node);
|
|
47
|
+
}
|
|
48
|
+
isFn(ref2) && ref2(node);
|
|
49
|
+
}
|
|
44
50
|
}), render = (h2, host) => {
|
|
45
|
-
|
|
51
|
+
const nodes = [];
|
|
52
|
+
let child = host.firstChild, node;
|
|
46
53
|
for (h2 of normalize(h2, host)) {
|
|
47
54
|
if (typeof h2 == "string") {
|
|
48
55
|
for (node = child; node; node = node.nextSibling)
|
|
@@ -52,120 +59,135 @@ const Fragment = ({ children }) => children, h = (nodeName, props, ...children)
|
|
|
52
59
|
} else if (h2 instanceof Node) {
|
|
53
60
|
node = h2;
|
|
54
61
|
} else {
|
|
55
|
-
const {
|
|
56
|
-
if (key != null
|
|
57
|
-
;
|
|
58
|
-
else
|
|
62
|
+
const { nodeName, key, skip, block, ref: ref2, children, ...props } = h2;
|
|
63
|
+
if (key != null) {
|
|
64
|
+
(host.$keyed ??= /* @__PURE__ */ new Map()).set(key, node = host.$keyed.get(key) ?? document.createElement(nodeName));
|
|
65
|
+
} else {
|
|
59
66
|
for (node = child; node; node = node.nextSibling)
|
|
60
67
|
if (node.localName == nodeName)
|
|
61
68
|
break;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
69
|
+
node ??= document.createElement(nodeName);
|
|
70
|
+
}
|
|
71
|
+
if (!(skip || block != null && every(node.$deps, node.$deps = block))) {
|
|
72
|
+
update(props, node);
|
|
73
|
+
render(children, node);
|
|
74
|
+
}
|
|
75
|
+
isFn(ref2) && ref2(node);
|
|
67
76
|
}
|
|
68
|
-
node === child
|
|
69
|
-
}
|
|
70
|
-
while (child) {
|
|
71
|
-
const next = child.nextSibling;
|
|
72
|
-
host.removeChild(child).nodeType == 1 && dispose(child);
|
|
73
|
-
child = next;
|
|
77
|
+
nodes.push(node) && node === child && (child = child.nextSibling);
|
|
74
78
|
}
|
|
75
|
-
|
|
79
|
+
arrange(host, [...host.childNodes], nodes);
|
|
80
|
+
}, refresh = (host) => {
|
|
76
81
|
try {
|
|
77
|
-
|
|
78
|
-
throwTypeError("Setup", setup, fn);
|
|
79
|
-
props = props ? memo.set(host, { ...setup?.props, ...props }) : memo.get(host) ?? {};
|
|
80
|
-
render((renders.get(host) ?? renders.set(host, setup(props, host)))(props, host), host);
|
|
82
|
+
render(host.$render(host.$params, host), host);
|
|
81
83
|
} catch (error) {
|
|
82
84
|
propagate(host, error);
|
|
83
85
|
}
|
|
84
|
-
}, provide = (host, key, value) => (provisions
|
|
86
|
+
}, provide = (host, key, value) => (host.$provisions ??= /* @__PURE__ */ new Map()).set(key, value), consume = (host, key, fallback) => {
|
|
85
87
|
let map;
|
|
86
88
|
while (host) {
|
|
87
|
-
if ((map = provisions
|
|
89
|
+
if ((map = host.$provisions) && map.has(key))
|
|
88
90
|
return map.get(key);
|
|
89
91
|
host = host.parentNode;
|
|
90
92
|
}
|
|
91
93
|
return fallback;
|
|
92
|
-
}, intercept = (host, interceptor) => {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}, propagate = (host, error) => {
|
|
97
|
-
for (let interceptor; host; host = host.parentNode)
|
|
98
|
-
if (interceptor = interceptors.get(host))
|
|
99
|
-
return render(host, interceptor(error));
|
|
94
|
+
}, intercept = (host, fn) => host.$interceptor = fn, propagate = (host, error) => {
|
|
95
|
+
for (let fn; host; host = host.parentNode)
|
|
96
|
+
if (fn = host.$interceptor)
|
|
97
|
+
return render(fn(error), host);
|
|
100
98
|
throw error;
|
|
101
|
-
}, cleanup = (host,
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
(
|
|
105
|
-
}, clx = (o) => keys(o).filter((k) => o[k]).join(" ") || null, stx = (o) => entries(o).map((t) => t.join(":")).join(";") || null, keb = (o) => keys(o).reduce((r, k) => (r[k.replace(search, replace).toLowerCase()] = o[k], r), {});
|
|
106
|
-
const wm = () => {
|
|
107
|
-
const instance = /* @__PURE__ */ new WeakMap(), { set } = instance;
|
|
108
|
-
instance.set = (key, value) => (set.call(instance, key, value), value);
|
|
109
|
-
return instance;
|
|
110
|
-
}, throwTypeError = (name, value, expected) => {
|
|
111
|
-
throw new TypeError(`Expected ${name} to be of type ${expected}, got ${typeof value} instead`);
|
|
112
|
-
}, every = (a, b) => a === b || isArray(a) && isArray(b) && a.length == b.length && a.every((v, i) => v === b[i]), apply = (o, { name, value }) => (o[name] = value, o), reduce = (list) => from(list).reduce(apply, {}), isFn = (v) => typeof v == fn, { keys, entries } = Object, { isArray, from } = Array, fn = "function", search = /([a-z0-9])([A-Z])/g, replace = "$1-$2", keyed = wm(), deps = wm(), memo = wm(), renders = wm(), provisions = wm(), interceptors = wm(), cleaners = wm(), cache = wm(), normalize = function* (h2, host) {
|
|
113
|
-
let type, buffer = "";
|
|
114
|
-
for (h2 of isFn(h2?.[Symbol.iterator]) ? h2 : [h2]) {
|
|
99
|
+
}, cleanup = (host, fn) => (host.$cleanups ??= /* @__PURE__ */ new Set()).add(fn), clx = (o) => keys(o).filter((k) => o[k]).join(" ") || null, stx = (o) => entries(o).map((t) => t.join(":")).join(";") || null, keb = (o) => keys(o).reduce((r, k) => (r[k.replace(search, replace).toLowerCase()] = o[k], r), {});
|
|
100
|
+
const every = (a, b) => a === b || isArray(a) && isArray(b) && a.length == b.length && a.every((v, i) => v === b[i]), apply = (o, { name, value }) => (o[name] = value, o), reduce = (list) => from(list).reduce(apply, {}), ref = (v) => (...args) => args.length ? v = args[0] : v, isFn = (v) => typeof v == "function", { keys, entries } = Object, { isArray, from } = Array, search = /([a-z0-9])([A-Z])/g, replace = "$1-$2", it = Symbol.iterator, normalize = function* (h2, host, buffer = ref(""), root = true) {
|
|
101
|
+
let type, text;
|
|
102
|
+
for (h2 of isFn(h2?.[it]) ? h2 : [h2]) {
|
|
115
103
|
if (h2 == null || (type = typeof h2) == "boolean")
|
|
116
104
|
continue;
|
|
117
105
|
if (type == "string" || type == "number") {
|
|
118
|
-
buffer
|
|
106
|
+
buffer(buffer() + h2);
|
|
119
107
|
continue;
|
|
120
108
|
}
|
|
121
109
|
if ("nodeName" in Object(h2)) {
|
|
122
110
|
if (isFn(h2.nodeName)) {
|
|
123
|
-
yield* normalize(h2.nodeName(h2, host
|
|
111
|
+
yield* normalize(h2.nodeName(h2), host, buffer, false);
|
|
124
112
|
continue;
|
|
125
113
|
}
|
|
126
|
-
if (buffer) {
|
|
127
|
-
yield
|
|
128
|
-
buffer
|
|
114
|
+
if (text = buffer()) {
|
|
115
|
+
yield text;
|
|
116
|
+
buffer("");
|
|
129
117
|
}
|
|
130
118
|
yield h2;
|
|
131
119
|
continue;
|
|
132
120
|
}
|
|
133
|
-
isFn(h2[
|
|
121
|
+
isFn(h2[it]) ? yield* normalize(h2, host, buffer, false) : buffer(buffer() + h2);
|
|
134
122
|
}
|
|
135
|
-
if (buffer)
|
|
136
|
-
yield
|
|
123
|
+
if (root && (text = buffer()))
|
|
124
|
+
yield text;
|
|
137
125
|
}, update = (props, host) => {
|
|
138
|
-
const prev =
|
|
126
|
+
const prev = host.$props ?? (host.hasAttributes() ? reduce(host.attributes) : {});
|
|
139
127
|
for (const name in { ...prev, ...props }) {
|
|
140
128
|
let value = props[name];
|
|
141
|
-
if (value === prev[name])
|
|
129
|
+
if (value === prev[name]) {
|
|
142
130
|
continue;
|
|
131
|
+
}
|
|
143
132
|
if (name.startsWith("set:")) {
|
|
144
133
|
host[name.slice(4)] = value;
|
|
145
134
|
continue;
|
|
146
135
|
}
|
|
147
|
-
if (value ===
|
|
148
|
-
value = "";
|
|
149
|
-
else if (value == null || value === false) {
|
|
136
|
+
if (value == null || value === false) {
|
|
150
137
|
host.removeAttribute(name);
|
|
151
138
|
continue;
|
|
152
139
|
}
|
|
153
|
-
host.setAttribute(name, value);
|
|
140
|
+
host.setAttribute(name, value === true ? "" : value);
|
|
154
141
|
}
|
|
155
|
-
|
|
156
|
-
},
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
142
|
+
host.$props = props;
|
|
143
|
+
}, arrange = (host, a, b) => {
|
|
144
|
+
const aLength = a.length, bLength = b.length;
|
|
145
|
+
let aIndex = 0, bIndex = 0, aValue, bValue, aMap, bMap, i;
|
|
146
|
+
while (aIndex !== aLength || bIndex !== bLength) {
|
|
147
|
+
aValue = a[aIndex], bValue = b[bIndex];
|
|
148
|
+
if (aValue === null) {
|
|
149
|
+
aIndex++;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (bLength <= bIndex) {
|
|
153
|
+
host.removeChild(aValue).nodeType == 1 && dispose(aValue);
|
|
154
|
+
aIndex++;
|
|
155
|
+
continue;
|
|
163
156
|
}
|
|
164
|
-
|
|
165
|
-
|
|
157
|
+
if (aLength <= aIndex) {
|
|
158
|
+
host.insertBefore(bValue, aValue);
|
|
159
|
+
bIndex++;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (aValue === bValue) {
|
|
163
|
+
aIndex++;
|
|
164
|
+
bIndex++;
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (!aMap) {
|
|
168
|
+
aMap = /* @__PURE__ */ new Map();
|
|
169
|
+
bMap = /* @__PURE__ */ new Map();
|
|
170
|
+
for (i = 0; i < aLength; i++)
|
|
171
|
+
aMap.set(a[i], i);
|
|
172
|
+
for (i = 0; i < bLength; i++)
|
|
173
|
+
bMap.set(b[i], i);
|
|
174
|
+
}
|
|
175
|
+
if (bMap.get(aValue) == null) {
|
|
176
|
+
host.removeChild(aValue).nodeType == 1 && dispose(aValue);
|
|
177
|
+
aIndex++;
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
host.insertBefore(bValue, aValue);
|
|
181
|
+
bIndex++;
|
|
182
|
+
if ((i = aMap.get(bValue)) != null) {
|
|
183
|
+
if (i > aIndex + 1)
|
|
184
|
+
aIndex++;
|
|
185
|
+
a[i] = null;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
166
188
|
}, dispose = (host) => {
|
|
167
189
|
for (const child of host.children)
|
|
168
190
|
dispose(child);
|
|
169
|
-
for (const
|
|
170
|
-
|
|
191
|
+
for (const fn of host.$cleanups ?? [])
|
|
192
|
+
fn(host);
|
|
171
193
|
};
|
package/index.js
CHANGED
|
@@ -6,13 +6,26 @@ export const
|
|
|
6
6
|
return { children, ...props, nodeName }
|
|
7
7
|
},
|
|
8
8
|
|
|
9
|
-
component = setup => ({ is, key,
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
component = setup => ({ nodeName, is, key, block, ref, host, ...props }) =>
|
|
10
|
+
h(is ?? setup.is ?? 'div', {
|
|
11
|
+
key, skip: true, ref: node => {
|
|
12
|
+
|
|
13
|
+
node.$params = { ...setup.props, ...props }
|
|
14
|
+
node.$render ??= setup(node.$params, node)
|
|
15
|
+
|
|
16
|
+
if (!(block != null && every(node.$deps, node.$deps = block))) {
|
|
17
|
+
update({ ...setup.host, ...host }, node)
|
|
18
|
+
refresh(node)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
isFn(ref) && ref(node)
|
|
22
|
+
}
|
|
23
|
+
}),
|
|
12
24
|
|
|
13
25
|
render = (h, host) => {
|
|
14
26
|
|
|
15
|
-
|
|
27
|
+
const nodes = []
|
|
28
|
+
let child = host.firstChild, node
|
|
16
29
|
|
|
17
30
|
for (h of normalize(h, host)) {
|
|
18
31
|
|
|
@@ -27,172 +40,191 @@ export const
|
|
|
27
40
|
|
|
28
41
|
} else {
|
|
29
42
|
|
|
30
|
-
const {
|
|
43
|
+
const { nodeName, key, skip, block, ref, children, ...props } = h
|
|
31
44
|
|
|
32
|
-
if (key != null
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
update(props, node)
|
|
45
|
+
if (key != null) {
|
|
46
|
+
(host.$keyed ??= new Map).set(key, node = host.$keyed.get(key) ?? document.createElement(nodeName))
|
|
47
|
+
} else {
|
|
48
|
+
for (node = child; node; node = node.nextSibling) if (node.localName == nodeName) break
|
|
49
|
+
node ??= document.createElement(nodeName)
|
|
50
|
+
}
|
|
40
51
|
|
|
41
|
-
!(skip || block != null && every(deps
|
|
52
|
+
if (!(skip || block != null && every(node.$deps, node.$deps = block))) {
|
|
53
|
+
update(props, node)
|
|
54
|
+
render(children, node)
|
|
55
|
+
}
|
|
42
56
|
|
|
43
57
|
isFn(ref) && ref(node)
|
|
44
58
|
}
|
|
45
59
|
|
|
46
|
-
node === child
|
|
60
|
+
nodes.push(node) && node === child && (child = child.nextSibling)
|
|
47
61
|
}
|
|
48
62
|
|
|
49
|
-
|
|
50
|
-
const next = child.nextSibling
|
|
51
|
-
host.removeChild(child).nodeType == 1 && dispose(child)
|
|
52
|
-
child = next
|
|
53
|
-
}
|
|
63
|
+
arrange(host, [...host.childNodes], nodes)
|
|
54
64
|
},
|
|
55
65
|
|
|
56
|
-
refresh =
|
|
66
|
+
refresh = host => {
|
|
57
67
|
try {
|
|
58
|
-
|
|
59
|
-
props = props ? memo.set(host, { ...setup?.props, ...props }) : memo.get(host) ?? {}
|
|
60
|
-
render((renders.get(host) ?? renders.set(host, setup(props, host)))(props, host), host)
|
|
68
|
+
render(host.$render(host.$params, host), host)
|
|
61
69
|
} catch (error) {
|
|
62
70
|
propagate(host, error)
|
|
63
71
|
}
|
|
64
72
|
},
|
|
65
73
|
|
|
66
|
-
provide = (host, key, value) => (provisions
|
|
74
|
+
provide = (host, key, value) => (host.$provisions ??= new Map).set(key, value),
|
|
67
75
|
|
|
68
76
|
consume = (host, key, fallback) => {
|
|
69
77
|
let map
|
|
70
78
|
while (host) {
|
|
71
|
-
if ((map = provisions
|
|
79
|
+
if ((map = host.$provisions) && map.has(key)) return map.get(key)
|
|
72
80
|
host = host.parentNode
|
|
73
81
|
}
|
|
74
82
|
return fallback
|
|
75
83
|
},
|
|
76
84
|
|
|
77
|
-
intercept = (host,
|
|
78
|
-
if (!isFn(interceptor)) throwTypeError('Interceptor', interceptor, fn)
|
|
79
|
-
interceptors.set(host, interceptor)
|
|
80
|
-
},
|
|
85
|
+
intercept = (host, fn) => host.$interceptor = fn,
|
|
81
86
|
|
|
82
87
|
propagate = (host, error) => {
|
|
83
|
-
for (let
|
|
84
|
-
if (interceptor = interceptors.get(host)) return render(host, interceptor(error))
|
|
88
|
+
for (let fn; host; host = host.parentNode) if (fn = host.$interceptor) return render(fn(error), host)
|
|
85
89
|
throw error
|
|
86
90
|
},
|
|
87
91
|
|
|
88
|
-
cleanup = (host,
|
|
89
|
-
if (!isFn(cleaner)) throwTypeError('Cleaner', cleaner, fn);
|
|
90
|
-
(cleaners.get(host) ?? cleaners.set(host, new Set)).add(cleaner)
|
|
91
|
-
},
|
|
92
|
+
cleanup = (host, fn) => (host.$cleanups ??= new Set).add(fn),
|
|
92
93
|
|
|
93
94
|
clx = o => keys(o).filter(k => o[k]).join(' ') || null,
|
|
94
95
|
stx = o => entries(o).map(t => t.join(':')).join(';') || null,
|
|
95
96
|
keb = o => keys(o).reduce((r, k) => ((r[k.replace(search, replace).toLowerCase()] = o[k]), r), {})
|
|
96
97
|
|
|
97
98
|
const
|
|
98
|
-
wm = () => {
|
|
99
|
-
const instance = new WeakMap, { set } = instance
|
|
100
|
-
instance.set = (key, value) => (set.call(instance, key, value), value)
|
|
101
|
-
return instance
|
|
102
|
-
},
|
|
103
|
-
|
|
104
|
-
throwTypeError = (name, value, expected) => {
|
|
105
|
-
throw new TypeError(`Expected ${name} to be of type ${expected}, got ${typeof value} instead`)
|
|
106
|
-
},
|
|
107
|
-
|
|
108
99
|
every = (a, b) => a === b || isArray(a) && isArray(b) && a.length == b.length && a.every((v, i) => v === b[i]),
|
|
109
100
|
apply = (o, { name, value }) => ((o[name] = value), o),
|
|
110
101
|
reduce = list => from(list).reduce(apply, {}),
|
|
111
|
-
|
|
102
|
+
ref = v => (...args) => args.length ? v = args[0] : v,
|
|
103
|
+
isFn = v => typeof v == 'function',
|
|
112
104
|
|
|
113
105
|
{ keys, entries } = Object, { isArray, from } = Array,
|
|
114
106
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
keyed = wm(), deps = wm(), memo = wm(), renders = wm(), provisions = wm(), interceptors = wm(), cleaners = wm(), cache = wm(),
|
|
107
|
+
search = /([a-z0-9])([A-Z])/g, replace = '$1-$2', it = Symbol.iterator,
|
|
118
108
|
|
|
119
|
-
normalize = function* (h, host) {
|
|
109
|
+
normalize = function* (h, host, buffer = ref(''), root = true) {
|
|
120
110
|
|
|
121
|
-
let type,
|
|
111
|
+
let type, text
|
|
122
112
|
|
|
123
|
-
for (h of isFn(h?.[
|
|
113
|
+
for (h of isFn(h?.[it]) ? h : [h]) {
|
|
124
114
|
|
|
125
115
|
if (h == null || (type = typeof h) == 'boolean') continue
|
|
126
116
|
|
|
127
117
|
if (type == 'string' || type == 'number') {
|
|
128
|
-
buffer
|
|
118
|
+
buffer(buffer() + h)
|
|
129
119
|
continue
|
|
130
120
|
}
|
|
131
121
|
|
|
132
122
|
if ('nodeName' in Object(h)) {
|
|
133
123
|
|
|
134
124
|
if (isFn(h.nodeName)) {
|
|
135
|
-
yield* normalize(h.nodeName(h, host
|
|
125
|
+
yield* normalize(h.nodeName(h), host, buffer, false)
|
|
136
126
|
continue
|
|
137
127
|
}
|
|
138
128
|
|
|
139
|
-
if (buffer) {
|
|
140
|
-
yield
|
|
141
|
-
buffer
|
|
129
|
+
if (text = buffer()) {
|
|
130
|
+
yield text
|
|
131
|
+
buffer('')
|
|
142
132
|
}
|
|
143
133
|
|
|
144
134
|
yield h
|
|
145
135
|
continue
|
|
146
136
|
}
|
|
147
137
|
|
|
148
|
-
isFn(h[
|
|
138
|
+
isFn(h[it]) ? yield* normalize(h, host, buffer, false) : buffer(buffer() + h)
|
|
149
139
|
}
|
|
150
140
|
|
|
151
|
-
if (buffer) yield
|
|
141
|
+
if (root && (text = buffer())) yield text
|
|
152
142
|
},
|
|
153
143
|
|
|
154
144
|
update = (props, host) => {
|
|
155
145
|
|
|
156
|
-
const prev =
|
|
146
|
+
const prev = host.$props ?? (host.hasAttributes() ? reduce(host.attributes) : {})
|
|
157
147
|
|
|
158
148
|
for (const name in { ...prev, ...props }) {
|
|
159
149
|
|
|
160
150
|
let value = props[name]
|
|
161
151
|
|
|
162
|
-
if (value === prev[name])
|
|
152
|
+
if (value === prev[name]) {
|
|
153
|
+
continue
|
|
154
|
+
}
|
|
163
155
|
|
|
164
156
|
if (name.startsWith('set:')) {
|
|
165
157
|
host[name.slice(4)] = value
|
|
166
158
|
continue
|
|
167
159
|
}
|
|
168
160
|
|
|
169
|
-
if (value
|
|
170
|
-
else if (value == null || value === false) {
|
|
161
|
+
if (value == null || value === false) {
|
|
171
162
|
host.removeAttribute(name)
|
|
172
163
|
continue
|
|
173
164
|
}
|
|
174
165
|
|
|
175
|
-
host.setAttribute(name, value)
|
|
166
|
+
host.setAttribute(name, value === true ? '' : value)
|
|
176
167
|
}
|
|
177
168
|
|
|
178
|
-
|
|
169
|
+
host.$props = props
|
|
179
170
|
},
|
|
180
171
|
|
|
181
|
-
|
|
182
|
-
if (node.contains?.(document.activeElement)) {
|
|
172
|
+
arrange = (host, a, b) => {
|
|
183
173
|
|
|
184
|
-
|
|
174
|
+
const aLength = a.length, bLength = b.length
|
|
175
|
+
let aIndex = 0, bIndex = 0, aValue, bValue, aMap, bMap, i
|
|
185
176
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
177
|
+
while (aIndex !== aLength || bIndex !== bLength) {
|
|
178
|
+
|
|
179
|
+
aValue = a[aIndex], bValue = b[bIndex]
|
|
180
|
+
|
|
181
|
+
if (aValue === null) {
|
|
182
|
+
aIndex++
|
|
183
|
+
continue
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (bLength <= bIndex) {
|
|
187
|
+
host.removeChild(aValue).nodeType == 1 && dispose(aValue)
|
|
188
|
+
aIndex++
|
|
189
|
+
continue
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (aLength <= aIndex) {
|
|
193
|
+
host.insertBefore(bValue, aValue)
|
|
194
|
+
bIndex++
|
|
195
|
+
continue
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (aValue === bValue) {
|
|
199
|
+
aIndex++
|
|
200
|
+
bIndex++
|
|
201
|
+
continue
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (!aMap) {
|
|
205
|
+
aMap = new Map()
|
|
206
|
+
bMap = new Map()
|
|
207
|
+
for (i = 0; i < aLength; i++) aMap.set(a[i], i)
|
|
208
|
+
for (i = 0; i < bLength; i++) bMap.set(b[i], i)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (bMap.get(aValue) == null) {
|
|
212
|
+
host.removeChild(aValue).nodeType == 1 && dispose(aValue)
|
|
213
|
+
aIndex++
|
|
214
|
+
continue
|
|
190
215
|
}
|
|
191
216
|
|
|
192
|
-
|
|
217
|
+
host.insertBefore(bValue, aValue)
|
|
218
|
+
bIndex++
|
|
219
|
+
|
|
220
|
+
if ((i = aMap.get(bValue)) != null) {
|
|
221
|
+
if (i > aIndex + 1) aIndex++
|
|
222
|
+
a[i] = null
|
|
223
|
+
}
|
|
224
|
+
}
|
|
193
225
|
},
|
|
194
226
|
|
|
195
227
|
dispose = host => {
|
|
196
228
|
for (const child of host.children) dispose(child)
|
|
197
|
-
for (const
|
|
229
|
+
for (const fn of host.$cleanups ?? []) fn(host)
|
|
198
230
|
}
|
package/index.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var ajo=(()=>{var
|
|
1
|
+
var ajo=(()=>{var m=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var S=Object.prototype.hasOwnProperty;var C=(e,n)=>{for(var t in n)m(e,t,{get:n[t],enumerable:!0})},T=(e,n,t,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let i of j(n))!S.call(e,i)&&i!==t&&m(e,i,{get:()=>n[i],enumerable:!(r=M(n,i))||r.enumerable});return e};var L=e=>T(m({},"__esModule",{value:!0}),e);var R={};C(R,{Fragment:()=>z,cleanup:()=>O,clx:()=>V,component:()=>B,consume:()=>F,h:()=>v,intercept:()=>I,keb:()=>Z,propagate:()=>w,provide:()=>E,refresh:()=>x,render:()=>s,stx:()=>W});const z=({children:e})=>e,v=(e,n,...t)=>(t=t.length==0?null:t.length==1?t[0]:t,{children:t,...n,nodeName:e}),B=e=>({nodeName:n,is:t,key:r,block:i,ref:l,host:p,...c})=>v(t??e.is??"div",{key:r,skip:!0,ref:a=>{a.$params={...e.props,...c},a.$render??=e(a.$params,a),i!=null&&k(a.$deps,a.$deps=i)||(A({...e.host,...p},a),x(a)),d(l)&&l(a)}}),s=(e,n)=>{const t=[];let r=n.firstChild,i;for(e of y(e,n)){if(typeof e=="string"){for(i=r;i&&i.nodeType!=3;i=i.nextSibling);i?i.data!==e&&(i.data=e):i=document.createTextNode(e)}else if(e instanceof Node)i=e;else{const{nodeName:l,key:p,skip:c,block:a,ref:f,children:u,...o}=e;if(p!=null)(n.$keyed??=new Map).set(p,i=n.$keyed.get(p)??document.createElement(l));else{for(i=r;i&&i.localName!=l;i=i.nextSibling);i??=document.createElement(l)}c||a!=null&&k(i.$deps,i.$deps=a)||(A(o,i),s(u,i)),d(f)&&f(i)}t.push(i)&&i===r&&(r=r.nextSibling)}Q(n,[...n.childNodes],t)},x=e=>{try{s(e.$render(e.$params,e),e)}catch(n){w(e,n)}},E=(e,n,t)=>(e.$provisions??=new Map).set(n,t),F=(e,n,t)=>{let r;for(;e;){if((r=e.$provisions)&&r.has(n))return r.get(n);e=e.parentNode}return t},I=(e,n)=>e.$interceptor=n,w=(e,n)=>{for(let t;e;e=e.parentNode)if(t=e.$interceptor)return s(t(n),e);throw n},O=(e,n)=>(e.$cleanups??=new Set).add(n),V=e=>b(e).filter(n=>e[n]).join(" ")||null,W=e=>H(e).map(n=>n.join(":")).join(";")||null,Z=e=>b(e).reduce((n,t)=>(n[t.replace(K,P).toLowerCase()]=e[t],n),{}),k=(e,n)=>e===n||$(e)&&$(n)&&e.length==n.length&&e.every((t,r)=>t===n[r]),q=(e,{name:n,value:t})=>(e[n]=t,e),D=e=>J(e).reduce(q,{}),G=e=>(...n)=>n.length?e=n[0]:e,d=e=>typeof e=="function",{keys:b,entries:H}=Object,{isArray:$,from:J}=Array,K=/([a-z0-9])([A-Z])/g,P="$1-$2",N=Symbol.iterator,y=function*(e,n,t=G(""),r=!0){let i,l;for(e of d(e?.[N])?e:[e])if(!(e==null||(i=typeof e)=="boolean")){if(i=="string"||i=="number"){t(t()+e);continue}if("nodeName"in Object(e)){if(d(e.nodeName)){yield*y(e.nodeName(e),n,t,!1);continue}(l=t())&&(yield l,t("")),yield e;continue}d(e[N])?yield*y(e,n,t,!1):t(t()+e)}r&&(l=t())&&(yield l)},A=(e,n)=>{const t=n.$props??(n.hasAttributes()?D(n.attributes):{});for(const r in{...t,...e}){let i=e[r];if(i!==t[r]){if(r.startsWith("set:")){n[r.slice(4)]=i;continue}if(i==null||i===!1){n.removeAttribute(r);continue}n.setAttribute(r,i===!0?"":i)}}n.$props=e},Q=(e,n,t)=>{const r=n.length,i=t.length;let l=0,p=0,c,a,f,u,o;for(;l!==r||p!==i;){if(c=n[l],a=t[p],c===null){l++;continue}if(i<=p){e.removeChild(c).nodeType==1&&g(c),l++;continue}if(r<=l){e.insertBefore(a,c),p++;continue}if(c===a){l++,p++;continue}if(!f){for(f=new Map,u=new Map,o=0;o<r;o++)f.set(n[o],o);for(o=0;o<i;o++)u.set(t[o],o)}if(u.get(c)==null){e.removeChild(c).nodeType==1&&g(c),l++;continue}e.insertBefore(a,c),p++,(o=f.get(a))!=null&&(o>l+1&&l++,n[o]=null)}},g=e=>{for(const n of e.children)g(n);for(const n of e.$cleanups??[])n(e)};return L(R);})();
|
package/license
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022, Cristian Falcone, @cristianfalcone
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
10
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
11
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
12
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
13
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
|
14
|
+
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
15
|
+
PERFORMANCE OF THIS SOFTWARE.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ajo",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.16",
|
|
4
4
|
"description": "ajo is a JavaScript view library for building user interfaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "index.js",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"bugs": "https://github.com/cristianfalcone/ajo/issues",
|
|
31
31
|
"homepage": "https://github.com/cristianfalcone/ajo#readme",
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"backdom": "^0.0.
|
|
34
|
-
"esbuild": "^0.
|
|
33
|
+
"backdom": "^0.0.5",
|
|
34
|
+
"esbuild": "^0.15.2",
|
|
35
35
|
"uvu": "^0.5.6"
|
|
36
36
|
}
|
|
37
37
|
}
|
package/readme.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# ajo
|
|
2
2
|
ajo is a JavaScript view library for building user interfaces
|
|
3
3
|
|
|
4
|
-
##
|
|
4
|
+
## install
|
|
5
5
|
|
|
6
6
|
```sh
|
|
7
7
|
npm install ajo
|
|
8
8
|
```
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## render JSX to a DOM element
|
|
11
11
|
|
|
12
12
|
```jsx
|
|
13
13
|
/** @jsx h */
|
|
@@ -18,7 +18,7 @@ document.body.innerHTML = '<div>Hello World</div>'
|
|
|
18
18
|
render(<div>Goodbye World</div>, document.body)
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## stateless component
|
|
22
22
|
|
|
23
23
|
```jsx
|
|
24
24
|
/** @jsx h */
|
|
@@ -29,7 +29,7 @@ const Greet = ({ name }) => <div>Hello {name}</div>
|
|
|
29
29
|
render(<Greet name="World" />, document.body)
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
##
|
|
32
|
+
## stateful component
|
|
33
33
|
|
|
34
34
|
```jsx
|
|
35
35
|
/** @jsx h */
|
|
@@ -45,10 +45,13 @@ const Counter = component(({ start = 0 }, host) => {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
return () =>
|
|
48
|
-
<button onclick={increment}>
|
|
48
|
+
<button set:onclick={increment}>
|
|
49
49
|
Current: {count}
|
|
50
50
|
</button>
|
|
51
51
|
})
|
|
52
52
|
|
|
53
53
|
render(<Counter start={1} />, document.body)
|
|
54
54
|
```
|
|
55
|
+
|
|
56
|
+
## acknowledgments
|
|
57
|
+
ajo takes heavy inspiration from [Incremental DOM](https://github.com/google/incremental-dom) and [Crank.js](https://github.com/bikeshaving/crank)
|