semajsx 0.1.1 → 0.1.2
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/{computed-BpjqvQu1.mjs → computed-BidG06Lt.mjs} +2 -2
- package/dist/{computed-BpjqvQu1.mjs.map → computed-BidG06Lt.mjs.map} +1 -1
- package/dist/{document-OGuk9jhK.mjs → document-BOJDaiBc.mjs} +19 -4
- package/dist/document-BOJDaiBc.mjs.map +1 -0
- package/dist/{document-DFsOtfef.mjs → document-CwHVG_PJ.mjs} +2 -2
- package/dist/dom/index.d.mts +68 -3
- package/dist/dom/index.d.mts.map +1 -1
- package/dist/dom/index.mjs +4 -4
- package/dist/dom/jsx-dev-runtime.d.mts +4 -4
- package/dist/dom/jsx-dev-runtime.mjs +1 -1
- package/dist/dom/jsx-runtime.d.mts +4 -4
- package/dist/dom/jsx-runtime.mjs +2 -2
- package/dist/{helpers-DrifjCXb.d.mts → helpers-CfRDJgcP.d.mts} +3 -3
- package/dist/{helpers-DrifjCXb.d.mts.map → helpers-CfRDJgcP.d.mts.map} +1 -1
- package/dist/{index-DS5X3Pvb.d.mts → index-B1pjI-Su.d.mts} +2 -2
- package/dist/{index-DS5X3Pvb.d.mts.map → index-B1pjI-Su.d.mts.map} +1 -1
- package/dist/index-DC3tthWf.d.mts +81 -0
- package/dist/index-DC3tthWf.d.mts.map +1 -0
- package/dist/index.d.mts +7 -7
- package/dist/index.mjs +5 -5
- package/dist/{island-marker-hZdmHMvx.d.mts → island-marker-BJIO07Vj.d.mts} +1 -1
- package/dist/island-marker-BJIO07Vj.d.mts.map +1 -0
- package/dist/{jsx-CGW4OyqA.d.mts → jsx-fNlLjLou.d.mts} +2 -2
- package/dist/{jsx-CGW4OyqA.d.mts.map → jsx-fNlLjLou.d.mts.map} +1 -1
- package/dist/{jsx-runtime-DU8DRISG.d.mts → jsx-runtime-BFuFPDzn.d.mts} +3 -3
- package/dist/{jsx-runtime-DU8DRISG.d.mts.map → jsx-runtime-BFuFPDzn.d.mts.map} +1 -1
- package/dist/jsx-runtime-D9ZNjMJ2.mjs.map +1 -1
- package/dist/{jsx-runtime-mBpL8czJ.d.mts → jsx-runtime-DZx2Yv-t.d.mts} +28 -6
- package/dist/{jsx-runtime-mBpL8czJ.d.mts.map → jsx-runtime-DZx2Yv-t.d.mts.map} +1 -1
- package/dist/lucide-CVtHepGM.mjs +126 -0
- package/dist/lucide-CVtHepGM.mjs.map +1 -0
- package/dist/{resource-B1IudM8_.d.mts → resource-BQI6AeJ0.d.mts} +23 -3
- package/dist/resource-BQI6AeJ0.d.mts.map +1 -0
- package/dist/{resource-BjsDAkbG.mjs → resource-DSlXDZZi.mjs} +2 -2
- package/dist/{resource-BjsDAkbG.mjs.map → resource-DSlXDZZi.mjs.map} +1 -1
- package/dist/signal/index.d.mts +2 -2
- package/dist/signal/index.mjs +3 -3
- package/dist/{signal-4PgGfydw.mjs → signal-BN8vHXDb.mjs} +1 -1
- package/dist/{signal-4PgGfydw.mjs.map → signal-BN8vHXDb.mjs.map} +1 -1
- package/dist/{signal-CLsaPA7c.d.mts → signal-BwxUlXKs.d.mts} +1 -1
- package/dist/{signal-CLsaPA7c.d.mts.map → signal-BwxUlXKs.d.mts.map} +1 -1
- package/dist/{src-CRi0xsNK.mjs → src-BqX3sryB.mjs} +68 -5
- package/dist/src-BqX3sryB.mjs.map +1 -0
- package/dist/src-DR-EWgVP.mjs +868 -0
- package/dist/src-DR-EWgVP.mjs.map +1 -0
- package/dist/{src-DEoBG1zB.mjs → src-DUpFNNM_.mjs} +4 -4
- package/dist/{src-DEoBG1zB.mjs.map → src-DUpFNNM_.mjs.map} +1 -1
- package/dist/{src-BlS3Hc-L.mjs → src-DW3tIczg.mjs} +75 -5
- package/dist/src-DW3tIczg.mjs.map +1 -0
- package/dist/{src-Jbt_w0hc.mjs → src-Ds9vl42d.mjs} +37 -35
- package/dist/src-Ds9vl42d.mjs.map +1 -0
- package/dist/{src-iC-NFwTy.mjs → src-DuSN6go_.mjs} +79 -22
- package/dist/src-DuSN6go_.mjs.map +1 -0
- package/dist/ssg/index.d.mts +4 -182
- package/dist/ssg/index.d.mts.map +1 -1
- package/dist/ssg/index.mjs +7 -756
- package/dist/ssg/index.mjs.map +1 -1
- package/dist/ssg/plugins/docs-theme.d.mts +180 -0
- package/dist/ssg/plugins/docs-theme.d.mts.map +1 -0
- package/dist/ssg/plugins/docs-theme.mjs +2042 -0
- package/dist/ssg/plugins/docs-theme.mjs.map +1 -0
- package/dist/ssg/plugins/lucide.d.mts +3 -0
- package/dist/ssg/plugins/lucide.mjs +7 -0
- package/dist/ssr/client.d.mts +3 -3
- package/dist/ssr/client.mjs +5 -5
- package/dist/ssr/index.d.mts +3 -3
- package/dist/ssr/index.d.mts.map +1 -1
- package/dist/ssr/index.mjs +6 -5
- package/dist/style/index.d.mts +2 -2
- package/dist/style/index.d.mts.map +1 -1
- package/dist/style/index.mjs +1 -1
- package/dist/style/react.d.mts +2 -2
- package/dist/style/react.mjs +2 -2
- package/dist/style/vue.d.mts +2 -2
- package/dist/style/vue.mjs +2 -2
- package/dist/terminal/index.d.mts +4 -4
- package/dist/terminal/index.mjs +2 -2
- package/dist/terminal/jsx-dev-runtime.d.mts +4 -4
- package/dist/terminal/jsx-dev-runtime.mjs +1 -1
- package/dist/terminal/jsx-runtime.d.mts +4 -4
- package/dist/terminal/jsx-runtime.mjs +1 -1
- package/dist/{types-DlNR9ZaJ.d.mts → types-BlaUrkq0.d.mts} +2 -2
- package/dist/{types-DlNR9ZaJ.d.mts.map → types-BlaUrkq0.d.mts.map} +1 -1
- package/dist/types-CGkRxnQB.d.mts +220 -0
- package/dist/types-CGkRxnQB.d.mts.map +1 -0
- package/dist/{types-Dgj6n-EE.d.mts → types-CZMcXQTW.d.mts} +9 -4
- package/dist/types-CZMcXQTW.d.mts.map +1 -0
- package/dist/{types-Bjx1Pp14.d.mts → types-D0jRO840.d.mts} +1 -1
- package/dist/{types-Bjx1Pp14.d.mts.map → types-D0jRO840.d.mts.map} +1 -1
- package/dist/{types-DEi0apQO.d.mts → types-DucvOZQ2.d.mts} +2 -2
- package/dist/{types-DEi0apQO.d.mts.map → types-DucvOZQ2.d.mts.map} +1 -1
- package/dist/{utils-BrGmTgfG.mjs → utils-DbTAs943.mjs} +1 -1
- package/dist/{utils-BrGmTgfG.mjs.map → utils-DbTAs943.mjs.map} +1 -1
- package/package.json +30 -2
- package/dist/document-OGuk9jhK.mjs.map +0 -1
- package/dist/island-marker-hZdmHMvx.d.mts.map +0 -1
- package/dist/jsx-runtime-D2B2BK8X.mjs +0 -4
- package/dist/resource-B1IudM8_.d.mts.map +0 -1
- package/dist/src-BlS3Hc-L.mjs.map +0 -1
- package/dist/src-CRi0xsNK.mjs.map +0 -1
- package/dist/src-Jbt_w0hc.mjs.map +0 -1
- package/dist/src-iC-NFwTy.mjs.map +0 -1
- package/dist/types-Dgj6n-EE.d.mts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"src-DW3tIczg.mjs","names":[],"sources":["../../core/src/types.ts","../../core/src/vnode.ts","../../core/src/shared/island-marker.ts","../../core/src/context.ts","../../core/src/helpers.ts","../../core/src/jsx.ts","../../core/src/component.ts","../../core/src/render-core.ts"],"sourcesContent":["import type { ReadableSignal, WritableSignal } from \"./signal\";\n\n/**\n * Special VNode type for fragment support\n */\nexport const Fragment: symbol = Symbol.for(\"semajsx.fragment\");\n\n/**\n * Special VNode type for portal support\n */\nexport const Portal: symbol = Symbol.for(\"semajsx.portal\");\n\n/**\n * Special VNode type for forward support\n * Forward merges its props onto its single child element without producing a DOM node\n */\nexport const Forward: symbol = Symbol.for(\"semajsx.forward\");\n\n/**\n * VNode types\n * - The runtime VNode tree always resolves to these `type` values\n */\nexport type VNodeType = string | Component<any> | typeof Fragment | typeof Portal | typeof Forward;\n\n/**\n * VNode: The basic unit of the runtime render tree\n * - `type`: the element/component type\n * - `props`: attributes or props passed to the node (may be null)\n * - `children`: resolved child nodes (always normalized to VNode[] at render time)\n */\nexport interface VNode {\n type: VNodeType;\n props: Record<string, any> | null;\n children: VNode[];\n key?: string | number | null;\n}\n\n/**\n * Primitive values allowed in JSX\n * - These are normalized during VNode construction\n */\nexport type JSXPrimitive = string | number | boolean | null | undefined;\n\n/**\n * A JSXNode represents any valid \"JSX expression result\"\n * - Could be a raw VNode/primitive, or wrapped in a reactive/async container\n */\nexport type JSXNode =\n | VNode\n | JSXPrimitive\n | Iterable<JSXNode>\n | ReadableSignal<JSXNode>\n | Promise<JSXNode>\n | AsyncIterableIterator<JSXNode>;\n\n/**\n * Component type\n * - Optional `ctx` parameter allows passing in custom API/runtime helpers\n */\nexport type Component<P = any> = (props: P, ctx?: ComponentAPI) => JSXNode;\n\n/**\n * ComponentAPI - Runtime API available to components via second parameter\n */\nexport interface ComponentAPI {\n /**\n * Inject a context value\n * @param context - The context to inject\n * @returns The current value of the context, or undefined if not provided\n */\n inject<T>(context: Context<T>): T | undefined;\n}\n\n/**\n * Ref types\n */\n\n/**\n * Ref - can be a WritableSignal or a callback function\n * This allows both reactive refs and imperative refs\n */\nexport type Ref<T> = WritableSignal<T | null> | ((instance: T | null) => void);\n\n/**\n * Context types\n */\n\n/**\n * Context - a typed Symbol for identifying context\n */\nexport type Context<T> = symbol & { __type?: T };\n\n/**\n * Context provide entry: [Context, value]\n */\nexport type ContextProvide<T = any> = [Context<T>, T];\n\n/**\n * Context component props - supports single or multiple context provides\n */\nexport interface ContextProps {\n // Single context: [ThemeContext, theme]\n // Multiple contexts: [[ThemeContext, theme], [UserContext, user]]\n provide: ContextProvide | ContextProvide[];\n children?: JSXNode;\n}\n\n/**\n * Helper type to allow Signal values for any attribute\n */\nexport type SignalOr<T> = T | ReadableSignal<T>;\n\n/**\n * Makes all properties in T accept Signal values\n * Excludes event handlers (functions) and children\n */\nexport type WithSignals<T> = {\n [K in keyof T]: K extends `on${string}`\n ? T[K] // Event handlers don't need Signal wrapper\n : K extends \"children\"\n ? T[K] // Children handled separately\n : T[K] extends (...args: any[]) => any\n ? T[K] // Other functions don't need Signal wrapper\n : SignalOr<T[K]>;\n};\n\n/**\n * Adds key property to element attributes for list reconciliation\n */\nexport type WithKey<T> = T & {\n key?: string | number;\n};\n","import type { JSXNode, VNode, VNodeType } from \"./types\";\nimport type { Signal } from \"@semajsx/signal\";\nimport { Fragment } from \"./types\";\nimport { isSignal } from \"@semajsx/signal\";\n\n/**\n * Create a VNode (Virtual Node)\n */\nexport function h(\n type: VNodeType,\n props: Record<string, any> | null,\n ...children: JSXNode[]\n): VNode {\n return {\n type,\n props: props || {},\n children: normalizeChildren(children),\n key: props?.key,\n };\n}\n\n/**\n * Create a text VNode\n */\nexport function createTextVNode(text: string | number): VNode {\n return {\n type: \"#text\",\n props: { nodeValue: String(text) },\n children: [],\n };\n}\n\n/**\n * Create a signal VNode wrapper\n */\nexport function createSignalVNode(signal: Signal<unknown>): VNode {\n return {\n type: \"#signal\",\n props: { signal },\n children: [],\n };\n}\n\n/**\n * Normalize children into an array of VNodes\n */\nfunction normalizeChildren(children: JSXNode[]): VNode[] {\n const result: VNode[] = [];\n\n for (const child of children) {\n if (child == null || typeof child === \"boolean\") {\n // Skip nullish and boolean values\n continue;\n }\n\n if (Array.isArray(child)) {\n // Recursively flatten arrays\n result.push(...normalizeChildren(child));\n } else if (typeof child === \"string\" || typeof child === \"number\") {\n // Convert primitives to text nodes\n result.push(createTextVNode(child));\n } else if (isSignal(child)) {\n // Wrap signals in special signal nodes\n result.push(createSignalVNode(child));\n } else if (isVNode(child)) {\n // Already a VNode\n result.push(child);\n } else {\n // Unknown type, skip\n console.warn(\"Unknown child type:\", typeof child);\n }\n }\n\n return result;\n}\n\n/**\n * Check if a value is a VNode\n */\nexport function isVNode(value: unknown): value is VNode {\n return (\n value != null &&\n typeof value === \"object\" &&\n \"type\" in value &&\n \"props\" in value &&\n \"children\" in value\n );\n}\n\n/**\n * Create a Fragment\n */\nexport function createFragment(children: JSXNode[]): VNode {\n return h(Fragment, null, ...children);\n}\n","/**\n * Unique symbol to mark Island components\n * This symbol is used to identify components that should be hydrated on the client\n */\nexport const ISLAND_MARKER: symbol = Symbol.for(\"semajsx.island\");\n","/**\n * Context API implementation\n */\n\nimport { h } from \"./vnode\";\nimport { Fragment } from \"./types\";\nimport type { ComponentAPI, Context as ContextType, ContextProps, VNode } from \"./types\";\n\n// Context map type - stores context values for current render environment\nexport type ContextMap = Map<symbol, any>;\n\n/**\n * Create a new Context (returns a typed Symbol)\n *\n * @param name - Optional name for debugging (defaults to \"anonymous\")\n * @returns Context symbol\n *\n * @example\n * ```typescript\n * const ThemeContext = context<Theme>();\n * const UserContext = context<User>('user'); // With debug name\n *\n * <Context provide={[ThemeContext, theme]}>\n * <App />\n * </Context>\n * ```\n */\nexport function context<T>(name?: string): ContextType<T> {\n const debugName = name || \"anonymous\";\n return Symbol(debugName) as ContextType<T>;\n}\n\n/**\n * Context component - provides context values to child components\n *\n * @example\n * ```typescript\n * // Single context\n * <Context provide={[ThemeContext, theme]}>\n * <App />\n * </Context>\n *\n * // Multiple contexts\n * <Context provide={[\n * [ThemeContext, theme],\n * [UserContext, user]\n * ]}>\n * <App />\n * </Context>\n * ```\n */\nexport function Context(props: ContextProps): VNode {\n const children = props.children\n ? Array.isArray(props.children)\n ? props.children\n : [props.children]\n : [];\n return h(Fragment, null, ...children);\n}\n\n// Mark as special context provider component\n(Context as any).__isContextProvider = true;\n\n/**\n * Create ComponentAPI instance for a component\n *\n * @param contextMap - The context map for current render environment\n * @returns ComponentAPI instance\n */\nexport function createComponentAPI(contextMap: ContextMap): ComponentAPI {\n return {\n inject<T>(context: ContextType<T>): T | undefined {\n return contextMap.get(context);\n },\n };\n}\n","import type { JSXNode } from \"./types\";\nimport type { Signal } from \"@semajsx/signal\";\nimport { computed, signal } from \"@semajsx/signal\";\n\n/**\n * Conditional rendering helper\n *\n * Renders content when condition signal is true, nothing when false.\n *\n * @example\n * // With VNode\n * const hint = when(showHint, <text>Press Ctrl+C to exit</text>);\n *\n * @example\n * // With function (lazy evaluation)\n * const hint = when(showHint, () => <text>Press Ctrl+C to exit</text>);\n */\nexport function when(\n condition: Signal<boolean>,\n content: JSXNode | (() => JSXNode),\n): Signal<JSXNode | null> {\n return computed([condition], (show) => {\n if (!show) return null;\n return typeof content === \"function\" ? content() : content;\n });\n}\n\n/**\n * Async resource helper for Promise<VNode>\n *\n * Renders pending content (or null) while the promise is pending, then renders\n * the resolved VNode. Handle errors in the promise itself using .catch().\n *\n * @example\n * // Handle everything in the promise\n * const content = resource(\n * fetchData()\n * .then(data => <text>{data}</text>)\n * .catch(err => <text color=\"red\">Error: {err.message}</text>)\n * );\n *\n * @example\n * // With optional pending content\n * const content = resource(\n * fetchData().then(data => <text>{data}</text>),\n * <text>Loading...</text>\n * );\n */\nexport function resource(promise: Promise<JSXNode>, pending?: JSXNode): Signal<JSXNode | null> {\n const content = signal<JSXNode | null>(pending || null);\n\n promise\n .then((result) => {\n content.value = result;\n })\n .catch((err) => {\n console.error(\"Unhandled promise rejection in resource():\", err);\n });\n\n return content;\n}\n\n/**\n * Async stream helper for AsyncIterable<VNode>\n *\n * Renders each yielded VNode from the async iterator, replacing the previous\n * content with each new value.\n *\n * @example\n * async function* generateContent() {\n * yield <text>Loading...</text>;\n * const data = await fetchData();\n * yield <text>Data: {data}</text>;\n * }\n *\n * const content = stream(generateContent());\n */\nexport function stream(\n iterator: AsyncIterable<JSXNode>,\n pending?: JSXNode,\n): Signal<JSXNode | null> {\n const content = signal<JSXNode | null>(pending || null);\n\n (async () => {\n try {\n for await (const vnode of iterator) {\n content.value = vnode;\n }\n } catch (err) {\n console.error(\"Error in stream():\", err);\n }\n })();\n\n return content;\n}\n","import { VNode, VNodeType } from \"./types\";\nimport { h } from \"./vnode\";\n\nexport function jsx(type: VNodeType, props: any, key?: any): VNode {\n const { children, ...restProps } = props || {};\n\n if (key !== undefined) {\n restProps.key = key;\n }\n\n if (children !== undefined) {\n return h(type, restProps, children);\n }\n\n return h(type, restProps);\n}\n\nexport function jsxs(type: VNodeType, props: any, key?: any): VNode {\n const { children, ...restProps } = props || {};\n\n if (key !== undefined) {\n restProps.key = key;\n }\n\n if (children !== undefined) {\n const childArray = Array.isArray(children) ? children : [children];\n return h(type, restProps, ...childArray);\n }\n\n return h(type, restProps);\n}\n","import type { JSXNode, JSXPrimitive, VNode } from \"./types\";\nimport { Fragment } from \"./types\";\nimport { isSignal } from \"@semajsx/signal\";\nimport { createSignalVNode, createTextVNode, isVNode } from \"./vnode\";\n\n/**\n * Normalize the `children` prop passed to components so it mirrors React semantics.\n * - 0 children => undefined\n * - 1 child => the child itself\n * - >1 children => array\n */\nexport function normalizeChildrenProp(children: VNode[]): VNode | VNode[] | undefined {\n if (children.length === 0) {\n return undefined;\n }\n if (children.length === 1) {\n return children[0];\n }\n return children;\n}\n\n/**\n * Normalize any JSXNode result from a component into a concrete VNode.\n */\nexport function normalizeComponentResult(result: VNode | JSXPrimitive | Iterable<JSXNode>): VNode {\n if (isVNode(result)) {\n return result;\n }\n\n if (typeof result === \"string\" || typeof result === \"number\") {\n return createTextVNode(result);\n }\n\n if (result == null || typeof result === \"boolean\") {\n return createTextVNode(\"\");\n }\n\n if (Array.isArray(result) || isIterable(result)) {\n const normalizedChildren = normalizeIterableChildren(result);\n return {\n type: Fragment,\n props: {},\n children: normalizedChildren,\n };\n }\n\n throw new Error(`Invalid component return type: ${typeof result}`);\n}\n\nfunction normalizeIterableChildren(children: Iterable<JSXNode>): VNode[] {\n const normalized: VNode[] = [];\n\n for (const child of children) {\n if (child == null || typeof child === \"boolean\") {\n continue;\n }\n\n if (Array.isArray(child) || isIterable(child)) {\n normalized.push(...normalizeIterableChildren(child as Iterable<JSXNode>));\n continue;\n }\n\n if (typeof child === \"string\" || typeof child === \"number\") {\n normalized.push(createTextVNode(child));\n continue;\n }\n\n if (isSignal(child)) {\n normalized.push(createSignalVNode(child));\n continue;\n }\n\n if (isVNode(child)) {\n normalized.push(child);\n continue;\n }\n\n throw new Error(`Invalid child in iterable: ${typeof child}`);\n }\n\n return normalized;\n}\n\nfunction isIterable(value: unknown): value is Iterable<unknown> {\n return value != null && typeof (value as any)[Symbol.iterator] === \"function\";\n}\n","import type { VNode, Ref } from \"./types\";\nimport { Fragment, Forward, Portal } from \"./types\";\nimport { isSignal } from \"@semajsx/signal\";\nimport { isVNode } from \"./vnode\";\nimport { resource, stream } from \"./helpers\";\nimport { type ContextMap, createComponentAPI } from \"./context\";\nimport { normalizeChildrenProp, normalizeComponentResult } from \"./component\";\n\n/**\n * Generic rendered node structure\n */\nexport interface RenderedNode<TNode> {\n vnode: VNode;\n node: TNode | null;\n subscriptions: Array<() => void>;\n children: RenderedNode<TNode>[];\n}\n\n/**\n * Operations strategy for different rendering targets\n */\nexport interface RenderStrategy<TNode> {\n /**\n * Create a text node\n */\n createTextNode(text: string): TNode;\n\n /**\n * Create a comment node (used for markers)\n */\n createComment(text: string): TNode;\n\n /**\n * Create an element node\n */\n createElement(type: string): TNode;\n\n /**\n * Get the parent node of a node\n */\n getParent(node: TNode): TNode | null;\n\n /**\n * Get the next sibling of a node\n */\n getNextSibling(node: TNode): TNode | null;\n\n /**\n * Insert a node before another node\n */\n insertBefore(parent: TNode, newNode: TNode, beforeNode: TNode | null): void;\n\n /**\n * Append child to parent\n */\n appendChild(parent: TNode, child: TNode): void;\n\n /**\n * Remove child from its parent\n */\n removeChild(node: TNode): void;\n\n /**\n * Replace old node with new node\n */\n replaceNode(oldNode: TNode, newNode: TNode): void;\n\n /**\n * Set a property on a node\n */\n setProperty(node: TNode, key: string, value: unknown): void;\n\n /**\n * Set a signal property on a node (returns unsubscribe function)\n */\n setSignalProperty(node: TNode, key: string, signal: any): () => void;\n\n /**\n * Optional: Set a ref on a node (returns cleanup function)\n * This is only used for DOM rendering\n */\n setRef?(node: TNode, ref: Ref<TNode>): () => void;\n\n /**\n * Optional: Try to reuse an existing node instead of replacing it\n * Returns true if the node was successfully reused\n * This is used for DOM optimization but not needed for terminal\n */\n tryReuseNode?(\n oldNode: TNode,\n newNode: TNode,\n oldRendered: RenderedNode<TNode>,\n newRendered: RenderedNode<TNode>,\n ): boolean;\n}\n\n/**\n * Check if a value is a Promise\n */\nexport function isPromise<T>(value: any): value is Promise<T> {\n return value && typeof value.then === \"function\";\n}\n\n/**\n * Check if a value is an AsyncIterator\n */\nexport function isAsyncIterator<T>(value: any): value is AsyncIterableIterator<T> {\n return value && typeof value[Symbol.asyncIterator] === \"function\";\n}\n\n/**\n * Core rendering logic - works for both DOM and Terminal\n */\nexport function createRenderer<TNode>(strategy: RenderStrategy<TNode>): {\n renderNode: (vnode: VNode, parentContext: ContextMap) => RenderedNode<TNode>;\n unmount: (node: RenderedNode<TNode>) => void;\n cleanupSubscriptions: (node: RenderedNode<TNode>) => void;\n} {\n /**\n * Helper to recursively collect all actual DOM nodes from a rendered node\n * Handles fragments and signal nodes that may not have their own DOM node\n */\n function collectNodes(rendered: RenderedNode<TNode>): TNode[] {\n const nodes: TNode[] = [];\n\n // Fragment: no node, only children\n if (rendered.vnode.type === Fragment) {\n for (const child of rendered.children) {\n nodes.push(...collectNodes(child));\n }\n return nodes;\n }\n\n // Portal: children are rendered into a different container,\n // so they should not be collected in the parent tree\n if (rendered.vnode.type === Portal) {\n return nodes;\n }\n\n // Signal marker: include marker node + content children\n if (rendered.vnode.type === \"#signal\") {\n if (rendered.node) {\n nodes.push(rendered.node); // marker\n }\n // Collect content children (after marker)\n for (const child of rendered.children) {\n nodes.push(...collectNodes(child));\n }\n return nodes;\n }\n\n // Regular elements and text nodes: just the node itself\n // Children are already attached to the node\n if (rendered.node) {\n nodes.push(rendered.node);\n }\n\n return nodes;\n }\n\n /**\n * Render a single VNode\n */\n function renderNode(vnode: VNode, parentContext: ContextMap): RenderedNode<TNode> {\n const { type } = vnode;\n\n // Text node\n if (type === \"#text\") {\n return renderTextNode(vnode);\n }\n\n // Signal VNode\n if (type === \"#signal\") {\n return renderSignalNode(vnode, parentContext);\n }\n\n // Fragment\n if (type === Fragment) {\n return renderFragment(vnode, parentContext);\n }\n\n // Portal\n if (type === Portal) {\n return renderPortal(vnode, parentContext);\n }\n\n // Forward\n if (type === Forward) {\n return renderForward(vnode, parentContext);\n }\n\n // Native node (pre-created element from external libraries)\n if (type === \"#native\") {\n return renderNativeNode(vnode);\n }\n\n // Component\n if (typeof type === \"function\") {\n return renderComponent(vnode, parentContext);\n }\n\n // Element\n if (typeof type === \"string\") {\n return renderElement(vnode, parentContext);\n }\n\n throw new Error(`Unknown VNode type: ${String(type)}`);\n }\n\n /**\n * Render a text node\n */\n function renderTextNode(vnode: VNode): RenderedNode<TNode> {\n const text = vnode.props?.nodeValue || \"\";\n const node = strategy.createTextNode(text);\n\n return {\n vnode,\n node,\n subscriptions: [],\n children: [],\n };\n }\n\n /**\n * Render a signal VNode\n */\n function renderSignalNode(vnode: VNode, parentContext: ContextMap): RenderedNode<TNode> {\n const signal = vnode.props?.signal;\n // Use captured context if available (for async components), otherwise parent context\n const contextForSignal = vnode.props?.context || parentContext;\n\n if (!isSignal(signal)) {\n throw new Error(\"Signal VNode must have a signal prop\");\n }\n\n // Create a comment node as a marker to track the signal's position in the DOM\n // This is necessary because signal content might be a Fragment (no direct node)\n // or might be empty initially\n const marker = strategy.createComment(\"signal\");\n\n // Get initial value and render it\n const initialValue = signal.value;\n let currentRendered = renderValueToNode(initialValue, contextForSignal);\n\n const subscriptions: Array<() => void> = [];\n\n // Subscribe to signal changes\n const unsubscribe = signal.subscribe((value) => {\n const newRendered = renderValueToNode(value, contextForSignal);\n\n // Collect actual DOM nodes from old and new rendered trees\n const oldContentNodes = collectNodes(currentRendered);\n const newContentNodes = collectNodes(newRendered);\n\n // Get the parent from the marker\n const parent = strategy.getParent(marker);\n if (!parent) {\n console.warn(\"[Signal] Marker not in DOM, cannot update\");\n return;\n }\n\n // Remove all old content nodes\n for (const node of oldContentNodes) {\n strategy.removeChild(node);\n }\n\n // Insert new content nodes after the marker\n let insertAfter = strategy.getNextSibling(marker);\n for (const node of newContentNodes) {\n strategy.insertBefore(parent, node, insertAfter);\n // Update insertAfter to maintain order (insert at the position after the last inserted)\n insertAfter = strategy.getNextSibling(node);\n }\n\n // Unmount old rendered tree: cleans up subscriptions AND removes\n // portal children from their containers (cleanupSubscriptions alone\n // would leave portal content orphaned in the portal container)\n unmount(currentRendered);\n\n currentRendered = newRendered;\n });\n\n subscriptions.push(unsubscribe);\n\n return {\n vnode,\n node: marker,\n subscriptions,\n children: currentRendered ? [currentRendered] : [],\n };\n }\n\n /**\n * Helper to convert a signal value to a rendered node\n */\n function renderValueToNode(value: unknown, context: ContextMap): RenderedNode<TNode> {\n let newVNode: VNode;\n\n // Convert value to VNode\n if (isVNode(value)) {\n newVNode = value;\n } else if (Array.isArray(value)) {\n // Support arrays - wrap in Fragment automatically\n // This allows: computed(todos, list => list.map(...))\n // Without requiring manual Fragment wrapping\n newVNode = {\n type: Fragment,\n props: {},\n children: value.filter(isVNode), // Filter out non-VNodes\n };\n } else if (typeof value === \"string\" || typeof value === \"number\") {\n newVNode = {\n type: \"#text\",\n props: { nodeValue: String(value) },\n children: [],\n };\n } else if (value == null || typeof value === \"boolean\") {\n // Render empty text for null/undefined/boolean\n // This works for both DOM and terminal\n newVNode = {\n type: \"#text\",\n props: { nodeValue: \"\" },\n children: [],\n };\n } else {\n throw new Error(`Invalid signal value type: ${typeof value}`);\n }\n\n return renderNode(newVNode, context);\n }\n\n /**\n * Render a fragment\n */\n function renderFragment(vnode: VNode, parentContext: ContextMap): RenderedNode<TNode> {\n const children = vnode.children.map((child) => renderNode(child, parentContext));\n\n // Fragment has no node of its own\n return {\n vnode,\n node: null,\n subscriptions: [],\n children,\n };\n }\n\n /**\n * Render a portal\n * Portal renders its children into a different container\n */\n function renderPortal(vnode: VNode, parentContext: ContextMap): RenderedNode<TNode> {\n const container = vnode.props?.container;\n\n if (!container) {\n throw new Error(\"Portal must have a container prop\");\n }\n\n // Render children with same context\n const children = vnode.children.map((child) => renderNode(child, parentContext));\n\n // Append all child nodes to the portal container (recursively handles fragments)\n for (const child of children) {\n const nodes = collectNodes(child);\n for (const node of nodes) {\n strategy.appendChild(container, node);\n }\n }\n\n // Portal has no node in the parent tree\n return {\n vnode,\n node: null,\n subscriptions: [],\n children,\n };\n }\n\n /**\n * Merge Forward's props into the child's props\n * - class/className: concatenated (array)\n * - style: merged objects (Forward overrides per-property)\n * - on* events: chained (both handlers run)\n * - other props: Forward overrides child\n */\n function mergeForwardProps(\n childProps: Record<string, any>,\n forwardProps: Record<string, any>,\n ): Record<string, any> {\n const merged = { ...childProps };\n\n for (const [key, value] of Object.entries(forwardProps)) {\n if (key === \"key\" || key === \"children\") continue;\n\n if ((key === \"class\" || key === \"className\") && merged[key] != null) {\n // Concatenate class values as array — renderers resolve arrays\n merged[key] = [merged[key], value];\n } else if (key === \"style\" && typeof merged[key] === \"object\" && typeof value === \"object\") {\n // Merge style objects (Forward properties override)\n merged[key] = { ...merged[key], ...value };\n } else if (\n key.startsWith(\"on\") &&\n typeof value === \"function\" &&\n typeof merged[key] === \"function\"\n ) {\n // Chain event handlers: Forward's runs first, then child's\n const existing = merged[key];\n merged[key] = (...args: unknown[]) => {\n value(...args);\n existing(...args);\n };\n } else {\n merged[key] = value;\n }\n }\n\n return merged;\n }\n\n /**\n * Render a Forward node\n * Forward merges its props onto its single child and renders it directly\n */\n function renderForward(vnode: VNode, parentContext: ContextMap): RenderedNode<TNode> {\n const child = vnode.children[0];\n\n if (!child || vnode.children.length !== 1) {\n throw new Error(\"Forward must have exactly one child element\");\n }\n\n const forwardProps = vnode.props || {};\n\n // Create a new VNode with merged props\n const mergedChild: VNode = {\n ...child,\n props: mergeForwardProps(child.props || {}, forwardProps),\n };\n\n // Render the merged child directly — Forward is completely transparent\n return renderNode(mergedChild, parentContext);\n }\n\n /**\n * Render a native node (pre-created element from external libraries)\n * The element is used directly without creating a new one.\n * Additional props are applied via the strategy's setProperty/setSignalProperty.\n */\n function renderNativeNode(vnode: VNode): RenderedNode<TNode> {\n const nativeNode = vnode.props?.__nativeNode as TNode;\n\n if (!nativeNode) {\n throw new Error(\"Native VNode must have an __nativeNode prop\");\n }\n\n const subscriptions: Array<() => void> = [];\n\n // Apply additional props to the native node\n const props = vnode.props || {};\n for (const [key, value] of Object.entries(props)) {\n if (key === \"__nativeNode\" || key === \"key\" || key === \"children\") continue;\n\n if (isSignal(value)) {\n const unsub = strategy.setSignalProperty(nativeNode, key, value);\n subscriptions.push(unsub);\n } else {\n strategy.setProperty(nativeNode, key, value);\n }\n }\n\n return {\n vnode,\n node: nativeNode,\n subscriptions,\n children: [],\n };\n }\n\n /**\n * Render a component\n */\n function renderComponent(vnode: VNode, parentContext: ContextMap): RenderedNode<TNode> {\n if (typeof vnode.type !== \"function\") {\n throw new Error(\"Component vnode must have a function type\");\n }\n\n const Component = vnode.type;\n const props = {\n ...vnode.props,\n children: normalizeChildrenProp(vnode.children),\n };\n\n // Prepare current component's context\n let currentContext = parentContext;\n\n // Check if this is a Context Provider\n const isContextProvider = (Component as any).__isContextProvider;\n\n if (isContextProvider) {\n // Context Provider: create new context map with provided values\n currentContext = new Map(parentContext);\n const provide = (props as any).provide;\n\n if (provide) {\n // Check if it's a single provide [Context, value] or multiple [[Context, value], ...]\n const isSingle = provide.length === 2 && typeof provide[0] === \"symbol\";\n\n if (isSingle) {\n // Single: [Context, value]\n const [context, value] = provide;\n currentContext.set(context, value);\n } else {\n // Multiple: [[Context, value], ...]\n for (const [context, value] of provide) {\n currentContext.set(context, value);\n }\n }\n }\n }\n\n // Create ComponentAPI\n const ctx = createComponentAPI(currentContext);\n\n // Call component function with props and ctx\n const result = Component(props, ctx);\n\n // Handle async component (Promise<VNode>)\n if (isPromise(result)) {\n const pending: VNode = {\n type: \"#text\",\n props: { nodeValue: \"\" },\n children: [],\n };\n const resultSignal = resource(result, pending);\n const signalVNode: VNode = {\n type: \"#signal\",\n props: { signal: resultSignal, context: currentContext },\n children: [],\n };\n const rendered = renderNode(signalVNode, currentContext);\n return {\n vnode,\n node: rendered.node,\n subscriptions: rendered.subscriptions,\n children: [rendered],\n };\n }\n\n // Handle async generator component (AsyncIterableIterator<VNode>)\n if (isAsyncIterator(result)) {\n const pending: VNode = {\n type: \"#text\",\n props: { nodeValue: \"\" },\n children: [],\n };\n const resultSignal = stream(result, pending);\n const signalVNode: VNode = {\n type: \"#signal\",\n props: { signal: resultSignal, context: currentContext },\n children: [],\n };\n const rendered = renderNode(signalVNode, currentContext);\n return {\n vnode,\n node: rendered.node,\n subscriptions: rendered.subscriptions,\n children: [rendered],\n };\n }\n\n // Handle signal component (Signal<VNode>)\n if (isSignal(result)) {\n const signalVNode: VNode = {\n type: \"#signal\",\n props: { signal: result, context: currentContext },\n children: [],\n };\n const rendered = renderNode(signalVNode, currentContext);\n return {\n vnode,\n node: rendered.node,\n subscriptions: rendered.subscriptions,\n children: [rendered],\n };\n }\n\n // Handle normal sync component (VNode)\n const normalizedResult = normalizeComponentResult(result);\n const rendered = renderNode(normalizedResult, currentContext);\n\n return {\n vnode,\n node: rendered.node,\n subscriptions: rendered.subscriptions,\n children: [rendered],\n };\n }\n\n /**\n * Render an element\n */\n function renderElement(vnode: VNode, parentContext: ContextMap): RenderedNode<TNode> {\n if (typeof vnode.type !== \"string\") {\n throw new Error(\"Element vnode must have a string type\");\n }\n\n const element = strategy.createElement(vnode.type);\n const subscriptions: Array<() => void> = [];\n\n // Apply props\n const props = vnode.props || {};\n for (const [key, value] of Object.entries(props)) {\n if (key === \"key\" || key === \"children\") continue;\n\n // Handle ref separately\n if (key === \"ref\") {\n if (strategy.setRef && value != null) {\n const cleanup = strategy.setRef(element, value as Ref<TNode>);\n subscriptions.push(cleanup);\n }\n continue;\n }\n\n if (isSignal(value)) {\n const unsub = strategy.setSignalProperty(element, key, value);\n subscriptions.push(unsub);\n } else {\n strategy.setProperty(element, key, value);\n }\n }\n\n // Render children with same context\n const children = vnode.children.map((child) => renderNode(child, parentContext));\n\n // Append all child nodes (recursively handles fragments and signal wrappers)\n for (const child of children) {\n const nodes = collectNodes(child);\n for (const node of nodes) {\n strategy.appendChild(element, node);\n }\n }\n\n return {\n vnode,\n node: element,\n subscriptions,\n children,\n };\n }\n\n /**\n * Unmount a rendered node\n */\n function unmount(node: RenderedNode<TNode>): void {\n // Cleanup subscriptions\n for (const unsub of node.subscriptions) {\n unsub();\n }\n\n // Recursively unmount children\n for (const child of node.children) {\n unmount(child);\n }\n\n // Remove from tree\n if (node.node) {\n strategy.removeChild(node.node);\n }\n }\n\n /**\n * Clean up subscriptions without removing nodes from tree\n */\n function cleanupSubscriptions(node: RenderedNode<TNode>): void {\n // Cleanup subscriptions\n for (const unsub of node.subscriptions) {\n unsub();\n }\n\n // Recursively cleanup children\n for (const child of node.children) {\n cleanupSubscriptions(child);\n }\n }\n\n return {\n renderNode: renderNode,\n unmount: unmount,\n cleanupSubscriptions: cleanupSubscriptions,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,42 +1,16 @@
|
|
|
1
|
-
import { t as isSignal } from "./utils-
|
|
1
|
+
import { t as isSignal } from "./utils-DbTAs943.mjs";
|
|
2
2
|
|
|
3
|
-
//#region ../style/src/hash.ts
|
|
4
|
-
/**
|
|
5
|
-
* Hash utilities for generating unique class names
|
|
6
|
-
*
|
|
7
|
-
* Uses a simple but effective hash algorithm that produces short,
|
|
8
|
-
* deterministic strings suitable for class names.
|
|
9
|
-
*/
|
|
10
|
-
/**
|
|
11
|
-
* Generate a short hash from a string
|
|
12
|
-
*
|
|
13
|
-
* Uses djb2 algorithm for fast, deterministic hashing
|
|
14
|
-
*/
|
|
15
|
-
function hashString(str) {
|
|
16
|
-
let hash = 5381;
|
|
17
|
-
for (let i = 0; i < str.length; i++) hash = (hash << 5) + hash ^ str.charCodeAt(i);
|
|
18
|
-
return Math.abs(hash).toString(36).slice(-5);
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Generate a unique ID using a counter + random suffix
|
|
22
|
-
*
|
|
23
|
-
* Used for runtime-generated class names where determinism isn't required
|
|
24
|
-
*/
|
|
25
|
-
let counter = 0;
|
|
26
|
-
function uniqueId() {
|
|
27
|
-
return (++counter).toString(36) + Math.random().toString(36).slice(2, 5);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
//#endregion
|
|
31
3
|
//#region ../style/src/classes.ts
|
|
32
4
|
/**
|
|
33
|
-
* Class name generation for @semajsx/style
|
|
34
|
-
*/
|
|
35
|
-
/**
|
|
36
5
|
* Symbol used to identify ClassRef objects
|
|
37
6
|
*/
|
|
38
7
|
const CLASS_REF_BRAND = Symbol.for("@semajsx/style/classRef");
|
|
39
8
|
/**
|
|
9
|
+
* Monotonic counter to ensure unique class names even when classes() is called
|
|
10
|
+
* multiple times in the same millisecond (e.g., multiple component modules).
|
|
11
|
+
*/
|
|
12
|
+
let classCounter = 0;
|
|
13
|
+
/**
|
|
40
14
|
* Create class name references with hashed values
|
|
41
15
|
*
|
|
42
16
|
* @example
|
|
@@ -50,7 +24,7 @@ const CLASS_REF_BRAND = Symbol.for("@semajsx/style/classRef");
|
|
|
50
24
|
function classes(names) {
|
|
51
25
|
const result = {};
|
|
52
26
|
for (const name of names) {
|
|
53
|
-
const className = `${name}-${
|
|
27
|
+
const className = `${name}-${(++classCounter).toString(36)}`;
|
|
54
28
|
const ref = {
|
|
55
29
|
id: Symbol(className),
|
|
56
30
|
toString() {
|
|
@@ -304,6 +278,34 @@ function preload(...styles) {
|
|
|
304
278
|
for (const style of styles) inject(style);
|
|
305
279
|
}
|
|
306
280
|
|
|
281
|
+
//#endregion
|
|
282
|
+
//#region ../style/src/hash.ts
|
|
283
|
+
/**
|
|
284
|
+
* Hash utilities for generating unique class names
|
|
285
|
+
*
|
|
286
|
+
* Uses a simple but effective hash algorithm that produces short,
|
|
287
|
+
* deterministic strings suitable for class names.
|
|
288
|
+
*/
|
|
289
|
+
/**
|
|
290
|
+
* Generate a short hash from a string
|
|
291
|
+
*
|
|
292
|
+
* Uses djb2 algorithm for fast, deterministic hashing
|
|
293
|
+
*/
|
|
294
|
+
function hashString(str) {
|
|
295
|
+
let hash = 5381;
|
|
296
|
+
for (let i = 0; i < str.length; i++) hash = (hash << 5) + hash ^ str.charCodeAt(i);
|
|
297
|
+
return Math.abs(hash).toString(36).slice(-5);
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Generate a unique ID using a counter + random suffix
|
|
301
|
+
*
|
|
302
|
+
* Used for runtime-generated class names where determinism isn't required
|
|
303
|
+
*/
|
|
304
|
+
let counter = 0;
|
|
305
|
+
function uniqueId() {
|
|
306
|
+
return (++counter).toString(36) + Math.random().toString(36).slice(2, 5);
|
|
307
|
+
}
|
|
308
|
+
|
|
307
309
|
//#endregion
|
|
308
310
|
//#region ../style/src/registry.ts
|
|
309
311
|
/**
|
|
@@ -1001,5 +1003,5 @@ function container(query, ...tokens) {
|
|
|
1001
1003
|
}
|
|
1002
1004
|
|
|
1003
1005
|
//#endregion
|
|
1004
|
-
export { keyframes as A,
|
|
1005
|
-
//# sourceMappingURL=src-
|
|
1006
|
+
export { keyframes as A, inject as B, slideRight as C, spin as D, slideUpKf as E, StyleRegistry as F, rules as G, preload as H, createCx as I, classes as K, createRegistry as L, createTheme as M, defineTokens as N, spinKf as O, isTokenRef as P, hashString as R, slideLeftKf as S, slideUp as T, isStyleToken as U, injectStyles as V, rule as W, scaleOut as _, bounce as a, slideDownKf as b, fadeInKf as c, ping as d, pingKf as f, scaleInKf as g, scaleIn as h, media as i, keyframesToken as j, isKeyframeRef as k, fadeOut as l, pulseKf as m, container as n, bounceKf as o, pulse as p, isClassRef as q, defineBreakpoints as r, fadeIn as s, breakpoints as t, fadeOutKf as u, scaleOutKf as v, slideRightKf as w, slideLeft as x, slideDown as y, uniqueId as z };
|
|
1007
|
+
//# sourceMappingURL=src-Ds9vl42d.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"src-Ds9vl42d.mjs","names":["STYLE_TOKEN_BRAND","STYLE_TOKEN_BRAND","STYLE_TOKEN_BRAND"],"sources":["../../style/src/classes.ts","../../style/src/rule.ts","../../style/src/inject.ts","../../style/src/hash.ts","../../style/src/registry.ts","../../style/src/theme.ts","../../style/src/keyframes.ts","../../style/src/animate.ts","../../style/src/responsive.ts"],"sourcesContent":["/**\n * Class name generation for @semajsx/style\n */\n\nimport type { ClassRef, ClassRefs } from \"./types\";\n\n/**\n * Symbol used to identify ClassRef objects\n */\nconst CLASS_REF_BRAND = Symbol.for(\"@semajsx/style/classRef\");\n\n/**\n * Monotonic counter to ensure unique class names even when classes() is called\n * multiple times in the same millisecond (e.g., multiple component modules).\n */\nlet classCounter = 0;\n\n/**\n * Create class name references with hashed values\n *\n * @example\n * ```ts\n * const c = classes([\"root\", \"icon\", \"label\"]);\n *\n * c.root.toString(); // \"root-x7f3a\"\n * `${c.root}`; // \"root-x7f3a\"\n * ```\n */\nexport function classes<T extends readonly string[]>(names: T): ClassRefs<T> {\n const result = {} as Record<string, ClassRef>;\n\n for (const name of names) {\n const id = (++classCounter).toString(36);\n const className = `${name}-${id}`;\n\n const ref: ClassRef = {\n id: Symbol(className),\n toString() {\n return className;\n },\n };\n\n // Add brand for type checking\n Object.defineProperty(ref, CLASS_REF_BRAND, { value: true });\n\n result[name] = ref;\n }\n\n return result as ClassRefs<T>;\n}\n\n/**\n * Check if a value is a ClassRef\n */\nexport function isClassRef(value: unknown): value is ClassRef {\n return (\n value != null &&\n typeof value === \"object\" &&\n CLASS_REF_BRAND in value &&\n (value as Record<symbol, unknown>)[CLASS_REF_BRAND] === true\n );\n}\n","/**\n * Rule creation for @semajsx/style\n *\n * The rule() function is a tagged template that creates StyleToken objects\n * from CSS selector + block syntax.\n */\n\nimport { isSignal } from \"@semajsx/signal\";\nimport type { ReadableSignal } from \"@semajsx/signal\";\nimport { isClassRef } from \"./classes\";\nimport type { ClassRef, SignalBindingDef, StyleToken } from \"./types\";\n\n/**\n * Symbol used to identify StyleToken objects\n */\nconst STYLE_TOKEN_BRAND = Symbol.for(\"@semajsx/style/token\");\n\n/**\n * Extract the class name from a CSS rule if it starts with a simple class selector\n *\n * @example\n * \".root-x7f3a { padding: 8px; }\" -> \"root-x7f3a\"\n * \".root-x7f3a:hover { ... }\" -> undefined (pseudo-class)\n * \".root-x7f3a > .icon { ... }\" -> undefined (combinator)\n */\nfunction extractClassName(css: string): string | undefined {\n // Match simple class selector at the start: .className { ... }\n const match = css.match(/^\\s*\\.([a-zA-Z0-9_-]+)\\s*\\{/);\n return match ? match[1] : undefined;\n}\n\n/**\n * Create a StyleToken from a tagged template containing selector + CSS block\n *\n * @example\n * ```ts\n * const c = classes([\"root\", \"icon\"]);\n *\n * // Simple class selector\n * const root = rule`${c.root} { padding: 8px 16px; }`;\n *\n * // Pseudo-class selector\n * const rootHover = rule`${c.root}:hover { background: blue; }`;\n *\n * // Descendant combinator\n * const rootIcon = rule`${c.root} > ${c.icon} { margin-right: 8px; }`;\n *\n * // With signal interpolation\n * const height = signal(100);\n * const box = rule`${c.box} { height: ${height}px; }`;\n * ```\n */\nexport function rule(\n strings: TemplateStringsArray,\n ...values: (ClassRef | ReadableSignal<unknown> | string | number | { toString(): string })[]\n): StyleToken {\n const bindingDefs: SignalBindingDef[] = [];\n\n // Build CSS template with placeholders for signals\n // strings[0] is always defined for template literals\n let cssTemplate = strings[0] ?? \"\";\n\n for (let i = 0; i < values.length; i++) {\n const value = values[i];\n const nextString = strings[i + 1] ?? \"\";\n\n if (isClassRef(value)) {\n // ClassRef: interpolate the hashed class name with dot prefix\n cssTemplate += \".\" + value.toString() + nextString;\n } else if (isSignal(value)) {\n // Signal: use placeholder {{index}}, variable name assigned by anchor later\n // No unit extraction - signal value should include unit if needed (e.g., \"100px\")\n const index = bindingDefs.length;\n bindingDefs.push({ signal: value, index });\n cssTemplate += `{{${index}}}` + nextString;\n } else {\n // Static value: interpolate directly\n cssTemplate += String(value) + nextString;\n }\n }\n\n const className = extractClassName(cssTemplate);\n\n const token: StyleToken = {\n __kind: \"style\",\n _: className,\n __cssTemplate: cssTemplate,\n __bindingDefs: bindingDefs.length > 0 ? bindingDefs : undefined,\n toString() {\n return this._ ?? \"\";\n },\n };\n\n // Add brand for type checking\n Object.defineProperty(token, STYLE_TOKEN_BRAND, { value: true });\n\n return token;\n}\n\n/**\n * Combine multiple StyleTokens into a single token for grouped injection\n *\n * @example\n * ```ts\n * const buttonStates = rules(\n * rule`${c.root}:hover { background: blue; }`,\n * rule`${c.root}:active { transform: scale(0.98); }`,\n * rule`${c.root}:disabled { opacity: 0.5; }`,\n * );\n * ```\n *\n * Note: The combined token has no className (_: undefined) since it may\n * contain multiple selectors. Use it for injection only, not as a className.\n */\nexport function rules(...tokens: StyleToken[]): StyleToken {\n const allBindingDefs: SignalBindingDef[] = [];\n\n // Build combined CSS with adjusted placeholder indices\n const combinedCSS = tokens\n .map((t, tokenIndex) => {\n let css = t.__cssTemplate;\n const bindings = t.__bindingDefs ?? [];\n\n // Adjust indices in both the CSS template and binding definitions\n for (const def of bindings) {\n const newIndex = def.index + tokenIndex * 100;\n // Replace placeholder with adjusted index\n css = css.replaceAll(`{{${def.index}}}`, `{{${newIndex}}}`);\n allBindingDefs.push({ ...def, index: newIndex });\n }\n\n return css;\n })\n .join(\"\\n\");\n\n const token: StyleToken = {\n __kind: \"style\",\n _: undefined, // Combined rules have no single class name\n __cssTemplate: combinedCSS,\n __bindingDefs: allBindingDefs.length > 0 ? allBindingDefs : undefined,\n toString() {\n return \"\";\n },\n };\n\n // Add brand for type checking\n Object.defineProperty(token, STYLE_TOKEN_BRAND, { value: true });\n\n return token;\n}\n\n/**\n * Check if a value is a StyleToken\n */\nexport function isStyleToken(value: unknown): value is StyleToken {\n return (\n value != null &&\n typeof value === \"object\" &&\n \"__kind\" in value &&\n (value as StyleToken).__kind === \"style\"\n );\n}\n","/**\n * CSS injection utilities for @semajsx/style\n */\n\nimport { isStyleToken } from \"./rule\";\nimport type { InjectOptions, StyleToken } from \"./types\";\n\n/**\n * Track injected styles per target to prevent duplicates\n */\nconst injectedStyles = new WeakMap<Element | ShadowRoot | Document, Set<string>>();\n\n/**\n * Get or create the set of injected class names for a target\n */\nfunction getInjectedSet(target: Element | ShadowRoot | Document): Set<string> {\n let set = injectedStyles.get(target);\n if (!set) {\n set = new Set();\n injectedStyles.set(target, set);\n }\n return set;\n}\n\n/**\n * Inject CSS into a target element\n *\n * @param css - The CSS string to inject\n * @param target - The target element (defaults to document.head)\n * @returns The created style element\n */\nexport function injectStyles(css: string, target?: Element | ShadowRoot): HTMLStyleElement {\n const styleElement = document.createElement(\"style\");\n styleElement.textContent = css;\n\n const actualTarget = target ?? document.head;\n actualTarget.appendChild(styleElement);\n\n return styleElement;\n}\n\n/**\n * Inject a StyleToken into the DOM\n *\n * Handles deduplication - if the same className has been injected to the\n * same target, it won't be injected again.\n *\n * Note: This function only handles CSS injection. Signal bindings must be\n * set up separately by StyleAnchor or similar.\n *\n * @param token - StyleToken to inject\n * @param options - Injection options (target)\n */\nfunction injectToken(token: StyleToken, target: Element | ShadowRoot | Document): void {\n const injected = getInjectedSet(target);\n\n // Deduplicate by className if available, otherwise by CSS content hash\n const key = token._ ?? token.__cssTemplate;\n\n if (!injected.has(key)) {\n // Replace signal placeholders with var() references for static injection\n let css = token.__cssTemplate;\n if (token.__bindingDefs) {\n for (const def of token.__bindingDefs) {\n // Use a default variable name for static injection\n css = css.replaceAll(`{{${def.index}}}`, `var(--style-${def.index})`);\n }\n }\n\n injectStyles(css, target === document ? document.head : (target as Element | ShadowRoot));\n injected.add(key);\n }\n}\n\n/**\n * Manually inject CSS into the DOM\n *\n * Supports single token, array of tokens, or object containing tokens.\n * Returns a cleanup function to remove the injected styles.\n *\n * @example\n * ```ts\n * // Single token\n * inject(button.root);\n *\n * // Array of tokens\n * inject([button.root, button.icon, button.rootIcon]);\n *\n * // Object - extracts all StyleTokens\n * inject(button);\n *\n * // With target\n * inject(button, { target: shadowRoot });\n *\n * // Cleanup\n * const cleanup = inject(button);\n * cleanup();\n * ```\n */\nexport function inject(\n tokens: StyleToken | StyleToken[] | Record<string, StyleToken>,\n options?: InjectOptions,\n): () => void {\n const target = options?.target ?? document.head;\n const styleElements: HTMLStyleElement[] = [];\n\n // Normalize input to array of tokens\n let tokenArray: StyleToken[];\n\n if (isStyleToken(tokens)) {\n tokenArray = [tokens];\n } else if (Array.isArray(tokens)) {\n tokenArray = tokens;\n } else {\n // Object: extract all StyleToken values\n tokenArray = Object.values(tokens).filter(isStyleToken);\n }\n\n // Inject each token\n for (const token of tokenArray) {\n injectToken(token, target);\n }\n\n // Return cleanup function\n return () => {\n for (const el of styleElements) {\n el.remove();\n }\n };\n}\n\n/**\n * Preload styles for better performance\n *\n * Use this at app startup or route entry to batch inject all styles\n * that will be needed, avoiding multiple DOM writes during rendering.\n *\n * @example\n * ```ts\n * // At app startup\n * preload(button, card, input);\n *\n * // At route entry\n * function ProductPage() {\n * preload(productCard, pricing, gallery);\n * return <div>...</div>;\n * }\n * ```\n */\nexport function preload(\n ...styles: (StyleToken | StyleToken[] | Record<string, StyleToken>)[]\n): void {\n for (const style of styles) {\n inject(style);\n }\n}\n","/**\n * Hash utilities for generating unique class names\n *\n * Uses a simple but effective hash algorithm that produces short,\n * deterministic strings suitable for class names.\n */\n\n/**\n * Generate a short hash from a string\n *\n * Uses djb2 algorithm for fast, deterministic hashing\n */\nexport function hashString(str: string): string {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) + hash) ^ str.charCodeAt(i);\n }\n // Convert to base36 for compact representation, take last 5 chars\n return Math.abs(hash).toString(36).slice(-5);\n}\n\n/**\n * Generate a unique ID using a counter + random suffix\n *\n * Used for runtime-generated class names where determinism isn't required\n */\nlet counter = 0;\nexport function uniqueId(): string {\n return (++counter).toString(36) + Math.random().toString(36).slice(2, 5);\n}\n","/**\n * StyleRegistry - Core class that manages all style state\n *\n * Can be used directly in vanilla JS or wrapped by framework integrations\n */\n\nimport type { ReadableSignal } from \"@semajsx/signal\";\nimport { injectStyles } from \"./inject\";\nimport { isStyleToken } from \"./rule\";\nimport { uniqueId } from \"./hash\";\nimport type { RegistryOptions, StyleToken } from \"./types\";\n\n/**\n * StyleRegistry - Manages all style-related state and side effects\n *\n * Responsibilities:\n * 1. Signal → CSS variable name mapping (scoped to this registry)\n * 2. CSS injection deduplication\n * 3. Signal subscriptions and cleanup\n */\nexport class StyleRegistry {\n /** Signal → CSS variable name mapping */\n private signalVars = new WeakMap<ReadableSignal<unknown>, string>();\n\n /** Already injected classNames (for deduplication) */\n private injectedClasses = new Set<string>();\n\n /** Active subscriptions (for cleanup) */\n private subscriptions = new Set<() => void>();\n\n /** Track which signals have been subscribed to prevent duplicates */\n private subscribedSignals = new WeakSet<ReadableSignal<unknown>>();\n\n /** Injection target */\n private target: Element | ShadowRoot;\n\n /** Element for CSS variable values (optional, for reactive styles) */\n private anchorElement: HTMLElement | null = null;\n\n constructor(options: RegistryOptions = {}) {\n this.target = options.target ?? document.head;\n }\n\n /**\n * Set anchor element for CSS variable values\n *\n * The anchor element is where CSS variables are set when signals change.\n * CSS variables cascade to descendants via CSS inheritance.\n */\n setAnchorElement(element: HTMLElement): void {\n this.anchorElement = element;\n }\n\n /**\n * Get or create a CSS variable name for a signal\n */\n private getSignalVarName(signal: ReadableSignal<unknown>): string {\n let varName = this.signalVars.get(signal);\n if (!varName) {\n varName = `--sig-${uniqueId()}`;\n this.signalVars.set(signal, varName);\n }\n return varName;\n }\n\n /**\n * Process a token: generate CSS, inject, set up signal bindings\n *\n * @returns The className for the token (or empty string if none)\n */\n processToken(token: StyleToken): string {\n // 1. Generate final CSS with var() references\n let css = token.__cssTemplate;\n const bindings: Array<{ signal: ReadableSignal<unknown>; varName: string }> = [];\n\n if (token.__bindingDefs) {\n for (const def of token.__bindingDefs) {\n const varName = this.getSignalVarName(def.signal);\n css = css.replaceAll(`{{${def.index}}}`, `var(${varName})`);\n bindings.push({ signal: def.signal, varName });\n }\n }\n\n // 2. Inject CSS if className not already injected\n const className = token._;\n if (className && !this.injectedClasses.has(className)) {\n injectStyles(css, this.target);\n this.injectedClasses.add(className);\n } else if (!className) {\n // For rules without className (combined rules, pseudo-selectors)\n // Use CSS content as dedup key\n const cssKey = css;\n if (!this.injectedClasses.has(cssKey)) {\n injectStyles(css, this.target);\n this.injectedClasses.add(cssKey);\n }\n }\n\n // 3. Set up signal subscriptions on the anchor element\n if (this.anchorElement && bindings.length > 0) {\n for (const { signal, varName } of bindings) {\n // Always update the current value\n this.anchorElement.style.setProperty(varName, String(signal.value));\n\n // Only subscribe if not already subscribed (prevents duplicates)\n if (!this.subscribedSignals.has(signal)) {\n this.subscribedSignals.add(signal);\n const unsub = signal.subscribe((newValue: unknown) => {\n this.anchorElement?.style.setProperty(varName, String(newValue));\n });\n this.subscriptions.add(unsub);\n }\n }\n }\n\n return token._ ?? \"\";\n }\n\n /**\n * Inject styles (without processing signal bindings)\n */\n inject(token: StyleToken | StyleToken[] | Record<string, StyleToken>): void {\n let tokenArray: StyleToken[];\n\n if (isStyleToken(token)) {\n tokenArray = [token];\n } else if (Array.isArray(token)) {\n tokenArray = token;\n } else {\n tokenArray = Object.values(token).filter(isStyleToken);\n }\n\n for (const t of tokenArray) {\n this.processToken(t);\n }\n }\n\n /**\n * Clear all injected styles and subscriptions\n */\n clear(): void {\n this.subscriptions.forEach((unsub) => unsub());\n this.subscriptions.clear();\n this.injectedClasses.clear();\n }\n\n /**\n * Dispose the registry (cleanup all subscriptions)\n */\n dispose(): void {\n this.clear();\n }\n}\n\n/**\n * Create a style registry\n *\n * @example\n * ```ts\n * const registry = createRegistry({\n * target: document.head,\n * dedupe: true,\n * });\n *\n * registry.inject(button);\n * registry.inject(card);\n * registry.clear();\n * ```\n */\nexport function createRegistry(options?: RegistryOptions): StyleRegistry {\n return new StyleRegistry(options);\n}\n\n/**\n * Create a cx() function bound to a registry\n *\n * The cx() function accepts StyleTokens, strings, and falsy values,\n * processes them, and returns a combined className string.\n *\n * @example\n * ```ts\n * const registry = createRegistry();\n * const cx = createCx(registry);\n *\n * const className = cx(button.root, isLarge && button.large, \"custom-class\");\n * ```\n */\nexport function createCx(\n registry: StyleRegistry,\n): (...args: (StyleToken | string | false | null | undefined)[]) => string {\n return (...args) => {\n const classes: string[] = [];\n\n for (const arg of args) {\n if (!arg) continue;\n\n if (isStyleToken(arg)) {\n const className = registry.processToken(arg);\n if (className) classes.push(className);\n } else {\n classes.push(arg);\n }\n }\n\n return classes.join(\" \");\n };\n}\n","/**\n * Theme system for @semajsx/style\n *\n * Provides a CSS custom properties-based theme system with type-safe\n * design tokens. Themes can be switched at runtime by toggling classes.\n *\n * @example\n * ```ts\n * import { defineTokens, createTheme } from \"@semajsx/style\";\n *\n * const tokens = defineTokens({\n * colors: {\n * primary: \"#3b82f6\",\n * background: \"#ffffff\",\n * text: \"#1f2937\",\n * },\n * space: {\n * sm: \"0.5rem\",\n * md: \"1rem\",\n * },\n * });\n *\n * // tokens.colors.primary.toString() === \"var(--colors-primary)\"\n *\n * const light = createTheme(tokens);\n * const dark = createTheme(tokens, {\n * colors: { primary: \"#60a5fa\", background: \"#1a1a2e\", text: \"#f0f0f0\" },\n * });\n *\n * // Use tokens in rules\n * const root = rule`${c.root} {\n * color: ${tokens.colors.text};\n * background: ${tokens.colors.background};\n * }`;\n * ```\n */\n\nimport { hashString } from \"./hash\";\n\n/**\n * A token reference that stringifies to a CSS var() expression\n */\nexport interface TokenRef {\n /** The CSS custom property name (e.g., \"--colors-primary\") */\n readonly varName: string;\n /** The default value for this token */\n readonly defaultValue: string;\n /** Returns var(--token-name) for use in CSS */\n toString(): string;\n}\n\n/**\n * Recursive type for token definitions\n * Supports nested objects of string values\n */\nexport type TokenDefinition = {\n [key: string]: string | TokenDefinition;\n};\n\n/**\n * Maps a TokenDefinition to TokenRef objects at leaves\n */\nexport type TokenRefs<T> = {\n readonly [K in keyof T]: T[K] extends string\n ? TokenRef\n : T[K] extends TokenDefinition\n ? TokenRefs<T[K]>\n : never;\n};\n\n/**\n * Partial override values matching token structure\n */\nexport type TokenOverrides<T> = {\n [K in keyof T]?: T[K] extends string\n ? string\n : T[K] extends TokenDefinition\n ? TokenOverrides<T[K]>\n : never;\n};\n\n/**\n * Internal flat map of varName -> defaultValue\n */\ninterface FlatTokenMap {\n varName: string;\n defaultValue: string;\n}\n\n/**\n * Symbol to identify TokenRef objects\n */\nconst TOKEN_REF_BRAND = Symbol.for(\"@semajsx/style/tokenRef\");\n\n/**\n * Check if a value is a TokenRef\n */\nexport function isTokenRef(value: unknown): value is TokenRef {\n return (\n value != null &&\n typeof value === \"object\" &&\n TOKEN_REF_BRAND in value &&\n (value as Record<symbol, unknown>)[TOKEN_REF_BRAND] === true\n );\n}\n\n/**\n * Define design tokens as CSS custom properties\n *\n * Creates a typed token object where each leaf value becomes a CSS custom property.\n * Token refs stringify to `var(--path-to-token)` for use in CSS rules.\n *\n * @example\n * ```ts\n * const tokens = defineTokens({\n * colors: {\n * primary: \"#3b82f6\",\n * secondary: \"#6b7280\",\n * },\n * space: {\n * sm: \"0.5rem\",\n * md: \"1rem\",\n * lg: \"1.5rem\",\n * },\n * radii: {\n * sm: \"4px\",\n * md: \"8px\",\n * },\n * });\n *\n * // tokens.colors.primary.toString() === \"var(--colors-primary)\"\n * // tokens.space.md.varName === \"--space-md\"\n * ```\n */\nexport function defineTokens<T extends TokenDefinition>(definition: T): TokenRefs<T> {\n return buildTokenRefs(definition, []) as TokenRefs<T>;\n}\n\n/**\n * Recursively build TokenRef objects from a definition\n */\nfunction buildTokenRefs(obj: TokenDefinition, path: string[]): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const key of Object.keys(obj)) {\n const value = obj[key];\n const currentPath = [...path, key];\n\n if (typeof value === \"string\") {\n const varName = \"--\" + currentPath.join(\"-\");\n const ref: TokenRef = {\n varName,\n defaultValue: value,\n toString() {\n return `var(${varName})`;\n },\n };\n Object.defineProperty(ref, TOKEN_REF_BRAND, { value: true });\n result[key] = ref;\n } else if (typeof value === \"object\" && value !== null) {\n result[key] = buildTokenRefs(value as TokenDefinition, currentPath);\n }\n }\n\n return result;\n}\n\n/**\n * Collect all TokenRef leaf nodes from a token tree\n */\nfunction collectTokenRefs(obj: unknown): FlatTokenMap[] {\n const refs: FlatTokenMap[] = [];\n\n if (isTokenRef(obj)) {\n refs.push({ varName: obj.varName, defaultValue: obj.defaultValue });\n return refs;\n }\n\n if (typeof obj === \"object\" && obj !== null) {\n for (const value of Object.values(obj)) {\n refs.push(...collectTokenRefs(value));\n }\n }\n\n return refs;\n}\n\n/**\n * Collect override values matching the token structure\n */\nfunction collectOverrides(\n tokens: unknown,\n overrides: Record<string, unknown>,\n): { varName: string; value: string }[] {\n const result: { varName: string; value: string }[] = [];\n\n for (const key of Object.keys(overrides)) {\n const overrideValue = overrides[key];\n const tokenValue = (tokens as Record<string, unknown>)[key];\n\n if (typeof overrideValue === \"string\" && isTokenRef(tokenValue)) {\n result.push({ varName: tokenValue.varName, value: overrideValue });\n } else if (\n typeof overrideValue === \"object\" &&\n overrideValue !== null &&\n typeof tokenValue === \"object\" &&\n tokenValue !== null\n ) {\n result.push(...collectOverrides(tokenValue, overrideValue as Record<string, unknown>));\n }\n }\n\n return result;\n}\n\n/**\n * Symbol used to identify theme StyleTokens\n */\nconst STYLE_TOKEN_BRAND = Symbol.for(\"@semajsx/style/token\");\n\n/**\n * Create a theme from token definitions\n *\n * Returns a StyleToken that sets all CSS custom properties. The default theme\n * uses `:root` selector, while overridden themes get a scoped class.\n *\n * @param tokens - Token refs from defineTokens()\n * @param overrides - Optional partial overrides for token values\n * @returns A StyleToken that can be injected or used as a class\n *\n * @example\n * ```ts\n * // Default theme (applies to :root)\n * const light = createTheme(tokens);\n * inject(light);\n *\n * // Override theme (scoped to a class)\n * const dark = createTheme(tokens, {\n * colors: { primary: \"#60a5fa\", background: \"#1a1a2e\" },\n * });\n * inject(dark);\n *\n * // Apply dark theme to an element\n * <div class={dark}>...</div>\n * ```\n */\nexport function createTheme<T extends TokenDefinition>(\n tokens: TokenRefs<T>,\n overrides?: TokenOverrides<T>,\n): import(\"./types\").StyleToken {\n if (!overrides) {\n // Default theme: set all token values on :root\n const allTokens = collectTokenRefs(tokens);\n const vars = allTokens.map((t) => ` ${t.varName}: ${t.defaultValue};`).join(\"\\n\");\n const css = `:root {\\n${vars}\\n}`;\n\n const token = {\n __kind: \"style\" as const,\n _: undefined,\n __cssTemplate: css,\n __bindingDefs: undefined,\n toString() {\n return \"\";\n },\n };\n Object.defineProperty(token, STYLE_TOKEN_BRAND, { value: true });\n return token;\n }\n\n // Override theme: scoped to a generated class\n const overrideList = collectOverrides(tokens, overrides as Record<string, unknown>);\n const hash = hashString(overrideList.map((o) => o.varName + o.value).join(\"\"));\n const className = `theme-${hash}`;\n const vars = overrideList.map((o) => ` ${o.varName}: ${o.value};`).join(\"\\n\");\n const css = `.${className} {\\n${vars}\\n}`;\n\n const token = {\n __kind: \"style\" as const,\n _: className,\n __cssTemplate: css,\n __bindingDefs: undefined,\n toString() {\n return this._ ?? \"\";\n },\n };\n Object.defineProperty(token, STYLE_TOKEN_BRAND, { value: true });\n return token;\n}\n","/**\n * Keyframes support for @semajsx/style\n *\n * Provides a tagged template for defining CSS @keyframes animations\n * that integrate with the rule() system.\n *\n * @example\n * ```ts\n * import { keyframes } from \"@semajsx/style\";\n * import { classes, rule } from \"@semajsx/style\";\n *\n * const fadeIn = keyframes`\n * from { opacity: 0; }\n * to { opacity: 1; }\n * `;\n *\n * const c = classes([\"root\"]);\n * const animated = rule`${c.root} {\n * animation: ${fadeIn} 0.3s ease-in;\n * }`;\n * ```\n */\n\nimport { hashString } from \"./hash\";\nimport type { StyleToken } from \"./types\";\n\n/**\n * Symbol to identify KeyframeRef objects\n */\nconst KEYFRAME_REF_BRAND = Symbol.for(\"@semajsx/style/keyframeRef\");\n\n/**\n * Symbol to identify StyleToken objects\n */\nconst STYLE_TOKEN_BRAND = Symbol.for(\"@semajsx/style/token\");\n\n/**\n * A reference to a @keyframes animation that can be used in rule() templates\n *\n * Stringifies to the animation name for use in CSS properties.\n * Also carries the @keyframes CSS for injection.\n */\nexport interface KeyframeRef {\n /** The generated animation name */\n readonly name: string;\n /** The full @keyframes CSS */\n readonly css: string;\n /** Returns the animation name */\n toString(): string;\n}\n\n/**\n * Check if a value is a KeyframeRef\n */\nexport function isKeyframeRef(value: unknown): value is KeyframeRef {\n return (\n value != null &&\n typeof value === \"object\" &&\n KEYFRAME_REF_BRAND in value &&\n (value as Record<symbol, unknown>)[KEYFRAME_REF_BRAND] === true\n );\n}\n\n/**\n * Define CSS @keyframes animation\n *\n * Returns a KeyframeRef that can be interpolated in rule() templates.\n * The keyframes CSS is automatically injected when used.\n *\n * @example\n * ```ts\n * const spin = keyframes`\n * from { transform: rotate(0deg); }\n * to { transform: rotate(360deg); }\n * `;\n *\n * const spinner = rule`${c.spinner} {\n * animation: ${spin} 1s linear infinite;\n * }`;\n * ```\n */\nexport function keyframes(\n strings: TemplateStringsArray,\n ...values: (string | number)[]\n): KeyframeRef {\n // Build the keyframes body\n let body = strings[0] ?? \"\";\n for (let i = 0; i < values.length; i++) {\n body += String(values[i]) + (strings[i + 1] ?? \"\");\n }\n\n body = body.trim();\n\n // Generate a deterministic name from the content\n const hash = hashString(body);\n const name = `kf-${hash}`;\n\n const css = `@keyframes ${name} {\\n ${body}\\n}`;\n\n const ref: KeyframeRef = {\n name,\n css,\n toString() {\n return name;\n },\n };\n\n Object.defineProperty(ref, KEYFRAME_REF_BRAND, { value: true });\n\n return ref;\n}\n\n/**\n * Create a StyleToken that injects keyframes CSS\n *\n * Use this when you need to inject keyframes without using them in a rule().\n * Normally, keyframes are auto-injected when used in rule() templates.\n *\n * @example\n * ```ts\n * const fadeIn = keyframes`\n * from { opacity: 0; }\n * to { opacity: 1; }\n * `;\n *\n * // Inject keyframes CSS\n * inject(keyframesToken(fadeIn));\n * ```\n */\nexport function keyframesToken(ref: KeyframeRef): StyleToken {\n const token: StyleToken = {\n __kind: \"style\",\n _: undefined,\n __cssTemplate: ref.css,\n __bindingDefs: undefined,\n toString() {\n return \"\";\n },\n };\n Object.defineProperty(token, STYLE_TOKEN_BRAND, { value: true });\n return token;\n}\n","/**\n * Pre-built animation utilities for @semajsx/style\n *\n * Provides ready-to-use keyframes and animation StyleTokens for common\n * animations like fade, slide, scale, spin, and bounce.\n *\n * @example\n * ```ts\n * import { fadeInKf, fadeIn, slideUpKf, slideUp } from \"@semajsx/style\";\n *\n * // Use keyframes in custom rules\n * const custom = rule`${c.root} {\n * animation: ${fadeInKf} 0.5s ease-out;\n * }`;\n *\n * // Or use pre-built animation classes\n * <div class={[myStyle, fadeIn]}>Fading in!</div>\n * ```\n */\n\nimport { keyframes, keyframesToken } from \"./keyframes\";\nimport type { KeyframeRef } from \"./keyframes\";\nimport { classes } from \"./classes\";\nimport { rule, rules } from \"./rule\";\nimport type { StyleToken } from \"./types\";\n\n// ──── Keyframe Definitions ──────────────────────────────────────────\n\n/** Fade in from transparent */\nexport const fadeInKf: KeyframeRef = keyframes`\n from { opacity: 0; }\n to { opacity: 1; }\n`;\n\n/** Fade out to transparent */\nexport const fadeOutKf: KeyframeRef = keyframes`\n from { opacity: 1; }\n to { opacity: 0; }\n`;\n\n/** Slide up from below */\nexport const slideUpKf: KeyframeRef = keyframes`\n from { transform: translateY(10px); opacity: 0; }\n to { transform: translateY(0); opacity: 1; }\n`;\n\n/** Slide down from above */\nexport const slideDownKf: KeyframeRef = keyframes`\n from { transform: translateY(-10px); opacity: 0; }\n to { transform: translateY(0); opacity: 1; }\n`;\n\n/** Slide in from left */\nexport const slideLeftKf: KeyframeRef = keyframes`\n from { transform: translateX(-10px); opacity: 0; }\n to { transform: translateX(0); opacity: 1; }\n`;\n\n/** Slide in from right */\nexport const slideRightKf: KeyframeRef = keyframes`\n from { transform: translateX(10px); opacity: 0; }\n to { transform: translateX(0); opacity: 1; }\n`;\n\n/** Scale in from smaller */\nexport const scaleInKf: KeyframeRef = keyframes`\n from { transform: scale(0.95); opacity: 0; }\n to { transform: scale(1); opacity: 1; }\n`;\n\n/** Scale out to smaller */\nexport const scaleOutKf: KeyframeRef = keyframes`\n from { transform: scale(1); opacity: 1; }\n to { transform: scale(0.95); opacity: 0; }\n`;\n\n/** Spin 360 degrees */\nexport const spinKf: KeyframeRef = keyframes`\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n`;\n\n/** Ping effect (for notifications) */\nexport const pingKf: KeyframeRef = keyframes`\n 75%, 100% { transform: scale(2); opacity: 0; }\n`;\n\n/** Pulse effect */\nexport const pulseKf: KeyframeRef = keyframes`\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.5; }\n`;\n\n/** Bounce effect */\nexport const bounceKf: KeyframeRef = keyframes`\n 0%, 100% { transform: translateY(-25%); animation-timing-function: cubic-bezier(0.8, 0, 1, 1); }\n 50% { transform: translateY(0); animation-timing-function: cubic-bezier(0, 0, 0.2, 1); }\n`;\n\n// ──── Animation Class Tokens ────────────────────────────────────────\n\nconst c = classes([\n \"fadeIn\",\n \"fadeOut\",\n \"slideUp\",\n \"slideDown\",\n \"slideLeft\",\n \"slideRight\",\n \"scaleIn\",\n \"scaleOut\",\n \"spin\",\n \"ping\",\n \"pulse\",\n \"bounce\",\n] as const);\n\n/** Fade in animation (0.3s ease-out) */\nexport const fadeIn: StyleToken = rules(\n keyframesToken(fadeInKf),\n rule`${c.fadeIn} { animation: ${fadeInKf} 0.3s ease-out; }`,\n);\n\n/** Fade out animation (0.3s ease-in) */\nexport const fadeOut: StyleToken = rules(\n keyframesToken(fadeOutKf),\n rule`${c.fadeOut} { animation: ${fadeOutKf} 0.3s ease-in; }`,\n);\n\n/** Slide up animation (0.3s ease-out) */\nexport const slideUp: StyleToken = rules(\n keyframesToken(slideUpKf),\n rule`${c.slideUp} { animation: ${slideUpKf} 0.3s ease-out; }`,\n);\n\n/** Slide down animation (0.3s ease-out) */\nexport const slideDown: StyleToken = rules(\n keyframesToken(slideDownKf),\n rule`${c.slideDown} { animation: ${slideDownKf} 0.3s ease-out; }`,\n);\n\n/** Slide in from left animation (0.3s ease-out) */\nexport const slideLeft: StyleToken = rules(\n keyframesToken(slideLeftKf),\n rule`${c.slideLeft} { animation: ${slideLeftKf} 0.3s ease-out; }`,\n);\n\n/** Slide in from right animation (0.3s ease-out) */\nexport const slideRight: StyleToken = rules(\n keyframesToken(slideRightKf),\n rule`${c.slideRight} { animation: ${slideRightKf} 0.3s ease-out; }`,\n);\n\n/** Scale in animation (0.2s ease-out) */\nexport const scaleIn: StyleToken = rules(\n keyframesToken(scaleInKf),\n rule`${c.scaleIn} { animation: ${scaleInKf} 0.2s ease-out; }`,\n);\n\n/** Scale out animation (0.2s ease-in) */\nexport const scaleOut: StyleToken = rules(\n keyframesToken(scaleOutKf),\n rule`${c.scaleOut} { animation: ${scaleOutKf} 0.2s ease-in; }`,\n);\n\n/** Spin animation (1s linear infinite) */\nexport const spin: StyleToken = rules(\n keyframesToken(spinKf),\n rule`${c.spin} { animation: ${spinKf} 1s linear infinite; }`,\n);\n\n/** Ping animation (1s cubic-bezier infinite) */\nexport const ping: StyleToken = rules(\n keyframesToken(pingKf),\n rule`${c.ping} { animation: ${pingKf} 1s cubic-bezier(0, 0, 0.2, 1) infinite; }`,\n);\n\n/** Pulse animation (2s ease-in-out infinite) */\nexport const pulse: StyleToken = rules(\n keyframesToken(pulseKf),\n rule`${c.pulse} { animation: ${pulseKf} 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; }`,\n);\n\n/** Bounce animation (1s infinite) */\nexport const bounce: StyleToken = rules(\n keyframesToken(bounceKf),\n rule`${c.bounce} { animation: ${bounceKf} 1s infinite; }`,\n);\n","/**\n * Responsive design utilities for @semajsx/style\n *\n * Provides breakpoint definitions and media query helpers for creating\n * responsive styles that integrate with the rule() system.\n *\n * @example\n * ```ts\n * import { breakpoints, media } from \"@semajsx/style\";\n *\n * const bp = breakpoints;\n *\n * // Use breakpoint values in media queries\n * const responsive = rules(\n * rule`${c.root} { padding: 8px; }`,\n * rule`@media ${bp.md} { .${c.root} { padding: 16px; } }`,\n * );\n *\n * // Or use the media() helper\n * const responsivePadding = media(bp.md,\n * rule`${c.root} { padding: 16px; }`,\n * );\n * ```\n */\n\nimport type { StyleToken } from \"./types\";\n\n/**\n * Symbol to identify StyleToken objects\n */\nconst STYLE_TOKEN_BRAND = Symbol.for(\"@semajsx/style/token\");\n\n/**\n * A breakpoint reference with min/max media query helpers\n */\nexport interface BreakpointRef {\n /** The breakpoint value (e.g., \"768px\") */\n readonly value: string;\n /** min-width media query: \"(min-width: 768px)\" */\n readonly min: string;\n /** max-width media query: \"(max-width: 767.98px)\" */\n readonly max: string;\n /** Returns the min-width media query by default */\n toString(): string;\n}\n\n/**\n * Collection of breakpoint refs\n */\nexport type BreakpointRefs<T extends Record<string, string>> = {\n readonly [K in keyof T]: BreakpointRef;\n};\n\n/**\n * Parse a CSS value to subtract 0.02px for max-width queries\n * This prevents overlap between min and max breakpoints\n */\nfunction subtractPixel(value: string): string {\n const match = value.match(/^(\\d+(?:\\.\\d+)?)(px|em|rem)$/);\n if (!match || !match[1] || !match[2]) return value;\n\n const num = parseFloat(match[1]);\n const unit = match[2];\n\n // Subtract 0.02 to avoid overlap\n return `${(num - 0.02).toFixed(2)}${unit}`;\n}\n\n/**\n * Define custom breakpoints\n *\n * Creates a typed breakpoint object where each entry becomes a BreakpointRef\n * with min/max media query helpers.\n *\n * @example\n * ```ts\n * const bp = defineBreakpoints({\n * sm: \"640px\",\n * md: \"768px\",\n * lg: \"1024px\",\n * xl: \"1280px\",\n * });\n *\n * // bp.md.toString() === \"(min-width: 768px)\"\n * // bp.md.min === \"(min-width: 768px)\"\n * // bp.md.max === \"(max-width: 767.98px)\"\n * ```\n */\nexport function defineBreakpoints<T extends Record<string, string>>(\n definition: T,\n): BreakpointRefs<T> {\n const result: Record<string, BreakpointRef> = {};\n\n for (const key of Object.keys(definition)) {\n const value = definition[key] as string;\n const maxValue = subtractPixel(value);\n\n result[key] = {\n value,\n min: `(min-width: ${value})`,\n max: `(max-width: ${maxValue})`,\n toString() {\n return this.min;\n },\n };\n }\n\n return result as BreakpointRefs<T>;\n}\n\n/**\n * Default breakpoints matching Tailwind CSS defaults\n */\nexport const breakpoints: BreakpointRefs<{\n sm: string;\n md: string;\n lg: string;\n xl: string;\n \"2xl\": string;\n}> = defineBreakpoints({\n sm: \"640px\",\n md: \"768px\",\n lg: \"1024px\",\n xl: \"1280px\",\n \"2xl\": \"1536px\",\n});\n\n/**\n * Wrap style tokens in a media query\n *\n * Takes a media query string and one or more StyleTokens,\n * wrapping their CSS in a @media block.\n *\n * @example\n * ```ts\n * import { breakpoints, media } from \"@semajsx/style\";\n *\n * const bp = breakpoints;\n *\n * // Single rule\n * const mdPadding = media(bp.md,\n * rule`${c.root} { padding: 16px; }`,\n * );\n *\n * // Multiple rules\n * const lgLayout = media(bp.lg,\n * rule`${c.root} { display: grid; }`,\n * rule`${c.sidebar} { width: 300px; }`,\n * );\n *\n * // Max-width (mobile-first breakpoint)\n * const mobileOnly = media(bp.md.max,\n * rule`${c.root} { flex-direction: column; }`,\n * );\n *\n * // Custom media query\n * const darkMode = media(\"(prefers-color-scheme: dark)\",\n * rule`${c.root} { background: #1a1a2e; color: #f0f0f0; }`,\n * );\n * ```\n */\nexport function media(query: string | BreakpointRef, ...tokens: StyleToken[]): StyleToken {\n const queryStr = typeof query === \"string\" ? query : query.toString();\n\n // Extract CSS from each token and wrap in @media block\n const innerCSS = tokens.map((t) => ` ${t.__cssTemplate}`).join(\"\\n\");\n const css = `@media ${queryStr} {\\n${innerCSS}\\n}`;\n\n const token: StyleToken = {\n __kind: \"style\",\n _: undefined,\n __cssTemplate: css,\n __bindingDefs: undefined,\n toString() {\n return \"\";\n },\n };\n Object.defineProperty(token, STYLE_TOKEN_BRAND, { value: true });\n return token;\n}\n\n/**\n * Create a container query\n *\n * @example\n * ```ts\n * const wide = container(\"(min-width: 600px)\",\n * rule`${c.root} { display: grid; grid-template-columns: 1fr 1fr; }`,\n * );\n * ```\n */\nexport function container(query: string, ...tokens: StyleToken[]): StyleToken {\n const innerCSS = tokens.map((t) => ` ${t.__cssTemplate}`).join(\"\\n\");\n const css = `@container ${query} {\\n${innerCSS}\\n}`;\n\n const token: StyleToken = {\n __kind: \"style\",\n _: undefined,\n __cssTemplate: css,\n __bindingDefs: undefined,\n toString() {\n return \"\";\n },\n };\n Object.defineProperty(token, STYLE_TOKEN_BRAND, { value: true });\n return token;\n}\n"],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { n as unwrap, t as isSignal } from "./utils-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { n as
|
|
1
|
+
import { n as unwrap, t as isSignal } from "./utils-DbTAs943.mjs";
|
|
2
|
+
import { a as jsxs, i as jsx, v as Fragment } from "./src-DW3tIczg.mjs";
|
|
3
|
+
import { U as isStyleToken } from "./src-Ds9vl42d.mjs";
|
|
4
|
+
import { n as print } from "./src-DUpFNNM_.mjs";
|
|
5
|
+
import { c as getIslandMetadata, n as LINK_MARKER, r as STYLE_MARKER, t as ASSET_MARKER, u as isIslandVNode } from "./resource-DSlXDZZi.mjs";
|
|
6
|
+
import { n as renderDocument } from "./document-BOJDaiBc.mjs";
|
|
6
7
|
import { build, createServer, mergeConfig } from "vite";
|
|
7
8
|
import { dirname, resolve } from "path";
|
|
8
9
|
|
|
@@ -125,6 +126,11 @@ async function renderVNodeToHTML(vnode, context) {
|
|
|
125
126
|
if (src && typeof src === "string") context.assets.add(src);
|
|
126
127
|
return "";
|
|
127
128
|
}
|
|
129
|
+
if (vnodeTyped.type === "#native") {
|
|
130
|
+
const nativeNode = vnodeTyped.props?.__nativeNode;
|
|
131
|
+
if (nativeNode && typeof nativeNode.outerHTML === "string") return nativeNode.outerHTML;
|
|
132
|
+
return "";
|
|
133
|
+
}
|
|
128
134
|
if (vnodeTyped.type === Fragment) return (await Promise.all(vnodeTyped.children.map((child) => renderVNodeToHTML(child, context)))).join("");
|
|
129
135
|
if (typeof vnodeTyped.type === "function") try {
|
|
130
136
|
const props = vnodeTyped.children && vnodeTyped.children.length > 0 ? {
|
|
@@ -243,9 +249,44 @@ async function renderElement(vnode, context) {
|
|
|
243
249
|
];
|
|
244
250
|
const attrs = renderAttributes(props);
|
|
245
251
|
if (selfClosing.includes(tag)) return `<${tag}${attrs} />`;
|
|
252
|
+
if (tag === "style" || tag === "script") return `<${tag}${attrs}>${(vnode.children || []).map((child) => extractRawText(child)).join("")}</${tag}>`;
|
|
246
253
|
return `<${tag}${attrs}>${(await Promise.all((vnode.children || []).map((child) => renderVNodeToHTML(child, context)))).join("")}</${tag}>`;
|
|
247
254
|
}
|
|
248
255
|
/**
|
|
256
|
+
* Extract raw text from a VNode without HTML escaping.
|
|
257
|
+
* Used for <style> and <script> content.
|
|
258
|
+
*/
|
|
259
|
+
function extractRawText(vnode) {
|
|
260
|
+
if (vnode == null || typeof vnode === "boolean") return "";
|
|
261
|
+
if (typeof vnode === "string" || typeof vnode === "number") return String(vnode);
|
|
262
|
+
if (Array.isArray(vnode)) return vnode.map(extractRawText).join("");
|
|
263
|
+
if (typeof vnode === "object" && "type" in vnode) {
|
|
264
|
+
const v = vnode;
|
|
265
|
+
if (v.type === "#text") return String(v.props?.nodeValue ?? "");
|
|
266
|
+
if (v.type === "#signal") {
|
|
267
|
+
const signal = v.props?.signal;
|
|
268
|
+
if (signal && isSignal(signal)) return String(unwrap(signal));
|
|
269
|
+
return "";
|
|
270
|
+
}
|
|
271
|
+
return (v.children || []).map(extractRawText).join("");
|
|
272
|
+
}
|
|
273
|
+
return "";
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Resolve a class value to a string for SSR output.
|
|
277
|
+
*
|
|
278
|
+
* Handles strings, StyleToken objects, arrays, and falsy values.
|
|
279
|
+
* Unlike the DOM version, this does NOT call inject() since CSS is
|
|
280
|
+
* collected statically (via componentCSS) for SSG/SSR output.
|
|
281
|
+
*/
|
|
282
|
+
function resolveClass(value) {
|
|
283
|
+
if (!value) return "";
|
|
284
|
+
if (typeof value === "string") return value;
|
|
285
|
+
if (isStyleToken(value)) return value._ ?? "";
|
|
286
|
+
if (Array.isArray(value)) return value.map(resolveClass).filter(Boolean).join(" ");
|
|
287
|
+
return String(value);
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
249
290
|
* Render element attributes
|
|
250
291
|
*/
|
|
251
292
|
function renderAttributes(props) {
|
|
@@ -261,7 +302,12 @@ function renderAttributes(props) {
|
|
|
261
302
|
if (attrValue) attrs.push(key);
|
|
262
303
|
continue;
|
|
263
304
|
}
|
|
264
|
-
const attrName = key === "className" ? "class" : key;
|
|
305
|
+
const attrName = key === "className" ? "class" : key === "htmlFor" ? "for" : key === "charSet" ? "charset" : key === "crossOrigin" ? "crossorigin" : key === "httpEquiv" ? "http-equiv" : key;
|
|
306
|
+
if (attrName === "class") {
|
|
307
|
+
const resolved = resolveClass(attrValue);
|
|
308
|
+
if (resolved) attrs.push(`class="${escapeHTML(resolved)}"`);
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
265
311
|
if (attrName === "style" && typeof attrValue === "object") {
|
|
266
312
|
const styleStr = Object.entries(attrValue).map(([k, v]) => `${camelToKebab(k)}: ${v}`).join("; ");
|
|
267
313
|
attrs.push(`style="${escapeHTML(styleStr)}"`);
|
|
@@ -937,7 +983,9 @@ var AppImpl = class {
|
|
|
937
983
|
"@semajsx/core",
|
|
938
984
|
"@semajsx/dom",
|
|
939
985
|
"@semajsx/signal",
|
|
940
|
-
"@semajsx/ssr"
|
|
986
|
+
"@semajsx/ssr",
|
|
987
|
+
"@semajsx/style",
|
|
988
|
+
"@semajsx/ui"
|
|
941
989
|
] },
|
|
942
990
|
resolve: {
|
|
943
991
|
conditions: [
|
|
@@ -954,7 +1002,9 @@ var AppImpl = class {
|
|
|
954
1002
|
noExternal: [
|
|
955
1003
|
"@semajsx/core",
|
|
956
1004
|
"@semajsx/dom",
|
|
957
|
-
"@semajsx/signal"
|
|
1005
|
+
"@semajsx/signal",
|
|
1006
|
+
"@semajsx/style",
|
|
1007
|
+
"@semajsx/ui"
|
|
958
1008
|
],
|
|
959
1009
|
external: ["lightningcss", "fsevents"]
|
|
960
1010
|
}
|
|
@@ -1027,7 +1077,7 @@ var AppImpl = class {
|
|
|
1027
1077
|
};
|
|
1028
1078
|
}
|
|
1029
1079
|
async build(options = {}) {
|
|
1030
|
-
const { outDir = "dist", mode = "full", minify = true, sourcemap = false, onIslandBuilt } = options;
|
|
1080
|
+
const { outDir = "dist", mode = "full", minify = true, sourcemap = false, onIslandBuilt, renderHtml: customRenderHtml } = options;
|
|
1031
1081
|
logger.info(`Building for production (mode: ${mode})...`);
|
|
1032
1082
|
const { mkdir } = await import("fs/promises");
|
|
1033
1083
|
const rootDir = this.config.root ? resolve(this.config.root) : process.cwd();
|
|
@@ -1047,25 +1097,32 @@ var AppImpl = class {
|
|
|
1047
1097
|
const htmlFileName = path === "/" ? "index.html" : `${path.replace(/^\//, "")}.html`;
|
|
1048
1098
|
const cssRefs = result.css;
|
|
1049
1099
|
const seenComponents = /* @__PURE__ */ new Set();
|
|
1050
|
-
const
|
|
1100
|
+
const islandScriptEntries = [];
|
|
1051
1101
|
for (const island of result.islands) {
|
|
1052
1102
|
const componentKey = this._getComponentKey(island.path, rootDir);
|
|
1053
1103
|
if (!seenComponents.has(componentKey)) {
|
|
1054
1104
|
seenComponents.add(componentKey);
|
|
1055
|
-
|
|
1105
|
+
islandScriptEntries.push({ src: `/_semajsx/islands/${componentKey}.ts` });
|
|
1056
1106
|
}
|
|
1057
1107
|
}
|
|
1058
|
-
|
|
1108
|
+
const pageTitle = this._routeMeta.get(path)?.title ?? this.config.title ?? "Page";
|
|
1109
|
+
modules[htmlFileName] = customRenderHtml ? customRenderHtml({
|
|
1110
|
+
html: result.html,
|
|
1111
|
+
css: cssRefs,
|
|
1112
|
+
scripts: islandScriptEntries,
|
|
1113
|
+
title: pageTitle,
|
|
1114
|
+
path
|
|
1115
|
+
}) : `<!DOCTYPE html>
|
|
1059
1116
|
<html lang="en">
|
|
1060
1117
|
<head>
|
|
1061
1118
|
<meta charset="UTF-8">
|
|
1062
1119
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
1063
|
-
<title>${
|
|
1120
|
+
<title>${pageTitle}</title>
|
|
1064
1121
|
${cssRefs.map((href) => `<link rel="stylesheet" href="${href}">`).join("\n ")}
|
|
1065
1122
|
</head>
|
|
1066
1123
|
<body>
|
|
1067
1124
|
${result.html}
|
|
1068
|
-
${
|
|
1125
|
+
${islandScriptEntries.map((s) => `<script type="module" src="${s.src}"><\/script>`).join("\n ")}
|
|
1069
1126
|
</body>
|
|
1070
1127
|
</html>`;
|
|
1071
1128
|
htmlInputs[htmlFileName.replace(".html", "")] = htmlFileName;
|
|
@@ -1078,7 +1135,7 @@ var AppImpl = class {
|
|
|
1078
1135
|
if (componentPath.startsWith("file://")) componentPath = new URL(componentPath).pathname;
|
|
1079
1136
|
const componentName = island.componentName;
|
|
1080
1137
|
const entryCode = `
|
|
1081
|
-
import { hydrateAllIslands } from '
|
|
1138
|
+
import { hydrateAllIslands } from 'semajsx/ssr/client';
|
|
1082
1139
|
import * as ComponentModule from '${componentPath}';
|
|
1083
1140
|
|
|
1084
1141
|
const Component = ${componentName ? `ComponentModule['${componentName}'] || ComponentModule.${componentName}` : "ComponentModule.default"} ||
|
|
@@ -1172,8 +1229,8 @@ if (Component) {
|
|
|
1172
1229
|
const componentPath = this._normalizeModulePath(island.path);
|
|
1173
1230
|
const componentName = island.componentName;
|
|
1174
1231
|
const entryCode = `
|
|
1175
|
-
import { hydrateIsland } from '
|
|
1176
|
-
import { markIslandHydrated } from '
|
|
1232
|
+
import { hydrateIsland } from 'semajsx/ssr/client';
|
|
1233
|
+
import { markIslandHydrated } from 'semajsx/ssr/client';
|
|
1177
1234
|
import * as ComponentModule from '${componentPath}';
|
|
1178
1235
|
|
|
1179
1236
|
// Get the component (try named export first, then default, then first function)
|
|
@@ -1279,8 +1336,8 @@ if (Component) {
|
|
|
1279
1336
|
const componentPath = normalizeModulePath(island.path);
|
|
1280
1337
|
const componentName = island.componentName;
|
|
1281
1338
|
return `
|
|
1282
|
-
import { hydrateIsland } from '
|
|
1283
|
-
import { markIslandHydrated } from '
|
|
1339
|
+
import { hydrateIsland } from 'semajsx/ssr/client';
|
|
1340
|
+
import { markIslandHydrated } from 'semajsx/ssr/client';
|
|
1284
1341
|
import * as ComponentModule from '${componentPath}';
|
|
1285
1342
|
|
|
1286
1343
|
// Get the component (try named export first, then default, then first function)
|
|
@@ -1399,7 +1456,7 @@ var ViteIslandBuilder = class {
|
|
|
1399
1456
|
const displayName = componentName || island.id;
|
|
1400
1457
|
return `
|
|
1401
1458
|
// Island hydration entry point: ${displayName}
|
|
1402
|
-
import { hydrate, markIslandHydrated } from '
|
|
1459
|
+
import { hydrate, markIslandHydrated } from 'semajsx/ssr/client';
|
|
1403
1460
|
import * as ComponentModule from '${componentPath}';
|
|
1404
1461
|
|
|
1405
1462
|
// Get the component
|
|
@@ -1554,7 +1611,7 @@ var ViteRouter = class {
|
|
|
1554
1611
|
const result = await renderToString(match.handler(context), { transformIslandScript: (island) => `<script type="module" src="${island.basePath}/${island.id}.js" async><\/script>` });
|
|
1555
1612
|
for (const island of result.islands) this.islandsCache.set(island.id, island);
|
|
1556
1613
|
if (this.config.document) {
|
|
1557
|
-
const { renderDocument } = await import("./document-
|
|
1614
|
+
const { renderDocument } = await import("./document-CwHVG_PJ.mjs");
|
|
1558
1615
|
result.document = renderDocument(this.config.document({
|
|
1559
1616
|
children: {
|
|
1560
1617
|
type: "template",
|
|
@@ -1752,4 +1809,4 @@ function createIslandCollector() {
|
|
|
1752
1809
|
|
|
1753
1810
|
//#endregion
|
|
1754
1811
|
export { ViteIslandBuilder as a, renderToString as c, createViteRouter as i, createIslandCollector as n, createViteIslandBuilder as o, ViteRouter as r, createApp as s, IslandCollector as t };
|
|
1755
|
-
//# sourceMappingURL=src-
|
|
1812
|
+
//# sourceMappingURL=src-DuSN6go_.mjs.map
|