olova 2.0.7 → 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.
Files changed (2) hide show
  1. package/dist/olova.js +1 -1
  2. package/package.json +1 -1
package/dist/olova.js CHANGED
@@ -1 +1 @@
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 WeakMap,this.componentStack=[],this.componentInstances=new WeakMap,this.pendingUpdates=new Set,this.pendingEffects=[],this.contextSubscriptions=new WeakMap,this.isBatchingUpdates=!1,this.hasScheduledFlush=!1,this.dirtyInstances=new Set,this.virtualDOM=null,this.errorBoundaries=new WeakMap,this.batchQueue=new Set,this.isProcessingBatch=!1,this.debugEnabled=!1}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:this.flattenChildren(n)}}:(console.error("Invalid element type:",e),null)}flattenChildren(e){const t=[],n=[...e];for(;n.length;){const e=n.pop();Array.isArray(e)?n.push(...e):t.push(e)}return t.reverse()}render(e,t){try{if(null==e)return;const n=this.createVirtualDOM(e);this.virtualDOM?this.updateDOM(t,this.virtualDOM,n):(t.innerHTML="",t.appendChild(this.createDOM(n))),this.virtualDOM=n}catch(e){console.error("Render error:",e)}}createVirtualDOM(e){if("string"==typeof e||"number"==typeof e)return e;if(Array.isArray(e))return e.map((e=>this.createVirtualDOM(e)));if("function"==typeof e.type){const t=e.type,n=this.getComponentInstance(t);this.componentStack.push(n),n.currentHook=0,n.lastProps=e.props;try{const o=t(e.props);return n.lastResult=o,this.createVirtualDOM(o)}finally{this.componentStack.pop()}}return"string"!=typeof e.type?(console.error("Invalid element type:",e.type),null):{type:e.type,props:e.props,children:(e.props.children||[]).map((e=>this.createVirtualDOM(e)))}}createDOM(e){if("string"==typeof e||"number"==typeof e)return document.createTextNode(e);if(Array.isArray(e)){const t=document.createDocumentFragment();return e.forEach((e=>t.appendChild(this.createDOM(e)))),t}const t=document.createElement(e.type);return this.applyProps(t,e.props),e.children.forEach((e=>t.appendChild(this.createDOM(e)))),t}updateDOM(e,t,n){if(!e)return void this.debug("Container is undefined in updateDOM");if(t===n)return;if("string"==typeof t||"number"==typeof t)return void(t!==n&&e.textContent!==String(n)&&(e.textContent=n));if(Array.isArray(t)&&Array.isArray(n))return void this.reconcileChildren(e,t,n);if(t?.type!==n?.type){const t=this.createDOM(n);return void e.parentNode?.replaceChild(t,e)}t?.props!==n?.props&&this.updateProps(e,t?.props||{},n?.props||{});const o=t?.children||[],r=n?.children||[];this.updateChildren(e,o,r)}reconcileChildren(e,t,n){const o=new Map,r=new Map;t.forEach(((e,t)=>{e?.props?.key&&o.set(e.props.key,t)})),n.forEach(((e,t)=>{e?.props?.key&&r.set(e.props.key,t)}));const s=[];n.forEach(((e,t)=>{const n=e?.props?.key;if(n&&o.has(n)){const e=o.get(n);e!==t&&s.push({from:e,to:t})}})),s.forEach((({from:t,to:n})=>{const o=e.childNodes[t],r=e.childNodes[n];e.insertBefore(o,r)})),this.updateChildNodes(e,t,n)}updateChildNodes(e,t,n){const o=Math.max(t.length,n.length);for(let r=0;r<o;r++){const o=e.childNodes[r];!o&&n[r]?e.appendChild(this.createDOM(n[r])):n[r]?this.updateDOM(o,t[r],n[r]):e.removeChild(o)}}updateProps(e,t,n){Object.keys(t).forEach((t=>{if(!(t in n))if(t.startsWith("on")){const n=t.toLowerCase().substring(2);e.removeEventListener(n,e[`_${n}`]),delete e[`_${n}`]}else"children"!==t&&(e[t]="")})),Object.keys(n).forEach((o=>{n[o]!==t[o]&&this.applyProp(e,o,n[o])}))}applyProp(e,t,n){if("ref"===t)n.current=e;else if(t.startsWith("on")){const o=t.toLowerCase().substring(2),r=e[`_${o}`];r&&e.removeEventListener(o,r);const s=n;e[`_${o}`]=s,e.addEventListener(o,s)}else"children"!==t&&("className"===t?e.setAttribute("class",n):e[t]=n)}updateChildren(e,t,n){const o=Math.max(t.length,n.length);for(let r=0;r<o;r++){const o=e.childNodes[r];!o&&n[r]?e.appendChild(this.createDOM(n[r])):n[r]?this.updateDOM(o,t[r],n[r]):e.removeChild(o)}}applyProps(e,t){Object.keys(t||{}).forEach((n=>{if("ref"===n&&t[n])t[n].current=e;else if(n.startsWith("on")){const o=n.toLowerCase().substring(2),r=e[`_${o}`];r&&e.removeEventListener(o,r);const s=e=>{t[n](e)};e[`_${o}`]=s,e.addEventListener(o,s)}else"children"!==n&&("className"===n?e.setAttribute("class",t[n]):e[n]=t[n])}))}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);try{n.currentHook=0;const o=e();n.lastResult=o;this.createVirtualDOM(o);return t&&this.render(o,t),n.pendingEffects.length>0&&(this.pendingEffects.push(...n.pendingEffects),n.pendingEffects=[]),o}finally{this.componentStack.pop()}}shouldComponentUpdate(e,t){return!t.__isMemoized||!e.lastProps||!this.deepEqual(e.lastProps,t.props)}getCurrentInstance(){return this.componentStack[this.componentStack.length-1]||null}createContext(e){const t={_currentValue:e,_defaultValue:e,_subscribers:new Set,_version:0,Provider:({value:e,children:n})=>{const o=this.getCurrentInstance(),r=o.currentHook++,s=o.hooks[r];return this.shallowEqual(s,e)||(t._currentValue=e,t._version++,t._subscribers.forEach((t=>{t.instance.hooks[t.hookIndex]=e,this.scheduleUpdate()}))),o.hooks[r]=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(){this.isBatchingUpdates||(this.isBatchingUpdates=!0,queueMicrotask((()=>{if(this.rootElement){const e=this.components.get(this.rootElement);if(e){const t=this.createVirtualDOM(this.renderComponent(e));this.updateDOM(this.rootElement,this.virtualDOM,t),this.virtualDOM=t}}for(;this.pendingEffects.length>0;){this.pendingEffects.shift()()}this.isBatchingUpdates=!1})))}findComponentByInstance(e){for(const[t,n]of this.components.entries())if(this.componentInstances.get(n)===e)return n;return null}flushUpdates(){this.pendingUpdates.forEach((e=>e())),this.pendingUpdates.clear(),this.hasScheduledFlush=!1}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++,r=n.hooks[o]||{props:null,result:null},s=!r.props||!this.deepEqual(t,r.props);if(!r.result||s){const r=e(t);return n.hooks[o]={props:t,result:r},r}return r.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])))}findComponentElement(e){const t=document.querySelectorAll("*");return Array.from(t).find((t=>{const n=this.components.get(t);return n&&this.componentInstances.get(n)===e}))||null}setState(e){this.getCurrentInstance()&&this.scheduleUpdate()}setErrorBoundary(e,t){this.errorBoundaries.set(e,t)}handleError(e,t){let n=t;for(;n;){const t=this.errorBoundaries.get(n);if(t)return void t(e);n=this.findParentComponent(n)}console.error("Unhandled error:",e)}batchUpdates(e){const t=this.isBatchingUpdates;this.isBatchingUpdates=!0;try{e()}finally{t||(this.isBatchingUpdates=!1,this.flushBatchQueue())}}flushBatchQueue(){if(!this.isProcessingBatch){this.isProcessingBatch=!0;try{for(const e of this.batchQueue)e();this.batchQueue.clear()}finally{this.isProcessingBatch=!1}}}componentDidMount(e){e.onComponentDidMount&&e.onComponentDidMount()}componentWillUnmount(e){e.onComponentWillUnmount&&e.onComponentWillUnmount()}debug(...e){this.debugEnabled&&console.log("[Olova Debug]:",...e)}enableDebug(){this.debugEnabled=!0}disableDebug(){this.debugEnabled=!1}}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}}export const enableDebug=Olova.enableDebug.bind(Olova);export const disableDebug=Olova.disableDebug.bind(Olova);export const setErrorBoundary=Olova.setErrorBoundary.bind(Olova);
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}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "olova",
3
- "version": "2.0.7",
3
+ "version": "2.0.8",
4
4
  "description": "A lightweight JavaScript framework for building reactive applications.",
5
5
  "main": "dist/olova.js",
6
6
  "keywords": [