frontend-hamroun 1.2.72 → 1.2.74
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/index.d.ts +1 -14
- package/dist/index.js +3 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/templates/go-wasm-app/build-wasm.js +84 -84
- package/templates/go-wasm-app/package-lock.json +112 -2839
- package/templates/go-wasm-app/package.json +5 -6
- package/templates/go-wasm-app/public/index.html +53 -49
- package/templates/go-wasm-app/server.js +188 -0
- package/dist/batch.d.ts +0 -3
- package/dist/component.d.ts +0 -14
- package/dist/components/Counter.d.ts +0 -0
- package/dist/context.d.ts +0 -13
- package/dist/hooks.d.ts +0 -8
- package/dist/index.client.d.ts +0 -12
- package/dist/jsx-runtime/jsx-dev-runtime.d.ts +0 -0
- package/dist/jsx-runtime/jsx-runtime.d.ts +0 -4
- package/dist/jsx-runtime.d.ts +0 -20
- package/dist/renderer.d.ts +0 -2
- package/dist/server-renderer.d.ts +0 -5
- package/dist/server-types.d.ts +0 -42
- package/dist/types.d.ts +0 -18
- package/dist/vdom.d.ts +0 -8
- package/dist/wasm.d.ts +0 -36
package/dist/index.d.ts
CHANGED
@@ -1,14 +1 @@
|
|
1
|
-
export {
|
2
|
-
export { createContext, useContext } from './context';
|
3
|
-
export { batchUpdates } from './batch';
|
4
|
-
export { jsx, jsxs, Fragment } from './jsx-runtime';
|
5
|
-
export { render, hydrate } from './renderer';
|
6
|
-
export { renderToString } from './server-renderer';
|
7
|
-
export type { Context } from './context';
|
8
|
-
export type { VNode } from './types';
|
9
|
-
export type { Server, ServerConfig, User, DbConfig, MiddlewareFunction } from './server-types';
|
10
|
-
export { loadGoWasm, createTypedWasmFunction, goValues } from './wasm';
|
11
|
-
export type { GoWasmInstance, GoWasmOptions } from './wasm';
|
12
|
-
export declare const server: {
|
13
|
-
getServer(): Promise<any>;
|
14
|
-
};
|
1
|
+
export {}
|
package/dist/index.js
CHANGED
@@ -168,21 +168,13 @@
|
|
168
168
|
}
|
169
169
|
function createContext(defaultValue) {
|
170
170
|
const context = {
|
171
|
-
|
172
|
-
|
173
|
-
},
|
174
|
-
Consumer: ({ children }) => {
|
175
|
-
return children(defaultValue);
|
176
|
-
},
|
177
|
-
_id: Symbol(),
|
178
|
-
useSelector: (selector) => {
|
179
|
-
return selector(defaultValue);
|
180
|
-
}
|
171
|
+
currentValue: defaultValue,
|
172
|
+
providers: /* @__PURE__ */ new Set()
|
181
173
|
};
|
182
174
|
return context;
|
183
175
|
}
|
184
176
|
function useContext(context) {
|
185
|
-
return context;
|
177
|
+
return context.currentValue;
|
186
178
|
}
|
187
179
|
function jsx(type, props) {
|
188
180
|
console.log("JSX Transform:", { type, props });
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/batch.ts","../src/hooks.ts","../src/context.ts","../src/jsx-runtime.ts","../src/renderer.ts","../src/server-renderer.ts","../src/index.client.ts"],"sourcesContent":["export let isBatching = false;\r\nconst queue: Function[] = [];\r\n\r\nexport function batchUpdates(fn: Function) {\r\n if (isBatching) {\r\n queue.push(fn);\r\n return;\r\n }\r\n\r\n isBatching = true;\r\n try {\r\n fn();\r\n while (queue.length > 0) {\r\n const nextFn = queue.shift();\r\n nextFn?.();\r\n }\r\n } finally {\r\n isBatching = false;\r\n }\r\n}\r\n\r\nexport function getIsBatching() {\r\n return isBatching;\r\n}\r\n","import { createElement } from './jsx-runtime';\r\nimport { batchUpdates, isBatching } from './batch';\r\nimport { diff } from './vdom';\r\n\r\nlet currentRender: number = 0;\r\nconst states = new Map<number, any[]>();\r\nconst stateIndices = new Map<number, number>();\r\nconst effects = new Map<number, Effect[]>();\r\nconst memos = new Map<number, { value: any; deps: any[] }[]>();\r\nconst refs = new Map<number, any[]>();\r\n\r\ninterface Effect {\r\n cleanup?: () => void;\r\n deps?: any[];\r\n}\r\n\r\n// Add at the top with other declarations\r\nlet globalRenderCallback: ((element: any, container: HTMLElement) => void) | null = null;\r\nlet globalContainer: HTMLElement | null = null;\r\nlet currentElement: any = null;\r\n\r\nconst isServer = typeof window === 'undefined';\r\nconst serverStates = new Map<number, any>();\r\n\r\nexport function setRenderCallback(\r\n callback: (element: any, container: HTMLElement) => void,\r\n element: any,\r\n container: HTMLElement\r\n) {\r\n globalRenderCallback = callback;\r\n globalContainer = container;\r\n currentElement = element;\r\n}\r\n\r\nexport function prepareRender() {\r\n currentRender++;\r\n stateIndices.set(currentRender, 0);\r\n return currentRender;\r\n}\r\n\r\nexport function finishRender() {\r\n if (isServer) {\r\n serverStates.delete(currentRender);\r\n }\r\n currentRender = 0;\r\n}\r\n\r\nexport function useState<T>(initial: T): [T, (value: T | ((prev: T) => T)) => void] {\r\n if (!currentRender) {\r\n throw new Error('useState must be called within a render');\r\n }\r\n\r\n if (isServer) {\r\n // Server-side state handling\r\n if (!serverStates.has(currentRender)) {\r\n serverStates.set(currentRender, new Map());\r\n }\r\n const componentState = serverStates.get(currentRender)!;\r\n const index = stateIndices.get(currentRender) || 0;\r\n \r\n if (!componentState.has(index)) {\r\n componentState.set(index, initial);\r\n }\r\n\r\n const state = componentState.get(index);\r\n const setState = (newValue: T | ((prev: T) => T)) => {\r\n // No-op for server-side\r\n };\r\n\r\n stateIndices.set(currentRender, index + 1);\r\n return [state, setState];\r\n }\r\n\r\n if (!states.has(currentRender)) {\r\n states.set(currentRender, []);\r\n }\r\n\r\n const componentStates = states.get(currentRender)!;\r\n const index = stateIndices.get(currentRender)!;\r\n \r\n if (index >= componentStates.length) {\r\n componentStates.push(initial);\r\n }\r\n\r\n const state = componentStates[index];\r\n const setState = (newValue: T | ((prev: T) => T)) => {\r\n const nextValue = typeof newValue === 'function' \r\n ? (newValue as Function)(componentStates[index])\r\n : newValue;\r\n\r\n if (componentStates[index] === nextValue) return; // Skip if value hasn't changed\r\n \r\n componentStates[index] = nextValue;\r\n \r\n if (isBatching) {\r\n batchUpdates(() => rerender(currentRender));\r\n } else {\r\n rerender(currentRender);\r\n }\r\n };\r\n\r\n stateIndices.set(currentRender, index + 1);\r\n return [state, setState];\r\n}\r\n\r\nexport function useEffect(callback: () => (() => void) | void, deps?: any[]) {\r\n if (!currentRender) throw new Error('useEffect must be called within a render');\r\n \r\n const effectIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!effects.has(currentRender)) {\r\n effects.set(currentRender, []);\r\n }\r\n\r\n const componentEffects = effects.get(currentRender)!;\r\n const prevEffect = componentEffects[effectIndex];\r\n \r\n // Run effect if deps changed\r\n if (!prevEffect || !deps || !prevEffect.deps || \r\n deps.some((dep, i) => dep !== prevEffect.deps![i])) {\r\n \r\n // Cleanup previous effect\r\n if (prevEffect?.cleanup) {\r\n prevEffect.cleanup();\r\n }\r\n\r\n // Schedule new effect\r\n queueMicrotask(() => {\r\n const cleanup = callback() || undefined;\r\n componentEffects[effectIndex] = { cleanup: cleanup, deps };\r\n });\r\n }\r\n \r\n stateIndices.set(currentRender, effectIndex + 1);\r\n}\r\n\r\nexport function useMemo<T>(factory: () => T, deps: any[]): T {\r\n if (!currentRender) throw new Error('useMemo must be called within a render');\r\n \r\n const memoIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!memos.has(currentRender)) {\r\n memos.set(currentRender, []);\r\n }\r\n\r\n const componentMemos = memos.get(currentRender)!;\r\n const prevMemo = componentMemos[memoIndex];\r\n \r\n if (!prevMemo || (deps && deps.some((dep, i) => !Object.is(dep, prevMemo.deps[i])))) {\r\n const value = factory();\r\n componentMemos[memoIndex] = { value, deps };\r\n stateIndices.set(currentRender, memoIndex + 1);\r\n return value;\r\n }\r\n\r\n stateIndices.set(currentRender, memoIndex + 1);\r\n return prevMemo.value;\r\n}\r\n\r\nexport function useRef<T>(initial: T) {\r\n if (!currentRender) throw new Error('useRef must be called within a render');\r\n \r\n const refIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!refs.has(currentRender)) {\r\n refs.set(currentRender, []);\r\n }\r\n\r\n const componentRefs = refs.get(currentRender)!;\r\n if (refIndex >= componentRefs.length) {\r\n // Initialize with an object that has a current property\r\n const ref = { current: initial };\r\n componentRefs.push(ref);\r\n stateIndices.set(currentRender, refIndex + 1);\r\n return ref;\r\n }\r\n\r\n const ref = componentRefs[refIndex];\r\n stateIndices.set(currentRender, refIndex + 1);\r\n return ref;\r\n}\r\n\r\n// Add a map to track component DOM nodes\r\nconst componentNodes = new Map<Function, Node>();\r\n\r\nasync function rerender(rendererId: number) {\r\n try {\r\n // Clean up effects\r\n const componentEffects = effects.get(rendererId);\r\n if (componentEffects) {\r\n componentEffects.forEach(effect => {\r\n if (effect.cleanup) effect.cleanup();\r\n });\r\n effects.set(rendererId, []);\r\n }\r\n\r\n if (globalRenderCallback && globalContainer && currentElement) {\r\n await globalRenderCallback(currentElement, globalContainer);\r\n }\r\n } catch (error) {\r\n console.error('Error during rerender:', error);\r\n }\r\n}\r\n\r\n// Add new hook for error boundaries\r\nexport function useErrorBoundary(): [Error | null, () => void] {\r\n const [error, setError] = useState<Error | null>(null);\r\n return [error, () => setError(null)];\r\n}\r\n\r\n// Remove withHooks export\r\n","\r\n\r\nconst contexts = new Map<symbol, any>();\r\nlet currentRender: Function | null = null;\r\n\r\nexport interface Context<T> {\r\n Provider: (props: { value: T; children?: any }) => any;\r\n Consumer: (props: { children: (value: T) => any }) => any;\r\n _id: symbol;\r\n useSelector: <S>(selector: (state: T) => S) => S;\r\n}\r\n\r\nexport function createContext<T>(defaultValue: T): Context<T> {\r\n const context = {\r\n Provider: ({ value, children }: { value: T, children?: any }) => {\r\n return children;\r\n },\r\n Consumer: ({ children }: { children: (value: T) => any }) => {\r\n return children(defaultValue);\r\n },\r\n _id: Symbol(),\r\n useSelector: <S>(selector: (state: T) => S) => {\r\n return selector(defaultValue);\r\n }\r\n };\r\n\r\n return context;\r\n}\r\n\r\nexport function useContext<T>(context: any): T {\r\n return context;\r\n}\r\n","import type { Component } from './component';\r\n\r\ninterface VNode {\r\n type: string | Function;\r\n props: Record<string, any>;\r\n}\r\n\r\nfunction jsx(type: string | Function, props: any): VNode {\r\n console.log('JSX Transform:', { type, props });\r\n const processedProps = { ...props };\r\n \r\n // Handle children properly\r\n if (arguments.length > 2) {\r\n processedProps.children = Array.prototype.slice.call(arguments, 2);\r\n }\r\n \r\n return { type, props: processedProps };\r\n}\r\n\r\nconst Fragment = ({ children }: { children: any }) => children;\r\n\r\nasync function createElement(vnode: VNode | any): Promise<Node> {\r\n console.log('Creating element from:', vnode);\r\n\r\n // Handle primitives and null\r\n if (vnode == null) {\r\n return document.createTextNode('');\r\n }\r\n \r\n if (typeof vnode === 'boolean') {\r\n return document.createTextNode('');\r\n }\r\n\r\n if (typeof vnode === 'number' || typeof vnode === 'string') {\r\n return document.createTextNode(String(vnode));\r\n }\r\n\r\n // Handle arrays\r\n if (Array.isArray(vnode)) {\r\n const fragment = document.createDocumentFragment();\r\n for (const child of vnode) {\r\n const node = await createElement(child);\r\n fragment.appendChild(node);\r\n }\r\n return fragment;\r\n }\r\n\r\n // Handle VNode\r\n if ('type' in vnode && vnode.props !== undefined) {\r\n const { type, props } = vnode;\r\n \r\n // Handle function components\r\n if (typeof type === 'function') {\r\n try {\r\n const result = await type(props || {});\r\n const node = await createElement(result);\r\n if (node instanceof Element) {\r\n node.setAttribute('data-component-id', type.name || type.toString());\r\n }\r\n return node;\r\n } catch (error) {\r\n console.error('Error rendering component:', error);\r\n return document.createTextNode('');\r\n }\r\n }\r\n\r\n // Create DOM element\r\n const element = document.createElement(type as string);\r\n \r\n // Handle props\r\n for (const [key, value] of Object.entries(props || {})) {\r\n if (key === 'children') continue;\r\n if (key.startsWith('on') && typeof value === 'function') {\r\n const eventName = key.toLowerCase().slice(2);\r\n // Remove existing event listener if any\r\n const existingHandler = (element as any).__events?.[eventName];\r\n if (existingHandler) {\r\n element.removeEventListener(eventName, existingHandler);\r\n }\r\n \r\n // Add new event listener\r\n element.addEventListener(eventName, value as EventListener);\r\n if (!(element as any).__events) {\r\n (element as any).__events = {};\r\n }\r\n (element as any).__events[eventName] = value;\r\n } else if (key === 'style' && typeof value === 'object') {\r\n Object.assign(element.style, value);\r\n } else if (key === 'className') {\r\n element.setAttribute('class', String(value));\r\n } else if (key !== 'key' && key !== 'ref') {\r\n element.setAttribute(key, String(value));\r\n }\r\n }\r\n\r\n // Handle children\r\n const children = props?.children;\r\n if (children != null) {\r\n const childArray = Array.isArray(children) ? children.flat() : [children];\r\n for (const child of childArray) {\r\n const childNode = await createElement(child);\r\n element.appendChild(childNode);\r\n }\r\n }\r\n\r\n return element;\r\n }\r\n\r\n // Handle other objects by converting to string\r\n return document.createTextNode(String(vnode));\r\n}\r\n\r\n// Export named functions and aliases without duplicates\r\nexport {\r\n jsx,\r\n jsx as jsxs,\r\n jsx as jsxDEV,\r\n Fragment,\r\n createElement\r\n};\r\n\r\n// Named exports object\r\nconst jsxRuntime = {\r\n jsx,\r\n jsxs: jsx,\r\n jsxDEV: jsx,\r\n Fragment,\r\n createElement\r\n};\r\n\r\nexport default jsxRuntime;\r\n","import { createElement } from './jsx-runtime';\r\nimport { prepareRender, finishRender, setRenderCallback } from './hooks';\r\nimport { batchUpdates } from './batch';\r\n\r\nlet isHydrating = false;\r\n\r\nexport async function hydrate(element: any, container: HTMLElement) {\r\n isHydrating = true;\r\n try {\r\n await render(element, container);\r\n } finally {\r\n isHydrating = false;\r\n }\r\n}\r\n\r\nexport async function render(element: any, container: HTMLElement) {\r\n console.log('Rendering to:', container.id);\r\n \r\n batchUpdates(async () => {\r\n const rendererId = prepareRender();\r\n try {\r\n setRenderCallback(render, element, container);\r\n const domNode = await createElement(element);\r\n \r\n if (!isHydrating) {\r\n container.innerHTML = '';\r\n }\r\n container.appendChild(domNode);\r\n \r\n } finally {\r\n finishRender();\r\n }\r\n });\r\n}\r\n","import { VNode, Component } from './types';\r\nimport { prepareRender, finishRender } from './hooks';\r\n\r\n/**\r\n * Renders a virtual DOM tree to an HTML string\r\n */\r\nexport function renderToString(vnode: VNode): string {\r\n // Reset hook state for this render\r\n prepareRender();\r\n \r\n // Render the tree to HTML\r\n const html = renderNodeToString(vnode);\r\n \r\n // Clean up after rendering\r\n finishRender();\r\n \r\n return html;\r\n}\r\n\r\n/**\r\n * Internal function to convert a virtual node to an HTML string\r\n */\r\nfunction renderNodeToString(vnode: VNode | string | number | boolean | null | undefined): string {\r\n // Handle primitive values\r\n if (vnode === null || vnode === undefined) return '';\r\n if (typeof vnode === 'boolean') return '';\r\n if (typeof vnode === 'number' || typeof vnode === 'string') return escapeHtml(String(vnode));\r\n \r\n // Handle function components\r\n if (typeof vnode.type === 'function') {\r\n const Component = vnode.type as Component;\r\n const renderedNode = Component(vnode.props || {});\r\n return renderNodeToString(renderedNode);\r\n }\r\n \r\n // Handle intrinsic elements (regular HTML tags)\r\n if (typeof vnode.type === 'string') {\r\n const tag = vnode.type;\r\n let attrs = '';\r\n let children = '';\r\n \r\n // Convert props to HTML attributes\r\n if (vnode.props) {\r\n for (const [key, value] of Object.entries(vnode.props)) {\r\n // Skip children prop as we handle it separately\r\n if (key === 'children') continue;\r\n \r\n // Skip event handlers (they start with 'on')\r\n if (key.startsWith('on')) continue;\r\n \r\n // Handle the className prop specially\r\n if (key === 'className') {\r\n attrs += ` class=\"${escapeHtml(value as string)}\"`;\r\n continue;\r\n }\r\n \r\n // Handle other attributes\r\n if (typeof value === 'string' || typeof value === 'number') {\r\n attrs += ` ${key}=\"${escapeHtml(String(value))}\"`;\r\n } else if (value === true) {\r\n // Boolean attributes\r\n attrs += ` ${key}`;\r\n }\r\n }\r\n }\r\n \r\n // Process children\r\n const childrenArray = (vnode.props?.children) \r\n ? Array.isArray(vnode.props.children) \r\n ? vnode.props.children \r\n : [vnode.props.children]\r\n : [];\r\n \r\n for (const child of childrenArray) {\r\n children += renderNodeToString(child);\r\n }\r\n \r\n // Self-closing tags\r\n const selfClosing = [\r\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\r\n 'link', 'meta', 'param', 'source', 'track', 'wbr'\r\n ];\r\n \r\n if (selfClosing.includes(tag)) {\r\n return `<${tag}${attrs}/>`;\r\n }\r\n \r\n // Regular tags with closing\r\n return `<${tag}${attrs}>${children}</${tag}>`;\r\n }\r\n \r\n // Handle fragments\r\n if (vnode.type === Symbol.for('react.fragment')) {\r\n let fragmentOutput = '';\r\n const children = Array.isArray(vnode.props?.children)\r\n ? vnode.props.children\r\n : vnode.props?.children ? [vnode.props.children] : [];\r\n \r\n for (const child of children) {\r\n fragmentOutput += renderNodeToString(child);\r\n }\r\n \r\n return fragmentOutput;\r\n }\r\n \r\n // Fallback for unknown node types\r\n console.warn('Unknown vnode type:', vnode.type);\r\n return '';\r\n}\r\n\r\n/**\r\n * Escape HTML special characters to prevent XSS\r\n */\r\nfunction escapeHtml(text: string): string {\r\n return text\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>')\r\n .replace(/\"/g, '"')\r\n .replace(/'/g, ''');\r\n}\r\n","import { createElement } from './jsx-runtime';\r\nimport { prepareRender, finishRender, setRenderCallback } from './hooks';\r\n\r\nexport { \r\n useState, \r\n useEffect, \r\n useMemo, \r\n useRef,\r\n useErrorBoundary \r\n} from './hooks';\r\n\r\nexport { createContext, useContext } from './context';\r\nexport { batchUpdates } from './batch';\r\nexport { jsx, jsxs, Fragment } from './jsx-runtime';\r\nexport { render, hydrate } from './renderer';\r\nexport { renderToString } from './server-renderer';\r\n\r\n// Re-export types for client-side usage\r\nexport type { Context } from './context';\r\nexport type { VNode } from './types';\r\n\r\n// Export server types for type checking\r\nexport type {\r\n Server,\r\n ServerConfig,\r\n User,\r\n DbConfig,\r\n MiddlewareFunction\r\n} from './server-types';\r\n\r\n// Provide placeholder server functionality\r\nexport const server = {\r\n async getServer() {\r\n throw new Error('Server module can only be used in Node.js environment');\r\n }\r\n};\r\n\r\nlet isHydrating = false;\r\n"],"names":["index","state","setState","ref","Component"],"mappings":";;;;AAAO,MAAI,aAAa;AACxB,QAAM,QAAoB,CAAA;AAEnB,WAAS,aAAa,IAAc;AACzC,QAAI,YAAY;AACd,YAAM,KAAK,EAAE;AACb;AAAA,IACF;AAEa,iBAAA;AACT,QAAA;AACC;AACI,aAAA,MAAM,SAAS,GAAG;AACjB,cAAA,SAAS,MAAM;AACZ;AAAA,MACX;AAAA,IAAA,UACA;AACa,mBAAA;AAAA,IACf;AAAA,EACF;ACfA,MAAI,gBAAwB;AAC5B,QAAM,6BAAa;AACnB,QAAM,mCAAmB;AACzB,QAAM,8BAAc;AACpB,QAAM,4BAAY;AAClB,QAAM,2BAAW;AAQjB,MAAI,uBAAgF;AACpF,MAAI,kBAAsC;AAC1C,MAAI,iBAAsB;AAE1B,QAAM,WAAW,OAAO,WAAW;AACnC,QAAM,mCAAmB;AAET,WAAA,kBACd,UACA,SACA,WACA;AACuB,2BAAA;AACL,sBAAA;AACD,qBAAA;AAAA,EACnB;AAEO,WAAS,gBAAgB;AAC9B;AACa,iBAAA,IAAI,eAAe,CAAC;AAC1B,WAAA;AAAA,EACT;AAEO,WAAS,eAAe;AAC7B,QAAI,UAAU;AACZ,mBAAa,OAAO,aAAa;AAAA,IACnC;AACgB,oBAAA;AAAA,EAClB;AAEO,WAAS,SAAY,SAAwD;AAClF,QAAI,CAAC,eAAe;AACZ,YAAA,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AAEA,QAAI,UAAU;AAEZ,UAAI,CAAC,aAAa,IAAI,aAAa,GAAG;AACpC,qBAAa,IAAI,eAAmB,oBAAA,IAAK,CAAA;AAAA,MAC3C;AACM,YAAA,iBAAiB,aAAa,IAAI,aAAa;AACrD,YAAMA,SAAQ,aAAa,IAAI,aAAa,KAAK;AAEjD,UAAI,CAAC,eAAe,IAAIA,MAAK,GAAG;AACf,uBAAA,IAAIA,QAAO,OAAO;AAAA,MACnC;AAEMC,YAAAA,SAAQ,eAAe,IAAID,MAAK;AAChCE,YAAAA,YAAW,CAAC,aAAmC;AAAA,MAAA;AAIxC,mBAAA,IAAI,eAAeF,SAAQ,CAAC;AAClC,aAAA,CAACC,QAAOC,SAAQ;AAAA,IACzB;AAEA,QAAI,CAAC,OAAO,IAAI,aAAa,GAAG;AACvB,aAAA,IAAI,eAAe,CAAA,CAAE;AAAA,IAC9B;AAEM,UAAA,kBAAkB,OAAO,IAAI,aAAa;AAC1C,UAAA,QAAQ,aAAa,IAAI,aAAa;AAExC,QAAA,SAAS,gBAAgB,QAAQ;AACnC,sBAAgB,KAAK,OAAO;AAAA,IAC9B;AAEM,UAAA,QAAQ,gBAAgB,KAAK;AAC7B,UAAA,WAAW,CAAC,aAAmC;AAC7C,YAAA,YAAY,OAAO,aAAa,aACjC,SAAsB,gBAAgB,KAAK,CAAC,IAC7C;AAEA,UAAA,gBAAgB,KAAK,MAAM;AAAW;AAE1C,sBAAgB,KAAK,IAAI;AAEzB,UAAI,YAAY;AACD,qBAAA,MAAM,SAAS,aAAa,CAAC;AAAA,MAAA,OACrC;AACL,iBAAS,aAAa;AAAA,MACxB;AAAA,IAAA;AAGW,iBAAA,IAAI,eAAe,QAAQ,CAAC;AAClC,WAAA,CAAC,OAAO,QAAQ;AAAA,EACzB;AAEgB,WAAA,UAAU,UAAqC,MAAc;AAC3E,QAAI,CAAC;AAAqB,YAAA,IAAI,MAAM,0CAA0C;AAExE,UAAA,cAAc,aAAa,IAAI,aAAa;AAElD,QAAI,CAAC,QAAQ,IAAI,aAAa,GAAG;AACvB,cAAA,IAAI,eAAe,CAAA,CAAE;AAAA,IAC/B;AAEM,UAAA,mBAAmB,QAAQ,IAAI,aAAa;AAC5C,UAAA,aAAa,iBAAiB,WAAW;AAG/C,QAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,WAAW,QACpC,KAAK,KAAK,CAAC,KAAK,MAAM,QAAQ,WAAW,KAAM,CAAC,CAAC,GAAG;AAGtD,UAAI,yCAAY,SAAS;AACvB,mBAAW,QAAQ;AAAA,MACrB;AAGA,qBAAe,MAAM;AACb,cAAA,UAAU,cAAc;AAC9B,yBAAiB,WAAW,IAAI,EAAE,SAAkB,KAAK;AAAA,MAAA,CAC1D;AAAA,IACH;AAEa,iBAAA,IAAI,eAAe,cAAc,CAAC;AAAA,EACjD;AAEgB,WAAA,QAAW,SAAkB,MAAgB;AAC3D,QAAI,CAAC;AAAqB,YAAA,IAAI,MAAM,wCAAwC;AAEtE,UAAA,YAAY,aAAa,IAAI,aAAa;AAEhD,QAAI,CAAC,MAAM,IAAI,aAAa,GAAG;AACvB,YAAA,IAAI,eAAe,CAAA,CAAE;AAAA,IAC7B;AAEM,UAAA,iBAAiB,MAAM,IAAI,aAAa;AACxC,UAAA,WAAW,eAAe,SAAS;AAEzC,QAAI,CAAC,YAAa,QAAQ,KAAK,KAAK,CAAC,KAAK,MAAM,CAAC,OAAO,GAAG,KAAK,SAAS,KAAK,CAAC,CAAC,CAAC,GAAI;AACnF,YAAM,QAAQ;AACd,qBAAe,SAAS,IAAI,EAAE,OAAO,KAAK;AAC7B,mBAAA,IAAI,eAAe,YAAY,CAAC;AACtC,aAAA;AAAA,IACT;AAEa,iBAAA,IAAI,eAAe,YAAY,CAAC;AAC7C,WAAO,SAAS;AAAA,EAClB;AAEO,WAAS,OAAU,SAAY;AACpC,QAAI,CAAC;AAAqB,YAAA,IAAI,MAAM,uCAAuC;AAErE,UAAA,WAAW,aAAa,IAAI,aAAa;AAE/C,QAAI,CAAC,KAAK,IAAI,aAAa,GAAG;AACvB,WAAA,IAAI,eAAe,CAAA,CAAE;AAAA,IAC5B;AAEM,UAAA,gBAAgB,KAAK,IAAI,aAAa;AACxC,QAAA,YAAY,cAAc,QAAQ;AAE9BC,YAAAA,OAAM,EAAE,SAAS;AACvB,oBAAc,KAAKA,IAAG;AACT,mBAAA,IAAI,eAAe,WAAW,CAAC;AACrCA,aAAAA;AAAAA,IACT;AAEM,UAAA,MAAM,cAAc,QAAQ;AACrB,iBAAA,IAAI,eAAe,WAAW,CAAC;AACrC,WAAA;AAAA,EACT;AAKA,iBAAe,SAAS,YAAoB;AACtC,QAAA;AAEI,YAAA,mBAAmB,QAAQ,IAAI,UAAU;AAC/C,UAAI,kBAAkB;AACpB,yBAAiB,QAAQ,CAAU,WAAA;AACjC,cAAI,OAAO;AAAS,mBAAO,QAAQ;AAAA,QAAA,CACpC;AACO,gBAAA,IAAI,YAAY,CAAA,CAAE;AAAA,MAC5B;AAEI,UAAA,wBAAwB,mBAAmB,gBAAgB;AACvD,cAAA,qBAAqB,gBAAgB,eAAe;AAAA,MAC5D;AAAA,aACO,OAAO;AACN,cAAA,MAAM,0BAA0B,KAAK;AAAA,IAC/C;AAAA,EACF;AAGO,WAAS,mBAA+C;AAC7D,UAAM,CAAC,OAAO,QAAQ,IAAI,SAAuB,IAAI;AACrD,WAAO,CAAC,OAAO,MAAM,SAAS,IAAI,CAAC;AAAA,EACrC;ACpMO,WAAS,cAAiB,cAA6B;AAC5D,UAAM,UAAU;AAAA,MACd,UAAU,CAAC,EAAE,OAAO,eAA6C;AACxD,eAAA;AAAA,MACT;AAAA,MACA,UAAU,CAAC,EAAE,eAAgD;AAC3D,eAAO,SAAS,YAAY;AAAA,MAC9B;AAAA,MACA,KAAK,OAAO;AAAA,MACZ,aAAa,CAAI,aAA8B;AAC7C,eAAO,SAAS,YAAY;AAAA,MAC9B;AAAA,IAAA;AAGK,WAAA;AAAA,EACT;AAEO,WAAS,WAAc,SAAiB;AACtC,WAAA;AAAA,EACT;ACxBA,WAAS,IAAI,MAAyB,OAAmB;AACvD,YAAQ,IAAI,kBAAkB,EAAE,MAAM,MAAO,CAAA;AACvC,UAAA,iBAAiB,EAAE,GAAG;AAGxB,QAAA,UAAU,SAAS,GAAG;AACxB,qBAAe,WAAW,MAAM,UAAU,MAAM,KAAK,WAAW,CAAC;AAAA,IACnE;AAEO,WAAA,EAAE,MAAM,OAAO;EACxB;AAEA,QAAM,WAAW,CAAC,EAAE,SAAA,MAAkC;AAEtD,iBAAe,cAAc,OAAmC;;AACtD,YAAA,IAAI,0BAA0B,KAAK;AAG3C,QAAI,SAAS,MAAM;AACV,aAAA,SAAS,eAAe,EAAE;AAAA,IACnC;AAEI,QAAA,OAAO,UAAU,WAAW;AACvB,aAAA,SAAS,eAAe,EAAE;AAAA,IACnC;AAEA,QAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAU;AAC1D,aAAO,SAAS,eAAe,OAAO,KAAK,CAAC;AAAA,IAC9C;AAGI,QAAA,MAAM,QAAQ,KAAK,GAAG;AAClB,YAAA,WAAW,SAAS;AAC1B,iBAAW,SAAS,OAAO;AACnB,cAAA,OAAO,MAAM,cAAc,KAAK;AACtC,iBAAS,YAAY,IAAI;AAAA,MAC3B;AACO,aAAA;AAAA,IACT;AAGA,QAAI,UAAU,SAAS,MAAM,UAAU,QAAW;AAC1C,YAAA,EAAE,MAAM,MAAU,IAAA;AAGpB,UAAA,OAAO,SAAS,YAAY;AAC1B,YAAA;AACF,gBAAM,SAAS,MAAM,KAAK,SAAS,CAAE,CAAA;AAC/B,gBAAA,OAAO,MAAM,cAAc,MAAM;AACvC,cAAI,gBAAgB,SAAS;AAC3B,iBAAK,aAAa,qBAAqB,KAAK,QAAQ,KAAK,UAAU;AAAA,UACrE;AACO,iBAAA;AAAA,iBACA,OAAO;AACN,kBAAA,MAAM,8BAA8B,KAAK;AAC1C,iBAAA,SAAS,eAAe,EAAE;AAAA,QACnC;AAAA,MACF;AAGM,YAAA,UAAU,SAAS,cAAc,IAAc;AAG1C,iBAAA,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,SAAS,CAAA,CAAE,GAAG;AACtD,YAAI,QAAQ;AAAY;AACxB,YAAI,IAAI,WAAW,IAAI,KAAK,OAAO,UAAU,YAAY;AACvD,gBAAM,YAAY,IAAI,YAAY,EAAE,MAAM,CAAC;AAErC,gBAAA,mBAAmB,aAAgB,aAAhB,mBAA2B;AACpD,cAAI,iBAAiB;AACX,oBAAA,oBAAoB,WAAW,eAAe;AAAA,UACxD;AAGQ,kBAAA,iBAAiB,WAAW,KAAsB;AACtD,cAAA,CAAE,QAAgB,UAAU;AAC7B,oBAAgB,WAAW;UAC9B;AACC,kBAAgB,SAAS,SAAS,IAAI;AAAA,QAC9B,WAAA,QAAQ,WAAW,OAAO,UAAU,UAAU;AAChD,iBAAA,OAAO,QAAQ,OAAO,KAAK;AAAA,QAAA,WACzB,QAAQ,aAAa;AAC9B,kBAAQ,aAAa,SAAS,OAAO,KAAK,CAAC;AAAA,QAClC,WAAA,QAAQ,SAAS,QAAQ,OAAO;AACzC,kBAAQ,aAAa,KAAK,OAAO,KAAK,CAAC;AAAA,QACzC;AAAA,MACF;AAGA,YAAM,WAAW,+BAAO;AACxB,UAAI,YAAY,MAAM;AACd,cAAA,aAAa,MAAM,QAAQ,QAAQ,IAAI,SAAS,KAAA,IAAS,CAAC,QAAQ;AACxE,mBAAW,SAAS,YAAY;AACxB,gBAAA,YAAY,MAAM,cAAc,KAAK;AAC3C,kBAAQ,YAAY,SAAS;AAAA,QAC/B;AAAA,MACF;AAEO,aAAA;AAAA,IACT;AAGA,WAAO,SAAS,eAAe,OAAO,KAAK,CAAC;AAAA,EAC9C;AC1GA,MAAI,cAAc;AAEI,iBAAA,QAAQ,SAAc,WAAwB;AACpD,kBAAA;AACV,QAAA;AACI,YAAA,OAAO,SAAS,SAAS;AAAA,IAAA,UAC/B;AACc,oBAAA;AAAA,IAChB;AAAA,EACF;AAEsB,iBAAA,OAAO,SAAc,WAAwB;AACzD,YAAA,IAAI,iBAAiB,UAAU,EAAE;AAEzC,iBAAa,YAAY;AACvB,YAAM,aAAa;AACf,UAAA;AACgB,0BAAA,QAAQ,SAAS,SAAS;AACtC,cAAA,UAAU,MAAM,cAAc,OAAO;AAE3C,YAAI,CAAC,aAAa;AAChB,oBAAU,YAAY;AAAA,QACxB;AACA,kBAAU,YAAY,OAAO;AAAA,MAAA,UAE7B;AACa;MACf;AAAA,IAAA,CACD;AAAA,EACH;AC3BO,WAAS,eAAe,OAAsB;AAErC;AAGR,UAAA,OAAO,mBAAmB,KAAK;AAGxB;AAEN,WAAA;AAAA,EACT;AAKA,WAAS,mBAAmB,OAAqE;;AAE3F,QAAA,UAAU,QAAQ,UAAU;AAAkB,aAAA;AAClD,QAAI,OAAO,UAAU;AAAkB,aAAA;AACvC,QAAI,OAAO,UAAU,YAAY,OAAO,UAAU;AAAiB,aAAA,WAAW,OAAO,KAAK,CAAC;AAGvF,QAAA,OAAO,MAAM,SAAS,YAAY;AACpC,YAAMC,aAAY,MAAM;AACxB,YAAM,eAAeA,WAAU,MAAM,SAAS,CAAE,CAAA;AAChD,aAAO,mBAAmB,YAAY;AAAA,IACxC;AAGI,QAAA,OAAO,MAAM,SAAS,UAAU;AAClC,YAAM,MAAM,MAAM;AAClB,UAAI,QAAQ;AACZ,UAAI,WAAW;AAGf,UAAI,MAAM,OAAO;AACJ,mBAAA,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,KAAK,GAAG;AAEtD,cAAI,QAAQ;AAAY;AAGpB,cAAA,IAAI,WAAW,IAAI;AAAG;AAG1B,cAAI,QAAQ,aAAa;AACd,qBAAA,WAAW,WAAW,KAAe,CAAC;AAC/C;AAAA,UACF;AAGA,cAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAU;AAC1D,qBAAS,IAAI,GAAG,KAAK,WAAW,OAAO,KAAK,CAAC,CAAC;AAAA,UAAA,WACrC,UAAU,MAAM;AAEzB,qBAAS,IAAI,GAAG;AAAA,UAClB;AAAA,QACF;AAAA,MACF;AAGA,YAAM,kBAAiB,WAAM,UAAN,mBAAa,YAChC,MAAM,QAAQ,MAAM,MAAM,QAAQ,IAChC,MAAM,MAAM,WACZ,CAAC,MAAM,MAAM,QAAQ,IACvB;AAEJ,iBAAW,SAAS,eAAe;AACjC,oBAAY,mBAAmB,KAAK;AAAA,MACtC;AAGA,YAAM,cAAc;AAAA,QAClB;AAAA,QAAQ;AAAA,QAAQ;AAAA,QAAM;AAAA,QAAO;AAAA,QAAS;AAAA,QAAM;AAAA,QAAO;AAAA,QACnD;AAAA,QAAQ;AAAA,QAAQ;AAAA,QAAS;AAAA,QAAU;AAAA,QAAS;AAAA,MAAA;AAG1C,UAAA,YAAY,SAAS,GAAG,GAAG;AACtB,eAAA,IAAI,GAAG,GAAG,KAAK;AAAA,MACxB;AAGA,aAAO,IAAI,GAAG,GAAG,KAAK,IAAI,QAAQ,KAAK,GAAG;AAAA,IAC5C;AAGA,QAAI,MAAM,SAAS,OAAO,IAAI,gBAAgB,GAAG;AAC/C,UAAI,iBAAiB;AACrB,YAAM,WAAW,MAAM,SAAQ,WAAM,UAAN,mBAAa,QAAQ,IAChD,MAAM,MAAM,aACZ,WAAM,UAAN,mBAAa,YAAW,CAAC,MAAM,MAAM,QAAQ,IAAI;AAErD,iBAAW,SAAS,UAAU;AAC5B,0BAAkB,mBAAmB,KAAK;AAAA,MAC5C;AAEO,aAAA;AAAA,IACT;AAGQ,YAAA,KAAK,uBAAuB,MAAM,IAAI;AACvC,WAAA;AAAA,EACT;AAKA,WAAS,WAAW,MAAsB;AACxC,WAAO,KACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,QAAQ;AAAA,EAC3B;ACzFO,QAAM,SAAS;AAAA,IACpB,MAAM,YAAY;AACV,YAAA,IAAI,MAAM,uDAAuD;AAAA,IACzE;AAAA,EACF;;;;;;;;;;;;;;;;;;"}
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/batch.ts","../src/hooks.ts","../src/context.ts","../src/jsx-runtime.ts","../src/renderer.ts","../src/server-renderer.ts","../src/index.client.ts"],"sourcesContent":["export let isBatching = false;\r\nconst queue: Function[] = [];\r\n\r\nexport function batchUpdates(fn: Function) {\r\n if (isBatching) {\r\n queue.push(fn);\r\n return;\r\n }\r\n\r\n isBatching = true;\r\n try {\r\n fn();\r\n while (queue.length > 0) {\r\n const nextFn = queue.shift();\r\n nextFn?.();\r\n }\r\n } finally {\r\n isBatching = false;\r\n }\r\n}\r\n\r\nexport function getIsBatching() {\r\n return isBatching;\r\n}\r\n","import { batchUpdates, isBatching } from './batch.js';\r\nimport { HookContext } from './types.js';\r\n\r\nlet currentRender: number = 0;\r\nconst states = new Map<number, any[]>();\r\nconst stateIndices = new Map<number, number>();\r\nconst effects = new Map<number, Effect[]>();\r\nconst memos = new Map<number, { value: any; deps: any[] }[]>();\r\nconst refs = new Map<number, any[]>();\r\n\r\n// Current hook context for the current render\r\nconst currentContext: HookContext = {\r\n hooks: [],\r\n currentHook: 0\r\n};\r\n\r\ninterface Effect {\r\n cleanup?: () => void;\r\n deps?: any[];\r\n}\r\n\r\n// Add at the top with other declarations\r\nlet globalRenderCallback: ((element: any, container: HTMLElement) => void) | null = null;\r\nlet globalContainer: HTMLElement | null = null;\r\nlet currentElement: any = null;\r\n\r\nconst isServer = typeof window === 'undefined';\r\nconst serverStates = new Map<number, any>();\r\n\r\nexport function setRenderCallback(\r\n callback: (element: any, container: HTMLElement) => void,\r\n element: any,\r\n container: HTMLElement\r\n) {\r\n globalRenderCallback = callback;\r\n globalContainer = container;\r\n currentElement = element;\r\n}\r\n\r\nexport function prepareRender() {\r\n // Reset hook index but preserve the hook state\r\n currentContext.currentHook = 0;\r\n currentRender++;\r\n stateIndices.set(currentRender, 0);\r\n return currentRender;\r\n}\r\n\r\nexport function finishRender() {\r\n // Any cleanup needed after rendering\r\n if (isServer) {\r\n serverStates.delete(currentRender);\r\n }\r\n currentRender = 0;\r\n}\r\n\r\nexport function useState<T>(initial: T): [T, (value: T | ((prev: T) => T)) => void] {\r\n if (!currentRender) {\r\n throw new Error('useState must be called within a render');\r\n }\r\n\r\n if (isServer) {\r\n // Server-side state handling\r\n if (!serverStates.has(currentRender)) {\r\n serverStates.set(currentRender, new Map());\r\n }\r\n const componentState = serverStates.get(currentRender)!;\r\n const index = stateIndices.get(currentRender) || 0;\r\n \r\n if (!componentState.has(index)) {\r\n componentState.set(index, initial);\r\n }\r\n\r\n const state = componentState.get(index);\r\n const setState = (newValue: T | ((prev: T) => T)) => {\r\n // No-op for server-side\r\n };\r\n\r\n stateIndices.set(currentRender, index + 1);\r\n return [state, setState];\r\n }\r\n\r\n if (!states.has(currentRender)) {\r\n states.set(currentRender, []);\r\n }\r\n\r\n const componentStates = states.get(currentRender)!;\r\n const index = stateIndices.get(currentRender)!;\r\n \r\n if (index >= componentStates.length) {\r\n componentStates.push(initial);\r\n }\r\n\r\n const state = componentStates[index];\r\n const setState = (newValue: T | ((prev: T) => T)) => {\r\n const nextValue = typeof newValue === 'function' \r\n ? (newValue as Function)(componentStates[index])\r\n : newValue;\r\n\r\n if (componentStates[index] === nextValue) return; // Skip if value hasn't changed\r\n \r\n componentStates[index] = nextValue;\r\n \r\n if (isBatching) {\r\n batchUpdates(() => rerender(currentRender));\r\n } else {\r\n rerender(currentRender);\r\n }\r\n };\r\n\r\n stateIndices.set(currentRender, index + 1);\r\n return [state, setState];\r\n}\r\n\r\nexport function useEffect(callback: () => (() => void) | void, deps?: any[]) {\r\n if (!currentRender) throw new Error('useEffect must be called within a render');\r\n \r\n const effectIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!effects.has(currentRender)) {\r\n effects.set(currentRender, []);\r\n }\r\n\r\n const componentEffects = effects.get(currentRender)!;\r\n const prevEffect = componentEffects[effectIndex];\r\n \r\n // Run effect if deps changed\r\n if (!prevEffect || !deps || !prevEffect.deps || \r\n deps.some((dep, i) => dep !== prevEffect.deps![i])) {\r\n \r\n // Cleanup previous effect\r\n if (prevEffect?.cleanup) {\r\n prevEffect.cleanup();\r\n }\r\n\r\n // Schedule new effect\r\n queueMicrotask(() => {\r\n const cleanup = callback() || undefined;\r\n componentEffects[effectIndex] = { cleanup: cleanup, deps };\r\n });\r\n }\r\n \r\n stateIndices.set(currentRender, effectIndex + 1);\r\n}\r\n\r\nexport function useMemo<T>(factory: () => T, deps: any[]): T {\r\n if (!currentRender) throw new Error('useMemo must be called within a render');\r\n \r\n const memoIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!memos.has(currentRender)) {\r\n memos.set(currentRender, []);\r\n }\r\n\r\n const componentMemos = memos.get(currentRender)!;\r\n const prevMemo = componentMemos[memoIndex];\r\n \r\n if (!prevMemo || (deps && deps.some((dep, i) => !Object.is(dep, prevMemo.deps[i])))) {\r\n const value = factory();\r\n componentMemos[memoIndex] = { value, deps };\r\n stateIndices.set(currentRender, memoIndex + 1);\r\n return value;\r\n }\r\n\r\n stateIndices.set(currentRender, memoIndex + 1);\r\n return prevMemo.value;\r\n}\r\n\r\nexport function useRef<T>(initial: T) {\r\n if (!currentRender) throw new Error('useRef must be called within a render');\r\n \r\n const refIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!refs.has(currentRender)) {\r\n refs.set(currentRender, []);\r\n }\r\n\r\n const componentRefs = refs.get(currentRender)!;\r\n if (refIndex >= componentRefs.length) {\r\n // Initialize with an object that has a current property\r\n const ref = { current: initial };\r\n componentRefs.push(ref);\r\n stateIndices.set(currentRender, refIndex + 1);\r\n return ref;\r\n }\r\n\r\n const ref = componentRefs[refIndex];\r\n stateIndices.set(currentRender, refIndex + 1);\r\n return ref;\r\n}\r\n\r\n// Add a map to track component DOM nodes\r\nconst componentNodes = new Map<Function, Node>();\r\n\r\nasync function rerender(rendererId: number) {\r\n try {\r\n // Clean up effects\r\n const componentEffects = effects.get(rendererId);\r\n if (componentEffects) {\r\n componentEffects.forEach(effect => {\r\n if (effect.cleanup) effect.cleanup();\r\n });\r\n effects.set(rendererId, []);\r\n }\r\n\r\n if (globalRenderCallback && globalContainer && currentElement) {\r\n await globalRenderCallback(currentElement, globalContainer);\r\n }\r\n } catch (error) {\r\n console.error('Error during rerender:', error);\r\n }\r\n}\r\n\r\n// Add new hook for error boundaries\r\nexport function useErrorBoundary(): [Error | null, () => void] {\r\n const [error, setError] = useState<Error | null>(null);\r\n return [error, () => setError(null)];\r\n}\r\n\r\n// Remove withHooks export\r\n","/**\r\n * Context API for state sharing between components\r\n */\r\n\r\nconst contexts = new Map<symbol, any>();\r\nlet currentRender: Function | null = null;\r\n\r\n/**\r\n * Interface for context objects\r\n */\r\nexport interface Context<T = any> {\r\n /** \r\n * The display name of the context \r\n */\r\n displayName?: string;\r\n \r\n /** \r\n * The current context value \r\n */\r\n currentValue: T;\r\n \r\n /**\r\n * Providers using this context\r\n */\r\n providers: Set<any>;\r\n}\r\n\r\n/**\r\n * Creates a context object with the specified default value\r\n * @param defaultValue The default value for the context\r\n */\r\nexport function createContext<T>(defaultValue: T): Context<T> {\r\n const context: Context<T> = {\r\n currentValue: defaultValue,\r\n providers: new Set()\r\n };\r\n \r\n return context;\r\n}\r\n\r\n/**\r\n * Get the current value of a context\r\n * @param context The context object\r\n */\r\nexport function useContext<T>(context: Context<T>): T {\r\n // In a real implementation, this would check for providers up the component tree\r\n return context.currentValue;\r\n}\r\n","// src/hooks.ts\r\ninterface VNode {\r\n type: string | Function;\r\n props: Record<string, any>;\r\n}\r\n\r\nfunction jsx(type: string | Function, props: any): VNode {\r\n console.log('JSX Transform:', { type, props });\r\n const processedProps = { ...props };\r\n \r\n // Handle children properly\r\n if (arguments.length > 2) {\r\n processedProps.children = Array.prototype.slice.call(arguments, 2);\r\n }\r\n \r\n return { type, props: processedProps };\r\n}\r\n\r\nconst Fragment = ({ children }: { children: any }) => children;\r\n\r\nasync function createElement(vnode: VNode | any): Promise<Node> {\r\n console.log('Creating element from:', vnode);\r\n\r\n // Handle primitives and null\r\n if (vnode == null) {\r\n return document.createTextNode('');\r\n }\r\n \r\n if (typeof vnode === 'boolean') {\r\n return document.createTextNode('');\r\n }\r\n\r\n if (typeof vnode === 'number' || typeof vnode === 'string') {\r\n return document.createTextNode(String(vnode));\r\n }\r\n\r\n // Handle arrays\r\n if (Array.isArray(vnode)) {\r\n const fragment = document.createDocumentFragment();\r\n for (const child of vnode) {\r\n const node = await createElement(child);\r\n fragment.appendChild(node);\r\n }\r\n return fragment;\r\n }\r\n\r\n // Handle VNode\r\n if ('type' in vnode && vnode.props !== undefined) {\r\n const { type, props } = vnode;\r\n \r\n // Handle function components\r\n if (typeof type === 'function') {\r\n try {\r\n const result = await type(props || {});\r\n const node = await createElement(result);\r\n if (node instanceof Element) {\r\n node.setAttribute('data-component-id', type.name || type.toString());\r\n }\r\n return node;\r\n } catch (error) {\r\n console.error('Error rendering component:', error);\r\n return document.createTextNode('');\r\n }\r\n }\r\n\r\n // Create DOM element\r\n const element = document.createElement(type as string);\r\n \r\n // Handle props\r\n for (const [key, value] of Object.entries(props || {})) {\r\n if (key === 'children') continue;\r\n if (key.startsWith('on') && typeof value === 'function') {\r\n const eventName = key.toLowerCase().slice(2);\r\n // Remove existing event listener if any\r\n const existingHandler = (element as any).__events?.[eventName];\r\n if (existingHandler) {\r\n element.removeEventListener(eventName, existingHandler);\r\n }\r\n \r\n // Add new event listener\r\n element.addEventListener(eventName, value as EventListener);\r\n if (!(element as any).__events) {\r\n (element as any).__events = {};\r\n }\r\n (element as any).__events[eventName] = value;\r\n } else if (key === 'style' && typeof value === 'object') {\r\n Object.assign(element.style, value);\r\n } else if (key === 'className') {\r\n element.setAttribute('class', String(value));\r\n } else if (key !== 'key' && key !== 'ref') {\r\n element.setAttribute(key, String(value));\r\n }\r\n }\r\n\r\n // Handle children\r\n const children = props?.children;\r\n if (children != null) {\r\n const childArray = Array.isArray(children) ? children.flat() : [children];\r\n for (const child of childArray) {\r\n const childNode = await createElement(child);\r\n element.appendChild(childNode);\r\n }\r\n }\r\n\r\n return element;\r\n }\r\n\r\n // Handle other objects by converting to string\r\n return document.createTextNode(String(vnode));\r\n}\r\n\r\n// Export named functions and aliases without duplicates\r\nexport {\r\n jsx,\r\n jsx as jsxs,\r\n jsx as jsxDEV,\r\n Fragment,\r\n createElement\r\n};\r\n\r\n// Named exports object\r\nconst jsxRuntime = {\r\n jsx,\r\n jsxs: jsx,\r\n jsxDEV: jsx,\r\n Fragment,\r\n createElement\r\n};\r\n\r\nexport default jsxRuntime;\r\n","import { createElement } from './jsx-runtime.js';\r\nimport { prepareRender, finishRender, setRenderCallback } from './hooks.js';\r\nimport { batchUpdates } from './batch.js';\r\n\r\nlet isHydrating = false;\r\n\r\nexport async function hydrate(element: any, container: HTMLElement) {\r\n isHydrating = true;\r\n try {\r\n await render(element, container);\r\n } finally {\r\n isHydrating = false;\r\n }\r\n}\r\n\r\nexport async function render(element: any, container: HTMLElement) {\r\n console.log('Rendering to:', container.id);\r\n \r\n batchUpdates(async () => {\r\n const rendererId = prepareRender();\r\n try {\r\n setRenderCallback(render, element, container);\r\n const domNode = await createElement(element);\r\n \r\n if (!isHydrating) {\r\n container.innerHTML = '';\r\n }\r\n container.appendChild(domNode);\r\n \r\n } finally {\r\n finishRender();\r\n }\r\n });\r\n}\r\n","import { VNode, Component } from './types.js';\r\nimport { prepareRender, finishRender } from './hooks.js';\r\n\r\n/**\r\n * Renders a virtual DOM tree to an HTML string\r\n */\r\nexport function renderToString(vnode: VNode): string {\r\n // Reset hook state for this render\r\n prepareRender();\r\n \r\n // Render the tree to HTML\r\n const html = renderNodeToString(vnode);\r\n \r\n // Clean up after rendering\r\n finishRender();\r\n \r\n return html;\r\n}\r\n\r\n/**\r\n * Internal function to convert a virtual node to an HTML string\r\n */\r\nfunction renderNodeToString(vnode: VNode | string | number | boolean | null | undefined): string {\r\n // Handle primitive values\r\n if (vnode === null || vnode === undefined) return '';\r\n if (typeof vnode === 'boolean') return '';\r\n if (typeof vnode === 'number' || typeof vnode === 'string') return escapeHtml(String(vnode));\r\n \r\n // Handle function components\r\n if (typeof vnode.type === 'function') {\r\n const Component = vnode.type as Component;\r\n const renderedNode = Component(vnode.props || {});\r\n return renderNodeToString(renderedNode);\r\n }\r\n \r\n // Handle intrinsic elements (regular HTML tags)\r\n if (typeof vnode.type === 'string') {\r\n const tag = vnode.type;\r\n let attrs = '';\r\n let children = '';\r\n \r\n // Convert props to HTML attributes\r\n if (vnode.props) {\r\n for (const [key, value] of Object.entries(vnode.props)) {\r\n // Skip children prop as we handle it separately\r\n if (key === 'children') continue;\r\n \r\n // Skip event handlers (they start with 'on')\r\n if (key.startsWith('on')) continue;\r\n \r\n // Handle the className prop specially\r\n if (key === 'className') {\r\n attrs += ` class=\"${escapeHtml(value as string)}\"`;\r\n continue;\r\n }\r\n \r\n // Handle other attributes\r\n if (typeof value === 'string' || typeof value === 'number') {\r\n attrs += ` ${key}=\"${escapeHtml(String(value))}\"`;\r\n } else if (value === true) {\r\n // Boolean attributes\r\n attrs += ` ${key}`;\r\n }\r\n }\r\n }\r\n \r\n // Process children\r\n const childrenArray = (vnode.props?.children) \r\n ? Array.isArray(vnode.props.children) \r\n ? vnode.props.children \r\n : [vnode.props.children]\r\n : [];\r\n \r\n for (const child of childrenArray) {\r\n children += renderNodeToString(child);\r\n }\r\n \r\n // Self-closing tags\r\n const selfClosing = [\r\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\r\n 'link', 'meta', 'param', 'source', 'track', 'wbr'\r\n ];\r\n \r\n if (selfClosing.includes(tag)) {\r\n return `<${tag}${attrs}/>`;\r\n }\r\n \r\n // Regular tags with closing\r\n return `<${tag}${attrs}>${children}</${tag}>`;\r\n }\r\n \r\n // Handle fragments\r\n if (vnode.type === Symbol.for('react.fragment')) {\r\n let fragmentOutput = '';\r\n const children = Array.isArray(vnode.props?.children)\r\n ? vnode.props.children\r\n : vnode.props?.children ? [vnode.props.children] : [];\r\n \r\n for (const child of children) {\r\n fragmentOutput += renderNodeToString(child);\r\n }\r\n \r\n return fragmentOutput;\r\n }\r\n \r\n // Fallback for unknown node types\r\n console.warn('Unknown vnode type:', vnode.type);\r\n return '';\r\n}\r\n\r\n/**\r\n * Escape HTML special characters to prevent XSS\r\n */\r\nfunction escapeHtml(text: string): string {\r\n return text\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>')\r\n .replace(/\"/g, '"')\r\n .replace(/'/g, ''');\r\n}\r\n","\r\nexport { \r\n useState, \r\n useEffect, \r\n useMemo, \r\n useRef,\r\n useErrorBoundary \r\n} from './hooks.js';\r\n\r\nexport { createContext, useContext } from './context.js';\r\nexport { batchUpdates } from './batch.js';\r\nexport { jsx, jsxs, Fragment } from './jsx-runtime.js';\r\nexport { render, hydrate } from './renderer.js';\r\nexport { renderToString } from './server-renderer.js';\r\n\r\n// Re-export types for client-side usage\r\nexport type { Context } from './context.js';\r\nexport type { VNode } from './types.js';\r\n\r\n// Export server types for type checking\r\nexport type {\r\n Server,\r\n ServerConfig,\r\n User,\r\n DbConfig,\r\n MiddlewareFunction\r\n} from './server-types.js';\r\n\r\n// Provide placeholder server functionality\r\nexport const server = {\r\n async getServer() {\r\n throw new Error('Server module can only be used in Node.js environment');\r\n }\r\n};\r\n\r\nlet isHydrating = false;\r\n"],"names":["index","state","setState","ref","Component"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
@@ -164,21 +164,13 @@ function useErrorBoundary() {
|
|
164
164
|
}
|
165
165
|
function createContext(defaultValue) {
|
166
166
|
const context = {
|
167
|
-
|
168
|
-
|
169
|
-
},
|
170
|
-
Consumer: ({ children }) => {
|
171
|
-
return children(defaultValue);
|
172
|
-
},
|
173
|
-
_id: Symbol(),
|
174
|
-
useSelector: (selector) => {
|
175
|
-
return selector(defaultValue);
|
176
|
-
}
|
167
|
+
currentValue: defaultValue,
|
168
|
+
providers: /* @__PURE__ */ new Set()
|
177
169
|
};
|
178
170
|
return context;
|
179
171
|
}
|
180
172
|
function useContext(context) {
|
181
|
-
return context;
|
173
|
+
return context.currentValue;
|
182
174
|
}
|
183
175
|
function jsx(type, props) {
|
184
176
|
console.log("JSX Transform:", { type, props });
|
package/dist/index.mjs.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/batch.ts","../src/hooks.ts","../src/context.ts","../src/jsx-runtime.ts","../src/renderer.ts","../src/server-renderer.ts","../src/index.client.ts"],"sourcesContent":["export let isBatching = false;\r\nconst queue: Function[] = [];\r\n\r\nexport function batchUpdates(fn: Function) {\r\n if (isBatching) {\r\n queue.push(fn);\r\n return;\r\n }\r\n\r\n isBatching = true;\r\n try {\r\n fn();\r\n while (queue.length > 0) {\r\n const nextFn = queue.shift();\r\n nextFn?.();\r\n }\r\n } finally {\r\n isBatching = false;\r\n }\r\n}\r\n\r\nexport function getIsBatching() {\r\n return isBatching;\r\n}\r\n","import { createElement } from './jsx-runtime';\r\nimport { batchUpdates, isBatching } from './batch';\r\nimport { diff } from './vdom';\r\n\r\nlet currentRender: number = 0;\r\nconst states = new Map<number, any[]>();\r\nconst stateIndices = new Map<number, number>();\r\nconst effects = new Map<number, Effect[]>();\r\nconst memos = new Map<number, { value: any; deps: any[] }[]>();\r\nconst refs = new Map<number, any[]>();\r\n\r\ninterface Effect {\r\n cleanup?: () => void;\r\n deps?: any[];\r\n}\r\n\r\n// Add at the top with other declarations\r\nlet globalRenderCallback: ((element: any, container: HTMLElement) => void) | null = null;\r\nlet globalContainer: HTMLElement | null = null;\r\nlet currentElement: any = null;\r\n\r\nconst isServer = typeof window === 'undefined';\r\nconst serverStates = new Map<number, any>();\r\n\r\nexport function setRenderCallback(\r\n callback: (element: any, container: HTMLElement) => void,\r\n element: any,\r\n container: HTMLElement\r\n) {\r\n globalRenderCallback = callback;\r\n globalContainer = container;\r\n currentElement = element;\r\n}\r\n\r\nexport function prepareRender() {\r\n currentRender++;\r\n stateIndices.set(currentRender, 0);\r\n return currentRender;\r\n}\r\n\r\nexport function finishRender() {\r\n if (isServer) {\r\n serverStates.delete(currentRender);\r\n }\r\n currentRender = 0;\r\n}\r\n\r\nexport function useState<T>(initial: T): [T, (value: T | ((prev: T) => T)) => void] {\r\n if (!currentRender) {\r\n throw new Error('useState must be called within a render');\r\n }\r\n\r\n if (isServer) {\r\n // Server-side state handling\r\n if (!serverStates.has(currentRender)) {\r\n serverStates.set(currentRender, new Map());\r\n }\r\n const componentState = serverStates.get(currentRender)!;\r\n const index = stateIndices.get(currentRender) || 0;\r\n \r\n if (!componentState.has(index)) {\r\n componentState.set(index, initial);\r\n }\r\n\r\n const state = componentState.get(index);\r\n const setState = (newValue: T | ((prev: T) => T)) => {\r\n // No-op for server-side\r\n };\r\n\r\n stateIndices.set(currentRender, index + 1);\r\n return [state, setState];\r\n }\r\n\r\n if (!states.has(currentRender)) {\r\n states.set(currentRender, []);\r\n }\r\n\r\n const componentStates = states.get(currentRender)!;\r\n const index = stateIndices.get(currentRender)!;\r\n \r\n if (index >= componentStates.length) {\r\n componentStates.push(initial);\r\n }\r\n\r\n const state = componentStates[index];\r\n const setState = (newValue: T | ((prev: T) => T)) => {\r\n const nextValue = typeof newValue === 'function' \r\n ? (newValue as Function)(componentStates[index])\r\n : newValue;\r\n\r\n if (componentStates[index] === nextValue) return; // Skip if value hasn't changed\r\n \r\n componentStates[index] = nextValue;\r\n \r\n if (isBatching) {\r\n batchUpdates(() => rerender(currentRender));\r\n } else {\r\n rerender(currentRender);\r\n }\r\n };\r\n\r\n stateIndices.set(currentRender, index + 1);\r\n return [state, setState];\r\n}\r\n\r\nexport function useEffect(callback: () => (() => void) | void, deps?: any[]) {\r\n if (!currentRender) throw new Error('useEffect must be called within a render');\r\n \r\n const effectIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!effects.has(currentRender)) {\r\n effects.set(currentRender, []);\r\n }\r\n\r\n const componentEffects = effects.get(currentRender)!;\r\n const prevEffect = componentEffects[effectIndex];\r\n \r\n // Run effect if deps changed\r\n if (!prevEffect || !deps || !prevEffect.deps || \r\n deps.some((dep, i) => dep !== prevEffect.deps![i])) {\r\n \r\n // Cleanup previous effect\r\n if (prevEffect?.cleanup) {\r\n prevEffect.cleanup();\r\n }\r\n\r\n // Schedule new effect\r\n queueMicrotask(() => {\r\n const cleanup = callback() || undefined;\r\n componentEffects[effectIndex] = { cleanup: cleanup, deps };\r\n });\r\n }\r\n \r\n stateIndices.set(currentRender, effectIndex + 1);\r\n}\r\n\r\nexport function useMemo<T>(factory: () => T, deps: any[]): T {\r\n if (!currentRender) throw new Error('useMemo must be called within a render');\r\n \r\n const memoIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!memos.has(currentRender)) {\r\n memos.set(currentRender, []);\r\n }\r\n\r\n const componentMemos = memos.get(currentRender)!;\r\n const prevMemo = componentMemos[memoIndex];\r\n \r\n if (!prevMemo || (deps && deps.some((dep, i) => !Object.is(dep, prevMemo.deps[i])))) {\r\n const value = factory();\r\n componentMemos[memoIndex] = { value, deps };\r\n stateIndices.set(currentRender, memoIndex + 1);\r\n return value;\r\n }\r\n\r\n stateIndices.set(currentRender, memoIndex + 1);\r\n return prevMemo.value;\r\n}\r\n\r\nexport function useRef<T>(initial: T) {\r\n if (!currentRender) throw new Error('useRef must be called within a render');\r\n \r\n const refIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!refs.has(currentRender)) {\r\n refs.set(currentRender, []);\r\n }\r\n\r\n const componentRefs = refs.get(currentRender)!;\r\n if (refIndex >= componentRefs.length) {\r\n // Initialize with an object that has a current property\r\n const ref = { current: initial };\r\n componentRefs.push(ref);\r\n stateIndices.set(currentRender, refIndex + 1);\r\n return ref;\r\n }\r\n\r\n const ref = componentRefs[refIndex];\r\n stateIndices.set(currentRender, refIndex + 1);\r\n return ref;\r\n}\r\n\r\n// Add a map to track component DOM nodes\r\nconst componentNodes = new Map<Function, Node>();\r\n\r\nasync function rerender(rendererId: number) {\r\n try {\r\n // Clean up effects\r\n const componentEffects = effects.get(rendererId);\r\n if (componentEffects) {\r\n componentEffects.forEach(effect => {\r\n if (effect.cleanup) effect.cleanup();\r\n });\r\n effects.set(rendererId, []);\r\n }\r\n\r\n if (globalRenderCallback && globalContainer && currentElement) {\r\n await globalRenderCallback(currentElement, globalContainer);\r\n }\r\n } catch (error) {\r\n console.error('Error during rerender:', error);\r\n }\r\n}\r\n\r\n// Add new hook for error boundaries\r\nexport function useErrorBoundary(): [Error | null, () => void] {\r\n const [error, setError] = useState<Error | null>(null);\r\n return [error, () => setError(null)];\r\n}\r\n\r\n// Remove withHooks export\r\n","\r\n\r\nconst contexts = new Map<symbol, any>();\r\nlet currentRender: Function | null = null;\r\n\r\nexport interface Context<T> {\r\n Provider: (props: { value: T; children?: any }) => any;\r\n Consumer: (props: { children: (value: T) => any }) => any;\r\n _id: symbol;\r\n useSelector: <S>(selector: (state: T) => S) => S;\r\n}\r\n\r\nexport function createContext<T>(defaultValue: T): Context<T> {\r\n const context = {\r\n Provider: ({ value, children }: { value: T, children?: any }) => {\r\n return children;\r\n },\r\n Consumer: ({ children }: { children: (value: T) => any }) => {\r\n return children(defaultValue);\r\n },\r\n _id: Symbol(),\r\n useSelector: <S>(selector: (state: T) => S) => {\r\n return selector(defaultValue);\r\n }\r\n };\r\n\r\n return context;\r\n}\r\n\r\nexport function useContext<T>(context: any): T {\r\n return context;\r\n}\r\n","import type { Component } from './component';\r\n\r\ninterface VNode {\r\n type: string | Function;\r\n props: Record<string, any>;\r\n}\r\n\r\nfunction jsx(type: string | Function, props: any): VNode {\r\n console.log('JSX Transform:', { type, props });\r\n const processedProps = { ...props };\r\n \r\n // Handle children properly\r\n if (arguments.length > 2) {\r\n processedProps.children = Array.prototype.slice.call(arguments, 2);\r\n }\r\n \r\n return { type, props: processedProps };\r\n}\r\n\r\nconst Fragment = ({ children }: { children: any }) => children;\r\n\r\nasync function createElement(vnode: VNode | any): Promise<Node> {\r\n console.log('Creating element from:', vnode);\r\n\r\n // Handle primitives and null\r\n if (vnode == null) {\r\n return document.createTextNode('');\r\n }\r\n \r\n if (typeof vnode === 'boolean') {\r\n return document.createTextNode('');\r\n }\r\n\r\n if (typeof vnode === 'number' || typeof vnode === 'string') {\r\n return document.createTextNode(String(vnode));\r\n }\r\n\r\n // Handle arrays\r\n if (Array.isArray(vnode)) {\r\n const fragment = document.createDocumentFragment();\r\n for (const child of vnode) {\r\n const node = await createElement(child);\r\n fragment.appendChild(node);\r\n }\r\n return fragment;\r\n }\r\n\r\n // Handle VNode\r\n if ('type' in vnode && vnode.props !== undefined) {\r\n const { type, props } = vnode;\r\n \r\n // Handle function components\r\n if (typeof type === 'function') {\r\n try {\r\n const result = await type(props || {});\r\n const node = await createElement(result);\r\n if (node instanceof Element) {\r\n node.setAttribute('data-component-id', type.name || type.toString());\r\n }\r\n return node;\r\n } catch (error) {\r\n console.error('Error rendering component:', error);\r\n return document.createTextNode('');\r\n }\r\n }\r\n\r\n // Create DOM element\r\n const element = document.createElement(type as string);\r\n \r\n // Handle props\r\n for (const [key, value] of Object.entries(props || {})) {\r\n if (key === 'children') continue;\r\n if (key.startsWith('on') && typeof value === 'function') {\r\n const eventName = key.toLowerCase().slice(2);\r\n // Remove existing event listener if any\r\n const existingHandler = (element as any).__events?.[eventName];\r\n if (existingHandler) {\r\n element.removeEventListener(eventName, existingHandler);\r\n }\r\n \r\n // Add new event listener\r\n element.addEventListener(eventName, value as EventListener);\r\n if (!(element as any).__events) {\r\n (element as any).__events = {};\r\n }\r\n (element as any).__events[eventName] = value;\r\n } else if (key === 'style' && typeof value === 'object') {\r\n Object.assign(element.style, value);\r\n } else if (key === 'className') {\r\n element.setAttribute('class', String(value));\r\n } else if (key !== 'key' && key !== 'ref') {\r\n element.setAttribute(key, String(value));\r\n }\r\n }\r\n\r\n // Handle children\r\n const children = props?.children;\r\n if (children != null) {\r\n const childArray = Array.isArray(children) ? children.flat() : [children];\r\n for (const child of childArray) {\r\n const childNode = await createElement(child);\r\n element.appendChild(childNode);\r\n }\r\n }\r\n\r\n return element;\r\n }\r\n\r\n // Handle other objects by converting to string\r\n return document.createTextNode(String(vnode));\r\n}\r\n\r\n// Export named functions and aliases without duplicates\r\nexport {\r\n jsx,\r\n jsx as jsxs,\r\n jsx as jsxDEV,\r\n Fragment,\r\n createElement\r\n};\r\n\r\n// Named exports object\r\nconst jsxRuntime = {\r\n jsx,\r\n jsxs: jsx,\r\n jsxDEV: jsx,\r\n Fragment,\r\n createElement\r\n};\r\n\r\nexport default jsxRuntime;\r\n","import { createElement } from './jsx-runtime';\r\nimport { prepareRender, finishRender, setRenderCallback } from './hooks';\r\nimport { batchUpdates } from './batch';\r\n\r\nlet isHydrating = false;\r\n\r\nexport async function hydrate(element: any, container: HTMLElement) {\r\n isHydrating = true;\r\n try {\r\n await render(element, container);\r\n } finally {\r\n isHydrating = false;\r\n }\r\n}\r\n\r\nexport async function render(element: any, container: HTMLElement) {\r\n console.log('Rendering to:', container.id);\r\n \r\n batchUpdates(async () => {\r\n const rendererId = prepareRender();\r\n try {\r\n setRenderCallback(render, element, container);\r\n const domNode = await createElement(element);\r\n \r\n if (!isHydrating) {\r\n container.innerHTML = '';\r\n }\r\n container.appendChild(domNode);\r\n \r\n } finally {\r\n finishRender();\r\n }\r\n });\r\n}\r\n","import { VNode, Component } from './types';\r\nimport { prepareRender, finishRender } from './hooks';\r\n\r\n/**\r\n * Renders a virtual DOM tree to an HTML string\r\n */\r\nexport function renderToString(vnode: VNode): string {\r\n // Reset hook state for this render\r\n prepareRender();\r\n \r\n // Render the tree to HTML\r\n const html = renderNodeToString(vnode);\r\n \r\n // Clean up after rendering\r\n finishRender();\r\n \r\n return html;\r\n}\r\n\r\n/**\r\n * Internal function to convert a virtual node to an HTML string\r\n */\r\nfunction renderNodeToString(vnode: VNode | string | number | boolean | null | undefined): string {\r\n // Handle primitive values\r\n if (vnode === null || vnode === undefined) return '';\r\n if (typeof vnode === 'boolean') return '';\r\n if (typeof vnode === 'number' || typeof vnode === 'string') return escapeHtml(String(vnode));\r\n \r\n // Handle function components\r\n if (typeof vnode.type === 'function') {\r\n const Component = vnode.type as Component;\r\n const renderedNode = Component(vnode.props || {});\r\n return renderNodeToString(renderedNode);\r\n }\r\n \r\n // Handle intrinsic elements (regular HTML tags)\r\n if (typeof vnode.type === 'string') {\r\n const tag = vnode.type;\r\n let attrs = '';\r\n let children = '';\r\n \r\n // Convert props to HTML attributes\r\n if (vnode.props) {\r\n for (const [key, value] of Object.entries(vnode.props)) {\r\n // Skip children prop as we handle it separately\r\n if (key === 'children') continue;\r\n \r\n // Skip event handlers (they start with 'on')\r\n if (key.startsWith('on')) continue;\r\n \r\n // Handle the className prop specially\r\n if (key === 'className') {\r\n attrs += ` class=\"${escapeHtml(value as string)}\"`;\r\n continue;\r\n }\r\n \r\n // Handle other attributes\r\n if (typeof value === 'string' || typeof value === 'number') {\r\n attrs += ` ${key}=\"${escapeHtml(String(value))}\"`;\r\n } else if (value === true) {\r\n // Boolean attributes\r\n attrs += ` ${key}`;\r\n }\r\n }\r\n }\r\n \r\n // Process children\r\n const childrenArray = (vnode.props?.children) \r\n ? Array.isArray(vnode.props.children) \r\n ? vnode.props.children \r\n : [vnode.props.children]\r\n : [];\r\n \r\n for (const child of childrenArray) {\r\n children += renderNodeToString(child);\r\n }\r\n \r\n // Self-closing tags\r\n const selfClosing = [\r\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\r\n 'link', 'meta', 'param', 'source', 'track', 'wbr'\r\n ];\r\n \r\n if (selfClosing.includes(tag)) {\r\n return `<${tag}${attrs}/>`;\r\n }\r\n \r\n // Regular tags with closing\r\n return `<${tag}${attrs}>${children}</${tag}>`;\r\n }\r\n \r\n // Handle fragments\r\n if (vnode.type === Symbol.for('react.fragment')) {\r\n let fragmentOutput = '';\r\n const children = Array.isArray(vnode.props?.children)\r\n ? vnode.props.children\r\n : vnode.props?.children ? [vnode.props.children] : [];\r\n \r\n for (const child of children) {\r\n fragmentOutput += renderNodeToString(child);\r\n }\r\n \r\n return fragmentOutput;\r\n }\r\n \r\n // Fallback for unknown node types\r\n console.warn('Unknown vnode type:', vnode.type);\r\n return '';\r\n}\r\n\r\n/**\r\n * Escape HTML special characters to prevent XSS\r\n */\r\nfunction escapeHtml(text: string): string {\r\n return text\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>')\r\n .replace(/\"/g, '"')\r\n .replace(/'/g, ''');\r\n}\r\n","import { createElement } from './jsx-runtime';\r\nimport { prepareRender, finishRender, setRenderCallback } from './hooks';\r\n\r\nexport { \r\n useState, \r\n useEffect, \r\n useMemo, \r\n useRef,\r\n useErrorBoundary \r\n} from './hooks';\r\n\r\nexport { createContext, useContext } from './context';\r\nexport { batchUpdates } from './batch';\r\nexport { jsx, jsxs, Fragment } from './jsx-runtime';\r\nexport { render, hydrate } from './renderer';\r\nexport { renderToString } from './server-renderer';\r\n\r\n// Re-export types for client-side usage\r\nexport type { Context } from './context';\r\nexport type { VNode } from './types';\r\n\r\n// Export server types for type checking\r\nexport type {\r\n Server,\r\n ServerConfig,\r\n User,\r\n DbConfig,\r\n MiddlewareFunction\r\n} from './server-types';\r\n\r\n// Provide placeholder server functionality\r\nexport const server = {\r\n async getServer() {\r\n throw new Error('Server module can only be used in Node.js environment');\r\n }\r\n};\r\n\r\nlet isHydrating = false;\r\n"],"names":["index","state","setState","ref","Component"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/batch.ts","../src/hooks.ts","../src/context.ts","../src/jsx-runtime.ts","../src/renderer.ts","../src/server-renderer.ts","../src/index.client.ts"],"sourcesContent":["export let isBatching = false;\r\nconst queue: Function[] = [];\r\n\r\nexport function batchUpdates(fn: Function) {\r\n if (isBatching) {\r\n queue.push(fn);\r\n return;\r\n }\r\n\r\n isBatching = true;\r\n try {\r\n fn();\r\n while (queue.length > 0) {\r\n const nextFn = queue.shift();\r\n nextFn?.();\r\n }\r\n } finally {\r\n isBatching = false;\r\n }\r\n}\r\n\r\nexport function getIsBatching() {\r\n return isBatching;\r\n}\r\n","import { batchUpdates, isBatching } from './batch.js';\r\nimport { HookContext } from './types.js';\r\n\r\nlet currentRender: number = 0;\r\nconst states = new Map<number, any[]>();\r\nconst stateIndices = new Map<number, number>();\r\nconst effects = new Map<number, Effect[]>();\r\nconst memos = new Map<number, { value: any; deps: any[] }[]>();\r\nconst refs = new Map<number, any[]>();\r\n\r\n// Current hook context for the current render\r\nconst currentContext: HookContext = {\r\n hooks: [],\r\n currentHook: 0\r\n};\r\n\r\ninterface Effect {\r\n cleanup?: () => void;\r\n deps?: any[];\r\n}\r\n\r\n// Add at the top with other declarations\r\nlet globalRenderCallback: ((element: any, container: HTMLElement) => void) | null = null;\r\nlet globalContainer: HTMLElement | null = null;\r\nlet currentElement: any = null;\r\n\r\nconst isServer = typeof window === 'undefined';\r\nconst serverStates = new Map<number, any>();\r\n\r\nexport function setRenderCallback(\r\n callback: (element: any, container: HTMLElement) => void,\r\n element: any,\r\n container: HTMLElement\r\n) {\r\n globalRenderCallback = callback;\r\n globalContainer = container;\r\n currentElement = element;\r\n}\r\n\r\nexport function prepareRender() {\r\n // Reset hook index but preserve the hook state\r\n currentContext.currentHook = 0;\r\n currentRender++;\r\n stateIndices.set(currentRender, 0);\r\n return currentRender;\r\n}\r\n\r\nexport function finishRender() {\r\n // Any cleanup needed after rendering\r\n if (isServer) {\r\n serverStates.delete(currentRender);\r\n }\r\n currentRender = 0;\r\n}\r\n\r\nexport function useState<T>(initial: T): [T, (value: T | ((prev: T) => T)) => void] {\r\n if (!currentRender) {\r\n throw new Error('useState must be called within a render');\r\n }\r\n\r\n if (isServer) {\r\n // Server-side state handling\r\n if (!serverStates.has(currentRender)) {\r\n serverStates.set(currentRender, new Map());\r\n }\r\n const componentState = serverStates.get(currentRender)!;\r\n const index = stateIndices.get(currentRender) || 0;\r\n \r\n if (!componentState.has(index)) {\r\n componentState.set(index, initial);\r\n }\r\n\r\n const state = componentState.get(index);\r\n const setState = (newValue: T | ((prev: T) => T)) => {\r\n // No-op for server-side\r\n };\r\n\r\n stateIndices.set(currentRender, index + 1);\r\n return [state, setState];\r\n }\r\n\r\n if (!states.has(currentRender)) {\r\n states.set(currentRender, []);\r\n }\r\n\r\n const componentStates = states.get(currentRender)!;\r\n const index = stateIndices.get(currentRender)!;\r\n \r\n if (index >= componentStates.length) {\r\n componentStates.push(initial);\r\n }\r\n\r\n const state = componentStates[index];\r\n const setState = (newValue: T | ((prev: T) => T)) => {\r\n const nextValue = typeof newValue === 'function' \r\n ? (newValue as Function)(componentStates[index])\r\n : newValue;\r\n\r\n if (componentStates[index] === nextValue) return; // Skip if value hasn't changed\r\n \r\n componentStates[index] = nextValue;\r\n \r\n if (isBatching) {\r\n batchUpdates(() => rerender(currentRender));\r\n } else {\r\n rerender(currentRender);\r\n }\r\n };\r\n\r\n stateIndices.set(currentRender, index + 1);\r\n return [state, setState];\r\n}\r\n\r\nexport function useEffect(callback: () => (() => void) | void, deps?: any[]) {\r\n if (!currentRender) throw new Error('useEffect must be called within a render');\r\n \r\n const effectIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!effects.has(currentRender)) {\r\n effects.set(currentRender, []);\r\n }\r\n\r\n const componentEffects = effects.get(currentRender)!;\r\n const prevEffect = componentEffects[effectIndex];\r\n \r\n // Run effect if deps changed\r\n if (!prevEffect || !deps || !prevEffect.deps || \r\n deps.some((dep, i) => dep !== prevEffect.deps![i])) {\r\n \r\n // Cleanup previous effect\r\n if (prevEffect?.cleanup) {\r\n prevEffect.cleanup();\r\n }\r\n\r\n // Schedule new effect\r\n queueMicrotask(() => {\r\n const cleanup = callback() || undefined;\r\n componentEffects[effectIndex] = { cleanup: cleanup, deps };\r\n });\r\n }\r\n \r\n stateIndices.set(currentRender, effectIndex + 1);\r\n}\r\n\r\nexport function useMemo<T>(factory: () => T, deps: any[]): T {\r\n if (!currentRender) throw new Error('useMemo must be called within a render');\r\n \r\n const memoIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!memos.has(currentRender)) {\r\n memos.set(currentRender, []);\r\n }\r\n\r\n const componentMemos = memos.get(currentRender)!;\r\n const prevMemo = componentMemos[memoIndex];\r\n \r\n if (!prevMemo || (deps && deps.some((dep, i) => !Object.is(dep, prevMemo.deps[i])))) {\r\n const value = factory();\r\n componentMemos[memoIndex] = { value, deps };\r\n stateIndices.set(currentRender, memoIndex + 1);\r\n return value;\r\n }\r\n\r\n stateIndices.set(currentRender, memoIndex + 1);\r\n return prevMemo.value;\r\n}\r\n\r\nexport function useRef<T>(initial: T) {\r\n if (!currentRender) throw new Error('useRef must be called within a render');\r\n \r\n const refIndex = stateIndices.get(currentRender)!;\r\n \r\n if (!refs.has(currentRender)) {\r\n refs.set(currentRender, []);\r\n }\r\n\r\n const componentRefs = refs.get(currentRender)!;\r\n if (refIndex >= componentRefs.length) {\r\n // Initialize with an object that has a current property\r\n const ref = { current: initial };\r\n componentRefs.push(ref);\r\n stateIndices.set(currentRender, refIndex + 1);\r\n return ref;\r\n }\r\n\r\n const ref = componentRefs[refIndex];\r\n stateIndices.set(currentRender, refIndex + 1);\r\n return ref;\r\n}\r\n\r\n// Add a map to track component DOM nodes\r\nconst componentNodes = new Map<Function, Node>();\r\n\r\nasync function rerender(rendererId: number) {\r\n try {\r\n // Clean up effects\r\n const componentEffects = effects.get(rendererId);\r\n if (componentEffects) {\r\n componentEffects.forEach(effect => {\r\n if (effect.cleanup) effect.cleanup();\r\n });\r\n effects.set(rendererId, []);\r\n }\r\n\r\n if (globalRenderCallback && globalContainer && currentElement) {\r\n await globalRenderCallback(currentElement, globalContainer);\r\n }\r\n } catch (error) {\r\n console.error('Error during rerender:', error);\r\n }\r\n}\r\n\r\n// Add new hook for error boundaries\r\nexport function useErrorBoundary(): [Error | null, () => void] {\r\n const [error, setError] = useState<Error | null>(null);\r\n return [error, () => setError(null)];\r\n}\r\n\r\n// Remove withHooks export\r\n","/**\r\n * Context API for state sharing between components\r\n */\r\n\r\nconst contexts = new Map<symbol, any>();\r\nlet currentRender: Function | null = null;\r\n\r\n/**\r\n * Interface for context objects\r\n */\r\nexport interface Context<T = any> {\r\n /** \r\n * The display name of the context \r\n */\r\n displayName?: string;\r\n \r\n /** \r\n * The current context value \r\n */\r\n currentValue: T;\r\n \r\n /**\r\n * Providers using this context\r\n */\r\n providers: Set<any>;\r\n}\r\n\r\n/**\r\n * Creates a context object with the specified default value\r\n * @param defaultValue The default value for the context\r\n */\r\nexport function createContext<T>(defaultValue: T): Context<T> {\r\n const context: Context<T> = {\r\n currentValue: defaultValue,\r\n providers: new Set()\r\n };\r\n \r\n return context;\r\n}\r\n\r\n/**\r\n * Get the current value of a context\r\n * @param context The context object\r\n */\r\nexport function useContext<T>(context: Context<T>): T {\r\n // In a real implementation, this would check for providers up the component tree\r\n return context.currentValue;\r\n}\r\n","// src/hooks.ts\r\ninterface VNode {\r\n type: string | Function;\r\n props: Record<string, any>;\r\n}\r\n\r\nfunction jsx(type: string | Function, props: any): VNode {\r\n console.log('JSX Transform:', { type, props });\r\n const processedProps = { ...props };\r\n \r\n // Handle children properly\r\n if (arguments.length > 2) {\r\n processedProps.children = Array.prototype.slice.call(arguments, 2);\r\n }\r\n \r\n return { type, props: processedProps };\r\n}\r\n\r\nconst Fragment = ({ children }: { children: any }) => children;\r\n\r\nasync function createElement(vnode: VNode | any): Promise<Node> {\r\n console.log('Creating element from:', vnode);\r\n\r\n // Handle primitives and null\r\n if (vnode == null) {\r\n return document.createTextNode('');\r\n }\r\n \r\n if (typeof vnode === 'boolean') {\r\n return document.createTextNode('');\r\n }\r\n\r\n if (typeof vnode === 'number' || typeof vnode === 'string') {\r\n return document.createTextNode(String(vnode));\r\n }\r\n\r\n // Handle arrays\r\n if (Array.isArray(vnode)) {\r\n const fragment = document.createDocumentFragment();\r\n for (const child of vnode) {\r\n const node = await createElement(child);\r\n fragment.appendChild(node);\r\n }\r\n return fragment;\r\n }\r\n\r\n // Handle VNode\r\n if ('type' in vnode && vnode.props !== undefined) {\r\n const { type, props } = vnode;\r\n \r\n // Handle function components\r\n if (typeof type === 'function') {\r\n try {\r\n const result = await type(props || {});\r\n const node = await createElement(result);\r\n if (node instanceof Element) {\r\n node.setAttribute('data-component-id', type.name || type.toString());\r\n }\r\n return node;\r\n } catch (error) {\r\n console.error('Error rendering component:', error);\r\n return document.createTextNode('');\r\n }\r\n }\r\n\r\n // Create DOM element\r\n const element = document.createElement(type as string);\r\n \r\n // Handle props\r\n for (const [key, value] of Object.entries(props || {})) {\r\n if (key === 'children') continue;\r\n if (key.startsWith('on') && typeof value === 'function') {\r\n const eventName = key.toLowerCase().slice(2);\r\n // Remove existing event listener if any\r\n const existingHandler = (element as any).__events?.[eventName];\r\n if (existingHandler) {\r\n element.removeEventListener(eventName, existingHandler);\r\n }\r\n \r\n // Add new event listener\r\n element.addEventListener(eventName, value as EventListener);\r\n if (!(element as any).__events) {\r\n (element as any).__events = {};\r\n }\r\n (element as any).__events[eventName] = value;\r\n } else if (key === 'style' && typeof value === 'object') {\r\n Object.assign(element.style, value);\r\n } else if (key === 'className') {\r\n element.setAttribute('class', String(value));\r\n } else if (key !== 'key' && key !== 'ref') {\r\n element.setAttribute(key, String(value));\r\n }\r\n }\r\n\r\n // Handle children\r\n const children = props?.children;\r\n if (children != null) {\r\n const childArray = Array.isArray(children) ? children.flat() : [children];\r\n for (const child of childArray) {\r\n const childNode = await createElement(child);\r\n element.appendChild(childNode);\r\n }\r\n }\r\n\r\n return element;\r\n }\r\n\r\n // Handle other objects by converting to string\r\n return document.createTextNode(String(vnode));\r\n}\r\n\r\n// Export named functions and aliases without duplicates\r\nexport {\r\n jsx,\r\n jsx as jsxs,\r\n jsx as jsxDEV,\r\n Fragment,\r\n createElement\r\n};\r\n\r\n// Named exports object\r\nconst jsxRuntime = {\r\n jsx,\r\n jsxs: jsx,\r\n jsxDEV: jsx,\r\n Fragment,\r\n createElement\r\n};\r\n\r\nexport default jsxRuntime;\r\n","import { createElement } from './jsx-runtime.js';\r\nimport { prepareRender, finishRender, setRenderCallback } from './hooks.js';\r\nimport { batchUpdates } from './batch.js';\r\n\r\nlet isHydrating = false;\r\n\r\nexport async function hydrate(element: any, container: HTMLElement) {\r\n isHydrating = true;\r\n try {\r\n await render(element, container);\r\n } finally {\r\n isHydrating = false;\r\n }\r\n}\r\n\r\nexport async function render(element: any, container: HTMLElement) {\r\n console.log('Rendering to:', container.id);\r\n \r\n batchUpdates(async () => {\r\n const rendererId = prepareRender();\r\n try {\r\n setRenderCallback(render, element, container);\r\n const domNode = await createElement(element);\r\n \r\n if (!isHydrating) {\r\n container.innerHTML = '';\r\n }\r\n container.appendChild(domNode);\r\n \r\n } finally {\r\n finishRender();\r\n }\r\n });\r\n}\r\n","import { VNode, Component } from './types.js';\r\nimport { prepareRender, finishRender } from './hooks.js';\r\n\r\n/**\r\n * Renders a virtual DOM tree to an HTML string\r\n */\r\nexport function renderToString(vnode: VNode): string {\r\n // Reset hook state for this render\r\n prepareRender();\r\n \r\n // Render the tree to HTML\r\n const html = renderNodeToString(vnode);\r\n \r\n // Clean up after rendering\r\n finishRender();\r\n \r\n return html;\r\n}\r\n\r\n/**\r\n * Internal function to convert a virtual node to an HTML string\r\n */\r\nfunction renderNodeToString(vnode: VNode | string | number | boolean | null | undefined): string {\r\n // Handle primitive values\r\n if (vnode === null || vnode === undefined) return '';\r\n if (typeof vnode === 'boolean') return '';\r\n if (typeof vnode === 'number' || typeof vnode === 'string') return escapeHtml(String(vnode));\r\n \r\n // Handle function components\r\n if (typeof vnode.type === 'function') {\r\n const Component = vnode.type as Component;\r\n const renderedNode = Component(vnode.props || {});\r\n return renderNodeToString(renderedNode);\r\n }\r\n \r\n // Handle intrinsic elements (regular HTML tags)\r\n if (typeof vnode.type === 'string') {\r\n const tag = vnode.type;\r\n let attrs = '';\r\n let children = '';\r\n \r\n // Convert props to HTML attributes\r\n if (vnode.props) {\r\n for (const [key, value] of Object.entries(vnode.props)) {\r\n // Skip children prop as we handle it separately\r\n if (key === 'children') continue;\r\n \r\n // Skip event handlers (they start with 'on')\r\n if (key.startsWith('on')) continue;\r\n \r\n // Handle the className prop specially\r\n if (key === 'className') {\r\n attrs += ` class=\"${escapeHtml(value as string)}\"`;\r\n continue;\r\n }\r\n \r\n // Handle other attributes\r\n if (typeof value === 'string' || typeof value === 'number') {\r\n attrs += ` ${key}=\"${escapeHtml(String(value))}\"`;\r\n } else if (value === true) {\r\n // Boolean attributes\r\n attrs += ` ${key}`;\r\n }\r\n }\r\n }\r\n \r\n // Process children\r\n const childrenArray = (vnode.props?.children) \r\n ? Array.isArray(vnode.props.children) \r\n ? vnode.props.children \r\n : [vnode.props.children]\r\n : [];\r\n \r\n for (const child of childrenArray) {\r\n children += renderNodeToString(child);\r\n }\r\n \r\n // Self-closing tags\r\n const selfClosing = [\r\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\r\n 'link', 'meta', 'param', 'source', 'track', 'wbr'\r\n ];\r\n \r\n if (selfClosing.includes(tag)) {\r\n return `<${tag}${attrs}/>`;\r\n }\r\n \r\n // Regular tags with closing\r\n return `<${tag}${attrs}>${children}</${tag}>`;\r\n }\r\n \r\n // Handle fragments\r\n if (vnode.type === Symbol.for('react.fragment')) {\r\n let fragmentOutput = '';\r\n const children = Array.isArray(vnode.props?.children)\r\n ? vnode.props.children\r\n : vnode.props?.children ? [vnode.props.children] : [];\r\n \r\n for (const child of children) {\r\n fragmentOutput += renderNodeToString(child);\r\n }\r\n \r\n return fragmentOutput;\r\n }\r\n \r\n // Fallback for unknown node types\r\n console.warn('Unknown vnode type:', vnode.type);\r\n return '';\r\n}\r\n\r\n/**\r\n * Escape HTML special characters to prevent XSS\r\n */\r\nfunction escapeHtml(text: string): string {\r\n return text\r\n .replace(/&/g, '&')\r\n .replace(/</g, '<')\r\n .replace(/>/g, '>')\r\n .replace(/\"/g, '"')\r\n .replace(/'/g, ''');\r\n}\r\n","\r\nexport { \r\n useState, \r\n useEffect, \r\n useMemo, \r\n useRef,\r\n useErrorBoundary \r\n} from './hooks.js';\r\n\r\nexport { createContext, useContext } from './context.js';\r\nexport { batchUpdates } from './batch.js';\r\nexport { jsx, jsxs, Fragment } from './jsx-runtime.js';\r\nexport { render, hydrate } from './renderer.js';\r\nexport { renderToString } from './server-renderer.js';\r\n\r\n// Re-export types for client-side usage\r\nexport type { Context } from './context.js';\r\nexport type { VNode } from './types.js';\r\n\r\n// Export server types for type checking\r\nexport type {\r\n Server,\r\n ServerConfig,\r\n User,\r\n DbConfig,\r\n MiddlewareFunction\r\n} from './server-types.js';\r\n\r\n// Provide placeholder server functionality\r\nexport const server = {\r\n async getServer() {\r\n throw new Error('Server module can only be used in Node.js environment');\r\n }\r\n};\r\n\r\nlet isHydrating = false;\r\n"],"names":["index","state","setState","ref","Component"],"mappings":"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"}
|
package/package.json
CHANGED
@@ -32,7 +32,86 @@ function ensureDir(dir) {
|
|
32
32
|
}
|
33
33
|
}
|
34
34
|
|
35
|
-
// Build Go WASM
|
35
|
+
// Build a single Go file to WASM
|
36
|
+
export async function buildGoFile(goFilePath, wasmFilePath) {
|
37
|
+
try {
|
38
|
+
if (!fs.existsSync(goFilePath)) {
|
39
|
+
throw new Error(`Go file not found: ${goFilePath}`);
|
40
|
+
}
|
41
|
+
|
42
|
+
console.log(`Building ${goFilePath} to ${wasmFilePath}`);
|
43
|
+
|
44
|
+
// Create a unique temporary directory with timestamp
|
45
|
+
const timestamp = Date.now();
|
46
|
+
const tempDir = join(os.tmpdir(), `go-wasm-build-${timestamp}`);
|
47
|
+
|
48
|
+
// Ensure the directory is clean
|
49
|
+
if (fs.existsSync(tempDir)) {
|
50
|
+
if (isWindows) {
|
51
|
+
execSync(`rmdir /s /q "${tempDir}"`, { shell: true });
|
52
|
+
} else {
|
53
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
// Create the temporary directory
|
58
|
+
ensureDir(tempDir);
|
59
|
+
|
60
|
+
// Copy the Go file to the temp directory
|
61
|
+
const goFileName = goFilePath.split(/[/\\]/).pop();
|
62
|
+
const tempGoFile = join(tempDir, goFileName);
|
63
|
+
fs.copyFileSync(goFilePath, tempGoFile);
|
64
|
+
|
65
|
+
// Initialize Go module
|
66
|
+
console.log(`Initializing Go module in ${tempDir}`);
|
67
|
+
execSync(`go mod init wasmapp`, { cwd: tempDir });
|
68
|
+
|
69
|
+
// Build the WASM module with OS-specific command
|
70
|
+
if (isWindows) {
|
71
|
+
// Windows-specific environment variable setting
|
72
|
+
execSync(`go build -o "${wasmFilePath}" "${tempGoFile}"`, {
|
73
|
+
cwd: tempDir,
|
74
|
+
env: {
|
75
|
+
...process.env,
|
76
|
+
GOOS: 'js',
|
77
|
+
GOARCH: 'wasm'
|
78
|
+
}
|
79
|
+
});
|
80
|
+
} else {
|
81
|
+
// Unix/Linux/Mac command
|
82
|
+
execSync(`GOOS=js GOARCH=wasm go build -o "${wasmFilePath}" "${tempGoFile}"`, {
|
83
|
+
cwd: tempDir
|
84
|
+
});
|
85
|
+
}
|
86
|
+
|
87
|
+
// Clean up temporary directory
|
88
|
+
try {
|
89
|
+
if (isWindows) {
|
90
|
+
execSync(`rmdir /s /q "${tempDir}"`, { shell: true });
|
91
|
+
} else {
|
92
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
93
|
+
}
|
94
|
+
} catch (cleanupError) {
|
95
|
+
console.warn(`Warning: Failed to clean up temp directory ${tempDir}:`, cleanupError);
|
96
|
+
}
|
97
|
+
|
98
|
+
console.log(`✓ Successfully built ${goFileName} to WASM`);
|
99
|
+
return {
|
100
|
+
success: true,
|
101
|
+
wasmPath: wasmFilePath,
|
102
|
+
goFile: goFilePath
|
103
|
+
};
|
104
|
+
} catch (error) {
|
105
|
+
console.error(`✗ Error building ${goFilePath}:`, error);
|
106
|
+
return {
|
107
|
+
success: false,
|
108
|
+
error: error.message,
|
109
|
+
goFile: goFilePath
|
110
|
+
};
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
// Build all Go WASM modules
|
36
115
|
async function buildWasmModules() {
|
37
116
|
// Check if Go is installed
|
38
117
|
if (!checkGoInstallation()) {
|
@@ -65,92 +144,13 @@ async function buildWasmModules() {
|
|
65
144
|
console.log(`Copying ${wasmExecNodeJsPath} to ${wasmExecNodeJsDest}`);
|
66
145
|
fs.copyFileSync(wasmExecNodeJsPath, wasmExecNodeJsDest);
|
67
146
|
|
68
|
-
//
|
69
|
-
const goFiles = fs.
|
147
|
+
// Generate a default example.go file if no Go files exist
|
148
|
+
const goFiles = fs.existsSync(goSourceDir) ?
|
149
|
+
fs.readdirSync(goSourceDir).filter(file => file.endsWith('.go')) : [];
|
70
150
|
|
71
151
|
if (goFiles.length === 0) {
|
72
|
-
console.log('No Go files found
|
73
|
-
|
74
|
-
// Create an example Go file
|
75
|
-
const exampleGoFile = join(goSourceDir, 'example.go');
|
76
|
-
const exampleGoContent = `//go:build js && wasm
|
77
|
-
// +build js,wasm
|
78
|
-
|
79
|
-
package main
|
80
|
-
|
81
|
-
import (
|
82
|
-
"encoding/json"
|
83
|
-
"fmt"
|
84
|
-
"syscall/js"
|
85
|
-
)
|
86
|
-
|
87
|
-
// Example Go function to be called from JavaScript
|
88
|
-
func add(this js.Value, args []js.Value) interface{} {
|
89
|
-
if len(args) != 2 {
|
90
|
-
return js.ValueOf("Error: Expected two arguments")
|
91
|
-
}
|
92
|
-
|
93
|
-
a := args[0].Int()
|
94
|
-
b := args[1].Int()
|
95
|
-
return js.ValueOf(a + b)
|
96
|
-
}
|
97
|
-
|
98
|
-
// Process complex data in Go
|
99
|
-
func processData(this js.Value, args []js.Value) interface{} {
|
100
|
-
if len(args) == 0 {
|
101
|
-
return js.ValueOf("Error: Expected at least one argument")
|
102
|
-
}
|
103
|
-
|
104
|
-
// Get input data
|
105
|
-
data := args[0]
|
106
|
-
if data.Type() != js.TypeObject {
|
107
|
-
return js.ValueOf("Error: Expected JSON object")
|
108
|
-
}
|
109
|
-
|
110
|
-
// Convert JS object to Go map
|
111
|
-
jsonStr := js.Global().Get("JSON").Call("stringify", data).String()
|
112
|
-
var inputMap map[string]interface{}
|
113
|
-
if err := json.Unmarshal([]byte(jsonStr), &inputMap); err != nil {
|
114
|
-
return js.ValueOf(fmt.Sprintf("Error parsing JSON: %s", err.Error()))
|
115
|
-
}
|
116
|
-
|
117
|
-
// Add new fields
|
118
|
-
inputMap["processed"] = true
|
119
|
-
inputMap["processor"] = "Go WASM"
|
120
|
-
|
121
|
-
// Add some computed fields
|
122
|
-
if values, ok := inputMap["values"].([]interface{}); ok {
|
123
|
-
sum := 0.0
|
124
|
-
for _, v := range values {
|
125
|
-
if num, ok := v.(float64); ok {
|
126
|
-
sum += num
|
127
|
-
}
|
128
|
-
}
|
129
|
-
inputMap["sum"] = sum
|
130
|
-
}
|
131
|
-
|
132
|
-
// Convert back to JS
|
133
|
-
resultJSON, err := json.Marshal(inputMap)
|
134
|
-
if err != nil {
|
135
|
-
return js.ValueOf(fmt.Sprintf("Error generating JSON: %s", err.Error()))
|
136
|
-
}
|
137
|
-
|
138
|
-
return js.ValueOf(string(resultJSON))
|
139
|
-
}
|
140
|
-
|
141
|
-
func main() {
|
142
|
-
fmt.Println("Go WASM Module initialized")
|
143
|
-
|
144
|
-
// Register functions to be callable from JavaScript
|
145
|
-
js.Global().Set("goAdd", js.FuncOf(add))
|
146
|
-
js.Global().Set("goProcessData", js.FuncOf(processData))
|
147
|
-
|
148
|
-
// Keep the program running
|
149
|
-
<-make(chan bool)
|
150
|
-
}
|
151
|
-
`;
|
152
|
+
console.log('No Go files found. Creating example.go...');
|
152
153
|
|
153
|
-
fs.writeFileSync(exampleGoFile, exampleGoContent);
|
154
154
|
console.log(`Created example Go file at ${exampleGoFile}`);
|
155
155
|
|
156
156
|
// Add the new file to the list
|