olova 2.0.6 → 2.0.8
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/dist/olova.js +1 -248
- package/package.json +1 -1
package/dist/olova.js
CHANGED
|
@@ -1,248 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import t from "./hooks/effect.js";
|
|
3
|
-
import n from "./hooks/memo.js";
|
|
4
|
-
import s from "./hooks/callback.js";
|
|
5
|
-
import o from "./hooks/reducer.js";
|
|
6
|
-
import r from "./hooks/ref.js";
|
|
7
|
-
import i from "./hooks/context.js";
|
|
8
|
-
const c = new (class {
|
|
9
|
-
constructor() {
|
|
10
|
-
(this.rootElement = null),
|
|
11
|
-
(this.components = new Map()),
|
|
12
|
-
(this.componentStack = []),
|
|
13
|
-
(this.componentInstances = new Map()),
|
|
14
|
-
(this.pendingUpdates = []),
|
|
15
|
-
(this.pendingEffects = []),
|
|
16
|
-
(this.contextSubscriptions = new WeakMap()),
|
|
17
|
-
(this.isBatchingUpdates = !1),
|
|
18
|
-
(this.hasScheduledFlush = !1),
|
|
19
|
-
(this.dirtyInstances = null);
|
|
20
|
-
}
|
|
21
|
-
createElement(e, t, ...n) {
|
|
22
|
-
return null == e
|
|
23
|
-
? (console.error("Element type cannot be null or undefined"), null)
|
|
24
|
-
: "function" == typeof e || "string" == typeof e
|
|
25
|
-
? { type: e, props: { ...t, children: n.flat() } }
|
|
26
|
-
: (console.error("Invalid element type:", e), null);
|
|
27
|
-
}
|
|
28
|
-
render(e, t) {
|
|
29
|
-
try {
|
|
30
|
-
if (null == e) return;
|
|
31
|
-
if ("string" == typeof e || "number" == typeof e)
|
|
32
|
-
return void t.appendChild(document.createTextNode(e));
|
|
33
|
-
if (Array.isArray(e)) return void e.forEach((e) => this.render(e, t));
|
|
34
|
-
if ("function" == typeof e.type) {
|
|
35
|
-
const n = e.type,
|
|
36
|
-
s = this.getComponentInstance(n);
|
|
37
|
-
if (n.__isMemoized) {
|
|
38
|
-
const n = s.lastProps;
|
|
39
|
-
if (n && this.deepEqual(n, e.props) && s.lastResult)
|
|
40
|
-
return void this.render(s.lastResult, t);
|
|
41
|
-
}
|
|
42
|
-
this.componentStack.push(s),
|
|
43
|
-
(s.currentHook = 0),
|
|
44
|
-
(s.lastProps = e.props);
|
|
45
|
-
const o = n(e.props);
|
|
46
|
-
return (
|
|
47
|
-
(s.lastResult = o), this.componentStack.pop(), void this.render(o, t)
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
if ("string" != typeof e.type)
|
|
51
|
-
return void console.error("Invalid element type:", e.type);
|
|
52
|
-
const n = document.createElement(e.type);
|
|
53
|
-
this.applyProps(n, e.props),
|
|
54
|
-
(e.props.children || []).forEach((e) => this.render(e, n)),
|
|
55
|
-
t.appendChild(n);
|
|
56
|
-
} catch (e) {
|
|
57
|
-
console.error("Render error:", e);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
applyProps(e, t) {
|
|
61
|
-
Object.keys(t || {}).forEach((n) => {
|
|
62
|
-
if ("ref" === n && t[n]) t[n].current = e;
|
|
63
|
-
else if (n.startsWith("on")) {
|
|
64
|
-
const s = n.toLowerCase().substring(2);
|
|
65
|
-
e.addEventListener(s, t[n]);
|
|
66
|
-
} else
|
|
67
|
-
"children" !== n &&
|
|
68
|
-
("className" === n ? e.setAttribute("class", t[n]) : (e[n] = t[n]));
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
getComponentInstance(e) {
|
|
72
|
-
return (
|
|
73
|
-
this.componentInstances.has(e) ||
|
|
74
|
-
this.componentInstances.set(e, {
|
|
75
|
-
hooks: [],
|
|
76
|
-
currentHook: 0,
|
|
77
|
-
effects: [],
|
|
78
|
-
cleanups: new Map(),
|
|
79
|
-
pendingEffects: [],
|
|
80
|
-
contextSubscriptions: new Set(),
|
|
81
|
-
lastProps: null,
|
|
82
|
-
lastResult: null,
|
|
83
|
-
}),
|
|
84
|
-
this.componentInstances.get(e)
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
renderComponent(e, t) {
|
|
88
|
-
const n = this.getComponentInstance(e);
|
|
89
|
-
this.componentStack.push(n), (n.currentHook = 0);
|
|
90
|
-
if (!n.lastResult || this.shouldComponentUpdate(n, e)) {
|
|
91
|
-
const s = e();
|
|
92
|
-
(n.lastResult = s),
|
|
93
|
-
this.render(s, t),
|
|
94
|
-
n.pendingEffects.length > 0 &&
|
|
95
|
-
(this.pendingEffects.push(...n.pendingEffects),
|
|
96
|
-
(n.pendingEffects = []));
|
|
97
|
-
} else this.render(n.lastResult, t);
|
|
98
|
-
this.componentStack.pop();
|
|
99
|
-
}
|
|
100
|
-
shouldComponentUpdate(e, t) {
|
|
101
|
-
return (
|
|
102
|
-
!t.__isMemoized || !e.lastProps || !this.deepEqual(e.lastProps, t.props)
|
|
103
|
-
);
|
|
104
|
-
}
|
|
105
|
-
getCurrentInstance() {
|
|
106
|
-
return this.componentStack[this.componentStack.length - 1];
|
|
107
|
-
}
|
|
108
|
-
createContext(e) {
|
|
109
|
-
const t = {
|
|
110
|
-
_currentValue: e,
|
|
111
|
-
_defaultValue: e,
|
|
112
|
-
_subscribers: new Set(),
|
|
113
|
-
_version: 0,
|
|
114
|
-
Provider: ({ value: e, children: n }) => {
|
|
115
|
-
const s = this.getCurrentInstance(),
|
|
116
|
-
o = s.currentHook++,
|
|
117
|
-
r = s.hooks[o];
|
|
118
|
-
return (
|
|
119
|
-
this.shallowEqual(r, e) ||
|
|
120
|
-
((t._currentValue = e),
|
|
121
|
-
t._version++,
|
|
122
|
-
t._subscribers.forEach((t) => {
|
|
123
|
-
(t.instance.hooks[t.hookIndex] = e), this.scheduleUpdate();
|
|
124
|
-
})),
|
|
125
|
-
(s.hooks[o] = e),
|
|
126
|
-
n
|
|
127
|
-
);
|
|
128
|
-
},
|
|
129
|
-
Consumer: ({ children: e }) => {
|
|
130
|
-
if ("function" != typeof e)
|
|
131
|
-
throw new Error("Context.Consumer expects a function as a child");
|
|
132
|
-
return e(t._currentValue);
|
|
133
|
-
},
|
|
134
|
-
};
|
|
135
|
-
return t;
|
|
136
|
-
}
|
|
137
|
-
scheduleUpdate() {
|
|
138
|
-
this.isBatchingUpdates ||
|
|
139
|
-
((this.isBatchingUpdates = !0),
|
|
140
|
-
this.pendingUpdates.push(() => {
|
|
141
|
-
if (this.rootElement) {
|
|
142
|
-
const e = this.dirtyInstances || new Set();
|
|
143
|
-
for (
|
|
144
|
-
this.components.forEach((t, n) => {
|
|
145
|
-
const s = this.getComponentInstance(t);
|
|
146
|
-
e.has(s) && ((n.innerHTML = ""), this.renderComponent(t, n));
|
|
147
|
-
}),
|
|
148
|
-
this.dirtyInstances = new Set();
|
|
149
|
-
this.pendingEffects.length > 0;
|
|
150
|
-
|
|
151
|
-
) {
|
|
152
|
-
this.pendingEffects.shift()();
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}),
|
|
156
|
-
this.hasScheduledFlush ||
|
|
157
|
-
((this.hasScheduledFlush = !0),
|
|
158
|
-
queueMicrotask(() => {
|
|
159
|
-
this.flushUpdates(), (this.isBatchingUpdates = !1);
|
|
160
|
-
})));
|
|
161
|
-
}
|
|
162
|
-
flushUpdates() {
|
|
163
|
-
for (; this.pendingUpdates.length > 0; ) {
|
|
164
|
-
this.pendingUpdates.shift()();
|
|
165
|
-
}
|
|
166
|
-
this.hasScheduledFlush = !1;
|
|
167
|
-
}
|
|
168
|
-
mount(e, t) {
|
|
169
|
-
for (
|
|
170
|
-
this.rootElement = t,
|
|
171
|
-
this.components.set(t, e),
|
|
172
|
-
this.renderComponent(e, t);
|
|
173
|
-
this.pendingEffects.length > 0;
|
|
174
|
-
|
|
175
|
-
) {
|
|
176
|
-
this.pendingEffects.shift()();
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
unmount(e) {
|
|
180
|
-
const t = this.components.get(e);
|
|
181
|
-
if (t) {
|
|
182
|
-
const n = this.componentInstances.get(t);
|
|
183
|
-
n &&
|
|
184
|
-
(n.contextSubscriptions.forEach((e) => e()),
|
|
185
|
-
n.contextSubscriptions.clear(),
|
|
186
|
-
n.cleanups.forEach((e) => e()),
|
|
187
|
-
n.cleanups.clear(),
|
|
188
|
-
this.componentInstances.delete(t)),
|
|
189
|
-
this.components.delete(e);
|
|
190
|
-
}
|
|
191
|
-
e.innerHTML = "";
|
|
192
|
-
}
|
|
193
|
-
memo(e) {
|
|
194
|
-
const t = (t) => {
|
|
195
|
-
const n = this.getCurrentInstance();
|
|
196
|
-
if (!n) return e(t);
|
|
197
|
-
const s = n.currentHook++,
|
|
198
|
-
o = n.hooks[s] || { props: null, result: null },
|
|
199
|
-
r = !o.props || !this.deepEqual(t, o.props);
|
|
200
|
-
if (!o.result || r) {
|
|
201
|
-
const o = e(t);
|
|
202
|
-
return (n.hooks[s] = { props: t, result: o }), o;
|
|
203
|
-
}
|
|
204
|
-
return o.result;
|
|
205
|
-
};
|
|
206
|
-
return (t.__isMemoized = !0), (t.__original = e), t;
|
|
207
|
-
}
|
|
208
|
-
shallowEqual(e, t) {
|
|
209
|
-
if (e === t) return !0;
|
|
210
|
-
if (!e || !t) return !1;
|
|
211
|
-
if ("object" != typeof e || "object" != typeof t) return e === t;
|
|
212
|
-
const n = Object.keys(e),
|
|
213
|
-
s = Object.keys(t);
|
|
214
|
-
return (
|
|
215
|
-
n.length === s.length &&
|
|
216
|
-
n.every((n) => t.hasOwnProperty(n) && e[n] === t[n])
|
|
217
|
-
);
|
|
218
|
-
}
|
|
219
|
-
deepEqual(e, t) {
|
|
220
|
-
if (e === t) return !0;
|
|
221
|
-
if (!e || !t) return !1;
|
|
222
|
-
if (typeof e != typeof t) return !1;
|
|
223
|
-
if ("object" != typeof e) return e === t;
|
|
224
|
-
if (Array.isArray(e))
|
|
225
|
-
return (
|
|
226
|
-
!(!Array.isArray(t) || e.length !== t.length) &&
|
|
227
|
-
e.every((e, n) => this.deepEqual(e, t[n]))
|
|
228
|
-
);
|
|
229
|
-
const n = Object.keys(e),
|
|
230
|
-
s = Object.keys(t);
|
|
231
|
-
return (
|
|
232
|
-
n.length === s.length &&
|
|
233
|
-
n.every((n) => t.hasOwnProperty(n) && this.deepEqual(e[n], t[n]))
|
|
234
|
-
);
|
|
235
|
-
}
|
|
236
|
-
})();
|
|
237
|
-
export const h = c.createElement.bind(c);
|
|
238
|
-
export const Fragment = (e) => (e ? e.children : null);
|
|
239
|
-
export const $state = (t) => e(c, t);
|
|
240
|
-
export const $effect = (e, n) => t(c, e, n);
|
|
241
|
-
export const $memo = (e, t) => n(c, e, t);
|
|
242
|
-
export const $callback = (e, t) => s(c, e, t);
|
|
243
|
-
export const $reducer = (e, t) => o(c, e, t);
|
|
244
|
-
export const $ref = (e) => r(c, e);
|
|
245
|
-
export const $context = (e) => i(c, e);
|
|
246
|
-
export const createContext = c.createContext.bind(c);
|
|
247
|
-
export const memo = c.memo.bind(c);
|
|
248
|
-
export default c;
|
|
1
|
+
import stateHook from"./hooks/state.js";import effectHook from"./hooks/effect.js";import memoHook from"./hooks/memo.js";import callbackHook from"./hooks/callback.js";import reducerHook from"./hooks/reducer.js";import refHook from"./hooks/ref.js";import contextHook from"./hooks/context.js";class Olovav2{constructor(){this.rootElement=null,this.components=new Map,this.componentStack=[],this.componentInstances=new Map,this.pendingUpdates=[],this.pendingEffects=[],this.contextSubscriptions=new WeakMap,this.isBatchingUpdates=!1,this.hasScheduledFlush=!1,this.dirtyInstances=null}createElement(e,t,...n){return null==e?(console.error("Element type cannot be null or undefined"),null):"function"==typeof e||"string"==typeof e?{type:e,props:{...t,children:n.flat()}}:(console.error("Invalid element type:",e),null)}render(e,t){try{if(null==e)return;if("string"==typeof e||"number"==typeof e){if(t.nodeType===Node.TEXT_NODE)t.textContent!==String(e)&&(t.textContent=String(e));else if(1===t.childNodes.length&&t.firstChild.nodeType===Node.TEXT_NODE)t.firstChild.textContent!==String(e)&&(t.firstChild.textContent=String(e));else{const n=document.createTextNode(String(e));t.innerHTML="",t.appendChild(n)}return}if(Array.isArray(e))return void this.reconcileChildren(t,e);if("function"==typeof e.type){const n=e.type,o=this.getComponentInstance(n);if(!n.__isMemoized||!o.lastProps||!this.shallowEqual(o.lastProps,e.props)){this.componentStack.push(o),o.currentHook=0,o.lastProps=e.props;const s=n(e.props);o.lastResult=s,this.componentStack.pop(),this.render(s,t)}else this.render(o.lastResult,t);return}if("string"==typeof e.type){let n;t.nodeType===Node.ELEMENT_NODE&&t.tagName.toLowerCase()===e.type?n=t:1===t.childNodes.length&&t.firstChild.nodeType===Node.ELEMENT_NODE&&t.firstChild.tagName.toLowerCase()===e.type?n=t.firstChild:(n=document.createElement(e.type),t.innerHTML="",t.appendChild(n)),this.applyProps(n,e.props);const o=e.props.children||[],s=Array.isArray(o)?o:[o];this.reconcileChildren(n,s)}}catch(e){console.error("Render error:",e)}}reconcileChildren(e,t){const n=Array.from(e.childNodes),o=Math.max(n.length,t.length);for(let s=0;s<o;s++)if(s>=t.length)e.removeChild(n[s]);else if(s>=n.length){const n="string"==typeof t[s]?.type?document.createElement(t[s].type):document.createTextNode("");e.appendChild(n),this.render(t[s],n)}else{const o=n[s],r=t[s];if("string"==typeof r?.type)if(o.nodeType===Node.ELEMENT_NODE&&o.tagName.toLowerCase()===r.type)this.render(r,o);else{const t=document.createElement(r.type);e.replaceChild(t,o),this.render(r,t)}else this.render(r,o)}}applyProps(e,t){const n=e._props||{},o=t||{};e._props=o,Object.keys(n).forEach((t=>{if(!(t in o)&&"children"!==t)if(t.startsWith("on")){const o=t.toLowerCase().substring(2);e.removeEventListener(o,n[t])}else"className"===t?e.removeAttribute("class"):e[t]=""})),Object.keys(o).forEach((t=>{if("ref"===t&&o[t])o[t].current=e;else if(t.startsWith("on")){const s=t.toLowerCase().substring(2);n[t]&&e.removeEventListener(s,n[t]),e.addEventListener(s,o[t])}else"children"!==t&&("className"===t?n[t]!==o[t]&&e.setAttribute("class",o[t]):n[t]!==o[t]&&(e[t]=o[t]))}))}getComponentInstance(e){return this.componentInstances.has(e)||this.componentInstances.set(e,{hooks:[],currentHook:0,effects:[],cleanups:new Map,pendingEffects:[],contextSubscriptions:new Set,lastProps:null,lastResult:null}),this.componentInstances.get(e)}renderComponent(e,t){const n=this.getComponentInstance(e);this.componentStack.push(n),n.currentHook=0;if(!n.lastResult||this.shouldComponentUpdate(n,e)){const o=e();n.lastResult=o,this.render(o,t),n.pendingEffects.length>0&&(this.pendingEffects.push(...n.pendingEffects),n.pendingEffects=[])}else this.render(n.lastResult,t);this.componentStack.pop()}shouldComponentUpdate(e,t){return!e.lastProps||!this.shallowEqual(e.lastProps,t)}getCurrentInstance(){return this.componentStack[this.componentStack.length-1]}createContext(e){const t={_currentValue:e,_defaultValue:e,_subscribers:new Set,_version:0,Provider:({value:e,children:n})=>{const o=this.getCurrentInstance(),s=o.currentHook++,r=o.hooks[s];return this.shallowEqual(r,e)||(t._currentValue=e,t._version++,t._subscribers.forEach((t=>{t.instance.hooks[t.hookIndex]=e,this.scheduleUpdate()}))),o.hooks[s]=e,n},Consumer:({children:e})=>{if("function"!=typeof e)throw new Error("Context.Consumer expects a function as a child");return e(t._currentValue)}};return t}scheduleUpdate(){if(!this.isBatchingUpdates){this.isBatchingUpdates=!0;const e=this.getCurrentInstance();if(e){this.dirtyInstances=new Set([e]);const t=this.componentStack[this.componentStack.length-2];t&&this.dirtyInstances.add(t)}this.hasScheduledFlush||(this.hasScheduledFlush=!0,queueMicrotask((()=>{this.flushUpdates(),this.isBatchingUpdates=!1})))}}flushUpdates(){try{if(this.rootElement&&this.dirtyInstances?.size>0)for(this.components.forEach(((e,t)=>{const n=this.getComponentInstance(e);this.dirtyInstances.has(n)&&this.renderComponent(e,t)}));this.pendingEffects.length>0;){this.pendingEffects.shift()()}}finally{this.dirtyInstances=new Set,this.hasScheduledFlush=!1,this.pendingUpdates=[]}}mount(e,t){for(this.rootElement=t,this.components.set(t,e),this.renderComponent(e,t);this.pendingEffects.length>0;){this.pendingEffects.shift()()}}unmount(e){const t=this.components.get(e);if(t){const n=this.componentInstances.get(t);n&&(n.contextSubscriptions.forEach((e=>e())),n.contextSubscriptions.clear(),n.cleanups.forEach((e=>e())),n.cleanups.clear(),this.componentInstances.delete(t)),this.components.delete(e)}e.innerHTML=""}memo(e){const t=t=>{const n=this.getCurrentInstance();if(!n)return e(t);const o=n.currentHook++,s=n.hooks[o]||{props:null,result:null},r=!s.props||!this.deepEqual(t,s.props);if(!s.result||r){const s=e(t);return n.hooks[o]={props:t,result:s},s}return s.result};return t.__isMemoized=!0,t.__original=e,t}shallowEqual(e,t){if(e===t)return!0;if(!e||!t)return!1;if("object"!=typeof e||"object"!=typeof t)return e===t;const n=Object.keys(e),o=Object.keys(t);return n.length===o.length&&n.every((n=>t.hasOwnProperty(n)&&e[n]===t[n]))}deepEqual(e,t){if(e===t)return!0;if(!e||!t)return!1;if(typeof e!=typeof t)return!1;if("object"!=typeof e)return e===t;if(Array.isArray(e))return!(!Array.isArray(t)||e.length!==t.length)&&e.every(((e,n)=>this.deepEqual(e,t[n])));const n=Object.keys(e),o=Object.keys(t);return n.length===o.length&&n.every((n=>t.hasOwnProperty(n)&&this.deepEqual(e[n],t[n])))}}const Olova=new Olovav2;export const h=Olova.createElement.bind(Olova);export const Fragment=e=>e?e.children:null;export const $state=e=>stateHook(Olova,e);export const $effect=(e,t)=>effectHook(Olova,e,t);export const $memo=(e,t)=>memoHook(Olova,e,t);export const $callback=(e,t)=>callbackHook(Olova,e,t);export const $reducer=(e,t)=>reducerHook(Olova,e,t);export const $ref=e=>refHook(Olova,e);export const $context=e=>contextHook(Olova,e);export const createContext=Olova.createContext.bind(Olova);export const memo=Olova.memo.bind(Olova);export default Olova;function isFunctionComponent(e){return"function"==typeof e}function renderComponent(e,t){try{return"function"==typeof e.type?e.type(e.props):"string"==typeof e?e:Array.isArray(e)?e.map((e=>renderComponent(e,t))):null==e?"":"object"==typeof e?e:String(e)}catch(e){return console.error("Error rendering component:",e),null}}
|