frontend-hamroun 1.2.16 → 1.2.17

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 (158) hide show
  1. package/README.md +4 -0
  2. package/bin/cli.js +673 -0
  3. package/dist/component.d.ts +1 -1
  4. package/dist/context.d.ts +4 -3
  5. package/dist/index.client.d.ts +11 -0
  6. package/dist/index.d.ts +9 -89
  7. package/dist/index.js +396 -67
  8. package/dist/index.js.map +1 -0
  9. package/dist/index.mjs +392 -0
  10. package/dist/index.mjs.map +1 -0
  11. package/dist/jsx-runtime/jsx-runtime.d.ts +0 -1
  12. package/dist/jsx-runtime.d.ts +1 -1
  13. package/dist/renderer.d.ts +0 -10
  14. package/dist/server-renderer.d.ts +0 -3
  15. package/dist/server-types.d.ts +42 -0
  16. package/package.json +69 -41
  17. package/templates/basic-app/index.html +6 -6
  18. package/templates/basic-app/package.json +18 -7
  19. package/templates/basic-app/postcss.config.js +0 -1
  20. package/templates/basic-app/src/main.tsx +1 -10
  21. package/templates/basic-app/tailwind.config.js +2 -23
  22. package/templates/basic-app/tsconfig.json +4 -17
  23. package/templates/basic-app/vite.config.ts +3 -54
  24. package/templates/fullstack-app/api/hello.ts +18 -0
  25. package/templates/fullstack-app/api/users/[id].ts +73 -0
  26. package/templates/fullstack-app/api/users/index.ts +32 -0
  27. package/templates/fullstack-app/package.json +31 -0
  28. package/templates/fullstack-app/server.ts +46 -0
  29. package/templates/fullstack-app/src/pages/index.tsx +59 -0
  30. package/templates/ssr-template/vite.config.ts +1 -11
  31. package/bin/cli.cjs +0 -16
  32. package/bin/cli.mjs +0 -237
  33. package/dist/backend/api-utils.d.ts +0 -38
  34. package/dist/backend/api-utils.js +0 -135
  35. package/dist/backend/auth.d.ts +0 -134
  36. package/dist/backend/auth.js +0 -387
  37. package/dist/backend/database.d.ts +0 -27
  38. package/dist/backend/database.js +0 -91
  39. package/dist/backend/model.d.ts +0 -43
  40. package/dist/backend/model.js +0 -178
  41. package/dist/backend/router.d.ts +0 -27
  42. package/dist/backend/router.js +0 -137
  43. package/dist/backend/server.d.ts +0 -19
  44. package/dist/backend/server.js +0 -268
  45. package/dist/backend/types.d.ts +0 -217
  46. package/dist/backend/types.js +0 -1
  47. package/dist/batch.js +0 -22
  48. package/dist/cli/index.d.ts +0 -2
  49. package/dist/cli/index.js +0 -215
  50. package/dist/component.js +0 -84
  51. package/dist/components/Counter.js +0 -2
  52. package/dist/context.js +0 -18
  53. package/dist/frontend-hamroun.es.js +0 -1378
  54. package/dist/frontend-hamroun.umd.js +0 -66
  55. package/dist/hooks.js +0 -164
  56. package/dist/jsx-runtime/index.d.ts +0 -11
  57. package/dist/jsx-runtime/index.js +0 -19
  58. package/dist/jsx-runtime/jsx-dev-runtime.js +0 -1
  59. package/dist/jsx-runtime/jsx-runtime.js +0 -95
  60. package/dist/jsx-runtime.js +0 -192
  61. package/dist/renderer.js +0 -51
  62. package/dist/server-renderer.js +0 -102
  63. package/dist/types.js +0 -1
  64. package/dist/vdom.js +0 -27
  65. package/scripts/build-cli.js +0 -1199
  66. package/scripts/generate.js +0 -134
  67. package/src/backend/api-utils.ts +0 -178
  68. package/src/backend/auth.ts +0 -544
  69. package/src/backend/database.ts +0 -104
  70. package/src/backend/model.ts +0 -198
  71. package/src/backend/router.ts +0 -176
  72. package/src/backend/server.ts +0 -330
  73. package/src/backend/types.ts +0 -257
  74. package/src/batch.ts +0 -24
  75. package/src/cli/index.js +0 -554
  76. package/src/cli/index.ts +0 -257
  77. package/src/component.ts +0 -98
  78. package/src/components/Counter.tsx +0 -4
  79. package/src/context.ts +0 -29
  80. package/src/hooks.ts +0 -211
  81. package/src/index.ts +0 -144
  82. package/src/jsx-runtime/index.ts +0 -27
  83. package/src/jsx-runtime/jsx-dev-runtime.ts +0 -0
  84. package/src/jsx-runtime/jsx-runtime.ts +0 -104
  85. package/src/jsx-runtime.ts +0 -226
  86. package/src/renderer.ts +0 -55
  87. package/src/server-renderer.ts +0 -114
  88. package/src/shims.d.ts +0 -20
  89. package/src/types/bcrypt.d.ts +0 -30
  90. package/src/types/jsonwebtoken.d.ts +0 -55
  91. package/src/types.d.ts +0 -26
  92. package/src/types.ts +0 -21
  93. package/src/vdom.ts +0 -34
  94. package/templates/basic/.eslintignore +0 -5
  95. package/templates/basic/.eslintrc.json +0 -25
  96. package/templates/basic/docs/rapport_pfe.aux +0 -27
  97. package/templates/basic/docs/rapport_pfe.log +0 -399
  98. package/templates/basic/docs/rapport_pfe.out +0 -10
  99. package/templates/basic/docs/rapport_pfe.pdf +0 -0
  100. package/templates/basic/docs/rapport_pfe.tex +0 -68
  101. package/templates/basic/docs/rapport_pfe.toc +0 -14
  102. package/templates/basic/index.html +0 -12
  103. package/templates/basic/jsconfig.json +0 -14
  104. package/templates/basic/package.json +0 -18
  105. package/templates/basic/postcss.config.js +0 -7
  106. package/templates/basic/src/App.js +0 -105
  107. package/templates/basic/src/App.tsx +0 -65
  108. package/templates/basic/src/api.ts +0 -58
  109. package/templates/basic/src/components/Counter.tsx +0 -26
  110. package/templates/basic/src/components/Header.tsx +0 -9
  111. package/templates/basic/src/components/TodoList.tsx +0 -90
  112. package/templates/basic/src/main.css +0 -3
  113. package/templates/basic/src/main.js +0 -11
  114. package/templates/basic/src/main.ts +0 -20
  115. package/templates/basic/src/main.tsx +0 -144
  116. package/templates/basic/src/server.ts +0 -99
  117. package/templates/basic/tailwind.config.js +0 -32
  118. package/templates/basic/tsconfig.json +0 -20
  119. package/templates/basic/tsconfig.node.json +0 -10
  120. package/templates/basic/vite.config.js +0 -18
  121. package/templates/basic/vite.config.ts +0 -86
  122. package/templates/basic-app/src/App.js +0 -105
  123. package/templates/basic-app/src/App.tsx +0 -143
  124. package/templates/basic-app/src/api.ts +0 -58
  125. package/templates/basic-app/src/components/Counter.tsx +0 -26
  126. package/templates/basic-app/src/components/Header.tsx +0 -9
  127. package/templates/basic-app/src/components/TodoList.tsx +0 -90
  128. package/templates/basic-app/src/main.js +0 -10
  129. package/templates/basic-app/src/main.ts +0 -21
  130. package/templates/basic-app/src/react/index.ts +0 -35
  131. package/templates/basic-app/src/react/jsx-dev-runtime.ts +0 -13
  132. package/templates/basic-app/src/react/jsx-runtime.ts +0 -12
  133. package/templates/basic-app/src/server.ts +0 -99
  134. package/templates/basic-app/src/shims.ts +0 -9
  135. package/templates/basic-app/tsconfig.node.json +0 -10
  136. package/templates/basic-app/vite.config.js +0 -22
  137. package/templates/full-stack/.env.example +0 -11
  138. package/templates/full-stack/README.md +0 -51
  139. package/templates/full-stack/index.html +0 -12
  140. package/templates/full-stack/jsconfig.json +0 -14
  141. package/templates/full-stack/package.json +0 -21
  142. package/templates/full-stack/src/App.js +0 -105
  143. package/templates/full-stack/src/client/App.tsx +0 -50
  144. package/templates/full-stack/src/client/components/Header.tsx +0 -42
  145. package/templates/full-stack/src/client/components/UserList.tsx +0 -29
  146. package/templates/full-stack/src/client/main.tsx +0 -5
  147. package/templates/full-stack/src/main.css +0 -3
  148. package/templates/full-stack/src/main.js +0 -11
  149. package/templates/full-stack/src/main.ts +0 -20
  150. package/templates/full-stack/src/server/index.ts +0 -99
  151. package/templates/full-stack/src/server/routes/auth.ts +0 -39
  152. package/templates/full-stack/src/server/routes/users.ts +0 -48
  153. package/templates/full-stack/src/shims.ts +0 -9
  154. package/templates/full-stack/tsconfig.json +0 -20
  155. package/templates/full-stack/tsconfig.node.json +0 -10
  156. package/templates/full-stack/tsconfig.server.json +0 -15
  157. package/templates/full-stack/vite.config.js +0 -18
  158. package/templates/full-stack/vite.config.ts +0 -85
@@ -1,66 +0,0 @@
1
- (function(u,v){typeof exports=="object"&&typeof module<"u"?v(exports,require("express"),require("path"),require("compression"),require("helmet"),require("morgan"),require("mongoose"),require("fs"),require("bcrypt")):typeof define=="function"&&define.amd?define(["exports","express","path","compression","helmet","morgan","mongoose","fs","bcrypt"],v):(u=typeof globalThis<"u"?globalThis:u||self,v(u["frontend-hamroun"]={},u.express,u.path,u.compression,u.helmet,u.morgan,u.mongoose,u.fs))})(this,function(u,v,Ee,Je,Qe,Ye,_,ze){"use strict";const be=globalThis||void 0||self;function Xe(r){return r&&r.__esModule&&Object.prototype.hasOwnProperty.call(r,"default")?r.default:r}var Te={exports:{}},y=Te.exports={},k,A;function K(){throw new Error("setTimeout has not been defined")}function ee(){throw new Error("clearTimeout has not been defined")}(function(){try{typeof setTimeout=="function"?k=setTimeout:k=K}catch{k=K}try{typeof clearTimeout=="function"?A=clearTimeout:A=ee}catch{A=ee}})();function ve(r){if(k===setTimeout)return setTimeout(r,0);if((k===K||!k)&&setTimeout)return k=setTimeout,setTimeout(r,0);try{return k(r,0)}catch{try{return k.call(null,r,0)}catch{return k.call(this,r,0)}}}function Ze(r){if(A===clearTimeout)return clearTimeout(r);if((A===ee||!A)&&clearTimeout)return A=clearTimeout,clearTimeout(r);try{return A(r)}catch{try{return A.call(null,r)}catch{return A.call(this,r)}}}var C=[],M=!1,R,W=-1;function Ke(){!M||!R||(M=!1,R.length?C=R.concat(C):W=-1,C.length&&Se())}function Se(){if(!M){var r=ve(Ke);M=!0;for(var t=C.length;t;){for(R=C,C=[];++W<t;)R&&R[W].run();W=-1,t=C.length}R=null,M=!1,Ze(r)}}y.nextTick=function(r){var t=new Array(arguments.length-1);if(arguments.length>1)for(var e=1;e<arguments.length;e++)t[e-1]=arguments[e];C.push(new ke(r,t)),C.length===1&&!M&&ve(Se)};function ke(r,t){this.fun=r,this.array=t}ke.prototype.run=function(){this.fun.apply(null,this.array)},y.title="browser",y.browser=!0,y.env={},y.argv=[],y.version="",y.versions={};function j(){}y.on=j,y.addListener=j,y.once=j,y.off=j,y.removeListener=j,y.removeAllListeners=j,y.emit=j,y.prependListener=j,y.prependOnceListener=j,y.listeners=function(r){return[]},y.binding=function(r){throw new Error("process.binding is not supported")},y.cwd=function(){return"/"},y.chdir=function(r){throw new Error("process.chdir is not supported")},y.umask=function(){return 0};var et=Te.exports;const E=Xe(et),x=typeof window<"u"?window:typeof be<"u"?be:{};function L(r,t,e){return{type:r,props:t||{},key:e}}function te(r,t,e){return L(r,t,e)}function U(r){if(typeof r=="string"||typeof r=="number")return document.createTextNode(String(r));if(typeof r.type=="function"){const e=r.type(r.props);return U(e)}const t=document.createElement(r.type);return Object.entries(r.props||{}).forEach(([e,n])=>{if(e==="children")(Array.isArray(n)?n:[n]).forEach(i=>{if(i!=null){const o=U(i);E.env.NODE_ENV==="test"&&typeof window<"u"&&(x.__renderStats||(x.__renderStats={elementsCreated:0,textNodesCreated:0,eventsAttached:0,renderTime:0},typeof afterAll=="function"&&afterAll(()=>{try{const a=require("fs"),f=require("path").resolve(E.cwd(),"jsx-runtime-stats.json");a.writeFileSync(f,JSON.stringify(x.__renderStats,null,2)),console.log(`JSX runtime stats written to ${f}`)}catch(a){console.error("Failed to write stats file:",a)}})),o instanceof Text?x.__renderStats.textNodesCreated++:x.__renderStats.elementsCreated++),t.appendChild(o)}});else if(e.startsWith("on")){const s=e.toLowerCase().substring(2);t.addEventListener(s,n),E.env.NODE_ENV==="test"&&typeof window<"u"&&x.__renderStats&&x.__renderStats.eventsAttached++}else e==="className"?t.setAttribute("class",n):e==="style"&&typeof n=="object"?Object.entries(n).forEach(([s,i])=>{t.style[s]=String(i)}):t.setAttribute(e,n)}),t}const re=Symbol("Fragment"),ne=L;typeof window<"u"&&(window.jsx=L,window.jsxs=te,window.jsxDEV=ne,window.Fragment=re);const tt=typeof window<"u"&&typeof document<"u";async function I(r){var t;if(console.log("Creating element from:",r),!tt){if(r==null)return{nodeType:3,textContent:""};if(typeof r=="boolean")return{nodeType:3,textContent:""};if(typeof r=="number"||typeof r=="string")return{nodeType:3,textContent:String(r)};if(Array.isArray(r)){const e={nodeType:11,childNodes:[]};for(const n of r){const s=await I(n);e.childNodes.push(s)}return e}if("type"in r&&r.props!==void 0){const{type:e,props:n}=r;if(typeof e=="function")try{const o=await e(n||{});return await I(o)}catch(o){return console.error("Error rendering component:",o),{nodeType:3,textContent:""}}const s={nodeType:1,tagName:e,attributes:{},style:{},childNodes:[],setAttribute:function(o,a){this.attributes[o]=a},appendChild:function(o){this.childNodes.push(o)}};for(const[o,a]of Object.entries(n||{}))if(o!=="children")if(o.startsWith("on")&&typeof a=="function"){const c=o.toLowerCase().slice(2);s.__events||(s.__events={}),s.__events[c]=a}else o==="style"&&typeof a=="object"?Object.assign(s.style,a):o==="className"?s.setAttribute("class",String(a)):o!=="key"&&o!=="ref"&&s.setAttribute(o,String(a));const i=n==null?void 0:n.children;if(i!=null){const o=Array.isArray(i)?i.flat():[i];for(const a of o){const c=await I(a);s.appendChild(c)}}return s}return{nodeType:3,textContent:String(r)}}if(r==null||typeof r=="boolean")return document.createTextNode("");if(typeof r=="number"||typeof r=="string")return document.createTextNode(String(r));if(Array.isArray(r)){const e=document.createDocumentFragment();for(const n of r){const s=await I(n);e.appendChild(s)}return e}if("type"in r&&r.props!==void 0){const{type:e,props:n}=r;if(typeof e=="function")try{const o=await e(n||{}),a=await I(o);return a instanceof Element&&a.setAttribute("data-component-id",e.name||e.toString()),a}catch(o){return console.error("Error rendering component:",o),document.createTextNode("")}const s=document.createElement(e);for(const[o,a]of Object.entries(n||{}))if(o!=="children")if(o.startsWith("on")&&typeof a=="function"){const c=o.toLowerCase().slice(2),f=(t=s.__events)==null?void 0:t[c];f&&s.removeEventListener(c,f),s.addEventListener(c,a),s.__events||(s.__events={}),s.__events[c]=a}else o==="style"&&typeof a=="object"?Object.assign(s.style,a):o==="className"?s.setAttribute("class",String(a)):o!=="key"&&o!=="ref"&&s.setAttribute(o,String(a));const i=n==null?void 0:n.children;if(i!=null){const o=Array.isArray(i)?i.flat():[i];for(const a of o){const c=await I(a);s.appendChild(c)}}return s}return document.createTextNode(String(r))}class Ae{constructor(t={}){this.state={},this.element=null,this._mounted=!1,this.props=t}componentDidMount(){}async setState(t){const e={...this.state};this.state={...e,...t},console.log(`${this.constructor.name} state updated:`,{prev:e,next:this.state}),await Promise.resolve(),this._mounted?await this.update():await this.update()}_replayEvents(t,e){const n=t.__events||{};Object.entries(n).forEach(([s,i])=>{e.addEventListener(s,i)}),e.__events=n}_deepCloneWithEvents(t){const e=t.cloneNode(!1),n=t.__events||{};return e.__events=n,Object.entries(n).forEach(([s,i])=>{e.addEventListener(s,i)}),Array.from(t.childNodes).forEach(s=>{s instanceof HTMLElement?e.appendChild(this._deepCloneWithEvents(s)):e.appendChild(s.cloneNode(!0))}),e}async update(){const t=this.render();if(!t)return document.createTextNode("");const e=await I(t);if(e instanceof HTMLElement)return this._updateElement(e);const n=document.createElement("div");return n.appendChild(e),this._updateElement(n)}async _updateElement(t){const e=this._deepCloneWithEvents(t);return e.__instance=this,this.element?this.element.parentNode&&(this.element.parentNode.replaceChild(e,this.element),this.element=e):(this.element=e,this._mounted||(this._mounted=!0,queueMicrotask(()=>this.componentDidMount()))),this.element}render(){throw new Error("Component must implement render() method")}}let G=!1;const se=[];function J(r){if(G){se.push(r);return}G=!0;try{for(r();se.length>0;){const t=se.shift();t==null||t()}}finally{G=!1}}let l=0;const oe=new Map,T=new Map,V=new Map,ie=new Map,ae=new Map;let ce=null,ue=null,le=null;const Ce=typeof window>"u",Q=new Map;function je(r,t,e){ce=r,ue=e,le=t}function B(){return l++,T.set(l,0),l}function q(){Ce&&Q.delete(l),l=0}function de(r){if(!l)throw new Error("useState must be called within a render");if(Ce){Q.has(l)||Q.set(l,new Map);const i=Q.get(l),o=T.get(l)||0;i.has(o)||i.set(o,r);const a=i.get(o),c=f=>{};return T.set(l,o+1),[a,c]}oe.has(l)||oe.set(l,[]);const t=oe.get(l),e=T.get(l);e>=t.length&&t.push(r);const n=t[e],s=i=>{const o=typeof i=="function"?i(t[e]):i;t[e]!==o&&(t[e]=o,G?J(()=>Re(l)):Re(l))};return T.set(l,e+1),[n,s]}function $e(r,t){if(!l)throw new Error("useEffect must be called within a render");const e=T.get(l);V.has(l)||V.set(l,[]);const n=V.get(l),s=n[e];(!s||!t||!s.deps||t.some((i,o)=>i!==s.deps[o]))&&(s!=null&&s.cleanup&&s.cleanup(),queueMicrotask(()=>{const i=r()||void 0;n[e]={cleanup:i,deps:t}})),T.set(l,e+1)}function _e(r,t){if(!l)throw new Error("useMemo must be called within a render");const e=T.get(l);ie.has(l)||ie.set(l,[]);const n=ie.get(l),s=n[e];if(!s||t&&t.some((i,o)=>!Object.is(i,s.deps[o]))){const i=r();return n[e]={value:i,deps:t},T.set(l,e+1),i}return T.set(l,e+1),s.value}function Ie(r){if(!l)throw new Error("useRef must be called within a render");const t=T.get(l);ae.has(l)||ae.set(l,[]);const e=ae.get(l);if(t>=e.length){const s={current:r};return e.push(s),T.set(l,t+1),s}const n=e[t];return T.set(l,t+1),n}async function Re(r){try{const t=V.get(r);t&&(t.forEach(e=>{e.cleanup&&e.cleanup()}),V.set(r,[])),ce&&ue&&le&&await ce(le,ue)}catch(t){console.error("Error during rerender:",t)}}function xe(){const[r,t]=de(null);return[r,()=>t(null)]}let Y=!1;async function Ne(r,t){Y=!0;try{await z(r,t)}finally{Y=!1}}async function z(r,t){console.log("Rendering to:",t.id||"unnamed-container"),J(async()=>{const e=B();try{je(z,r,t);const n=await I(r);Y||(t.innerHTML=""),Y&&t.firstChild?console.log("Hydrating existing DOM"):t.appendChild(n)}finally{q()}})}async function N(r){B(),je(()=>{},r,null);try{if(r==null||typeof r=="boolean")return"";if(typeof r=="number"||typeof r=="string")return X(String(r));if(Array.isArray(r))return(await Promise.all(r.map(N))).join("");if("type"in r&&r.props!==void 0){const{type:t,props:e}=r;if(typeof t=="function")try{B();const i=await t(e||{}),o=await N(i);return q(),o}catch(i){return console.error("Error rendering component:",i),""}if(t===Symbol.for("react.fragment")||t.name==="Fragment"){if(e.children){const i=Array.isArray(e.children)?e.children:[e.children];return(await Promise.all(i.map(N))).join("")}return""}let n=`<${t}`;for(const[i,o]of Object.entries(e||{}))i==="children"||i==="key"||(i==="className"?n+=` class="${X(String(o))}"`:i==="style"&&typeof o=="object"?n+=` style="${rt(o||{})}"`:i.startsWith("on")||(n+=` ${i}="${X(String(o))}"`));if(new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]).has(t))return n+"/>";if(n+=">",e!=null&&e.children){const i=Array.isArray(e.children)?e.children:[e.children];for(const o of i)n+=await N(o)}return n+`</${t}>`}return X(String(r))}finally{q()}}function X(r){return r.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function rt(r){return Object.entries(r).map(([t,e])=>`${nt(t)}:${e}`).join(";")}function nt(r){return r.replace(/[A-Z]/g,t=>"-"+t.toLowerCase())}function Oe(r){const t={_currentValue:r,Provider:function({value:n,children:s}){return t._currentValue=n,s},Consumer:function({children:n}){return n(t._currentValue)}};return t}function Pe(r){return r._currentValue}class fe{constructor(t){this.connection=null,this._connected=!1,this.options={retryAttempts:3,retryDelay:1e3,connectionTimeout:1e4,autoIndex:!0,...t}}async connect(){try{if(this._connected&&this.connection)return this.connection;_.set("strictQuery",!0);let t=0;for(;t<(this.options.retryAttempts||3);)try{await _.connect(this.options.uri,{dbName:this.options.name,connectTimeoutMS:this.options.connectionTimeout,autoIndex:this.options.autoIndex,...this.options.options});break}catch(e){if(t++,t>=(this.options.retryAttempts||3))throw e;console.log(`Connection attempt ${t} failed. Retrying in ${this.options.retryDelay}ms...`),await new Promise(n=>setTimeout(n,this.options.retryDelay))}return this.connection=_.connection,this._connected=!0,console.log(`Connected to MongoDB at ${this.options.uri}/${this.options.name}`),this.connection.on("error",e=>{console.error("MongoDB connection error:",e),this._connected=!1}),this.connection.on("disconnected",()=>{console.log("MongoDB disconnected"),this._connected=!1}),this.connection}catch(t){throw console.error("Failed to connect to MongoDB:",t),t}}async disconnect(){this.connection&&(await _.disconnect(),this._connected=!1,this.connection=null,console.log("Disconnected from MongoDB"))}isConnected(){return this._connected}getConnection(){return this.connection}}function De(r={}){const t=v(),{port:e=3e3,staticDir:n="public",enableCors:s=!0,apiPrefix:i="/api",ssrEnabled:o=!0,middlewares:a=[],enableCompression:c=!0,enableHelmet:f=!0,logFormat:p="dev",trustProxy:b=!1,showErrorDetails:$=E.env.NODE_ENV!=="production"}=r;if(b&&t.set("trust proxy",b),t.use(v.json()),t.use(v.urlencoded({extended:!0})),c&&t.use(Je()),f&&t.use(Qe({contentSecurityPolicy:r.disableCSP?!1:void 0})),p&&t.use(Ye(p)),s&&t.use((d,m,h)=>{if(m.header("Access-Control-Allow-Origin","*"),m.header("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, PATCH, OPTIONS"),m.header("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept, Authorization"),d.method==="OPTIONS")return m.sendStatus(200);h()}),a.forEach(d=>t.use(d)),n){const d=Ee.resolve(E.cwd(),n);ze.existsSync(d)?(t.use(v.static(d,{maxAge:r.staticCacheAge||"1d",etag:!0})),console.log(`📂 Serving static files from: ${d}`)):console.warn(`⚠️ Static directory not found: ${d}`)}let g=null;t.connectToDatabase=async d=>{try{return g&&g.isConnected()?(console.log("✅ Using existing database connection"),g):(g=new fe(d),await g.connect(),console.log("✅ Database connected successfully"),E.on("SIGTERM",async()=>{g&&g.isConnected()&&(await g.disconnect(),console.log("Database connection closed"))}),g)}catch(m){throw console.error("❌ Failed to connect to database:",m),m}};const F={},me={};return t.registerApi=(d,m,h={})=>{try{const{prefix:w=i}=h,S=Ee.posix.join(w,d).replace(/\\/g,"/");t.use(S,m),F[S]={router:m,options:h},console.log(`🔌 API registered: ${S}`)}catch(w){console.error(`❌ Failed to register API at ${d}:`,w)}return t},t.registerSSR=(d,m,h={})=>o?(me[d]={component:m,options:h},t.get(d,async(w,S,ge)=>{try{if(w.query.nossr==="true")return ge();const we={req:w,res:S,params:w.params,query:w.query,user:w.user,...h.props},at=await N(m(we));S.send(`
2
- <!DOCTYPE html>
3
- <html lang="${h.lang||"en"}">
4
- <head>
5
- <meta charset="UTF-8">
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>${h.title||"Frontend Hamroun App"}</title>
8
- ${h.meta?h.meta.map(H=>`<meta ${Object.entries(H).map(([ct,ut])=>`${ct}="${ut}"`).join(" ")}>`).join(`
9
- `):""}
10
- ${h.head||""}
11
- ${h.styles?`<style>${h.styles}</style>`:""}
12
- ${h.styleSheets?h.styleSheets.map(H=>`<link rel="stylesheet" href="${H}">`).join(`
13
- `):""}
14
- </head>
15
- <body ${h.bodyAttributes||""}>
16
- <div id="${h.rootId||"root"}">${at}</div>
17
- <script>
18
- window.__INITIAL_DATA__ = ${JSON.stringify(h.initialData||{})};
19
- <\/script>
20
- ${h.scripts?h.scripts.map(H=>`<script src="${H}"><\/script>`).join(`
21
- `):""}
22
- </body>
23
- </html>
24
- `)}catch(we){if(console.error("SSR Error:",we),h.fallback)return ge();S.status(500).send("Server rendering error")}}),console.log(`🖥️ SSR registered: ${d}`),t):(console.log(`⚠️ SSR disabled: skipping registration of ${d}`),t),t.use((d,m,h,w)=>{console.error("Server error:",d);const S=d.statusCode||d.status||500;m.path.startsWith(i)?h.status(S).json({success:!1,error:$?d.message:"Internal Server Error",stack:$?d.stack:void 0}):h.status(S).send(`
25
- <!DOCTYPE html>
26
- <html>
27
- <head>
28
- <title>Error - ${S}</title>
29
- <style>
30
- body { font-family: system-ui, sans-serif; padding: 2rem; max-width: 800px; margin: 0 auto; }
31
- .error { background: #f8d7da; border: 1px solid #f5c6cb; padding: 1rem; border-radius: 4px; }
32
- .stack { background: #f8f9fa; padding: 1rem; border-radius: 4px; overflow: auto; }
33
- </style>
34
- </head>
35
- <body>
36
- <h1>Error ${S}</h1>
37
- <div class="error">${$?d.message:"Internal Server Error"}</div>
38
- ${$&&d.stack?`<pre class="stack">${d.stack}</pre>`:""}
39
- </body>
40
- </html>
41
- `)}),t.use((d,m)=>{d.path.startsWith(i)?m.status(404).json({success:!1,error:"Not Found"}):m.status(404).send(`
42
- <!DOCTYPE html>
43
- <html>
44
- <head>
45
- <title>404 - Not Found</title>
46
- <style>
47
- body { font-family: system-ui, sans-serif; padding: 2rem; max-width: 800px; margin: 0 auto; }
48
- </style>
49
- </head>
50
- <body>
51
- <h1>404 - Not Found</h1>
52
- <p>The requested resource was not found on this server.</p>
53
- <p><a href="/">Return to homepage</a></p>
54
- </body>
55
- </html>
56
- `)}),t.start=d=>{const m=t.listen(e,()=>{console.log(`
57
- 🚀 Frontend Hamroun server running at http://localhost:${e}
58
- ${Object.keys(F).length>0?`
59
- 📡 Registered API Routes:
60
- ${Object.keys(F).map(w=>` ${w}`).join(`
61
- `)}`:""}
62
- ${Object.keys(me).length>0?`
63
- 🖥️ Registered SSR Routes:
64
- ${Object.keys(me).map(w=>` ${w}`).join(`
65
- `)}`:""}
66
- `),d&&d()}),h=async w=>{console.log(`${w} signal received: closing HTTP server and cleaning up`),m.close(async()=>{console.log("HTTP server closed"),g&&g.isConnected()&&(await g.disconnect(),console.log("Database connection closed")),E.exit(0)}),setTimeout(()=>{console.error("Could not close connections in time, forcefully shutting down"),E.exit(1)},1e4)};return E.on("SIGTERM",()=>h("SIGTERM")),E.on("SIGINT",()=>h("SIGINT")),m},t}const he=require("jsonwebtoken"),Me=require("bcrypt"),st=require("crypto");class ot{constructor(t){if(this.loginAttempts=new Map,this.login=async(e,n)=>{try{const{username:s,password:i}=e.body,o=e.ip||e.connection.remoteAddress||"";if(!this.checkRateLimit(o)){n.status(429).json({success:!1,message:"Too many login attempts. Please try again later."});return}if(!s||!i){n.status(400).json({success:!1,message:"Username and password are required"});return}if(!this.options.findUser){n.status(500).json({success:!1,message:"User finder function not configured"});return}const a=await this.options.findUser(s);if(!a){n.status(401).json({success:!1,message:"Invalid credentials"});return}if(!await this.options.verifyPassword(i,a.password)){n.status(401).json({success:!1,message:"Invalid credentials"});return}const f={...a};delete f.password;const p=this.generateTokenPair({id:a.id||a._id,username:a.username,role:a.role||"user"});if(this.options.saveRefreshToken){const b=new Date;b.setSeconds(b.getSeconds()+this.getExpirationSeconds(this.options.refreshExpiration||"7d")),await this.options.saveRefreshToken(a.id||a._id,p.refreshToken,b)}e.body.useCookies&&this.setAuthCookies(n,p),n.json({success:!0,message:"Authentication successful",tokens:p,user:f})}catch(s){console.error("Authentication error:",s),n.status(500).json({success:!1,message:"Authentication failed",error:E.env.NODE_ENV!=="production"?s.message:void 0})}},this.refreshToken=async(e,n)=>{var s,i;try{const o=((s=e.cookies)==null?void 0:s.refreshToken)||e.body.refreshToken;if(!o){n.status(401).json({success:!1,message:"Refresh token required"});return}const a=this.verifyToken(o,"refresh");if(this.options.verifyRefreshToken&&!await this.options.verifyRefreshToken(a.id,o)){this.clearAuthCookies(n),n.status(401).json({success:!1,message:"Invalid refresh token"});return}const c=this.generateTokenPair({id:a.id,...this.options.findUser?await this.options.findUser(a.id):{}});if(this.options.saveRefreshToken){const p=new Date;p.setSeconds(p.getSeconds()+this.getExpirationSeconds(this.options.refreshExpiration||"7d")),await this.options.saveRefreshToken(a.id,c.refreshToken,p)}(((i=e.cookies)==null?void 0:i.accessToken)||e.body.useCookies)&&this.setAuthCookies(n,c),n.json({success:!0,message:"Token refreshed successfully",tokens:c})}catch(o){this.clearAuthCookies(n),n.status(401).json({success:!1,message:"Invalid or expired refresh token",error:E.env.NODE_ENV!=="production"?o.message:void 0})}},this.logout=async(e,n)=>{var s;try{this.clearAuthCookies(n);const i=((s=e.cookies)==null?void 0:s.refreshToken)||e.body.refreshToken;if(i&&this.options.saveRefreshToken)try{const o=this.verifyToken(i,"refresh");typeof this.options.saveRefreshToken=="function"&&await this.options.saveRefreshToken(o.id,"",new Date)}catch{}n.json({success:!0,message:"Logged out successfully"})}catch(i){console.error("Logout error:",i),n.status(500).json({success:!1,message:"Logout failed",error:i.message})}},this.authenticate=(e,n,s)=>{var i;try{let o=(i=e.cookies)==null?void 0:i.accessToken;if(!o){const c=e.headers.authorization;c&&c.startsWith("Bearer ")&&(o=c.split(" ")[1])}if(!o){n.status(401).json({success:!1,message:"Authentication required"});return}const a=this.verifyToken(o,"access");e.user=a,s()}catch(o){n.status(401).json({success:!1,message:"Invalid or expired token",error:E.env.NODE_ENV!=="production"?o.message:void 0})}},this.hasRole=e=>(n,s,i)=>{const o=n.user;if(!o){s.status(401).json({success:!1,message:"Authentication required"});return}(Array.isArray(e)?e:[e]).includes(o.role)?i():s.status(403).json({success:!1,message:"Insufficient permissions"})},this.options={tokenExpiration:"15m",refreshExpiration:"7d",saltRounds:10,secureCookies:E.env.NODE_ENV==="production",httpOnlyCookies:!0,rateLimit:!0,...t,refreshSecret:t.refreshSecret||t.jwtSecret},!t.jwtSecret)throw new Error("JWT secret is required for authentication");this.options.verifyPassword||(this.options.verifyPassword=this.verifyPasswordWithBcrypt)}async hashPassword(t){return await Me.hash(t,this.options.saltRounds||10)}async verifyPasswordWithBcrypt(t,e){return await Me.compare(t,e)}generateSecureToken(t=32){return st.randomBytes(t).toString("hex")}generateTokenPair(t){const e=this.getExpirationSeconds(this.options.tokenExpiration||"15m"),n=he.sign({...t,type:"access"},this.options.jwtSecret,{expiresIn:this.options.tokenExpiration}),s=he.sign({id:t.id,type:"refresh"},this.options.refreshSecret,{expiresIn:this.options.refreshExpiration});return{accessToken:n,refreshToken:s,expiresIn:e}}getExpirationSeconds(t){const e=t.charAt(t.length-1),n=parseInt(t.slice(0,-1));switch(e){case"s":return n;case"m":return n*60;case"h":return n*60*60;case"d":return n*60*60*24;default:return 3600}}verifyToken(t,e="access"){try{const n=e==="access"?this.options.jwtSecret:this.options.refreshSecret,s=he.verify(t,n);if(typeof s=="object"&&s.type!==e)throw new Error("Invalid token type");return s}catch{throw new Error("Invalid or expired token")}}setAuthCookies(t,e){t.cookie("accessToken",e.accessToken,{httpOnly:this.options.httpOnlyCookies,secure:this.options.secureCookies,domain:this.options.cookieDomain,sameSite:"strict",maxAge:e.expiresIn*1e3});const n=this.getExpirationSeconds(this.options.refreshExpiration||"7d");t.cookie("refreshToken",e.refreshToken,{httpOnly:!0,secure:this.options.secureCookies,domain:this.options.cookieDomain,sameSite:"strict",maxAge:n*1e3,path:"/api/auth/refresh"})}clearAuthCookies(t){t.clearCookie("accessToken"),t.clearCookie("refreshToken",{path:"/api/auth/refresh"})}checkRateLimit(t){if(!this.options.rateLimit)return!0;const e=Date.now(),n=this.loginAttempts.get(t);return n?e>n.resetTime?(this.loginAttempts.set(t,{count:1,resetTime:e+36e5}),!0):n.count>=5?!1:(n.count++,this.loginAttempts.set(t,n),!0):(this.loginAttempts.set(t,{count:1,resetTime:e+36e5}),!0)}}function Fe(r){return new ot(r)}function Le(r,t){const e=_.model(r,t);return{getAll:async n=>{try{const{page:s=1,limit:i=10,sort:o="_id",order:a="desc"}=n||{},c=(s-1)*i,f=a==="asc"?1:-1,p={[o]:f},[b,$]=await Promise.all([e.find().sort(p).skip(c).limit(i).exec(),e.countDocuments().exec()]),g=Math.ceil($/i);return{data:b,pagination:{total:$,totalPages:g,currentPage:s,limit:i,hasNextPage:s<g,hasPrevPage:s>1}}}catch(s){throw console.error(`Error in ${r}.getAll:`,s),new Error(`Failed to retrieve ${r} records: ${s.message}`)}},getById:async n=>{try{return _.isValidObjectId(n)?await e.findById(n).exec():null}catch(s){throw console.error(`Error in ${r}.getById:`,s),new Error(`Failed to retrieve ${r} by ID: ${s.message}`)}},create:async n=>{try{return await new e(n).save()}catch(s){throw console.error(`Error in ${r}.create:`,s),new Error(`Failed to create ${r}: ${s.message}`)}},createMany:async n=>{try{return await e.insertMany(n)}catch(s){throw console.error(`Error in ${r}.createMany:`,s),new Error(`Failed to create multiple ${r} records: ${s.message}`)}},update:async(n,s)=>{try{return _.isValidObjectId(n)?await e.findByIdAndUpdate(n,{$set:s},{new:!0,runValidators:!0}).exec():null}catch(i){throw console.error(`Error in ${r}.update:`,i),new Error(`Failed to update ${r}: ${i.message}`)}},delete:async n=>{try{return _.isValidObjectId(n)?await e.findByIdAndDelete(n).exec()!==null:!1}catch(s){throw console.error(`Error in ${r}.delete:`,s),new Error(`Failed to delete ${r}: ${s.message}`)}},find:async(n,s)=>{try{const{page:i=1,limit:o=10,sort:a="_id",order:c="desc"}=s||{},f=(i-1)*o,p=c==="asc"?1:-1,b={[a]:p},[$,g]=await Promise.all([e.find(n).sort(b).skip(f).limit(o).exec(),e.countDocuments(n).exec()]),F=Math.ceil(g/o);return{data:$,pagination:{total:g,totalPages:F,currentPage:i,limit:o,hasNextPage:i<F,hasPrevPage:i>1}}}catch(i){throw console.error(`Error in ${r}.find:`,i),new Error(`Failed to find ${r} records: ${i.message}`)}},count:async n=>{try{return await e.countDocuments(n||{}).exec()}catch(s){throw console.error(`Error in ${r}.count:`,s),new Error(`Failed to count ${r} records: ${s.message}`)}},findOne:async n=>{try{return await e.findOne(n).exec()}catch(s){throw console.error(`Error in ${r}.findOne:`,s),new Error(`Failed to find ${r} record: ${s.message}`)}}}}const Ve={String:{type:String},Number:{type:Number},Boolean:{type:Boolean},Date:{type:Date},ObjectId:{type:String},Required:r=>({...r,required:!0}),Unique:r=>({...r,unique:!0}),Ref:r=>({type:String,ref:r}),Enum:r=>({type:String,enum:r}),Default:(r,t)=>({...r,default:t}),Array:r=>({type:[r]})},Be=(r,{res:t})=>{console.error("API Error:",r);const e=r.status||r.statusCode||500,n=r.message||"Internal server error";t.status(e).json({success:!1,error:n,stack:E.env.NODE_ENV!=="production"?r.stack:void 0})};function qe(r,t={}){const e=v.Router(),{middleware:n=[],errorHandler:s=Be}=t;n.forEach(o=>e.use(o));const i=o=>async(a,c,f)=>{try{const p={req:a,res:c,next:f,params:a.params,query:a.query,body:a.body};return await o(p)}catch(p){const b={req:a,res:c,next:f,params:a.params,query:a.query,body:a.body};return s(p,b)}};return e.get("/",i(async({req:o,res:a})=>{const c=o.pagination||{page:1,limit:10},f=await r.getAll(c);a.json({success:!0,...f})})),e.get("/:id",i(async({params:o,res:a})=>{const c=await r.getById(o.id);if(!c){a.status(404).json({success:!1,error:"Item not found"});return}a.json({success:!0,data:c})})),e.post("/",i(async({body:o,res:a})=>{const c=await r.create(o);a.status(201).json({success:!0,data:c,message:"Item created successfully"})})),e.put("/:id",i(async({params:o,body:a,res:c})=>{const f=await r.update(o.id,a);if(!f){c.status(404).json({success:!1,error:"Item not found"});return}c.json({success:!0,data:f,message:"Item updated successfully"})})),e.delete("/:id",i(async({params:o,res:a})=>{if(!await r.delete(o.id)){a.status(404).json({success:!1,error:"Item not found"});return}a.json({success:!0,message:"Item deleted successfully"})})),e}function He(r,t={}){const e=v.Router(),{middleware:n=[],errorHandler:s=Be}=t;n.forEach(o=>e.use(o));const i=o=>async(a,c,f)=>{try{const p={req:a,res:c,next:f,params:a.params,query:a.query,body:a.body};return c.headersSent?void 0:await o(p)}catch(p){if(c.headersSent){console.error("Error occurred after response was sent:",p);return}const b={req:a,res:c,next:f,params:a.params,query:a.query,body:a.body};return s(p,b)}};return Object.entries(r).forEach(([o,a])=>{const{method:c,handler:f}=a;e[c](o,i(f))}),e}function Z(r,t,e,n,s){const i={success:r};return t!==void 0&&(i.data=t),e&&(i.message=e),n&&(i.error=n),s&&(i.meta=s),i}function O(r,t,e,n=200,s){r.status(n).json(Z(!0,t,e,void 0,s))}function P(r,t,e=400,n){const s=t instanceof Error?t.message:t;r.status(e).json(Z(!1,void 0,void 0,s,n))}function pe(r){const t=parseInt(r.query.page)||1,e=parseInt(r.query.limit)||10,n=r.query.sort||"createdAt",s=r.query.order==="asc"?"asc":"desc";return{page:t,limit:e,sort:n,order:s}}function ye(r,t,e){r.pagination=pe(r),e()}function We(r){return(t,e,n)=>{try{const{error:s,value:i}=r.validate(t.body);if(s){P(e,`Validation error: ${s.message}`,400);return}t.body=i,n()}catch{P(e,"Validation error",400)}}}function Ue(r={},t){const e=v.Router();return r.requireAuth&&t&&(e.use(t.authenticate),r.requiredRole&&e.use(t.hasRole(r.requiredRole))),r.rateLimit&&console.warn("Rate limiting is disabled: express-rate-limit dependency is not installed"),e}function D(r){return(t,e,n)=>{r(t,e,n).catch(n)}}function Ge(r){const t=v.Router();return t.get("/",ye,D(async(e,n)=>{const s=await r.getAll(e.pagination);O(n,s)})),t.get("/:id",D(async(e,n)=>{const s=await r.getById(e.params.id);if(!s)return P(n,"Item not found",404);O(n,s)})),t.post("/",D(async(e,n)=>{const s=await r.create(e.body);O(n,s,"Item created successfully",201)})),t.put("/:id",D(async(e,n)=>{const s=await r.update(e.params.id,e.body);if(!s)return P(n,"Item not found",404);O(n,s,"Item updated successfully")})),t.delete("/:id",D(async(e,n)=>{if(!await r.delete(e.params.id))return P(n,"Item not found",404);O(n,null,"Item deleted successfully")})),t}const it={jsx:L,jsxs:te,jsxDEV:ne,createElement:U,Fragment:re,Component:Ae,useState:de,useEffect:$e,useRef:Ie,useMemo:_e,useErrorBoundary:xe,render:z,hydrate:Ne,renderToString:N,prepareRender:B,finishRender:q,batchUpdates:J,createContext:Oe,useContext:Pe,createServer:De,createAuth:Fe,createModel:Le,FieldTypes:Ve,createModelRouter:qe,createCustomRouter:He,createApiRouter:Ue,sendSuccess:O,sendError:P,apiResponse:Z,getPaginationParams:pe,paginationMiddleware:ye,validateRequest:We,asyncHandler:D,createRestEndpoints:Ge,DatabaseConnector:fe};u.Component=Ae,u.DatabaseConnector=fe,u.FieldTypes=Ve,u.Fragment=re,u.apiResponse=Z,u.asyncHandler=D,u.batchUpdates=J,u.createApiRouter=Ue,u.createAuth=Fe,u.createContext=Oe,u.createCustomRouter=He,u.createElement=U,u.createModel=Le,u.createModelRouter=qe,u.createRestEndpoints=Ge,u.createServer=De,u.default=it,u.finishRender=q,u.getPaginationParams=pe,u.hydrate=Ne,u.jsx=L,u.jsxDEV=ne,u.jsxs=te,u.paginationMiddleware=ye,u.prepareRender=B,u.render=z,u.renderToString=N,u.sendError=P,u.sendSuccess=O,u.useContext=Pe,u.useEffect=$e,u.useErrorBoundary=xe,u.useMemo=_e,u.useRef=Ie,u.useState=de,u.validateRequest=We,Object.defineProperties(u,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
package/dist/hooks.js DELETED
@@ -1,164 +0,0 @@
1
- import { batchUpdates, isBatching } from './batch';
2
- let currentRender = 0;
3
- const states = new Map();
4
- const stateIndices = new Map();
5
- const effects = new Map();
6
- const memos = new Map();
7
- const refs = new Map();
8
- // Add at the top with other declarations
9
- let globalRenderCallback = null;
10
- let globalContainer = null;
11
- let currentElement = null;
12
- const isServer = typeof window === 'undefined';
13
- const serverStates = new Map();
14
- export function setRenderCallback(callback, element, container) {
15
- globalRenderCallback = callback;
16
- globalContainer = container;
17
- currentElement = element;
18
- }
19
- export function prepareRender() {
20
- currentRender++;
21
- stateIndices.set(currentRender, 0);
22
- return currentRender;
23
- }
24
- export function finishRender() {
25
- if (isServer) {
26
- serverStates.delete(currentRender);
27
- }
28
- currentRender = 0;
29
- }
30
- export function useState(initial) {
31
- if (!currentRender) {
32
- throw new Error('useState must be called within a render');
33
- }
34
- if (isServer) {
35
- // Server-side state handling
36
- if (!serverStates.has(currentRender)) {
37
- serverStates.set(currentRender, new Map());
38
- }
39
- const componentState = serverStates.get(currentRender);
40
- const index = stateIndices.get(currentRender) || 0;
41
- if (!componentState.has(index)) {
42
- componentState.set(index, initial);
43
- }
44
- const state = componentState.get(index);
45
- const setState = (newValue) => {
46
- // No-op for server-side
47
- };
48
- stateIndices.set(currentRender, index + 1);
49
- return [state, setState];
50
- }
51
- if (!states.has(currentRender)) {
52
- states.set(currentRender, []);
53
- }
54
- const componentStates = states.get(currentRender);
55
- const index = stateIndices.get(currentRender);
56
- if (index >= componentStates.length) {
57
- componentStates.push(initial);
58
- }
59
- const state = componentStates[index];
60
- const setState = (newValue) => {
61
- const nextValue = typeof newValue === 'function'
62
- ? newValue(componentStates[index])
63
- : newValue;
64
- if (componentStates[index] === nextValue)
65
- return; // Skip if value hasn't changed
66
- componentStates[index] = nextValue;
67
- if (isBatching) {
68
- batchUpdates(() => rerender(currentRender));
69
- }
70
- else {
71
- rerender(currentRender);
72
- }
73
- };
74
- stateIndices.set(currentRender, index + 1);
75
- return [state, setState];
76
- }
77
- export function useEffect(callback, deps) {
78
- if (!currentRender)
79
- throw new Error('useEffect must be called within a render');
80
- const effectIndex = stateIndices.get(currentRender);
81
- if (!effects.has(currentRender)) {
82
- effects.set(currentRender, []);
83
- }
84
- const componentEffects = effects.get(currentRender);
85
- const prevEffect = componentEffects[effectIndex];
86
- // Run effect if deps changed
87
- if (!prevEffect || !deps || !prevEffect.deps ||
88
- deps.some((dep, i) => dep !== prevEffect.deps[i])) {
89
- // Cleanup previous effect
90
- if (prevEffect?.cleanup) {
91
- prevEffect.cleanup();
92
- }
93
- // Schedule new effect
94
- queueMicrotask(() => {
95
- const cleanup = callback() || undefined;
96
- componentEffects[effectIndex] = { cleanup: cleanup, deps };
97
- });
98
- }
99
- stateIndices.set(currentRender, effectIndex + 1);
100
- }
101
- export function useMemo(factory, deps) {
102
- if (!currentRender)
103
- throw new Error('useMemo must be called within a render');
104
- const memoIndex = stateIndices.get(currentRender);
105
- if (!memos.has(currentRender)) {
106
- memos.set(currentRender, []);
107
- }
108
- const componentMemos = memos.get(currentRender);
109
- const prevMemo = componentMemos[memoIndex];
110
- if (!prevMemo || (deps && deps.some((dep, i) => !Object.is(dep, prevMemo.deps[i])))) {
111
- const value = factory();
112
- componentMemos[memoIndex] = { value, deps };
113
- stateIndices.set(currentRender, memoIndex + 1);
114
- return value;
115
- }
116
- stateIndices.set(currentRender, memoIndex + 1);
117
- return prevMemo.value;
118
- }
119
- export function useRef(initial) {
120
- if (!currentRender)
121
- throw new Error('useRef must be called within a render');
122
- const refIndex = stateIndices.get(currentRender);
123
- if (!refs.has(currentRender)) {
124
- refs.set(currentRender, []);
125
- }
126
- const componentRefs = refs.get(currentRender);
127
- if (refIndex >= componentRefs.length) {
128
- // Initialize with an object that has a current property
129
- const ref = { current: initial };
130
- componentRefs.push(ref);
131
- stateIndices.set(currentRender, refIndex + 1);
132
- return ref;
133
- }
134
- const ref = componentRefs[refIndex];
135
- stateIndices.set(currentRender, refIndex + 1);
136
- return ref;
137
- }
138
- // Add a map to track component DOM nodes
139
- const componentNodes = new Map();
140
- async function rerender(rendererId) {
141
- try {
142
- // Clean up effects
143
- const componentEffects = effects.get(rendererId);
144
- if (componentEffects) {
145
- componentEffects.forEach(effect => {
146
- if (effect.cleanup)
147
- effect.cleanup();
148
- });
149
- effects.set(rendererId, []);
150
- }
151
- if (globalRenderCallback && globalContainer && currentElement) {
152
- await globalRenderCallback(currentElement, globalContainer);
153
- }
154
- }
155
- catch (error) {
156
- console.error('Error during rerender:', error);
157
- }
158
- }
159
- // Add new hook for error boundaries
160
- export function useErrorBoundary() {
161
- const [error, setError] = useState(null);
162
- return [error, () => setError(null)];
163
- }
164
- // Remove withHooks export
@@ -1,11 +0,0 @@
1
- import { jsx, jsxs, createElement, Fragment, jsxDEV } from './jsx-runtime';
2
- export { jsx, jsxs, jsxDEV, // Add export for jsxDEV
3
- createElement, Fragment };
4
- declare const _default: {
5
- jsx: typeof jsx;
6
- jsxs: typeof jsxs;
7
- jsxDEV: typeof jsx;
8
- createElement: typeof createElement;
9
- Fragment: symbol;
10
- };
11
- export default _default;
@@ -1,19 +0,0 @@
1
- import { jsx, jsxs, createElement, Fragment, jsxDEV } from './jsx-runtime';
2
- export { jsx, jsxs, jsxDEV, // Add export for jsxDEV
3
- createElement, Fragment };
4
- // For global access in browsers
5
- if (typeof window !== 'undefined') {
6
- // TypeScript safe way to add properties to window
7
- window.jsx = jsx;
8
- window.jsxs = jsxs;
9
- window.jsxDEV = jsxDEV; // Add jsxDEV
10
- window.Fragment = Fragment;
11
- }
12
- // Default export for module usage
13
- export default {
14
- jsx,
15
- jsxs,
16
- jsxDEV,
17
- createElement,
18
- Fragment
19
- };
@@ -1 +0,0 @@
1
- "use strict";
@@ -1,95 +0,0 @@
1
- // Create a safe global object reference that works in both browser and Node
2
- const globalObj = typeof window !== 'undefined' ? window :
3
- typeof global !== 'undefined' ? global : {};
4
- export function jsx(type, props, key) {
5
- return {
6
- type,
7
- props: props || {},
8
- key
9
- };
10
- }
11
- // Use the jsx function for jsxs as well
12
- export function jsxs(type, props, key) {
13
- return jsx(type, props, key);
14
- }
15
- export function createElement(vnode) {
16
- if (typeof vnode === 'string' || typeof vnode === 'number') {
17
- return document.createTextNode(String(vnode));
18
- }
19
- if (typeof vnode.type === 'function') {
20
- const result = vnode.type(vnode.props);
21
- return createElement(result);
22
- }
23
- const element = document.createElement(vnode.type);
24
- Object.entries(vnode.props || {}).forEach(([name, value]) => {
25
- if (name === 'children') {
26
- const children = Array.isArray(value) ? value : [value];
27
- children.forEach((child) => {
28
- if (child != null) {
29
- const childElement = createElement(child);
30
- // Generate stats for testing
31
- if (process.env.NODE_ENV === 'test' && typeof window !== 'undefined') {
32
- // Create stats tracking
33
- if (!globalObj.__renderStats) {
34
- globalObj.__renderStats = {
35
- elementsCreated: 0,
36
- textNodesCreated: 0,
37
- eventsAttached: 0,
38
- renderTime: 0
39
- };
40
- // Write stats to file when tests complete
41
- if (typeof afterAll === 'function') {
42
- afterAll(() => {
43
- try {
44
- const fs = require('fs');
45
- const path = require('path');
46
- const statsPath = path.resolve(process.cwd(), 'jsx-runtime-stats.json');
47
- fs.writeFileSync(statsPath, JSON.stringify(globalObj.__renderStats, null, 2));
48
- console.log(`JSX runtime stats written to ${statsPath}`);
49
- }
50
- catch (error) {
51
- console.error('Failed to write stats file:', error);
52
- }
53
- });
54
- }
55
- }
56
- // Increment stats based on element type
57
- if (childElement instanceof Text) {
58
- globalObj.__renderStats.textNodesCreated++;
59
- }
60
- else {
61
- globalObj.__renderStats.elementsCreated++;
62
- }
63
- }
64
- element.appendChild(childElement);
65
- }
66
- });
67
- }
68
- else if (name.startsWith('on')) {
69
- const eventName = name.toLowerCase().substring(2);
70
- element.addEventListener(eventName, value);
71
- // Track event attachment in stats
72
- if (process.env.NODE_ENV === 'test' && typeof window !== 'undefined' && globalObj.__renderStats) {
73
- globalObj.__renderStats.eventsAttached++;
74
- }
75
- }
76
- else if (name === 'className') {
77
- // Handle className specially by setting it as the class attribute
78
- element.setAttribute('class', value);
79
- }
80
- else if (name === 'style' && typeof value === 'object') {
81
- // Handle style objects by merging them into element.style
82
- Object.entries(value).forEach(([styleProp, styleValue]) => {
83
- element.style[styleProp] = String(styleValue);
84
- });
85
- }
86
- else {
87
- element.setAttribute(name, value);
88
- }
89
- });
90
- return element;
91
- }
92
- export const Fragment = Symbol('Fragment');
93
- // Add named exports for React JSX compatibility
94
- export const jsxDEV = jsx;
95
- // Don't export jsxs again - it's already exported above
@@ -1,192 +0,0 @@
1
- function jsx(type, props, p0) {
2
- console.log('JSX Transform:', { type, props });
3
- const processedProps = { ...props };
4
- // Handle children properly
5
- if (arguments.length > 2) {
6
- processedProps.children = Array.prototype.slice.call(arguments, 2);
7
- }
8
- return { type, props: processedProps };
9
- }
10
- const Fragment = ({ children }) => children;
11
- // Check if we're in a browser environment
12
- const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';
13
- async function createElement(vnode) {
14
- console.log('Creating element from:', vnode);
15
- // Create mock DOM elements when in Node environment
16
- if (!isBrowser) {
17
- // Return mock node objects in Node.js environment
18
- if (vnode == null) {
19
- return { nodeType: 3, textContent: '' };
20
- }
21
- if (typeof vnode === 'boolean') {
22
- return { nodeType: 3, textContent: '' };
23
- }
24
- if (typeof vnode === 'number' || typeof vnode === 'string') {
25
- return { nodeType: 3, textContent: String(vnode) };
26
- }
27
- // Handle arrays
28
- if (Array.isArray(vnode)) {
29
- const fragment = { nodeType: 11, childNodes: [] };
30
- for (const child of vnode) {
31
- const node = await createElement(child);
32
- fragment.childNodes.push(node);
33
- }
34
- return fragment;
35
- }
36
- // Handle VNode
37
- if ('type' in vnode && vnode.props !== undefined) {
38
- const { type, props } = vnode;
39
- // Handle function components
40
- if (typeof type === 'function') {
41
- try {
42
- const result = await type(props || {});
43
- const node = await createElement(result);
44
- return node;
45
- }
46
- catch (error) {
47
- console.error('Error rendering component:', error);
48
- return { nodeType: 3, textContent: '' };
49
- }
50
- }
51
- // Mock element creation
52
- const element = {
53
- nodeType: 1,
54
- tagName: type,
55
- attributes: {},
56
- style: {},
57
- childNodes: [],
58
- setAttribute: function (key, value) {
59
- this.attributes[key] = value;
60
- },
61
- appendChild: function (child) {
62
- this.childNodes.push(child);
63
- }
64
- };
65
- // Handle props
66
- for (const [key, value] of Object.entries(props || {})) {
67
- if (key === 'children')
68
- continue;
69
- if (key.startsWith('on') && typeof value === 'function') {
70
- // Mock event handlers
71
- const eventName = key.toLowerCase().slice(2);
72
- if (!element.__events) {
73
- element.__events = {};
74
- }
75
- element.__events[eventName] = value;
76
- }
77
- else if (key === 'style' && typeof value === 'object') {
78
- Object.assign(element.style, value);
79
- }
80
- else if (key === 'className') {
81
- element.setAttribute('class', String(value));
82
- }
83
- else if (key !== 'key' && key !== 'ref') {
84
- element.setAttribute(key, String(value));
85
- }
86
- }
87
- // Handle children
88
- const children = props?.children;
89
- if (children != null) {
90
- const childArray = Array.isArray(children) ? children.flat() : [children];
91
- for (const child of childArray) {
92
- const childNode = await createElement(child);
93
- element.appendChild(childNode);
94
- }
95
- }
96
- return element;
97
- }
98
- // Handle other objects by converting to string
99
- return { nodeType: 3, textContent: String(vnode) };
100
- }
101
- // Browser environment implementation
102
- if (vnode == null) {
103
- return document.createTextNode('');
104
- }
105
- if (typeof vnode === 'boolean') {
106
- return document.createTextNode('');
107
- }
108
- if (typeof vnode === 'number' || typeof vnode === 'string') {
109
- return document.createTextNode(String(vnode));
110
- }
111
- // Handle arrays
112
- if (Array.isArray(vnode)) {
113
- const fragment = document.createDocumentFragment();
114
- for (const child of vnode) {
115
- const node = await createElement(child);
116
- fragment.appendChild(node);
117
- }
118
- return fragment;
119
- }
120
- // Handle VNode
121
- if ('type' in vnode && vnode.props !== undefined) {
122
- const { type, props } = vnode;
123
- // Handle function components
124
- if (typeof type === 'function') {
125
- try {
126
- const result = await type(props || {});
127
- const node = await createElement(result);
128
- if (node instanceof Element) {
129
- node.setAttribute('data-component-id', type.name || type.toString());
130
- }
131
- return node;
132
- }
133
- catch (error) {
134
- console.error('Error rendering component:', error);
135
- return document.createTextNode('');
136
- }
137
- }
138
- // Create DOM element
139
- const element = document.createElement(type);
140
- // Handle props
141
- for (const [key, value] of Object.entries(props || {})) {
142
- if (key === 'children')
143
- continue;
144
- if (key.startsWith('on') && typeof value === 'function') {
145
- const eventName = key.toLowerCase().slice(2);
146
- // Remove existing event listener if any
147
- const existingHandler = element.__events?.[eventName];
148
- if (existingHandler) {
149
- element.removeEventListener(eventName, existingHandler);
150
- }
151
- // Add new event listener
152
- element.addEventListener(eventName, value);
153
- if (!element.__events) {
154
- element.__events = {};
155
- }
156
- element.__events[eventName] = value;
157
- }
158
- else if (key === 'style' && typeof value === 'object') {
159
- Object.assign(element.style, value);
160
- }
161
- else if (key === 'className') {
162
- element.setAttribute('class', String(value));
163
- }
164
- else if (key !== 'key' && key !== 'ref') {
165
- element.setAttribute(key, String(value));
166
- }
167
- }
168
- // Handle children
169
- const children = props?.children;
170
- if (children != null) {
171
- const childArray = Array.isArray(children) ? children.flat() : [children];
172
- for (const child of childArray) {
173
- const childNode = await createElement(child);
174
- element.appendChild(childNode);
175
- }
176
- }
177
- return element;
178
- }
179
- // Handle other objects by converting to string
180
- return document.createTextNode(String(vnode));
181
- }
182
- // Export named functions and aliases without duplicates
183
- export { jsx, jsx as jsxs, jsx as jsxDEV, Fragment, createElement };
184
- // Named exports object
185
- const jsxRuntime = {
186
- jsx,
187
- jsxs: jsx,
188
- jsxDEV: jsx,
189
- Fragment,
190
- createElement
191
- };
192
- export default jsxRuntime;