nuclo 0.1.127 → 0.2.1
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/core/runtimeBootstrap.d.ts.map +1 -1
- package/dist/nuclo.cjs +1 -1
- package/dist/nuclo.cjs.map +1 -1
- package/dist/nuclo.mjs +1 -1
- package/dist/nuclo.mjs.map +1 -1
- package/dist/nuclo.umd.js +1 -1
- package/dist/nuclo.umd.js.map +1 -1
- package/dist/polyfill/Document.d.ts.map +1 -1
- package/dist/polyfill/Element.d.ts.map +1 -1
- package/dist/polyfill/Event.d.ts.map +1 -1
- package/dist/polyfill/nuclo.polyfill.cjs +1 -1
- package/dist/polyfill/nuclo.polyfill.cjs.map +1 -1
- package/dist/polyfill/nuclo.polyfill.mjs +1 -1
- package/dist/polyfill/nuclo.polyfill.mjs.map +1 -1
- package/dist/ssr/index.d.ts +1 -1
- package/dist/ssr/index.d.ts.map +1 -1
- package/dist/ssr/nuclo.ssr.cjs +1 -1
- package/dist/ssr/nuclo.ssr.cjs.map +1 -1
- package/dist/ssr/nuclo.ssr.mjs +1 -1
- package/dist/ssr/nuclo.ssr.mjs.map +1 -1
- package/dist/ssr/renderToString.d.ts.map +1 -1
- package/dist/style/css.d.ts +314 -0
- package/dist/style/css.d.ts.map +1 -0
- package/dist/style/engine.d.ts +34 -0
- package/dist/style/engine.d.ts.map +1 -0
- package/dist/style/index.d.ts +2 -4
- package/dist/style/index.d.ts.map +1 -1
- package/dist/utility/errorHandler.d.ts.map +1 -1
- package/package.json +11 -10
- package/types/features/list.d.ts +1 -0
- package/types/features/style.d.ts +61 -1954
- package/dist/environment-BNEQOK9T.mjs +0 -2
- package/dist/environment-BNEQOK9T.mjs.map +0 -1
- package/dist/environment-BQwVWSG6.cjs +0 -2
- package/dist/environment-BQwVWSG6.cjs.map +0 -1
- package/dist/style/cssGenerator.d.ts +0 -13
- package/dist/style/cssGenerator.d.ts.map +0 -1
- package/dist/style/cssPropertyTypes.d.ts +0 -98
- package/dist/style/cssPropertyTypes.d.ts.map +0 -1
- package/dist/style/styleBuilder.d.ts +0 -337
- package/dist/style/styleBuilder.d.ts.map +0 -1
- package/dist/style/styleCache.d.ts +0 -5
- package/dist/style/styleCache.d.ts.map +0 -1
- package/dist/style/styleProperties.d.ts +0 -13
- package/dist/style/styleProperties.d.ts.map +0 -1
- package/dist/style/styleQueries.d.ts +0 -25
- package/dist/style/styleQueries.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nuclo.ssr.mjs","names":[],"sources":["../../src/utility/stringUtils.ts","../../src/utility/dom.ts","../../src/ssr/renderToString.ts","../../src/style/cssGenerator.ts"],"sourcesContent":["/**\n * String utility functions\n */\n\n/**\n * Converts camelCase to kebab-case (optimized for performance)\n * Uses direct character code manipulation for maximum speed\n * @example camelToKebab('backgroundColor') => 'background-color'\n */\nexport function camelToKebab(str: string): string {\n let result = '';\n for (let i = 0; i < str.length; i++) {\n const code = str.charCodeAt(i);\n // A-Z is 65-90, a-z is 97-122 (difference of 32)\n if (code >= 65 && code <= 90) {\n if (i > 0) result += '-';\n result += String.fromCharCode(code + 32);\n } else {\n result += str[i];\n }\n }\n return result;\n}\n\n/**\n * Escapes HTML special characters in attribute values (includes \" and ')\n */\nexport function escapeHtml(text: string): string {\n const map: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n };\n return text.replace(/[&<>\"']/g, (char) => map[char]);\n}\n\n/**\n * Escapes HTML special characters in text node content.\n * Only &, < and > need escaping — quotes are safe inside text nodes.\n */\nexport function escapeText(text: string): string {\n return text.replace(/[&<>]/g, (char) => (char === '&' ? '&' : char === '<' ? '<' : '>'));\n}\n","import { logError } from \"./errorHandler\";\nimport { removeAllListeners } from \"./on\";\nimport { cleanupReactiveTextNode, cleanupReactiveElement } from \"../core/reactiveCleanup\";\nimport { unregisterConditionalNode } from \"./conditionalInfo\";\n\nexport const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n\n/**\n * Creates an HTML element.\n * Wrapper for document.createElement with type safety.\n */\nexport function createElement<K extends keyof HTMLElementTagNameMap>(\n tagName: K\n): HTMLElementTagNameMap[K] | null;\nexport function createElement(tagName: string): ExpandedElement | null;\nexport function createElement(tagName: string): ExpandedElement | null {\n return globalThis.document ? document.createElement(tagName) as ExpandedElement : null;\n}\n\n/**\n * Creates an element in the given namespace (typically for SVG elements).\n * Wrapper for document.createElementNS with type safety.\n */\nexport function createElementNS(\n namespace: string,\n tagName: string\n): ExpandedElement | null {\n return globalThis.document ? document.createElementNS(namespace, tagName) as ExpandedElement : null;\n}\n\n/**\n * Creates a text node with the given content.\n * Wrapper for document.createTextNode.\n */\nexport function createTextNode(text: string): Text | null {\n return globalThis.document ? document.createTextNode(text) : null;\n}\n\n/**\n * Creates a document fragment.\n * Wrapper for document.createDocumentFragment.\n */\nexport function createDocumentFragment(): DocumentFragment | null {\n return globalThis.document ? document.createDocumentFragment() : null;\n}\n\nfunction safeAppendChild(parent: Element | Node, child: Node): boolean {\n try {\n parent.appendChild(child);\n return true;\n } catch (error) {\n logError('Failed to append child node', error);\n return false;\n }\n}\n\n/**\n * Recursively removes all event listeners and reactive subscriptions from a node and its descendants\n * to prevent memory leaks when elements are removed from the DOM.\n */\nfunction cleanupEventListeners(node: Node): void {\n // Clean up the node itself based on its type\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as HTMLElement;\n // Remove all event listeners\n removeAllListeners(element);\n // Remove reactive attribute resolvers\n cleanupReactiveElement(element);\n // Remove conditional info\n unregisterConditionalNode(element);\n } else if (node.nodeType === Node.TEXT_NODE) {\n // Remove reactive text node info\n cleanupReactiveTextNode(node as Text);\n } else if (node.nodeType === Node.COMMENT_NODE) {\n // Remove conditional info from comment nodes (used by when/list)\n unregisterConditionalNode(node);\n }\n \n // Recursively clean up all child nodes\n if (node.childNodes && node.childNodes.length > 0) {\n for (let i = 0; i < node.childNodes.length; i++) {\n cleanupEventListeners(node.childNodes[i]);\n }\n }\n}\n\nexport function safeRemoveChild(child: Node): boolean {\n if (!child?.parentNode) return false;\n try {\n // Clean up all event listeners before removing the element\n cleanupEventListeners(child);\n child.parentNode.removeChild(child);\n return true;\n } catch (error) {\n logError('Failed to remove child node', error);\n return false;\n }\n}\n\nfunction safeInsertBefore(parent: Node, newNode: Node, referenceNode: Node | null): boolean {\n try {\n parent.insertBefore(newNode, referenceNode);\n return true;\n } catch (error) {\n logError('Failed to insert node before reference', error);\n return false;\n }\n}\n\nexport function createComment(text: string): Comment | null {\n return globalThis.document ? globalThis.document.createComment(text) : null;\n}\n\nexport function createConditionalComment(tagName: string, suffix = \"hidden\"): Comment | null {\n return globalThis.document ? globalThis.document.createComment(`conditional-${tagName}-${suffix}`) : null;\n}\n\nexport function createMarkerPair(prefix: string, id: number | string): { start: Comment; end: Comment } {\n const endComment = createComment(`${prefix}-end`);\n if (!endComment) throw new Error(\"Failed to create comment: document not available\");\n const startComment = createComment(`${prefix}-start-${id}`);\n if (!startComment) throw new Error(\"Failed to create comment: document not available\");\n return { start: startComment, end: endComment };\n}\n\nexport function clearBetweenMarkers(startMarker: Comment, endMarker: Comment): void {\n let current = startMarker.nextSibling;\n while (current && current !== endMarker) {\n const next = current.nextSibling;\n safeRemoveChild(current);\n current = next;\n }\n}\n\nexport function insertNodesBefore(nodes: Node[], referenceNode: Node): void {\n const parent = referenceNode.parentNode;\n if (parent) {\n for (let i = 0; i < nodes.length; i++) {\n safeInsertBefore(parent, nodes[i], referenceNode);\n }\n }\n}\n\nexport function appendChildren(\n parent: Element | Node,\n ...children: Array<Element | Node | string | null | undefined>\n): Element | Node {\n if (!parent) return parent;\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (child != null) {\n let nodeToAppend: Node;\n\n if (typeof child === \"string\") {\n const textNode = createTextNode(child);\n if (textNode) {\n nodeToAppend = textNode;\n } else {\n continue;\n }\n } else {\n nodeToAppend = child as Node;\n }\n\n safeAppendChild(parent, nodeToAppend);\n }\n }\n\n return parent;\n}\n\nexport function isNodeConnected(node: Node | null | undefined): boolean {\n if (!node) return false;\n return node.isConnected === true;\n}\n\n/**\n * Safely replaces an old node with a new node in the DOM.\n * Returns true on success, false on failure (and logs the error).\n */\nexport function replaceNodeSafely(oldNode: Node, newNode: Node): boolean {\n if (!oldNode?.parentNode) return false;\n try {\n oldNode.parentNode.replaceChild(newNode, oldNode);\n return true;\n } catch (error) {\n logError(\"Error replacing conditional node\", error);\n return false;\n }\n}\n","/**\n * Server-Side Rendering (SSR) utilities for Nuclo\n * Renders Nuclo components to HTML strings in Node.js environment\n */\n\nimport { escapeHtml, escapeText, camelToKebab } from '../utility/stringUtils';\nimport { createElement } from '../utility/dom';\n\ntype RenderableInput =\n | NodeModFn<ElementTagName>\n | Element\n | Node\n | null\n | undefined;\n\n/**\n * SVG attributes that are natively camelCase and must NOT be converted to kebab-case.\n * Most SVG attributes are already kebab-case (stroke-width, fill-rule, etc.), but a\n * handful are defined as camelCase in the SVG spec and must be preserved.\n */\nconst SVG_PRESERVE_CASE_ATTRS = new Set([\n 'viewBox', 'preserveAspectRatio', 'markerWidth', 'markerHeight',\n 'gradientTransform', 'patternTransform', 'clipPathUnits', 'gradientUnits',\n 'patternUnits', 'pathLength', 'refX', 'refY', 'stdDeviation',\n 'baseFrequency', 'numOctaves', 'kernelMatrix', 'tableValues',\n 'targetX', 'targetY', 'specularExponent', 'specularConstant',\n 'diffuseConstant', 'surfaceScale', 'xChannelSelector', 'yChannelSelector',\n 'edgeMode', 'stitchTiles', 'spreadMethod', 'patternContentUnits',\n 'markerUnits', 'startOffset', 'textLength', 'lengthAdjust',\n]);\n\n/**\n * HTML boolean attributes — presence means true, absence means false.\n * When the stored value is the string \"true\" or \"false\" (from setAttribute),\n * we must re-apply boolean semantics instead of outputting the raw string.\n */\nconst HTML_BOOLEAN_ATTRIBUTES = new Set([\n 'allowfullscreen', 'async', 'autofocus', 'autoplay', 'checked', 'controls',\n 'default', 'defer', 'disabled', 'formnovalidate', 'hidden', 'ismap', 'loop',\n 'multiple', 'muted', 'nomodule', 'novalidate', 'open', 'readonly', 'required',\n 'reversed', 'selected',\n]);\n\n/**\n * Serializes a DOM attribute value\n */\nfunction serializeAttribute(name: string, value: unknown): string {\n if (value === null || value === undefined || value === false) {\n return '';\n }\n\n if (value === true) {\n return ` ${name}`;\n }\n\n // Boolean attributes stored as strings via setAttribute() need special handling\n if (HTML_BOOLEAN_ATTRIBUTES.has(name)) {\n if (value === 'false') return '';\n if (value === 'true' || value === '' || value === name) return ` ${name}`;\n }\n\n if (name === 'style' && typeof value === 'object') {\n const styleStr = Object.entries(value)\n .filter(([, val]) => val != null && val !== '')\n .map(([key, val]) => `${camelToKebab(key)}: ${val};`)\n .join(' ');\n return styleStr ? ` style=\"${escapeHtml(styleStr)}\"` : '';\n }\n\n return ` ${name}=\"${escapeHtml(String(value))}\"`;\n}\n\n/**\n * Serializes DOM element attributes to HTML string\n */\nfunction serializeAttributes(element: Element): string {\n let result = '';\n\n // Handle polyfill elements with Map-based attributes\n if ('attributes' in element && element.attributes instanceof Map) {\n const el = element as any;\n\n // id — may live on the property rather than in the Map\n if (el.id && !element.attributes.has('id')) {\n result += serializeAttribute('id', el.id);\n }\n\n // class — kept on .className, mirrored to Map only when setAttribute is used\n if (el.className && !element.attributes.has('class')) {\n result += serializeAttribute('class', el.className);\n }\n\n // style — lives on the Proxy, not in the attributes Map.\n // cssText returns camelCase keys (\"backgroundColor: red\"), so convert them.\n if (!element.attributes.has('style') && el.style) {\n const rawCssText: string = el.style.cssText || '';\n if (rawCssText) {\n const kebabStyle = rawCssText\n .split(';')\n .map((decl: string) => decl.trim())\n .filter(Boolean)\n .map((decl: string) => {\n const colonIdx = decl.indexOf(':');\n if (colonIdx === -1) return decl;\n const key = decl.slice(0, colonIdx).trim();\n const val = decl.slice(colonIdx + 1).trim();\n // Skip declarations with empty values (e.g. reactive styles that resolved to undefined)\n if (!val) return '';\n return `${camelToKebab(key)}: ${val};`;\n })\n .filter(Boolean)\n .join(' ');\n if (kebabStyle) {\n result += ` style=\"${escapeHtml(kebabStyle)}\"`;\n }\n }\n }\n\n // All remaining attributes from the Map\n // Convert camelCase ARIA/HTML attribute names (e.g. ariaLabel → aria-label) that the\n // polyfill stores as-is because NucloElement lacks the browser property mappings.\n // SVG attributes that are natively camelCase (e.g. viewBox, preserveAspectRatio) must\n // NOT be converted — they are stored via setAttribute() as-is.\n for (const [name, value] of element.attributes) {\n const htmlName = SVG_PRESERVE_CASE_ATTRS.has(name) ? name : camelToKebab(name);\n result += serializeAttribute(htmlName, value);\n }\n return result;\n }\n\n // Handle browser elements with NamedNodeMap attributes\n if (element.attributes && element.attributes.length) {\n for (let i = 0; i < element.attributes.length; i++) {\n const attr = element.attributes[i];\n if (attr && attr.name) {\n result += serializeAttribute(attr.name, attr.value);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Self-closing HTML tags that don't have closing tags\n */\nconst VOID_ELEMENTS = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n 'link', 'meta', 'param', 'source', 'track', 'wbr'\n]);\n\n/**\n * Get child nodes from a node (handles both browser and polyfill elements).\n *\n * NucloElement stores ALL children (elements, text, comments) in a plain Array\n * called `children` — it is the authoritative list. DocumentFragments in the\n * polyfill also have a `children` array, but it only holds Element children;\n * their full set of nodes lives in `childNodes`. We therefore only prefer\n * `children` when the node is an actual element (has `tagName`).\n */\nfunction getChildNodes(node: Node): ArrayLike<Node> {\n // NucloElement: tagName exists and children is a plain Array containing every node type\n if ('tagName' in node && 'children' in node) {\n const children = (node as any).children;\n if (Array.isArray(children)) {\n return children as ArrayLike<Node>;\n }\n }\n // DocumentFragments and browser elements: use childNodes\n if ('childNodes' in node) {\n const childNodes = (node as any).childNodes;\n if (childNodes && (Array.isArray(childNodes) || childNodes.length !== undefined)) {\n return childNodes;\n }\n }\n return [] as ArrayLike<Node>;\n}\n\n/**\n * Serializes a DOM node to HTML string\n */\nfunction serializeNode(node: Node): string {\n // Text node — only & < > need escaping; quotes are safe in text content\n if (node.nodeType === 3) { // Node.TEXT_NODE\n return escapeText(node.textContent || '');\n }\n\n // Comment node\n if (node.nodeType === 8) { // Node.COMMENT_NODE\n return `<!--${node.textContent || ''}-->`;\n }\n\n // Element node\n if (node.nodeType === 1) { // Node.ELEMENT_NODE\n const element = node as Element;\n const tagName = element.tagName.toLowerCase();\n const attributes = serializeAttributes(element);\n\n // Self-closing tags\n if (VOID_ELEMENTS.has(tagName)) {\n return `<${tagName}${attributes} />`;\n }\n\n // Regular elements with children\n let childrenHtml = '';\n const childNodes = getChildNodes(element);\n if (childNodes && childNodes.length > 0) {\n for (let i = 0; i < childNodes.length; i++) {\n const child = childNodes[i];\n if (child) {\n childrenHtml += serializeNode(child);\n }\n }\n } else {\n // Fallback: textContent set directly on the element (e.g. el.textContent = \"...\")\n const tc = (node as any).textContent;\n if (typeof tc === 'string' && tc) {\n childrenHtml = escapeText(tc);\n }\n }\n\n return `<${tagName}${attributes}>${childrenHtml}</${tagName}>`;\n }\n\n // Document fragment\n if (node.nodeType === 11) { // Node.DOCUMENT_FRAGMENT_NODE\n let result = '';\n const childNodes = getChildNodes(node);\n if (childNodes && childNodes.length > 0) {\n for (let i = 0; i < childNodes.length; i++) {\n const child = childNodes[i];\n if (child) {\n result += serializeNode(child);\n }\n }\n }\n return result;\n }\n\n return '';\n}\n\n/**\n * Renders a Nuclo component to an HTML string for server-side rendering\n *\n * @param input - A Nuclo component function, DOM element, or node\n * @returns HTML string representation of the component\n *\n * @example\n * ```ts\n * import { renderToString } from 'nuclo/ssr';\n * import { div } from 'nuclo';\n *\n * const html = renderToString(\n * div(\"Hello, World!\")\n * );\n * // Returns: '<div>Hello, World!</div>'\n * ```\n */\nexport function renderToString(input: RenderableInput): string {\n if (!input) return '';\n\n if (typeof input === 'function') {\n try {\n const container = createElement('div');\n if (!container) throw new Error('Document is not available. Make sure polyfills are loaded.');\n const element = input(container as ExpandedElement<ElementTagName>, 0);\n return element && typeof element === 'object' && 'nodeType' in element ? serializeNode(element as Node) : '';\n } catch (error) {\n console.error('Error rendering component to string:', error);\n return '';\n }\n }\n\n if ('nodeType' in input) {\n return serializeNode(input as Node);\n }\n\n return '';\n}\n\n/**\n * Renders multiple Nuclo components to HTML strings\n *\n * @param inputs - Array of Nuclo components\n * @returns Array of HTML strings\n */\nexport function renderManyToString(inputs: RenderableInput[]): string[] {\n return inputs.map(input => renderToString(input));\n}\n\n/**\n * Renders a Nuclo component and wraps it in a container element\n *\n * @param input - A Nuclo component\n * @param containerTag - The tag name for the container (default: 'div')\n * @param containerAttrs - Attributes for the container element\n * @returns HTML string with container wrapper\n */\nexport function renderToStringWithContainer(\n input: RenderableInput,\n containerTag: string = 'div',\n containerAttrs: Record<string, string> = {}\n): string {\n const content = renderToString(input);\n const attrs = Object.entries(containerAttrs)\n .map(([key, value]) => serializeAttribute(key, value))\n .join('');\n\n return `<${containerTag}${attrs}>${content}</${containerTag}>`;\n}\n","import { createElement } from \"../utility/dom\";\nimport { isBrowser } from \"../utility/environment\";\n\ntype AtRuleType = 'media' | 'container' | 'supports' | 'style' | 'pseudo';\n\n// SSR collector — a single function reference installed once at server startup.\n// Keeping this as a plain function slot (no global Set, no ALS) means the nuclo\n// package stays browser-safe and free of Node-specific imports. The server is\n// responsible for wiring in whatever collection strategy it wants (e.g. an\n// AsyncLocalStorage-backed dispatcher). null = no-op (browser default).\ntype SSRCollector = (rule: string) => void;\nlet _ssrCollector: SSRCollector | null = null;\n\n/**\n * Install a CSS rule collector for SSR. Call once at server startup with a\n * function that receives every rule string emitted by cn() / createStyleQueries.\n * Pass null to remove the collector (not normally needed).\n */\nexport function setSSRCollector(fn: SSRCollector | null): void {\n\t_ssrCollector = fn;\n}\n\nfunction isAtRule(rule: CSSRule): boolean {\n\treturn rule instanceof CSSMediaRule ||\n\t\trule instanceof CSSContainerRule ||\n\t\trule instanceof CSSSupportsRule;\n}\n\nfunction matchesAtRule(rule: CSSRule, atRuleType: AtRuleType, condition: string): boolean {\n\tif (atRuleType === 'media' && rule instanceof CSSMediaRule) {\n\t\treturn rule.media.mediaText === condition;\n\t}\n\tif (atRuleType === 'container' && rule instanceof CSSContainerRule) {\n\t\treturn rule.conditionText === condition;\n\t}\n\tif (atRuleType === 'supports' && rule instanceof CSSSupportsRule) {\n\t\treturn rule.conditionText === condition;\n\t}\n\treturn false;\n}\n\nfunction findStyleRule(rules: CSSRuleList, selector: string): CSSStyleRule | null {\n\tfor (let i = 0; i < rules.length; i++) {\n\t\tconst rule = rules[i];\n\t\tif (rule instanceof CSSStyleRule && rule.selectorText === selector) {\n\t\t\treturn rule;\n\t\t}\n\t}\n\treturn null;\n}\n\nfunction updateRuleStyles(rule: CSSStyleRule, styles: Record<string, string>): void {\n\trule.style.cssText = '';\n\tfor (const [property, value] of Object.entries(styles)) {\n\t\trule.style.setProperty(property, value);\n\t}\n}\n\nfunction getStyleSheet(): HTMLStyleElement | null {\n\tif (!isBrowser) return null;\n\tlet el = document.querySelector(\"#nuclo-styles\") as HTMLStyleElement;\n\tif (!el) {\n\t\tel = createElement(\"style\") as HTMLStyleElement;\n\t\tel.id = \"nuclo-styles\";\n\t\tdocument.head.appendChild(el);\n\t}\n\treturn el;\n}\n\nfunction buildRulesString(styles: Record<string, string>): string {\n\tconst entries = Object.entries(styles);\n\tlet result = '';\n\tfor (let i = 0; i < entries.length; i++) {\n\t\tif (i > 0) result += '; ';\n\t\tresult += `${entries[i][0]}: ${entries[i][1]}`;\n\t}\n\treturn result;\n}\n\nexport function classExistsInDOM(className: string, condition?: string, atRuleType: AtRuleType = 'media', pseudoClass?: string): boolean {\n\tif (!isBrowser) return false;\n\tconst styleSheet = document.querySelector(\"#nuclo-styles\") as HTMLStyleElement;\n\tif (!styleSheet?.sheet) return false;\n\n\tconst rules = styleSheet.sheet.cssRules;\n\n\tif (pseudoClass) {\n\t\treturn findStyleRule(rules, `.${className}${pseudoClass}`) !== null;\n\t}\n\n\tif (condition) {\n\t\tfor (let i = 0; i < rules.length; i++) {\n\t\t\tif (matchesAtRule(rules[i], atRuleType, condition)) {\n\t\t\t\treturn findStyleRule((rules[i] as CSSGroupingRule).cssRules, `.${className}`) !== null;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\treturn findStyleRule(rules, `.${className}`) !== null;\n}\n\nexport function createCSSClassWithStyles(\n\tclassName: string,\n\tstyles: Record<string, string>,\n\tcondition?: string,\n\tatRuleType: AtRuleType = 'media',\n\tpseudoClass?: string\n): void {\n\tif (!isBrowser) {\n\t\tconst rulesStr = buildRulesString(styles);\n\t\tlet rule: string;\n\t\tif (pseudoClass) {\n\t\t\trule = `.${className}${pseudoClass} { ${rulesStr} }`;\n\t\t} else if (condition) {\n\t\t\tconst prefix = atRuleType === 'container' ? '@container'\n\t\t\t\t: atRuleType === 'supports' ? '@supports'\n\t\t\t\t: '@media';\n\t\t\trule = `${prefix} ${condition} { .${className} { ${rulesStr} } }`;\n\t\t} else {\n\t\t\trule = `.${className} { ${rulesStr} }`;\n\t\t}\n\t\t_ssrCollector?.(rule);\n\t\treturn;\n\t}\n\n\tconst styleSheet = getStyleSheet();\n\tif (!styleSheet) return;\n\n\tconst sheet = styleSheet.sheet;\n\tif (!sheet) return;\n\n\tconst rulesStr = buildRulesString(styles);\n\n\tif (pseudoClass) {\n\t\tconst selector = `.${className}${pseudoClass}`;\n\t\tconst allRules = sheet.cssRules;\n\t\tconst rulesLength = allRules.length;\n\n\t\tlet existingRule: CSSStyleRule | null = null;\n\t\tlet insertIndex = rulesLength;\n\n\t\tfor (let i = 0; i < rulesLength; i++) {\n\t\t\tconst rule = allRules[i];\n\t\t\tif (rule instanceof CSSStyleRule) {\n\t\t\t\tif (rule.selectorText === selector) {\n\t\t\t\t\texistingRule = rule;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (!rule.selectorText.includes(':')) {\n\t\t\t\t\tinsertIndex = i + 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (existingRule) {\n\t\t\tupdateRuleStyles(existingRule, styles);\n\t\t} else {\n\t\t\tsheet.insertRule(`${selector} { ${rulesStr} }`, insertIndex);\n\t\t}\n\t\treturn;\n\t}\n\n\tif (condition) {\n\t\tconst existingRules = sheet.cssRules;\n\t\tconst rulesLength = existingRules.length;\n\t\tlet groupingRule: CSSGroupingRule | null = null;\n\n\t\tfor (let i = 0; i < rulesLength; i++) {\n\t\t\tif (matchesAtRule(existingRules[i], atRuleType, condition)) {\n\t\t\t\tgroupingRule = existingRules[i] as CSSGroupingRule;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (!groupingRule) {\n\t\t\tlet insertIndex = rulesLength;\n\t\t\tfor (let i = rulesLength - 1; i >= 0; i--) {\n\t\t\t\tif (isAtRule(existingRules[i]) || existingRules[i] instanceof CSSStyleRule) {\n\t\t\t\t\tinsertIndex = i + 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst atRulePrefix = atRuleType === 'media' ? '@media' :\n\t\t\t\tatRuleType === 'container' ? '@container' :\n\t\t\t\tatRuleType === 'supports' ? '@supports' :\n\t\t\t\t'@media';\n\n\t\t\tsheet.insertRule(`${atRulePrefix} ${condition} {}`, insertIndex);\n\t\t\tgroupingRule = sheet.cssRules[insertIndex] as CSSGroupingRule;\n\t\t}\n\n\t\tconst existingRule = findStyleRule(groupingRule.cssRules, `.${className}`);\n\t\tif (existingRule) {\n\t\t\tupdateRuleStyles(existingRule, styles);\n\t\t} else {\n\t\t\tgroupingRule.insertRule(`.${className} { ${rulesStr} }`, groupingRule.cssRules.length);\n\t\t}\n\t} else {\n\t\tlet existingRule: CSSStyleRule | null = null;\n\t\tlet insertIndex = 0;\n\n\t\tconst allRules = sheet.cssRules;\n\t\tconst rulesLength = allRules.length;\n\t\tfor (let i = 0; i < rulesLength; i++) {\n\t\t\tconst rule = allRules[i];\n\t\t\tif (rule instanceof CSSStyleRule && rule.selectorText === `.${className}`) {\n\t\t\t\texistingRule = rule;\n\t\t\t\tinsertIndex = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!isAtRule(rule)) {\n\t\t\t\tinsertIndex = i + 1;\n\t\t\t}\n\t\t}\n\n\t\tif (existingRule) {\n\t\t\tupdateRuleStyles(existingRule, styles);\n\t\t} else {\n\t\t\tsheet.insertRule(`.${className} { ${rulesStr} }`, insertIndex);\n\t\t}\n\t}\n}\n\nexport function createCSSClass(className: string, styles: Record<string, string>): void {\n\tcreateCSSClassWithStyles(className, styles);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"nuclo.ssr.mjs","names":[],"sources":["../../src/utility/stringUtils.ts","../../src/utility/dom.ts","../../src/ssr/renderToString.ts","../../src/style/engine.ts"],"sourcesContent":["/**\n * String utility functions\n */\n\n/**\n * Converts camelCase to kebab-case (optimized for performance)\n * Uses direct character code manipulation for maximum speed\n * @example camelToKebab('backgroundColor') => 'background-color'\n */\nexport function camelToKebab(str: string): string {\n let result = '';\n for (let i = 0; i < str.length; i++) {\n const code = str.charCodeAt(i);\n // A-Z is 65-90, a-z is 97-122 (difference of 32)\n if (code >= 65 && code <= 90) {\n if (i > 0) result += '-';\n result += String.fromCharCode(code + 32);\n } else {\n result += str[i];\n }\n }\n return result;\n}\n\n/**\n * Escapes HTML special characters in attribute values (includes \" and ')\n */\nexport function escapeHtml(text: string): string {\n const map: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n };\n return text.replace(/[&<>\"']/g, (char) => map[char]);\n}\n\n/**\n * Escapes HTML special characters in text node content.\n * Only &, < and > need escaping — quotes are safe inside text nodes.\n */\nexport function escapeText(text: string): string {\n return text.replace(/[&<>]/g, (char) => (char === '&' ? '&' : char === '<' ? '<' : '>'));\n}\n","import { logError } from \"./errorHandler\";\nimport { removeAllListeners } from \"./on\";\nimport { cleanupReactiveTextNode, cleanupReactiveElement } from \"../core/reactiveCleanup\";\nimport { unregisterConditionalNode } from \"./conditionalInfo\";\n\nexport const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n\n/**\n * Creates an HTML element.\n * Wrapper for document.createElement with type safety.\n */\nexport function createElement<K extends keyof HTMLElementTagNameMap>(\n tagName: K\n): HTMLElementTagNameMap[K] | null;\nexport function createElement(tagName: string): ExpandedElement | null;\nexport function createElement(tagName: string): ExpandedElement | null {\n return globalThis.document ? document.createElement(tagName) as ExpandedElement : null;\n}\n\n/**\n * Creates an element in the given namespace (typically for SVG elements).\n * Wrapper for document.createElementNS with type safety.\n */\nexport function createElementNS(\n namespace: string,\n tagName: string\n): ExpandedElement | null {\n return globalThis.document ? document.createElementNS(namespace, tagName) as ExpandedElement : null;\n}\n\n/**\n * Creates a text node with the given content.\n * Wrapper for document.createTextNode.\n */\nexport function createTextNode(text: string): Text | null {\n return globalThis.document ? document.createTextNode(text) : null;\n}\n\n/**\n * Creates a document fragment.\n * Wrapper for document.createDocumentFragment.\n */\nexport function createDocumentFragment(): DocumentFragment | null {\n return globalThis.document ? document.createDocumentFragment() : null;\n}\n\nfunction safeAppendChild(parent: Element | Node, child: Node): boolean {\n try {\n parent.appendChild(child);\n return true;\n } catch (error) {\n logError('Failed to append child node', error);\n return false;\n }\n}\n\n/**\n * Recursively removes all event listeners and reactive subscriptions from a node and its descendants\n * to prevent memory leaks when elements are removed from the DOM.\n */\nfunction cleanupEventListeners(node: Node): void {\n // Clean up the node itself based on its type\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as HTMLElement;\n // Remove all event listeners\n removeAllListeners(element);\n // Remove reactive attribute resolvers\n cleanupReactiveElement(element);\n // Remove conditional info\n unregisterConditionalNode(element);\n } else if (node.nodeType === Node.TEXT_NODE) {\n // Remove reactive text node info\n cleanupReactiveTextNode(node as Text);\n } else if (node.nodeType === Node.COMMENT_NODE) {\n // Remove conditional info from comment nodes (used by when/list)\n unregisterConditionalNode(node);\n }\n \n // Recursively clean up all child nodes\n if (node.childNodes && node.childNodes.length > 0) {\n for (let i = 0; i < node.childNodes.length; i++) {\n cleanupEventListeners(node.childNodes[i]);\n }\n }\n}\n\nexport function safeRemoveChild(child: Node): boolean {\n if (!child?.parentNode) return false;\n try {\n // Clean up all event listeners before removing the element\n cleanupEventListeners(child);\n child.parentNode.removeChild(child);\n return true;\n } catch (error) {\n logError('Failed to remove child node', error);\n return false;\n }\n}\n\nfunction safeInsertBefore(parent: Node, newNode: Node, referenceNode: Node | null): boolean {\n try {\n parent.insertBefore(newNode, referenceNode);\n return true;\n } catch (error) {\n logError('Failed to insert node before reference', error);\n return false;\n }\n}\n\nexport function createComment(text: string): Comment | null {\n return globalThis.document ? globalThis.document.createComment(text) : null;\n}\n\nexport function createConditionalComment(tagName: string, suffix = \"hidden\"): Comment | null {\n return globalThis.document ? globalThis.document.createComment(`conditional-${tagName}-${suffix}`) : null;\n}\n\nexport function createMarkerPair(prefix: string, id: number | string): { start: Comment; end: Comment } {\n const endComment = createComment(`${prefix}-end`);\n if (!endComment) throw new Error(\"Failed to create comment: document not available\");\n const startComment = createComment(`${prefix}-start-${id}`);\n if (!startComment) throw new Error(\"Failed to create comment: document not available\");\n return { start: startComment, end: endComment };\n}\n\nexport function clearBetweenMarkers(startMarker: Comment, endMarker: Comment): void {\n let current = startMarker.nextSibling;\n while (current && current !== endMarker) {\n const next = current.nextSibling;\n safeRemoveChild(current);\n current = next;\n }\n}\n\nexport function insertNodesBefore(nodes: Node[], referenceNode: Node): void {\n const parent = referenceNode.parentNode;\n if (parent) {\n for (let i = 0; i < nodes.length; i++) {\n safeInsertBefore(parent, nodes[i], referenceNode);\n }\n }\n}\n\nexport function appendChildren(\n parent: Element | Node,\n ...children: Array<Element | Node | string | null | undefined>\n): Element | Node {\n if (!parent) return parent;\n\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (child != null) {\n let nodeToAppend: Node;\n\n if (typeof child === \"string\") {\n const textNode = createTextNode(child);\n if (textNode) {\n nodeToAppend = textNode;\n } else {\n continue;\n }\n } else {\n nodeToAppend = child as Node;\n }\n\n safeAppendChild(parent, nodeToAppend);\n }\n }\n\n return parent;\n}\n\nexport function isNodeConnected(node: Node | null | undefined): boolean {\n if (!node) return false;\n return node.isConnected === true;\n}\n\n/**\n * Safely replaces an old node with a new node in the DOM.\n * Returns true on success, false on failure (and logs the error).\n */\nexport function replaceNodeSafely(oldNode: Node, newNode: Node): boolean {\n if (!oldNode?.parentNode) return false;\n try {\n oldNode.parentNode.replaceChild(newNode, oldNode);\n return true;\n } catch (error) {\n logError(\"Error replacing conditional node\", error);\n return false;\n }\n}\n","/**\n * Server-Side Rendering (SSR) utilities for Nuclo\n * Renders Nuclo components to HTML strings in Node.js environment\n */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport { escapeHtml, escapeText, camelToKebab } from '../utility/stringUtils';\nimport { createElement } from '../utility/dom';\n\ntype RenderableInput =\n | NodeModFn<ElementTagName>\n | Element\n | Node\n | null\n | undefined;\n\n/**\n * SVG attributes that are natively camelCase and must NOT be converted to kebab-case.\n * Most SVG attributes are already kebab-case (stroke-width, fill-rule, etc.), but a\n * handful are defined as camelCase in the SVG spec and must be preserved.\n */\nconst SVG_PRESERVE_CASE_ATTRS = new Set([\n 'viewBox', 'preserveAspectRatio', 'markerWidth', 'markerHeight',\n 'gradientTransform', 'patternTransform', 'clipPathUnits', 'gradientUnits',\n 'patternUnits', 'pathLength', 'refX', 'refY', 'stdDeviation',\n 'baseFrequency', 'numOctaves', 'kernelMatrix', 'tableValues',\n 'targetX', 'targetY', 'specularExponent', 'specularConstant',\n 'diffuseConstant', 'surfaceScale', 'xChannelSelector', 'yChannelSelector',\n 'edgeMode', 'stitchTiles', 'spreadMethod', 'patternContentUnits',\n 'markerUnits', 'startOffset', 'textLength', 'lengthAdjust',\n]);\n\n/**\n * HTML boolean attributes — presence means true, absence means false.\n * When the stored value is the string \"true\" or \"false\" (from setAttribute),\n * we must re-apply boolean semantics instead of outputting the raw string.\n */\nconst HTML_BOOLEAN_ATTRIBUTES = new Set([\n 'allowfullscreen', 'async', 'autofocus', 'autoplay', 'checked', 'controls',\n 'default', 'defer', 'disabled', 'formnovalidate', 'hidden', 'ismap', 'loop',\n 'multiple', 'muted', 'nomodule', 'novalidate', 'open', 'readonly', 'required',\n 'reversed', 'selected',\n]);\n\n/**\n * Serializes a DOM attribute value\n */\nfunction serializeAttribute(name: string, value: unknown): string {\n if (value === null || value === undefined || value === false) {\n return '';\n }\n\n if (value === true) {\n return ` ${name}`;\n }\n\n // Boolean attributes stored as strings via setAttribute() need special handling\n if (HTML_BOOLEAN_ATTRIBUTES.has(name)) {\n if (value === 'false') return '';\n if (value === 'true' || value === '' || value === name) return ` ${name}`;\n }\n\n if (name === 'style' && typeof value === 'object') {\n const styleStr = Object.entries(value)\n .filter(([, val]) => val != null && val !== '')\n .map(([key, val]) => `${camelToKebab(key)}: ${val};`)\n .join(' ');\n return styleStr ? ` style=\"${escapeHtml(styleStr)}\"` : '';\n }\n\n return ` ${name}=\"${escapeHtml(String(value))}\"`;\n}\n\n/**\n * Serializes DOM element attributes to HTML string\n */\nfunction serializeAttributes(element: Element): string {\n let result = '';\n\n // Handle polyfill elements with Map-based attributes\n if ('attributes' in element && element.attributes instanceof Map) {\n const el = element as any;\n\n // id — may live on the property rather than in the Map\n if (el.id && !element.attributes.has('id')) {\n result += serializeAttribute('id', el.id);\n }\n\n // class — kept on .className, mirrored to Map only when setAttribute is used\n if (el.className && !element.attributes.has('class')) {\n result += serializeAttribute('class', el.className);\n }\n\n // style — lives on the Proxy, not in the attributes Map.\n // cssText returns camelCase keys (\"backgroundColor: red\"), so convert them.\n if (!element.attributes.has('style') && el.style) {\n const rawCssText: string = el.style.cssText || '';\n if (rawCssText) {\n const kebabStyle = rawCssText\n .split(';')\n .map((decl: string) => decl.trim())\n .filter(Boolean)\n .map((decl: string) => {\n const colonIdx = decl.indexOf(':');\n if (colonIdx === -1) return decl;\n const key = decl.slice(0, colonIdx).trim();\n const val = decl.slice(colonIdx + 1).trim();\n // Skip declarations with empty values (e.g. reactive styles that resolved to undefined)\n if (!val) return '';\n return `${camelToKebab(key)}: ${val};`;\n })\n .filter(Boolean)\n .join(' ');\n if (kebabStyle) {\n result += ` style=\"${escapeHtml(kebabStyle)}\"`;\n }\n }\n }\n\n // All remaining attributes from the Map\n // Convert camelCase ARIA/HTML attribute names (e.g. ariaLabel → aria-label) that the\n // polyfill stores as-is because NucloElement lacks the browser property mappings.\n // SVG attributes that are natively camelCase (e.g. viewBox, preserveAspectRatio) must\n // NOT be converted — they are stored via setAttribute() as-is.\n for (const [name, value] of element.attributes) {\n const htmlName = SVG_PRESERVE_CASE_ATTRS.has(name) ? name : camelToKebab(name);\n result += serializeAttribute(htmlName, value);\n }\n return result;\n }\n\n // Handle browser elements with NamedNodeMap attributes\n if (element.attributes && element.attributes.length) {\n for (let i = 0; i < element.attributes.length; i++) {\n const attr = element.attributes[i];\n if (attr && attr.name) {\n result += serializeAttribute(attr.name, attr.value);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Self-closing HTML tags that don't have closing tags\n */\nconst VOID_ELEMENTS = new Set([\n 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',\n 'link', 'meta', 'param', 'source', 'track', 'wbr'\n]);\n\n/**\n * Get child nodes from a node (handles both browser and polyfill elements).\n *\n * NucloElement stores ALL children (elements, text, comments) in a plain Array\n * called `children` — it is the authoritative list. DocumentFragments in the\n * polyfill also have a `children` array, but it only holds Element children;\n * their full set of nodes lives in `childNodes`. We therefore only prefer\n * `children` when the node is an actual element (has `tagName`).\n */\nfunction getChildNodes(node: Node): ArrayLike<Node> {\n // NucloElement: tagName exists and children is a plain Array containing every node type\n if ('tagName' in node && 'children' in node) {\n const children = (node as any).children;\n if (Array.isArray(children)) {\n return children as ArrayLike<Node>;\n }\n }\n // DocumentFragments and browser elements: use childNodes\n if ('childNodes' in node) {\n const childNodes = (node as any).childNodes;\n if (childNodes && (Array.isArray(childNodes) || childNodes.length !== undefined)) {\n return childNodes;\n }\n }\n return [] as ArrayLike<Node>;\n}\n\n/**\n * Serializes a DOM node to HTML string\n */\nfunction serializeNode(node: Node): string {\n // Text node — only & < > need escaping; quotes are safe in text content\n if (node.nodeType === 3) { // Node.TEXT_NODE\n return escapeText(node.textContent || '');\n }\n\n // Comment node\n if (node.nodeType === 8) { // Node.COMMENT_NODE\n return `<!--${node.textContent || ''}-->`;\n }\n\n // Element node\n if (node.nodeType === 1) { // Node.ELEMENT_NODE\n const element = node as Element;\n const tagName = element.tagName.toLowerCase();\n const attributes = serializeAttributes(element);\n\n // Self-closing tags\n if (VOID_ELEMENTS.has(tagName)) {\n return `<${tagName}${attributes} />`;\n }\n\n // Regular elements with children\n let childrenHtml = '';\n const childNodes = getChildNodes(element);\n if (childNodes && childNodes.length > 0) {\n for (let i = 0; i < childNodes.length; i++) {\n const child = childNodes[i];\n if (child) {\n childrenHtml += serializeNode(child);\n }\n }\n } else {\n // Fallback: textContent set directly on the element (e.g. el.textContent = \"...\")\n const tc = (node as any).textContent;\n if (typeof tc === 'string' && tc) {\n childrenHtml = escapeText(tc);\n }\n }\n\n return `<${tagName}${attributes}>${childrenHtml}</${tagName}>`;\n }\n\n // Document fragment\n if (node.nodeType === 11) { // Node.DOCUMENT_FRAGMENT_NODE\n let result = '';\n const childNodes = getChildNodes(node);\n if (childNodes && childNodes.length > 0) {\n for (let i = 0; i < childNodes.length; i++) {\n const child = childNodes[i];\n if (child) {\n result += serializeNode(child);\n }\n }\n }\n return result;\n }\n\n return '';\n}\n\n/**\n * Renders a Nuclo component to an HTML string for server-side rendering\n *\n * @param input - A Nuclo component function, DOM element, or node\n * @returns HTML string representation of the component\n *\n * @example\n * ```ts\n * import { renderToString } from 'nuclo/ssr';\n * import { div } from 'nuclo';\n *\n * const html = renderToString(\n * div(\"Hello, World!\")\n * );\n * // Returns: '<div>Hello, World!</div>'\n * ```\n */\nexport function renderToString(input: RenderableInput): string {\n if (!input) return '';\n\n if (typeof input === 'function') {\n try {\n const container = createElement('div');\n if (!container) throw new Error('Document is not available. Make sure polyfills are loaded.');\n const element = input(container as ExpandedElement<ElementTagName>, 0);\n return element && typeof element === 'object' && 'nodeType' in element ? serializeNode(element as Node) : '';\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('Error rendering component to string:', error);\n return '';\n }\n }\n\n if ('nodeType' in input) {\n return serializeNode(input as Node);\n }\n\n return '';\n}\n\n/**\n * Renders multiple Nuclo components to HTML strings\n *\n * @param inputs - Array of Nuclo components\n * @returns Array of HTML strings\n */\nexport function renderManyToString(inputs: RenderableInput[]): string[] {\n return inputs.map(input => renderToString(input));\n}\n\n/**\n * Renders a Nuclo component and wraps it in a container element\n *\n * @param input - A Nuclo component\n * @param containerTag - The tag name for the container (default: 'div')\n * @param containerAttrs - Attributes for the container element\n * @returns HTML string with container wrapper\n */\nexport function renderToStringWithContainer(\n input: RenderableInput,\n containerTag: string = 'div',\n containerAttrs: Record<string, string> = {}\n): string {\n const content = renderToString(input);\n const attrs = Object.entries(containerAttrs)\n .map(([key, value]) => serializeAttribute(key, value))\n .join('');\n\n return `<${containerTag}${attrs}>${content}</${containerTag}>`;\n}\n","/**\n * Shared atomic-CSS engine state.\n *\n * One stylesheet, one rule registry, shared by every `createCss` instance so\n * identical declarations dedupe globally and cascade order stays deterministic:\n * base rules first (insertion order), then one grouping rule per at-rule query\n * in registration order (theme `screens` order).\n *\n * Browser: rules are injected through CSSOM with O(1) appends — no rescans.\n * SSR: rules accumulate in the registry; `getCssText()` serializes them.\n */\n\n// SSR collector — optional hook that receives every newly minted rule string\n// (wrapped in its at-rule, if any). Installed once at server startup.\ntype SSRCollector = (rule: string) => void;\nlet ssrCollector: SSRCollector | null = null;\n\nexport function setSSRCollector(fn: SSRCollector | null): void {\n\tssrCollector = fn;\n}\n\n// Registry — the source of truth for all generated CSS.\n// atomCache: declaration key -> class name (dedup)\n// atomOwner: class name -> conflict key (query|suffix|property), used by cx()\nconst atomCache = new Map<string, string>();\nconst atomOwner = new Map<string, string>();\nconst rawKeys = new Set<string>();\nconst baseRules: string[] = [];\nconst queryRules = new Map<string, string[]>();\n\n// Browser CSSOM state. Base rules occupy [0, baseRuleCount); grouping rules\n// (one per query, created in registration order) live after them. CSSRule\n// references stay live when indices shift, so insertion never rescans.\nlet sheet: CSSStyleSheet | null = null;\nlet sheetDocument: Document | null = null;\nlet baseRuleCount = 0;\nconst groupRules = new Map<string, CSSGroupingRule>();\n\n/** Pre-register at-rule queries so their cascade order follows theme order. */\nexport function registerQueries(queries: Iterable<string>): void {\n\tfor (const query of queries) {\n\t\tif (!queryRules.has(query)) queryRules.set(query, []);\n\t}\n}\n\nfunction createGroup(s: CSSStyleSheet, query: string): CSSGroupingRule | null {\n\ttry {\n\t\tconst idx = s.cssRules.length;\n\t\ts.insertRule(query + \"{}\", idx);\n\t\tconst group = s.cssRules[idx] as CSSGroupingRule;\n\t\tgroupRules.set(query, group);\n\t\treturn group;\n\t} catch {\n\t\treturn null; // unsupported at-rule in this environment\n\t}\n}\n\nfunction insertBase(s: CSSStyleSheet, rule: string): void {\n\ttry {\n\t\ts.insertRule(rule, baseRuleCount);\n\t\tbaseRuleCount++;\n\t} catch {\n\t\t// Invalid value/selector: drop the declaration, like browsers do for bad CSS.\n\t}\n}\n\n/**\n * Returns the live stylesheet, (re)binding when the document changes — e.g.\n * fresh jsdom documents between tests. Rebinding replays the whole registry,\n * which replaces v1's per-call classExistsInDOM() DOM scans with a single\n * replay per document.\n */\nfunction ensureSheet(): CSSStyleSheet | null {\n\tif (typeof document === \"undefined\") return null;\n\t// The nuclo SSR polyfill provides a document without getElementById — in\n\t// that context rules accumulate in the registry for getCssText() only.\n\tif (typeof document.getElementById !== \"function\") return null;\n\tif (sheet && sheetDocument === document && sheet.ownerNode && (sheet.ownerNode as Element).isConnected) {\n\t\treturn sheet;\n\t}\n\tlet el = document.getElementById(\"nuclo-styles\") as HTMLStyleElement | null;\n\tif (!el) {\n\t\tel = document.createElement(\"style\");\n\t\tel.id = \"nuclo-styles\";\n\t\tdocument.head.appendChild(el);\n\t}\n\tsheet = el.sheet;\n\tsheetDocument = document;\n\tgroupRules.clear();\n\tbaseRuleCount = 0;\n\tif (!sheet) return null;\n\tfor (const rule of baseRules) insertBase(sheet, rule);\n\tfor (const [query, rules] of queryRules) {\n\t\tconst group = createGroup(sheet, query);\n\t\tif (group) {\n\t\t\tfor (const rule of rules) {\n\t\t\t\ttry {\n\t\t\t\t\tgroup.insertRule(rule, group.cssRules.length);\n\t\t\t\t} catch { /* drop invalid rule */ }\n\t\t\t}\n\t\t}\n\t}\n\treturn sheet;\n}\n\nfunction record(rule: string, query: string | undefined): void {\n\tif (query === undefined) {\n\t\tbaseRules.push(rule);\n\t} else {\n\t\tlet bucket = queryRules.get(query);\n\t\tif (!bucket) {\n\t\t\tbucket = [];\n\t\t\tqueryRules.set(query, bucket);\n\t\t}\n\t\tbucket.push(rule);\n\t}\n\tssrCollector?.(query === undefined ? rule : query + \"{\" + rule + \"}\");\n\n\tconst s = ensureSheet();\n\tif (!s) return;\n\tif (query === undefined) {\n\t\tinsertBase(s, rule);\n\t} else {\n\t\tconst group = groupRules.get(query) ?? createGroup(s, query);\n\t\tif (group) {\n\t\t\ttry {\n\t\t\t\tgroup.insertRule(rule, group.cssRules.length);\n\t\t\t} catch { /* drop invalid rule */ }\n\t\t}\n\t}\n}\n\n/**\n * Order-independent 53-bit content hash (two interleaved FNV-1a style passes).\n * Class names must match between server and client for SSR hydration, so a\n * counter is not an option; 53 bits keeps collision odds negligible (~1e-5 at\n * 10k unique declarations).\n */\nexport function hash(input: string): string {\n\tlet a = 0x811c9dc5;\n\tlet b = 0x7ee3623b;\n\tfor (let i = 0; i < input.length; i++) {\n\t\tconst c = input.charCodeAt(i);\n\t\ta = Math.imul(a ^ c, 0x01000193);\n\t\tb = Math.imul(b ^ c, 0x85ebca6b);\n\t}\n\treturn (a >>> 0).toString(36) + ((b >>> 9) % 1296).toString(36);\n}\n\n/** One class per (query, selector-suffix, declaration) — the atomic core. */\nexport function atom(query: string | undefined, suffix: string, property: string, value: string): string {\n\tconst declKey = (query ?? \"\") + \"|\" + suffix + \"|\" + property + \":\" + value;\n\tlet className = atomCache.get(declKey);\n\tif (className !== undefined) {\n\t\t// Touch the sheet so a swapped document (tests) gets the replayed rules.\n\t\tensureSheet();\n\t\treturn className;\n\t}\n\tclassName = \"n\" + hash(declKey);\n\tatomCache.set(declKey, className);\n\tatomOwner.set(className, (query ?? \"\") + \"|\" + suffix + \"|\" + property);\n\trecord(\".\" + className + suffix + \"{\" + property + \":\" + value + \"}\", query);\n\treturn className;\n}\n\n/** Conflict key for a generated class — lets cx() resolve overrides exactly. */\nexport function conflictKeyOf(className: string): string | undefined {\n\treturn atomOwner.get(className);\n}\n\n/** Register a non-atomic rule (keyframes, global styles) once per dedupe key. */\nexport function addRawRule(dedupeKey: string, rule: string): void {\n\tif (rawKeys.has(dedupeKey)) {\n\t\tensureSheet();\n\t\treturn;\n\t}\n\trawKeys.add(dedupeKey);\n\trecord(rule, undefined);\n}\n\n/** All generated CSS — base rules first, then at-rule groups in registration order. */\nexport function getCssText(): string {\n\tlet out = baseRules.join(\"\");\n\tfor (const [query, rules] of queryRules) {\n\t\tif (rules.length > 0) out += query + \"{\" + rules.join(\"\") + \"}\";\n\t}\n\treturn out;\n}\n\n/** Clear all engine state (test helper). Removes the injected style element. */\nexport function resetStyles(): void {\n\tatomCache.clear();\n\tatomOwner.clear();\n\trawKeys.clear();\n\tbaseRules.length = 0;\n\tqueryRules.clear();\n\tgroupRules.clear();\n\tbaseRuleCount = 0;\n\tsheet = null;\n\tsheetDocument = null;\n\tif (typeof document !== \"undefined\") {\n\t\tdocument.getElementById(\"nuclo-styles\")?.remove();\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderToString.d.ts","sourceRoot":"","sources":["../../src/ssr/renderToString.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"renderToString.d.ts","sourceRoot":"","sources":["../../src/ssr/renderToString.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,KAAK,eAAe,GAChB,SAAS,CAAC,cAAc,CAAC,GACzB,OAAO,GACP,IAAI,GACJ,IAAI,GACJ,SAAS,CAAC;AAqOd;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAqB7D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,EAAE,CAEtE;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,eAAe,EACtB,YAAY,GAAE,MAAc,EAC5B,cAAc,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAC1C,MAAM,CAOR"}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
type Loose<T extends string> = T | (string & {});
|
|
2
|
+
/** Length values: numbers become px (except unitless properties), strings pass through. */
|
|
3
|
+
export type Size = number | (string & {});
|
|
4
|
+
type Display = Loose<"block" | "inline" | "inline-block" | "flex" | "inline-flex" | "grid" | "inline-grid" | "none" | "contents" | "flow-root" | "table" | "table-cell" | "list-item">;
|
|
5
|
+
type Position = Loose<"static" | "relative" | "absolute" | "fixed" | "sticky">;
|
|
6
|
+
type Overflow = Loose<"visible" | "hidden" | "clip" | "scroll" | "auto">;
|
|
7
|
+
type TextAlign = Loose<"left" | "right" | "center" | "justify" | "start" | "end">;
|
|
8
|
+
type FontWeight = number | Loose<"normal" | "bold" | "lighter" | "bolder" | "400" | "500" | "600" | "700">;
|
|
9
|
+
type AlignItems = Loose<"stretch" | "center" | "start" | "end" | "flex-start" | "flex-end" | "baseline">;
|
|
10
|
+
type JustifyContent = Loose<"center" | "start" | "end" | "flex-start" | "flex-end" | "space-between" | "space-around" | "space-evenly" | "stretch">;
|
|
11
|
+
type FlexDirection = Loose<"row" | "row-reverse" | "column" | "column-reverse">;
|
|
12
|
+
type FlexWrap = Loose<"nowrap" | "wrap" | "wrap-reverse">;
|
|
13
|
+
type BorderStyle = Loose<"none" | "solid" | "dashed" | "dotted" | "double" | "hidden">;
|
|
14
|
+
type Cursor = Loose<"auto" | "default" | "pointer" | "grab" | "grabbing" | "text" | "move" | "not-allowed" | "wait" | "crosshair" | "zoom-in" | "zoom-out">;
|
|
15
|
+
type ObjectFit = Loose<"fill" | "contain" | "cover" | "none" | "scale-down">;
|
|
16
|
+
type UserSelect = Loose<"none" | "auto" | "text" | "all" | "contain">;
|
|
17
|
+
type PointerEvents = Loose<"auto" | "none">;
|
|
18
|
+
type WhiteSpace = Loose<"normal" | "nowrap" | "pre" | "pre-wrap" | "pre-line" | "break-spaces">;
|
|
19
|
+
type TextTransform = Loose<"none" | "capitalize" | "uppercase" | "lowercase">;
|
|
20
|
+
type BoxSizing = Loose<"border-box" | "content-box">;
|
|
21
|
+
type Visibility = Loose<"visible" | "hidden" | "collapse">;
|
|
22
|
+
/**
|
|
23
|
+
* Plain CSS properties (camelCase, converted to kebab-case at runtime).
|
|
24
|
+
* Color/font/shadow/radius properties live in TokenProps so they pick up theme tokens.
|
|
25
|
+
*/
|
|
26
|
+
export interface CSSProperties {
|
|
27
|
+
display?: Display;
|
|
28
|
+
position?: Position;
|
|
29
|
+
inset?: Size;
|
|
30
|
+
top?: Size;
|
|
31
|
+
right?: Size;
|
|
32
|
+
bottom?: Size;
|
|
33
|
+
left?: Size;
|
|
34
|
+
zIndex?: number | "auto";
|
|
35
|
+
boxSizing?: BoxSizing;
|
|
36
|
+
aspectRatio?: Size;
|
|
37
|
+
overflow?: Overflow;
|
|
38
|
+
overflowX?: Overflow;
|
|
39
|
+
overflowY?: Overflow;
|
|
40
|
+
visibility?: Visibility;
|
|
41
|
+
objectFit?: ObjectFit;
|
|
42
|
+
objectPosition?: string;
|
|
43
|
+
isolation?: Loose<"auto" | "isolate">;
|
|
44
|
+
float?: Loose<"none" | "left" | "right" | "inline-start" | "inline-end">;
|
|
45
|
+
clear?: Loose<"none" | "left" | "right" | "both" | "inline-start" | "inline-end">;
|
|
46
|
+
flex?: Size;
|
|
47
|
+
flexDirection?: FlexDirection;
|
|
48
|
+
flexWrap?: FlexWrap;
|
|
49
|
+
flexGrow?: number;
|
|
50
|
+
flexShrink?: number;
|
|
51
|
+
flexBasis?: Size;
|
|
52
|
+
order?: number;
|
|
53
|
+
alignItems?: AlignItems;
|
|
54
|
+
alignContent?: JustifyContent;
|
|
55
|
+
alignSelf?: AlignItems | "auto";
|
|
56
|
+
justifyContent?: JustifyContent;
|
|
57
|
+
justifyItems?: AlignItems;
|
|
58
|
+
justifySelf?: AlignItems | "auto";
|
|
59
|
+
placeItems?: string;
|
|
60
|
+
placeContent?: string;
|
|
61
|
+
placeSelf?: string;
|
|
62
|
+
gap?: Size;
|
|
63
|
+
rowGap?: Size;
|
|
64
|
+
columnGap?: Size;
|
|
65
|
+
gridTemplateColumns?: string;
|
|
66
|
+
gridTemplateRows?: string;
|
|
67
|
+
gridTemplateAreas?: string;
|
|
68
|
+
gridColumn?: Size;
|
|
69
|
+
gridRow?: Size;
|
|
70
|
+
gridArea?: string;
|
|
71
|
+
gridAutoFlow?: Loose<"row" | "column" | "dense" | "row dense" | "column dense">;
|
|
72
|
+
gridAutoRows?: Size;
|
|
73
|
+
gridAutoColumns?: Size;
|
|
74
|
+
padding?: Size;
|
|
75
|
+
paddingTop?: Size;
|
|
76
|
+
paddingRight?: Size;
|
|
77
|
+
paddingBottom?: Size;
|
|
78
|
+
paddingLeft?: Size;
|
|
79
|
+
margin?: Size;
|
|
80
|
+
marginTop?: Size;
|
|
81
|
+
marginRight?: Size;
|
|
82
|
+
marginBottom?: Size;
|
|
83
|
+
marginLeft?: Size;
|
|
84
|
+
width?: Size;
|
|
85
|
+
height?: Size;
|
|
86
|
+
minWidth?: Size;
|
|
87
|
+
minHeight?: Size;
|
|
88
|
+
maxWidth?: Size;
|
|
89
|
+
maxHeight?: Size;
|
|
90
|
+
fontSize?: Size;
|
|
91
|
+
fontStyle?: Loose<"normal" | "italic" | "oblique">;
|
|
92
|
+
fontWeight?: FontWeight;
|
|
93
|
+
lineHeight?: Size;
|
|
94
|
+
letterSpacing?: Size;
|
|
95
|
+
textAlign?: TextAlign;
|
|
96
|
+
textTransform?: TextTransform;
|
|
97
|
+
textDecoration?: Loose<"none" | "underline" | "overline" | "line-through">;
|
|
98
|
+
textDecorationLine?: Loose<"none" | "underline" | "overline" | "line-through">;
|
|
99
|
+
textDecorationStyle?: Loose<"solid" | "double" | "dotted" | "dashed" | "wavy">;
|
|
100
|
+
textDecorationThickness?: Size;
|
|
101
|
+
textUnderlineOffset?: Size;
|
|
102
|
+
textOverflow?: Loose<"clip" | "ellipsis">;
|
|
103
|
+
textShadow?: string;
|
|
104
|
+
textIndent?: Size;
|
|
105
|
+
whiteSpace?: WhiteSpace;
|
|
106
|
+
wordBreak?: Loose<"normal" | "break-all" | "keep-all" | "break-word">;
|
|
107
|
+
overflowWrap?: Loose<"normal" | "break-word" | "anywhere">;
|
|
108
|
+
verticalAlign?: Loose<"baseline" | "top" | "middle" | "bottom" | "text-top" | "text-bottom">;
|
|
109
|
+
fontVariantNumeric?: string;
|
|
110
|
+
fontFeatureSettings?: string;
|
|
111
|
+
border?: string;
|
|
112
|
+
borderTop?: string;
|
|
113
|
+
borderRight?: string;
|
|
114
|
+
borderBottom?: string;
|
|
115
|
+
borderLeft?: string;
|
|
116
|
+
borderWidth?: Size;
|
|
117
|
+
borderStyle?: BorderStyle;
|
|
118
|
+
outline?: string;
|
|
119
|
+
outlineWidth?: Size;
|
|
120
|
+
outlineStyle?: BorderStyle;
|
|
121
|
+
outlineOffset?: Size;
|
|
122
|
+
backgroundImage?: string;
|
|
123
|
+
backgroundSize?: Loose<"auto" | "cover" | "contain">;
|
|
124
|
+
backgroundPosition?: string;
|
|
125
|
+
backgroundRepeat?: Loose<"repeat" | "no-repeat" | "repeat-x" | "repeat-y" | "round" | "space">;
|
|
126
|
+
backgroundAttachment?: Loose<"scroll" | "fixed" | "local">;
|
|
127
|
+
backgroundClip?: Loose<"border-box" | "padding-box" | "content-box" | "text">;
|
|
128
|
+
opacity?: number | string;
|
|
129
|
+
filter?: string;
|
|
130
|
+
backdropFilter?: string;
|
|
131
|
+
mixBlendMode?: string;
|
|
132
|
+
transform?: string;
|
|
133
|
+
transformOrigin?: string;
|
|
134
|
+
transition?: string;
|
|
135
|
+
transitionProperty?: string;
|
|
136
|
+
transitionDuration?: string;
|
|
137
|
+
transitionTimingFunction?: string;
|
|
138
|
+
transitionDelay?: string;
|
|
139
|
+
animation?: string;
|
|
140
|
+
willChange?: string;
|
|
141
|
+
clipPath?: string;
|
|
142
|
+
cursor?: Cursor;
|
|
143
|
+
pointerEvents?: PointerEvents;
|
|
144
|
+
userSelect?: UserSelect;
|
|
145
|
+
touchAction?: string;
|
|
146
|
+
resize?: Loose<"none" | "both" | "horizontal" | "vertical">;
|
|
147
|
+
scrollBehavior?: Loose<"auto" | "smooth">;
|
|
148
|
+
scrollSnapType?: string;
|
|
149
|
+
scrollSnapAlign?: string;
|
|
150
|
+
appearance?: Loose<"none" | "auto">;
|
|
151
|
+
accentColor?: string;
|
|
152
|
+
content?: string;
|
|
153
|
+
listStyle?: string;
|
|
154
|
+
tableLayout?: Loose<"auto" | "fixed">;
|
|
155
|
+
borderCollapse?: Loose<"collapse" | "separate">;
|
|
156
|
+
borderSpacing?: Size;
|
|
157
|
+
colorScheme?: Loose<"light" | "dark" | "light dark">;
|
|
158
|
+
containerType?: Loose<"normal" | "size" | "inline-size">;
|
|
159
|
+
containerName?: string;
|
|
160
|
+
}
|
|
161
|
+
export interface ThemeConfig {
|
|
162
|
+
/** Color tokens — usable in bg, color, borderColor, outlineColor, caretColor, textDecorationColor. */
|
|
163
|
+
colors?: Record<string, string>;
|
|
164
|
+
/** Font-family tokens — usable in font / fontFamily. */
|
|
165
|
+
fonts?: Record<string, string>;
|
|
166
|
+
/** Box-shadow tokens — usable in shadow / boxShadow. */
|
|
167
|
+
shadows?: Record<string, string>;
|
|
168
|
+
/** Border-radius tokens — usable in rounded / borderRadius. */
|
|
169
|
+
radii?: Record<string, string>;
|
|
170
|
+
/**
|
|
171
|
+
* Responsive variants: name → media condition ("(min-width: 768px)")
|
|
172
|
+
* or a full at-rule prelude ("@container (min-width: 400px)").
|
|
173
|
+
* Declaration order = cascade order. Names must not collide with property names.
|
|
174
|
+
*/
|
|
175
|
+
screens?: Record<string, string>;
|
|
176
|
+
}
|
|
177
|
+
type Tokens<T extends ThemeConfig, K extends keyof ThemeConfig> = T[K] extends Record<string, string> ? Extract<keyof T[K], string> : never;
|
|
178
|
+
/** Properties whose string values resolve against theme tokens. */
|
|
179
|
+
interface TokenProps<T extends ThemeConfig> {
|
|
180
|
+
/** background — color token, color, gradient, or any CSS background shorthand */
|
|
181
|
+
bg?: Loose<Tokens<T, "colors">>;
|
|
182
|
+
backgroundColor?: Loose<Tokens<T, "colors">>;
|
|
183
|
+
color?: Loose<Tokens<T, "colors">>;
|
|
184
|
+
borderColor?: Loose<Tokens<T, "colors">>;
|
|
185
|
+
borderTopColor?: Loose<Tokens<T, "colors">>;
|
|
186
|
+
borderRightColor?: Loose<Tokens<T, "colors">>;
|
|
187
|
+
borderBottomColor?: Loose<Tokens<T, "colors">>;
|
|
188
|
+
borderLeftColor?: Loose<Tokens<T, "colors">>;
|
|
189
|
+
outlineColor?: Loose<Tokens<T, "colors">>;
|
|
190
|
+
caretColor?: Loose<Tokens<T, "colors">>;
|
|
191
|
+
textDecorationColor?: Loose<Tokens<T, "colors">>;
|
|
192
|
+
/** font-family — token or font stack */
|
|
193
|
+
font?: Loose<Tokens<T, "fonts">>;
|
|
194
|
+
fontFamily?: Loose<Tokens<T, "fonts">>;
|
|
195
|
+
/** box-shadow — token or raw value */
|
|
196
|
+
shadow?: Loose<Tokens<T, "shadows">>;
|
|
197
|
+
boxShadow?: Loose<Tokens<T, "shadows">>;
|
|
198
|
+
/** border-radius — token, number (px), or raw value */
|
|
199
|
+
rounded?: Tokens<T, "radii"> | Size;
|
|
200
|
+
borderRadius?: Tokens<T, "radii"> | Size;
|
|
201
|
+
}
|
|
202
|
+
/** Tailwind-flavored short aliases. */
|
|
203
|
+
interface ShorthandProps {
|
|
204
|
+
/** padding */ p?: Size;
|
|
205
|
+
/** padding-left + padding-right */ px?: Size;
|
|
206
|
+
/** padding-top + padding-bottom */ py?: Size;
|
|
207
|
+
pt?: Size;
|
|
208
|
+
pr?: Size;
|
|
209
|
+
pb?: Size;
|
|
210
|
+
pl?: Size;
|
|
211
|
+
/** margin */ m?: Size;
|
|
212
|
+
/** margin-left + margin-right */ mx?: Size;
|
|
213
|
+
/** margin-top + margin-bottom */ my?: Size;
|
|
214
|
+
mt?: Size;
|
|
215
|
+
mr?: Size;
|
|
216
|
+
mb?: Size;
|
|
217
|
+
ml?: Size;
|
|
218
|
+
/** width */ w?: Size;
|
|
219
|
+
/** height */ h?: Size;
|
|
220
|
+
minW?: Size;
|
|
221
|
+
maxW?: Size;
|
|
222
|
+
minH?: Size;
|
|
223
|
+
maxH?: Size;
|
|
224
|
+
/** width + height */ size?: Size;
|
|
225
|
+
/** font-size */ text?: Size;
|
|
226
|
+
/** font-weight */ weight?: FontWeight;
|
|
227
|
+
/** line-height */ leading?: Size;
|
|
228
|
+
/** letter-spacing */ tracking?: Size;
|
|
229
|
+
/** text-align */ align?: TextAlign;
|
|
230
|
+
/** align-items */ items?: AlignItems;
|
|
231
|
+
/** justify-content */ justify?: JustifyContent;
|
|
232
|
+
/** z-index */ z?: number | "auto";
|
|
233
|
+
/** user-select */ select?: UserSelect;
|
|
234
|
+
/** display:flex + flex-direction:row */ row?: boolean;
|
|
235
|
+
/** display:flex + flex-direction:column */ col?: boolean;
|
|
236
|
+
/** align-items:center + justify-content:center */ center?: boolean;
|
|
237
|
+
/** overflow:hidden + text-overflow:ellipsis + white-space:nowrap */ truncate?: boolean;
|
|
238
|
+
}
|
|
239
|
+
declare const PSEUDO: {
|
|
240
|
+
readonly hover: ":hover";
|
|
241
|
+
readonly focus: ":focus";
|
|
242
|
+
readonly focusVisible: ":focus-visible";
|
|
243
|
+
readonly focusWithin: ":focus-within";
|
|
244
|
+
readonly active: ":active";
|
|
245
|
+
readonly visited: ":visited";
|
|
246
|
+
readonly disabled: ":disabled";
|
|
247
|
+
readonly enabled: ":enabled";
|
|
248
|
+
readonly checked: ":checked";
|
|
249
|
+
readonly required: ":required";
|
|
250
|
+
readonly invalid: ":invalid";
|
|
251
|
+
readonly valid: ":valid";
|
|
252
|
+
readonly readOnly: ":read-only";
|
|
253
|
+
readonly first: ":first-child";
|
|
254
|
+
readonly last: ":last-child";
|
|
255
|
+
readonly only: ":only-child";
|
|
256
|
+
readonly odd: ":nth-child(odd)";
|
|
257
|
+
readonly even: ":nth-child(even)";
|
|
258
|
+
readonly empty: ":empty";
|
|
259
|
+
readonly placeholderShown: ":placeholder-shown";
|
|
260
|
+
readonly placeholder: "::placeholder";
|
|
261
|
+
readonly before: "::before";
|
|
262
|
+
readonly after: "::after";
|
|
263
|
+
readonly selection: "::selection";
|
|
264
|
+
readonly marker: "::marker";
|
|
265
|
+
readonly firstLine: "::first-line";
|
|
266
|
+
readonly firstLetter: "::first-letter";
|
|
267
|
+
};
|
|
268
|
+
type Pseudo = keyof typeof PSEUDO;
|
|
269
|
+
/** Flat style: properties only, no variant nesting (used by keyframes/globalStyle). */
|
|
270
|
+
export type FlatStyle<T extends ThemeConfig = ThemeConfig> = TokenProps<T> & ShorthandProps & CSSProperties & {
|
|
271
|
+
/** Escape hatch: raw CSS declarations, property names passed through as-is. */
|
|
272
|
+
raw?: Record<string, string | number>;
|
|
273
|
+
};
|
|
274
|
+
/**
|
|
275
|
+
* Full style object: properties + pseudo variants + theme screens +
|
|
276
|
+
* arbitrary selectors ("&:nth-child(2)", "& > svg") + inline at-rules
|
|
277
|
+
* ("@media (min-width: 768px)", "@container (…)", "@supports (…)").
|
|
278
|
+
*/
|
|
279
|
+
export type Style<T extends ThemeConfig = ThemeConfig> = FlatStyle<T> & {
|
|
280
|
+
[K in Pseudo]?: Style<T>;
|
|
281
|
+
} & {
|
|
282
|
+
[K in Tokens<T, "screens">]?: Style<T>;
|
|
283
|
+
} & {
|
|
284
|
+
[K in `&${string}`]?: Style<T>;
|
|
285
|
+
} & {
|
|
286
|
+
[K in `@${string}`]?: Style<T>;
|
|
287
|
+
};
|
|
288
|
+
export type StyleResult = {
|
|
289
|
+
className: string;
|
|
290
|
+
toString(): string;
|
|
291
|
+
};
|
|
292
|
+
/** Inputs accepted by cx(): results, raw class strings, and falsy values. */
|
|
293
|
+
export type ClassInput = StyleResult | string | false | null | undefined;
|
|
294
|
+
/**
|
|
295
|
+
* Compose class lists with exact conflict resolution: when two inputs style
|
|
296
|
+
* the same (query, selector, property), the last one wins. Works because the
|
|
297
|
+
* engine knows what every class it generated means.
|
|
298
|
+
*/
|
|
299
|
+
export declare function cx(...inputs: ClassInput[]): StyleResult;
|
|
300
|
+
export declare function createCss<const T extends ThemeConfig>(theme?: T): {
|
|
301
|
+
css: (style: Style<T>) => StyleResult;
|
|
302
|
+
cx: typeof cx;
|
|
303
|
+
keyframes: (frames: Record<string, FlatStyle<T>>) => string;
|
|
304
|
+
globalStyle: (selector: string, style: FlatStyle<T>) => void;
|
|
305
|
+
theme: T;
|
|
306
|
+
};
|
|
307
|
+
/** Themeless css() — full property/variant typing, no tokens or screens. */
|
|
308
|
+
export declare const css: (style: Style<object>) => StyleResult;
|
|
309
|
+
/** Themeless keyframes() helper. */
|
|
310
|
+
export declare const keyframes: (frames: Record<string, FlatStyle<object>>) => string;
|
|
311
|
+
/** Themeless globalStyle() helper. */
|
|
312
|
+
export declare const globalStyle: (selector: string, style: FlatStyle<object>) => void;
|
|
313
|
+
export {};
|
|
314
|
+
//# sourceMappingURL=css.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css.d.ts","sourceRoot":"","sources":["../../src/style/css.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared atomic-CSS engine state.
|
|
3
|
+
*
|
|
4
|
+
* One stylesheet, one rule registry, shared by every `createCss` instance so
|
|
5
|
+
* identical declarations dedupe globally and cascade order stays deterministic:
|
|
6
|
+
* base rules first (insertion order), then one grouping rule per at-rule query
|
|
7
|
+
* in registration order (theme `screens` order).
|
|
8
|
+
*
|
|
9
|
+
* Browser: rules are injected through CSSOM with O(1) appends — no rescans.
|
|
10
|
+
* SSR: rules accumulate in the registry; `getCssText()` serializes them.
|
|
11
|
+
*/
|
|
12
|
+
type SSRCollector = (rule: string) => void;
|
|
13
|
+
export declare function setSSRCollector(fn: SSRCollector | null): void;
|
|
14
|
+
/** Pre-register at-rule queries so their cascade order follows theme order. */
|
|
15
|
+
export declare function registerQueries(queries: Iterable<string>): void;
|
|
16
|
+
/**
|
|
17
|
+
* Order-independent 53-bit content hash (two interleaved FNV-1a style passes).
|
|
18
|
+
* Class names must match between server and client for SSR hydration, so a
|
|
19
|
+
* counter is not an option; 53 bits keeps collision odds negligible (~1e-5 at
|
|
20
|
+
* 10k unique declarations).
|
|
21
|
+
*/
|
|
22
|
+
export declare function hash(input: string): string;
|
|
23
|
+
/** One class per (query, selector-suffix, declaration) — the atomic core. */
|
|
24
|
+
export declare function atom(query: string | undefined, suffix: string, property: string, value: string): string;
|
|
25
|
+
/** Conflict key for a generated class — lets cx() resolve overrides exactly. */
|
|
26
|
+
export declare function conflictKeyOf(className: string): string | undefined;
|
|
27
|
+
/** Register a non-atomic rule (keyframes, global styles) once per dedupe key. */
|
|
28
|
+
export declare function addRawRule(dedupeKey: string, rule: string): void;
|
|
29
|
+
/** All generated CSS — base rules first, then at-rule groups in registration order. */
|
|
30
|
+
export declare function getCssText(): string;
|
|
31
|
+
/** Clear all engine state (test helper). Removes the injected style element. */
|
|
32
|
+
export declare function resetStyles(): void;
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/style/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,KAAK,YAAY,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAG3C,wBAAgB,eAAe,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,GAAG,IAAI,CAE7D;AAmBD,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,CAI/D;AAyFD;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAS1C;AAED,6EAA6E;AAC7E,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAavG;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEnE;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAOhE;AAED,uFAAuF;AACvF,wBAAgB,UAAU,IAAI,MAAM,CAMnC;AAED,gFAAgF;AAChF,wBAAgB,WAAW,IAAI,IAAI,CAalC"}
|
package/dist/style/index.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export { createCSSClass } from "./cssGenerator";
|
|
4
|
-
export { display, flex, grid, bg, color, accentColor, fontSize, fontWeight, fontFamily, lineHeight, letterSpacing, textAlign, textDecoration, bold, fontStyle, fontVariant, fontStretch, textTransform, textIndent, textOverflow, textShadow, whiteSpace, wordSpacing, wordWrap, overflowWrap, textAlignLast, textJustify, textDecorationLine, textDecorationColor, textDecorationStyle, textDecorationThickness, textUnderlineOffset, verticalAlign, position, padding, paddingTop, paddingRight, paddingBottom, paddingLeft, margin, marginTop, marginRight, marginBottom, marginLeft, width, height, minWidth, maxWidth, minHeight, maxHeight, boxSizing, top, right, bottom, left, zIndex, flexDirection, alignItems, justifyContent, center, gap, flexWrap, flexGrow, flexShrink, flexBasis, alignSelf, alignContent, justifySelf, justifyItems, gridTemplateColumns, gridTemplateRows, gridTemplateAreas, gridColumn, gridRow, gridColumnStart, gridColumnEnd, gridRowStart, gridRowEnd, gridArea, gridAutoColumns, gridAutoRows, gridAutoFlow, border, borderTop, borderRight, borderBottom, borderLeft, borderWidth, borderStyle, borderColor, borderTopWidth, borderRightWidth, borderBottomWidth, borderLeftWidth, borderTopStyle, borderRightStyle, borderBottomStyle, borderLeftStyle, borderTopColor, borderRightColor, borderBottomColor, borderLeftColor, borderRadius, borderTopLeftRadius, borderTopRightRadius, borderBottomLeftRadius, borderBottomRightRadius, outline, outlineWidth, outlineStyle, outlineColor, outlineOffset, backgroundColor, backgroundImage, backgroundRepeat, backgroundPosition, backgroundSize, backgroundAttachment, backgroundClip, backgroundOrigin, boxShadow, opacity, transition, transitionProperty, transitionDuration, transitionTimingFunction, transitionDelay, transform, transformOrigin, transformStyle, perspective, perspectiveOrigin, backfaceVisibility, animation, animationName, animationDuration, animationTimingFunction, animationDelay, animationIterationCount, animationDirection, animationFillMode, animationPlayState, filter, backdropFilter, overflow, overflowX, overflowY, visibility, objectFit, objectPosition, listStyle, listStyleType, listStylePosition, listStyleImage, borderCollapse, borderSpacing, captionSide, emptyCells, tableLayout, content, quotes, counterReset, counterIncrement, appearance, userSelect, pointerEvents, resize, scrollBehavior, clip, clipPath, isolation, mixBlendMode, willChange, contain, pageBreakBefore, pageBreakAfter, pageBreakInside, breakBefore, breakAfter, breakInside, orphans, widows, columnCount, columnFill, columnGap, columnRule, columnRuleColor, columnRuleStyle, columnRuleWidth, columnSpan, columnWidth, columns, cursor, } from "./styleBuilder";
|
|
1
|
+
export { createCss, css, cx, keyframes, globalStyle, type ClassInput, type CSSProperties, type FlatStyle, type Size, type Style, type StyleResult, type ThemeConfig, } from "./css";
|
|
2
|
+
export { getCssText, resetStyles, setSSRCollector } from "./engine";
|
|
5
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/style/index.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/style/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,SAAS,EACT,GAAG,EACH,EAAE,EACF,SAAS,EACT,WAAW,EACX,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,IAAI,EACT,KAAK,KAAK,EACV,KAAK,WAAW,EAChB,KAAK,WAAW,GAChB,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/utility/errorHandler.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/utility/errorHandler.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,IAAI,CAKvE"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuclo",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.1
|
|
4
|
+
"version": "0.2.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/nuclo.cjs",
|
|
7
7
|
"module": "./dist/nuclo.mjs",
|
|
@@ -44,19 +44,20 @@
|
|
|
44
44
|
"lint:fix": "eslint . --ext .ts,.js,.json,.jsonc,.json5,.md,.css --fix"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@eslint/css": "^1.
|
|
47
|
+
"@eslint/css": "^1.3.0",
|
|
48
48
|
"@eslint/js": "^10.0.1",
|
|
49
|
-
"@eslint/json": "^
|
|
50
|
-
"@eslint/markdown": "^8.0.
|
|
51
|
-
"@types/node": "^25.
|
|
52
|
-
"@vitest/coverage-v8": "4.1.
|
|
53
|
-
"eslint": "^10.4.
|
|
49
|
+
"@eslint/json": "^2.0.0",
|
|
50
|
+
"@eslint/markdown": "^8.0.2",
|
|
51
|
+
"@types/node": "^25.9.3",
|
|
52
|
+
"@vitest/coverage-v8": "4.1.7",
|
|
53
|
+
"eslint": "^10.4.1",
|
|
54
54
|
"globals": "^17.6.0",
|
|
55
|
+
"jiti": "^2.7.0",
|
|
55
56
|
"jsdom": "^29.1.1",
|
|
56
|
-
"tsdown": "^0.22.
|
|
57
|
+
"tsdown": "^0.22.2",
|
|
57
58
|
"typescript": "^6.0.3",
|
|
58
|
-
"typescript-eslint": "^8.
|
|
59
|
-
"vitest": "^4.1.
|
|
59
|
+
"typescript-eslint": "^8.61.0",
|
|
60
|
+
"vitest": "^4.1.8"
|
|
60
61
|
},
|
|
61
62
|
"repository": {
|
|
62
63
|
"type": "git",
|
package/types/features/list.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ declare global {
|
|
|
24
24
|
* parent element, regardless of the tag of the items it renders.
|
|
25
25
|
* (TTagName represents the child element tag, not the parent.)
|
|
26
26
|
*/
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
27
28
|
export type ListModifier<TTagName extends ElementTagName = ElementTagName> =
|
|
28
29
|
(<TParent extends ElementTagName>(parent: ExpandedElement<TParent>, index: number) => Comment) &
|
|
29
30
|
((parent: Node & ParentNode, index: number) => Comment);
|