olum 0.2.4 → 0.5.1
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/LICENSE.md +1 -1
- package/README.md +1 -1
- package/dist/olum.js +505 -230
- package/dist/olum.min.js +3 -3
- package/package.json +1 -1
package/LICENSE.md
CHANGED
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<p align="center"><img width="100" src="https://
|
|
1
|
+
<p align="center"><img width="100" src="https://github.com/olumjs.png" alt="Olum logo"></p>
|
|
2
2
|
<p align="center">
|
|
3
3
|
<a href="https://www.npmjs.com/package/olum" target="_blank"><img src="https://img.shields.io/npm/v/olum" alt="npm"></a>
|
|
4
4
|
<img src="https://img.shields.io/npm/dm/olum" alt="npm">
|
package/dist/olum.js
CHANGED
|
@@ -1,272 +1,547 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @name Olum.js
|
|
3
|
-
* @version 0.
|
|
4
|
-
* @copyright
|
|
3
|
+
* @version 0.5.1
|
|
4
|
+
* @copyright 2026
|
|
5
5
|
* @author Eissa Saber
|
|
6
6
|
* @license MIT
|
|
7
7
|
*/
|
|
8
|
-
(function (
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
8
|
+
export default (function () {
|
|
9
|
+
var olum = {
|
|
10
|
+
app: {}, // this is a must to access live changes
|
|
11
|
+
$emit(event, data) {
|
|
12
|
+
this.dispatchEvent(event, data);
|
|
13
|
+
},
|
|
14
|
+
dispatchEvent(event, data) {
|
|
15
|
+
window.dispatchEvent(new CustomEvent(event, { detail: data }));
|
|
16
|
+
},
|
|
17
|
+
mkElm(type, compName, compId) {
|
|
18
|
+
const el = document.createElement(type);
|
|
19
|
+
if (compName && compId) el.setAttribute("data-olum", JSON.stringify({ compName, compId }));
|
|
20
|
+
return el;
|
|
21
|
+
},
|
|
22
|
+
injectStyle(compName, cssContent) {
|
|
23
|
+
if (!cssContent || !cssContent.trim()) return;
|
|
24
|
+
const id = "olum-style-" + compName;
|
|
25
|
+
if (document.getElementById(id)) return;
|
|
26
|
+
const tag = document.createElement("style");
|
|
27
|
+
tag.id = id;
|
|
28
|
+
tag.textContent = cssContent;
|
|
29
|
+
document.head.appendChild(tag);
|
|
30
|
+
},
|
|
31
|
+
proxyHandler(obj, watcher, el) {
|
|
32
|
+
function mkHash(str) {
|
|
33
|
+
var hash = 0;
|
|
34
|
+
var i;
|
|
35
|
+
var char;
|
|
36
|
+
if (str.length === 0) return hash;
|
|
37
|
+
for (i = 0; i < str.length; i++) {
|
|
38
|
+
char = str.charCodeAt(i);
|
|
39
|
+
hash = (hash << 5) - hash + char;
|
|
40
|
+
hash |= 0; // Convert to 32bit integer
|
|
41
|
+
}
|
|
42
|
+
return hash;
|
|
43
|
+
}
|
|
44
|
+
var handler = {
|
|
45
|
+
get: function (obj, key) {
|
|
46
|
+
return obj[key];
|
|
47
|
+
},
|
|
48
|
+
set: function (obj, key, newVal) {
|
|
49
|
+
if (key === "__olum__") return false;
|
|
50
|
+
const oldVal = obj[key];
|
|
51
|
+
if (oldVal === newVal) return true;
|
|
52
|
+
obj[key] = newVal;
|
|
53
|
+
if (watcher && watcher[key] && typeof watcher[key] === "function") watcher[key](oldVal, newVal);
|
|
54
|
+
// todo prefix compName with instance e.g. you may have one component used twice so compName-1 & compName-2
|
|
55
|
+
const dataObj = { compName: obj.__olum__.compName, compId: obj.__olum__.compId };
|
|
56
|
+
const hash = mkHash(dataObj.compName + dataObj.compId);
|
|
57
|
+
dataObj.hash = hash;
|
|
22
58
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
59
|
+
window.olum.$emit("updateOlumComp", dataObj);
|
|
60
|
+
return true;
|
|
61
|
+
},
|
|
62
|
+
deleteProperty: function (obj, key) {
|
|
63
|
+
if (key === "__olum__") return false;
|
|
64
|
+
delete obj[key];
|
|
65
|
+
// todo prefix compName with instance e.g. you may have one component used twice so compName-1 & compName-2
|
|
66
|
+
const dataObj = { compName: obj.__olum__.compName, compId: obj.__olum__.compId };
|
|
67
|
+
const hash = mkHash(dataObj.compName + dataObj.compId);
|
|
68
|
+
dataObj.hash = hash;
|
|
26
69
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
70
|
+
window.olum.$emit("updateOlumComp", dataObj);
|
|
71
|
+
return true;
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
return new Proxy(obj, handler);
|
|
75
|
+
},
|
|
76
|
+
proxyHandlerForStore(obj, originalProxy) {
|
|
77
|
+
const handler = {
|
|
78
|
+
get: function (obj, key) {
|
|
79
|
+
return originalProxy[key];
|
|
80
|
+
},
|
|
81
|
+
set: function (obj, key, val) {
|
|
82
|
+
obj[key] = val;
|
|
83
|
+
originalProxy[key] = val;
|
|
84
|
+
return true;
|
|
85
|
+
},
|
|
86
|
+
deleteProperty: function (obj, key) {
|
|
87
|
+
delete obj[key];
|
|
88
|
+
delete originalProxy[key];
|
|
89
|
+
return true;
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
return new Proxy(obj, handler);
|
|
93
|
+
},
|
|
94
|
+
clean(fragment) {
|
|
95
|
+
const str = String(fragment).trim();
|
|
96
|
+
if (str === "null") return null;
|
|
97
|
+
return str;
|
|
98
|
+
},
|
|
99
|
+
// #2 (escape-by-default): HTML-escape a value before it is interpolated into a template.
|
|
100
|
+
// The compiler wraps every text/attribute interpolation `{expr}` in `olum.esc(expr)` so a
|
|
101
|
+
// user-supplied string (a todo title, a comment, anything) can't inject markup/scripts (XSS)
|
|
102
|
+
// or visually break rendering when it contains <, >, &, or quotes.
|
|
103
|
+
// - null/undefined render as "" (instead of the literal text "null"/"undefined").
|
|
104
|
+
// - To render trusted HTML on purpose, opt out explicitly with `olum.html(value)` (below);
|
|
105
|
+
// esc() detects the marker it returns and passes the HTML through unescaped.
|
|
106
|
+
esc(value) {
|
|
107
|
+
if (value === null || value === undefined) return "";
|
|
108
|
+
if (value && value.__olumHtml === true) return value.html; // explicit raw-HTML opt-in
|
|
109
|
+
return String(value)
|
|
110
|
+
.replace(/&/g, "&") // must run first so the entities below aren't double-escaped
|
|
111
|
+
.replace(/</g, "<")
|
|
112
|
+
.replace(/>/g, ">")
|
|
113
|
+
.replace(/"/g, """)
|
|
114
|
+
.replace(/'/g, "'");
|
|
115
|
+
},
|
|
116
|
+
// #2 opt-in escape hatch: mark a string as trusted raw HTML so `esc()` leaves it untouched.
|
|
117
|
+
// Usage in a template: {olum.html(props.richText)}. Use it ONLY on HTML you control or have
|
|
118
|
+
// already sanitized — this is the deliberate, greppable way to bypass auto-escaping.
|
|
119
|
+
html(value) {
|
|
120
|
+
return { __olumHtml: true, html: value == null ? "" : String(value) };
|
|
121
|
+
},
|
|
122
|
+
eventsHandler(el, nodes, compName, methodsRefObj) {
|
|
123
|
+
function event(item, str, modifiers) {
|
|
124
|
+
const eventName = str.split("|")[0];
|
|
125
|
+
str = str.split("|").slice(1).join();
|
|
30
126
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
127
|
+
let methods = str.split("&");
|
|
128
|
+
const data = methods.map((chunk) => {
|
|
129
|
+
const chunks = chunk.split("=");
|
|
130
|
+
const name = chunks[0];
|
|
131
|
+
const args = JSON.parse(chunks.slice(1).join(""));
|
|
132
|
+
return { args, methodName: name };
|
|
133
|
+
});
|
|
34
134
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
135
|
+
const opts = {
|
|
136
|
+
once: false,
|
|
137
|
+
passive: false,
|
|
138
|
+
capture: false,
|
|
139
|
+
};
|
|
38
140
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
String.prototype.cap = function () {
|
|
47
|
-
return this.toLowerCase().split(" ").map(function (word) {
|
|
48
|
-
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
49
|
-
}).join(" ");
|
|
50
|
-
};
|
|
141
|
+
if (modifiers && modifiers.length) {
|
|
142
|
+
if (modifiers.includes("once")) opts.once = true;
|
|
143
|
+
if (modifiers.includes("passive")) opts.passive = true;
|
|
144
|
+
if (modifiers.includes("capture")) opts.capture = true;
|
|
145
|
+
}
|
|
51
146
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
147
|
+
item.addEventListener(
|
|
148
|
+
eventName.slice(2),
|
|
149
|
+
(e) => {
|
|
150
|
+
if (modifiers && modifiers.length) {
|
|
151
|
+
if (modifiers.includes("prevent")) e.preventDefault();
|
|
152
|
+
if (modifiers.includes("stop")) e.stopPropagation();
|
|
153
|
+
}
|
|
57
154
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
155
|
+
function init() {
|
|
156
|
+
data.forEach((obj) => {
|
|
157
|
+
if (methodsRefObj[obj.methodName]) {
|
|
158
|
+
if (obj.args.length) {
|
|
159
|
+
const eventIndex = obj.args.indexOf("$event");
|
|
160
|
+
if (eventIndex !== -1) obj.args.splice(eventIndex, 1, e);
|
|
161
|
+
methodsRefObj[obj.methodName](...obj.args);
|
|
162
|
+
} else {
|
|
163
|
+
methodsRefObj[obj.methodName](e);
|
|
164
|
+
}
|
|
165
|
+
} else {
|
|
166
|
+
console.warn("olum: can't access the method");
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (modifiers && modifiers.length && modifiers.includes("self")) {
|
|
172
|
+
if (e.target === item) init();
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
init();
|
|
176
|
+
},
|
|
177
|
+
opts
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
item.removeAttribute("data-o-event");
|
|
181
|
+
item.removeAttribute("data-o-event-mode");
|
|
182
|
+
// item.removeAttribute("data-child-of");
|
|
76
183
|
}
|
|
77
|
-
}
|
|
78
184
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
185
|
+
nodes.forEach((node) => {
|
|
186
|
+
const hasEvent = olum.clean(node.getAttribute("data-o-event"));
|
|
187
|
+
const hasMode = olum.clean(node.getAttribute("data-o-event-mode"));
|
|
188
|
+
const mode = hasMode && hasMode.trim() !== "" ? hasMode.split(".") : [];
|
|
189
|
+
if (hasEvent) event(node, hasEvent, mode);
|
|
190
|
+
});
|
|
191
|
+
},
|
|
192
|
+
stylesHandler(el, nodes, compName) {
|
|
193
|
+
function setStyles(item, obj, keys) {
|
|
194
|
+
let str = "";
|
|
195
|
+
keys.forEach((key) => {
|
|
196
|
+
const val = obj[key];
|
|
197
|
+
if (val) {
|
|
198
|
+
// console.log({ key, val });
|
|
199
|
+
str += key + ": " + val + "; ";
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
str = str.trim();
|
|
203
|
+
// console.log(str);
|
|
204
|
+
if (str !== "") item.setAttribute("style", str);
|
|
205
|
+
item.removeAttribute("data-o-style");
|
|
206
|
+
// item.removeAttribute("data-child-of");
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function style(item, str) {
|
|
210
|
+
const obj = JSON.parse(str);
|
|
211
|
+
const keys = Object.keys(obj);
|
|
212
|
+
if (keys.length) {
|
|
213
|
+
// console.log("directObj: ", obj);
|
|
214
|
+
setStyles(item, obj, keys);
|
|
215
|
+
}
|
|
92
216
|
}
|
|
93
|
-
return this;
|
|
94
|
-
}
|
|
95
217
|
|
|
96
|
-
|
|
97
|
-
|
|
218
|
+
nodes.forEach((node) => {
|
|
219
|
+
const hasStyle = olum.clean(node.getAttribute("data-o-style"));
|
|
220
|
+
if (hasStyle) style(node, hasStyle);
|
|
221
|
+
});
|
|
222
|
+
},
|
|
223
|
+
handleMarkup(compName, id, el, methods) {
|
|
224
|
+
el.setAttribute("data-child-of", compName);
|
|
225
|
+
el.setAttribute("data-o-" + id, "");
|
|
226
|
+
var nodes = el.querySelectorAll("*");
|
|
227
|
+
nodes.forEach((node) => {
|
|
228
|
+
node.setAttribute("data-child-of", compName);
|
|
229
|
+
node.setAttribute("data-o-" + id, "");
|
|
230
|
+
});
|
|
231
|
+
this.eventsHandler(el, nodes, compName, methods);
|
|
232
|
+
this.stylesHandler(el, nodes, compName);
|
|
233
|
+
return el;
|
|
234
|
+
},
|
|
235
|
+
isObj(obj) {
|
|
236
|
+
return obj !== null && typeof obj === "object";
|
|
237
|
+
},
|
|
238
|
+
isFullArr(arr) {
|
|
239
|
+
return !!(this.isObj(arr) && Array.isArray(arr) && arr.length);
|
|
240
|
+
},
|
|
241
|
+
isFullObj(obj) {
|
|
242
|
+
return !!(this.isObj(obj) && Array.isArray(Object.keys(obj)) && Object.keys(obj).length);
|
|
243
|
+
},
|
|
244
|
+
createStore(entry) {
|
|
245
|
+
const store = {};
|
|
246
|
+
const map = [];
|
|
247
|
+
store[entry.__OLUM__.compName] = entry; // bind root component
|
|
98
248
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
var item = comp.components[i];
|
|
249
|
+
// bind children components
|
|
250
|
+
const recursive = (comp) => {
|
|
251
|
+
if (this.isFullArr(comp.__OLUM__.components)) {
|
|
252
|
+
comp.__OLUM__.components.forEach((item) => {
|
|
105
253
|
var key = Object.keys(item)[0];
|
|
106
|
-
var
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
if (obj.hasOwnProperty("child") && obj.child.hasOwnProperty("olumCompData")) {
|
|
115
|
-
var nextEntry = obj.child.olumCompData;
|
|
116
|
-
recursive(nextEntry);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
|
|
254
|
+
var newComp = item[key]();
|
|
255
|
+
if (!store[key]) store[key] = newComp;
|
|
256
|
+
|
|
257
|
+
const obj = { name: key, children: newComp.__OLUM__.components.map((obj) => Object.keys(obj)[0]) };
|
|
258
|
+
map.push(obj);
|
|
259
|
+
|
|
260
|
+
if (this.isFullArr(obj.children)) recursive(newComp);
|
|
261
|
+
});
|
|
121
262
|
}
|
|
122
263
|
};
|
|
123
264
|
recursive(entry);
|
|
124
|
-
return compsArr;
|
|
125
|
-
}
|
|
126
265
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
266
|
+
return { store, map };
|
|
267
|
+
},
|
|
268
|
+
|
|
269
|
+
// direct <olum> placeholders of a container: those with no <olum> ancestor inside the container.
|
|
270
|
+
// (deeper placeholders belong to a nested component and are handled when that component renders)
|
|
271
|
+
directOlums(container) {
|
|
272
|
+
return Array.prototype.slice.call(container.querySelectorAll("olum")).filter((p) => {
|
|
273
|
+
const anc = p.parentElement && p.parentElement.closest && p.parentElement.closest("olum");
|
|
274
|
+
return !anc || !container.contains(anc);
|
|
275
|
+
});
|
|
276
|
+
},
|
|
277
|
+
buildTree(comp, store, compKey) {
|
|
278
|
+
const rootElm = comp.__OLUM__.getElm;
|
|
279
|
+
if (!rootElm) return null;
|
|
280
|
+
const self = this;
|
|
281
|
+
// lazy global factory registry: name -> factory. Accumulated from every instance's components map
|
|
282
|
+
// as we descend, so slot-passed and cross-file components resolve regardless of where they were declared.
|
|
283
|
+
const registry = window.olum.app.registry || (window.olum.app.registry = {});
|
|
284
|
+
|
|
285
|
+
function renderChildren(containerComp, containerKey, containerElm) {
|
|
286
|
+
if (containerComp.__OLUM__.components) Object.assign(registry, containerComp.__OLUM__.components);
|
|
287
|
+
const placeholders = self.directOlums(containerElm);
|
|
288
|
+
const occ = {}; // per-name occurrence counter -> positional instance keys, stable across re-renders
|
|
289
|
+
placeholders.forEach((placeholder) => {
|
|
290
|
+
const name = placeholder.getAttribute("name");
|
|
291
|
+
const factory = registry[name] || (containerComp.__OLUM__.components && containerComp.__OLUM__.components[name]);
|
|
292
|
+
if (!factory) {
|
|
293
|
+
console.warn("olum: couldn't find " + name + " Component while building the tree!");
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
// #3 (keyed reconciliation): a placeholder rendered inside a keyed <for> carries data-o-key
|
|
297
|
+
// (the evaluated `key={...}` value for that item). Keyed instances are stored under
|
|
298
|
+
// "...Name@<key>", so the SAME instance — and therefore its state and DOM — is reused for a
|
|
299
|
+
// given item no matter where it moves, is inserted, or is removed in the list. Without a key
|
|
300
|
+
// we fall back to positional "...Name#<i>" keys, where state follows position, not identity
|
|
301
|
+
// (delete the middle item of a list and the survivors inherit the wrong neighbour's state).
|
|
302
|
+
const keyVal = placeholder.getAttribute("data-o-key");
|
|
303
|
+
let instanceKey;
|
|
304
|
+
if (keyVal !== null && keyVal !== "") {
|
|
305
|
+
instanceKey = containerKey + ">" + name + "@" + keyVal;
|
|
306
|
+
} else {
|
|
307
|
+
occ[name] = occ[name] === undefined ? 0 : occ[name] + 1;
|
|
308
|
+
instanceKey = containerKey + ">" + name + "#" + occ[name];
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// reuse the instance from a previous render (preserves its state) or mint a fresh one
|
|
312
|
+
let child = store[instanceKey];
|
|
313
|
+
if (!child) {
|
|
314
|
+
child = factory(instanceKey);
|
|
315
|
+
store[instanceKey] = child;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// handle props
|
|
319
|
+
child.parentCompName = containerKey;
|
|
320
|
+
const propsJson = placeholder.getAttribute("data-o-props");
|
|
321
|
+
child.incomingProps = propsJson ? JSON.parse(decodeURIComponent(propsJson)) : {};
|
|
322
|
+
const srcStr = placeholder.getAttribute("data-o-props-src") || "";
|
|
323
|
+
child.incomingPropSources = {};
|
|
324
|
+
if (srcStr)
|
|
325
|
+
srcStr.split("|").forEach((pair) => {
|
|
326
|
+
const parts = pair.split(":"); // propKey:kind:srcKey
|
|
327
|
+
const propKey = parts[0],
|
|
328
|
+
kind = parts[1],
|
|
329
|
+
srcKey = parts[2];
|
|
330
|
+
if (propKey && kind && srcKey) child.incomingPropSources[propKey] = { kind, key: srcKey };
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
// handle slot/children — must be set before getElm so ${children} resolves in the child's template
|
|
334
|
+
child.children = placeholder.innerHTML.trim();
|
|
335
|
+
|
|
336
|
+
const elm = child.__OLUM__.getElm;
|
|
337
|
+
if (elm) {
|
|
338
|
+
elm.setAttribute("data-o-if", placeholder.getAttribute("if") ? placeholder.getAttribute("if") : "olum-no-condition"); // display if condition value (truthy, falsy)
|
|
339
|
+
placeholder.replaceWith(elm);
|
|
340
|
+
renderChildren(child, instanceKey, elm); // recurse into this child's own subtree
|
|
341
|
+
}
|
|
342
|
+
});
|
|
134
343
|
}
|
|
135
|
-
styleTag.innerHTML = css + "\n [to] * {pointer-events: none;}";
|
|
136
|
-
}
|
|
137
344
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
// children
|
|
149
|
-
if (isFullArr(compsArr)) {
|
|
150
|
-
for(var i = 0; i < compsArr.length; i++) {
|
|
151
|
-
var olumCompData = compsArr[i].child.olumCompData;
|
|
152
|
-
var html = olumCompData.template || "";
|
|
153
|
-
var css = olumCompData.style || "";
|
|
154
|
-
var js = olumCompData.render || null;
|
|
155
|
-
var name = prefix ? prefix + "-" + olumCompData.name : olumCompData.name;
|
|
156
|
-
var regex = new RegExp("<(" + name + "\\s{0,})\\/>", "gi"); // detect components e.g. <App-AddTodo /> or <AddTodo />
|
|
157
|
-
|
|
158
|
-
template = template.replace(regex, html);
|
|
159
|
-
style += css;
|
|
160
|
-
if (js !== null) script[i + 1] = js;
|
|
161
|
-
}
|
|
345
|
+
renderChildren(comp, compKey, rootElm);
|
|
346
|
+
return rootElm;
|
|
347
|
+
},
|
|
348
|
+
getInnerNames(entry) {
|
|
349
|
+
const comps = [];
|
|
350
|
+
const map = window.olum.app.map;
|
|
351
|
+
if (map) {
|
|
352
|
+
map.find((obj) => {
|
|
353
|
+
if (obj.name == entry) obj.children.forEach((child) => comps.push(child));
|
|
354
|
+
});
|
|
162
355
|
}
|
|
163
356
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
357
|
+
function recursive(num) {
|
|
358
|
+
const child = comps[num];
|
|
359
|
+
map.forEach((obj) => {
|
|
360
|
+
if (obj.name == child) obj.children.forEach((item) => comps.push(item));
|
|
361
|
+
});
|
|
362
|
+
if (num + 1 <= comps.length) recursive(num + 1);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (comps.length) recursive(0);
|
|
366
|
+
|
|
367
|
+
// console.warn("innerComps: ", comps);
|
|
368
|
+
return comps;
|
|
369
|
+
},
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
if (typeof window !== "undefined") window.olum = olum;
|
|
373
|
+
|
|
374
|
+
class Olum {
|
|
375
|
+
root = null;
|
|
376
|
+
$(s) {
|
|
377
|
+
this.root = document.querySelector(s);
|
|
378
|
+
return this;
|
|
169
379
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
380
|
+
|
|
381
|
+
use(comp) {
|
|
382
|
+
const entry = comp();
|
|
383
|
+
const { store, rootKey } = this.share(entry);
|
|
384
|
+
const tree = window.olum.buildTree(entry, store, rootKey);
|
|
385
|
+
if (!tree) return console.warn("olum: couldn't build tree!");
|
|
386
|
+
|
|
387
|
+
this.setupListeners(store); // unmounted hook & state system
|
|
388
|
+
|
|
389
|
+
this.root.append(tree); // bind full comps tree
|
|
390
|
+
// handle mounted hook
|
|
391
|
+
if (entry.hooks.mounted) entry.hooks.mounted(); // force mounting parent component (entry point comp) regardless of the data-o-if value
|
|
392
|
+
entry.hooks.isMounted = true;
|
|
393
|
+
// mount every instance created during buildTree (keyed by runtime instance key)
|
|
394
|
+
Object.keys(store).forEach((key) => {
|
|
395
|
+
if (key === rootKey) return;
|
|
396
|
+
const c = store[key];
|
|
397
|
+
if (!c || !c.el) return;
|
|
398
|
+
const ifConValue = c.el.getAttribute("data-o-if");
|
|
399
|
+
if (!ifConValue) {
|
|
400
|
+
// don't render comp because it has falsy value
|
|
401
|
+
} else {
|
|
402
|
+
if (["olum-no-condition", "true"].includes(ifConValue)) {
|
|
403
|
+
if (c.hooks.mounted) c.hooks.mounted();
|
|
404
|
+
c.hooks.isMounted = true;
|
|
189
405
|
}
|
|
190
406
|
}
|
|
191
|
-
}
|
|
407
|
+
});
|
|
408
|
+
}
|
|
192
409
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
compWrapper[0],
|
|
203
|
-
compWrapper[0].replace(greaterCharRegex, " olum-component='"+name+"' olum-view='"+name+"'>")
|
|
204
|
-
);
|
|
205
|
-
}
|
|
410
|
+
getPath(el, root) {
|
|
411
|
+
const path = [];
|
|
412
|
+
let cur = el;
|
|
413
|
+
while (cur && cur !== root) {
|
|
414
|
+
const parent = cur.parentElement;
|
|
415
|
+
if (!parent) break;
|
|
416
|
+
const siblings = Array.from(parent.children).filter((c) => c.tagName === cur.tagName);
|
|
417
|
+
path.unshift({ tag: cur.tagName, index: siblings.indexOf(cur) });
|
|
418
|
+
cur = parent;
|
|
206
419
|
}
|
|
420
|
+
return path;
|
|
421
|
+
}
|
|
207
422
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
}
|
|
423
|
+
findByPath(root, path) {
|
|
424
|
+
let cur = root;
|
|
425
|
+
for (const step of path) {
|
|
426
|
+
const siblings = Array.from(cur.children).filter((c) => c.tagName === step.tag);
|
|
427
|
+
cur = siblings[step.index];
|
|
428
|
+
if (!cur) return null;
|
|
429
|
+
}
|
|
430
|
+
return cur;
|
|
215
431
|
}
|
|
216
432
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
buildStyles(viewObj.style);
|
|
228
|
-
// html
|
|
229
|
-
rootElm.innerHTML = viewObj.template;
|
|
230
|
-
// js
|
|
231
|
-
setTimeout(function () {
|
|
232
|
-
for (var key in viewObj.script) {
|
|
233
|
-
viewObj.script[key]();
|
|
433
|
+
setupListeners(store) {
|
|
434
|
+
function mkHash(str) {
|
|
435
|
+
var hash = 0;
|
|
436
|
+
var i;
|
|
437
|
+
var char;
|
|
438
|
+
if (str.length === 0) return hash;
|
|
439
|
+
for (i = 0; i < str.length; i++) {
|
|
440
|
+
char = str.charCodeAt(i);
|
|
441
|
+
hash = (hash << 5) - hash + char;
|
|
442
|
+
hash |= 0;
|
|
234
443
|
}
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
function useRouter() {
|
|
239
|
-
debug("use OlumRouter");
|
|
240
|
-
var router = which.cb;
|
|
241
|
-
// share core functionalites with router
|
|
242
|
-
// props
|
|
243
|
-
router.__proto__.rootElm = rootElm;
|
|
244
|
-
// methods
|
|
245
|
-
router.__proto__.buildStyles = buildStyles;
|
|
246
|
-
router.__proto__.buildTree = buildTree;
|
|
247
|
-
router.__proto__.labelView = labelView;
|
|
248
|
-
router.__proto__.merge = merge;
|
|
249
|
-
|
|
250
|
-
if (router.isReady) router.listen();
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
function mount() {
|
|
254
|
-
debug({mount:"mount()",rootElm, which});
|
|
255
|
-
|
|
256
|
-
if (which && which.type && which.cb) {
|
|
257
|
-
if (which.type === "router") useRouter();
|
|
258
|
-
else if (which.type === "component") useComponent();
|
|
259
|
-
} else {
|
|
260
|
-
throw new Error(debugStr + " Can't mount, Missing component or router @use()");
|
|
444
|
+
return hash;
|
|
261
445
|
}
|
|
446
|
+
|
|
447
|
+
// const snapshots = {}; // persists across re-renders: { [compName]: Map<pathKey, entry> }
|
|
448
|
+
|
|
449
|
+
window.addEventListener("updateOlumComp", (e) => {
|
|
450
|
+
if (e && e.detail && e.detail.compName && e.detail.compId && e.detail.hash) {
|
|
451
|
+
if (e.detail.hash !== mkHash(e.detail.compName + e.detail.compId)) return;
|
|
452
|
+
const comp = store[e.detail.compName];
|
|
453
|
+
if (!comp || !comp.el) return;
|
|
454
|
+
if (!document.body.contains(comp.el)) return; // comp was unmounted; ignore stale state updates
|
|
455
|
+
|
|
456
|
+
const compName = e.detail.compName;
|
|
457
|
+
|
|
458
|
+
// snapshot input values of child components currently in DOM
|
|
459
|
+
// only child components (data-child-of !== compName) so we don't overwrite state inputs with stale values
|
|
460
|
+
// entries not updated here (hidden components) keep their previous snapshot value intact
|
|
461
|
+
// if (!snapshots[compName]) snapshots[compName] = new Map();
|
|
462
|
+
// comp.el.querySelectorAll("input, textarea, select").forEach(field => {
|
|
463
|
+
// const childOf = field.getAttribute("data-child-of");
|
|
464
|
+
// if (childOf && childOf !== compName) {
|
|
465
|
+
// const path = this.getPath(field, comp.el);
|
|
466
|
+
// const entry = { path };
|
|
467
|
+
// if (field.type === "checkbox" || field.type === "radio") entry.checked = field.checked;
|
|
468
|
+
// else entry.value = field.value;
|
|
469
|
+
// snapshots[compName].set(JSON.stringify(path), entry);
|
|
470
|
+
// }
|
|
471
|
+
// });
|
|
472
|
+
|
|
473
|
+
const innerNames = Object.keys(store).filter((name) => name !== compName);
|
|
474
|
+
const prevMounted = {};
|
|
475
|
+
innerNames.forEach((name) => {
|
|
476
|
+
const c = store[name];
|
|
477
|
+
if (c) prevMounted[name] = c.hooks.isMounted;
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
// get current active element location/path before re-render (buildTree)
|
|
481
|
+
const activeEl = document.activeElement;
|
|
482
|
+
const selStart = activeEl && activeEl.selectionStart != null ? activeEl.selectionStart : null;
|
|
483
|
+
const selEnd = activeEl && activeEl.selectionEnd != null ? activeEl.selectionEnd : null;
|
|
484
|
+
const activePath = activeEl && comp.el.contains(activeEl) ? this.getPath(activeEl, comp.el) : null;
|
|
485
|
+
|
|
486
|
+
const treeElm = window.olum.buildTree(comp, store, compName);
|
|
487
|
+
if (!treeElm) return console.warn("olum: couldn't build tree!");
|
|
488
|
+
comp.el.replaceWith(treeElm);
|
|
489
|
+
|
|
490
|
+
// restore child component input values after rebuild
|
|
491
|
+
// snapshots[compName].forEach(({ path, value, checked }) => {
|
|
492
|
+
// const field = this.findByPath(treeElm, path);
|
|
493
|
+
// if (!field) return; // component is hidden in this render, skip
|
|
494
|
+
// if (checked !== undefined) field.checked = checked;
|
|
495
|
+
// else if (value !== undefined) field.value = value;
|
|
496
|
+
// });
|
|
497
|
+
|
|
498
|
+
// load prev active element after re-render (buildTree) to focus (e.g. input) or restore its data (e.g. forms)
|
|
499
|
+
if (activePath && activePath.length) {
|
|
500
|
+
const toRestore = this.findByPath(treeElm, activePath);
|
|
501
|
+
if (toRestore) {
|
|
502
|
+
if (toRestore.focus && typeof toRestore.focus == "function") toRestore.focus();
|
|
503
|
+
if (selStart !== null && toRestore.setSelectionRange && typeof toRestore.setSelectionRange == "function")
|
|
504
|
+
toRestore.setSelectionRange(selStart, selEnd);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
// after rebuild, call lifecycle hooks for any inner component that changed visibility.
|
|
509
|
+
// recompute keys here so instances created during this rebuild (e.g. a grown loop) are included.
|
|
510
|
+
const afterNames = Object.keys(store).filter((name) => name !== compName);
|
|
511
|
+
afterNames.forEach((name) => {
|
|
512
|
+
const c = store[name];
|
|
513
|
+
if (!c) return;
|
|
514
|
+
const isInDOM = document.body.contains(c.el);
|
|
515
|
+
if (prevMounted[name] && !isInDOM) {
|
|
516
|
+
// was mounted, now removed from DOM → unMounted
|
|
517
|
+
if (c.hooks.unMounted && !c.hooks.isUnMounted) {
|
|
518
|
+
c.hooks.unMounted();
|
|
519
|
+
c.hooks.isUnMounted = true;
|
|
520
|
+
c.hooks.isMounted = false;
|
|
521
|
+
}
|
|
522
|
+
} else if (!prevMounted[name] && isInDOM) {
|
|
523
|
+
// was not mounted, now in DOM → mounted
|
|
524
|
+
if (c.hooks.mounted && !c.hooks.isMounted) {
|
|
525
|
+
c.hooks.mounted();
|
|
526
|
+
c.hooks.isMounted = true;
|
|
527
|
+
c.hooks.isUnMounted = false;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
});
|
|
262
533
|
}
|
|
263
534
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
535
|
+
share(entry) {
|
|
536
|
+
// store now holds live instances keyed by runtime instance key; buildTree populates it lazily.
|
|
537
|
+
// registry holds name->factory and is accumulated as the tree is walked.
|
|
538
|
+
const store = {};
|
|
539
|
+
const rootKey = entry.__OLUM__.compName;
|
|
540
|
+
store[rootKey] = entry;
|
|
541
|
+
Object.assign(window.olum.app, { store, registry: {} }); // this is a must to access live changes
|
|
542
|
+
return { store, rootKey };
|
|
267
543
|
}
|
|
268
|
-
|
|
269
544
|
}
|
|
270
545
|
|
|
271
546
|
return Olum;
|
|
272
|
-
});
|
|
547
|
+
})();
|
package/dist/olum.min.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @name olum
|
|
3
|
-
* @version 0.
|
|
4
|
-
* @copyright
|
|
3
|
+
* @version 0.5.1
|
|
4
|
+
* @copyright 2026
|
|
5
5
|
* @author Eissa Saber
|
|
6
6
|
* @license MIT
|
|
7
7
|
*/
|
|
8
|
-
|
|
8
|
+
export default(()=>{var i={app:{},$emit(e,t){this.dispatchEvent(e,t)},dispatchEvent(e,t){window.dispatchEvent(new CustomEvent(e,{detail:t}))},mkElm(e,t,o){e=document.createElement(e);return t&&o&&e.setAttribute("data-olum",JSON.stringify({compName:t,compId:o})),e},injectStyle(e,t){var o;t&&t.trim()&&(e="olum-style-"+e,document.getElementById(e)||((o=document.createElement("style")).id=e,o.textContent=t,document.head.appendChild(o)))},proxyHandler(e,r,t){function l(e){var t,o=0;if(0!==e.length)for(t=0;t<e.length;t++)o=(o<<5)-o+e.charCodeAt(t),o|=0;return o}return new Proxy(e,{get:function(e,t){return e[t]},set:function(e,t,o){var n;return"__olum__"!==t&&((n=e[t])!==o&&(e[t]=o,r&&r[t]&&"function"==typeof r[t]&&r[t](n,o),n=l((t={compName:e.__olum__.compName,compId:e.__olum__.compId}).compName+t.compId),t.hash=n,window.olum.$emit("updateOlumComp",t)),!0)},deleteProperty:function(e,t){if("__olum__"===t)return!1;delete e[t];t={compName:e.__olum__.compName,compId:e.__olum__.compId},e=l(t.compName+t.compId);return t.hash=e,window.olum.$emit("updateOlumComp",t),!0}})},proxyHandlerForStore(e,n){return new Proxy(e,{get:function(e,t){return n[t]},set:function(e,t,o){return e[t]=o,n[t]=o,!0},deleteProperty:function(e,t){return delete e[t],delete n[t],!0}})},clean(e){e=String(e).trim();return"null"===e?null:e},esc(e){return null==e?"":e&&!0===e.__olumHtml?e.html:String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")},html(e){return{__olumHtml:!0,html:null==e?"":String(e)}},eventsHandler(e,t,o,a){t.forEach(e=>{var o=i.clean(e.getAttribute("data-o-event")),n=i.clean(e.getAttribute("data-o-event-mode")),n=n&&""!==n.trim()?n.split("."):[];if(o){var r=e,e=o,l=n,o=e.split("|")[0];let t=(e=e.split("|").slice(1).join()).split("&").map(e=>{var e=e.split("="),t=e[0];return{args:JSON.parse(e.slice(1).join("")),methodName:t}});e={once:!1,passive:!1,capture:!1},l&&l.length&&(l.includes("once")&&(e.once=!0),l.includes("passive")&&(e.passive=!0),l.includes("capture"))&&(e.capture=!0),r.addEventListener(o.slice(2),o=>{function e(){t.forEach(e=>{var t;a[e.methodName]?e.args.length?(-1!==(t=e.args.indexOf("$event"))&&e.args.splice(t,1,o),a[e.methodName](...e.args)):a[e.methodName](o):console.warn("olum: can't access the method")})}l&&l.length&&(l.includes("prevent")&&o.preventDefault(),l.includes("stop"))&&o.stopPropagation(),l&&l.length&&l.includes("self")&&o.target!==r||e()},e),r.removeAttribute("data-o-event"),r.removeAttribute("data-o-event-mode")}})},stylesHandler(e,t,o){t.forEach(e=>{var t=i.clean(e.getAttribute("data-o-style"));if(t){var t=JSON.parse(t),n=Object.keys(t);if(n.length){var r=t;t=n;let o="";t.forEach(e=>{var t=r[e];t&&(o+=e+": "+t+"; ")}),""!==(o=o.trim())&&e.setAttribute("style",o),e.removeAttribute("data-o-style")}}})},handleMarkup(t,o,e,n){e.setAttribute("data-child-of",t),e.setAttribute("data-o-"+o,"");var r=e.querySelectorAll("*");return r.forEach(e=>{e.setAttribute("data-child-of",t),e.setAttribute("data-o-"+o,"")}),this.eventsHandler(e,r,t,n),this.stylesHandler(e,r,t),e},isObj(e){return null!==e&&"object"==typeof e},isFullArr(e){return!!(this.isObj(e)&&Array.isArray(e)&&e.length)},isFullObj(e){return!!(this.isObj(e)&&Array.isArray(Object.keys(e))&&Object.keys(e).length)},createStore(e){let o={},n=[],r=(o[e.__OLUM__.compName]=e,e=>{this.isFullArr(e.__OLUM__.components)&&e.__OLUM__.components.forEach(e=>{var t=Object.keys(e)[0],e=e[t](),t=(o[t]||(o[t]=e),{name:t,children:e.__OLUM__.components.map(e=>Object.keys(e)[0])});n.push(t),this.isFullArr(t.children)&&r(e)})});return r(e),{store:o,map:n}},directOlums(t){return Array.prototype.slice.call(t.querySelectorAll("olum")).filter(e=>{e=e.parentElement&&e.parentElement.closest&&e.parentElement.closest("olum");return!e||!t.contains(e)})},buildTree(e,u,t){var o=e.__OLUM__.getElm;if(!o)return null;let n=this,c=window.olum.app.registry||(window.olum.app.registry={});return function a(e,i,t){e.__OLUM__.components&&Object.assign(c,e.__OLUM__.components);t=n.directOlums(t);let s={};t.forEach(t=>{var o=t.getAttribute("name"),r=c[o]||e.__OLUM__.components&&e.__OLUM__.components[o];if(r){var l=t.getAttribute("data-o-key");let e,n=(e=null!==l&&""!==l?i+">"+o+"@"+l:(s[o]=void 0===s[o]?0:s[o]+1,i+">"+o+"#"+s[o]),u[e]);n||(n=r(e),u[e]=n),n.parentCompName=i,l=t.getAttribute("data-o-props"),n.incomingProps=l?JSON.parse(decodeURIComponent(l)):{},r=t.getAttribute("data-o-props-src")||"",n.incomingPropSources={},r&&r.split("|").forEach(e=>{var t=(e=e.split(":"))[0],o=e[1],e=e[2];t&&o&&e&&(n.incomingPropSources[t]={kind:o,key:e})}),n.children=t.innerHTML.trim(),(l=n.__OLUM__.getElm)&&(l.setAttribute("data-o-if",t.getAttribute("if")?t.getAttribute("if"):"olum-no-condition"),t.replaceWith(l),a(n,e,l))}else console.warn("olum: couldn't find "+o+" Component while building the tree!")})}(e,t,o),o},getInnerNames(t){let n=[],r=window.olum.app.map;return r&&r.find(e=>{e.name==t&&e.children.forEach(e=>n.push(e))}),n.length&&function e(t){let o=n[t];r.forEach(e=>{e.name==o&&e.children.forEach(e=>n.push(e))}),t+1<=n.length&&e(t+1)}(0),n}};"undefined"!=typeof window&&(window.olum=i);class e{root=null;$(e){return this.root=document.querySelector(e),this}use(e){e=e();let{store:o,rootKey:n}=this.share(e);var t=window.olum.buildTree(e,o,n);if(!t)return console.warn("olum: couldn't build tree!");this.setupListeners(o),this.root.append(t),e.hooks.mounted&&e.hooks.mounted(),e.hooks.isMounted=!0,Object.keys(o).forEach(e=>{var t;e!==n&&(e=o[e])&&e.el&&(t=e.el.getAttribute("data-o-if"))&&["olum-no-condition","true"].includes(t)&&(e.hooks.mounted&&e.hooks.mounted(),e.hooks.isMounted=!0)})}getPath(e,t){var o=[];let n=e;for(;n&&n!==t;){var r=n.parentElement;if(!r)break;var l=Array.from(r.children).filter(e=>e.tagName===n.tagName);o.unshift({tag:n.tagName,index:l.indexOf(n)}),n=r}return o}findByPath(e,o){let n=e;for(let t of o){var r=Array.from(n.children).filter(e=>e.tagName===t.tag);if(!(n=r[t.index]))return null}return n}setupListeners(i){window.addEventListener("updateOlumComp",e=>{if(e&&e.detail&&e.detail.compName&&e.detail.compId&&e.detail.hash&&e.detail.hash===(e=>{var t,o=0;if(0!==e.length)for(t=0;t<e.length;t++)o=(o<<5)-o+e.charCodeAt(t),o|=0;return o})(e.detail.compName+e.detail.compId)){var o=i[e.detail.compName];if(o&&o.el&&document.body.contains(o.el)){let t=e.detail.compName;e=Object.keys(i).filter(e=>e!==t);let n={};e.forEach(e=>{var t=i[e];t&&(n[e]=t.hooks.isMounted)});var e=document.activeElement,r=e&&null!=e.selectionStart?e.selectionStart:null,l=e&&null!=e.selectionEnd?e.selectionEnd:null,e=e&&o.el.contains(e)?this.getPath(e,o.el):null,a=window.olum.buildTree(o,i,t);if(!a)return console.warn("olum: couldn't build tree!");o.el.replaceWith(a),e&&e.length&&(o=this.findByPath(a,e))&&(o.focus&&"function"==typeof o.focus&&o.focus(),null!==r)&&o.setSelectionRange&&"function"==typeof o.setSelectionRange&&o.setSelectionRange(r,l),Object.keys(i).filter(e=>e!==t).forEach(e=>{var t,o=i[e];o&&(t=document.body.contains(o.el),n[e]&&!t?o.hooks.unMounted&&!o.hooks.isUnMounted&&(o.hooks.unMounted(),o.hooks.isUnMounted=!0,o.hooks.isMounted=!1):!n[e]&&t&&o.hooks.mounted&&!o.hooks.isMounted&&(o.hooks.mounted(),o.hooks.isMounted=!0,o.hooks.isUnMounted=!1))})}}})}share(e){var t={},o=e.__OLUM__.compName;return t[o]=e,Object.assign(window.olum.app,{store:t,registry:{}}),{store:t,rootKey:o}}}return e})();
|