@pyreon/connector-document 0.14.0 → 0.15.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pyreon/connector-document",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "description": "Bridge between @pyreon/pyreon styled components and @pyreon/document rendering",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -10,6 +10,7 @@
10
10
  },
11
11
  "files": [
12
12
  "lib",
13
+ "!lib/**/*.map",
13
14
  "!lib/analysis",
14
15
  "README.md",
15
16
  "LICENSE",
@@ -41,17 +42,17 @@
41
42
  "typecheck": "tsc --noEmit"
42
43
  },
43
44
  "devDependencies": {
44
- "@pyreon/core": "^0.14.0",
45
- "@pyreon/document": "^0.14.0",
46
- "@pyreon/reactivity": "^0.14.0",
45
+ "@pyreon/core": "^0.15.0",
46
+ "@pyreon/document": "^0.15.0",
47
+ "@pyreon/reactivity": "^0.15.0",
47
48
  "@pyreon/test-utils": "^0.13.2",
48
- "@pyreon/typescript": "^0.14.0",
49
+ "@pyreon/typescript": "^0.15.0",
49
50
  "@vitest/browser-playwright": "^4.1.4",
50
- "@vitus-labs/tools-rolldown": "^1.15.4"
51
+ "@vitus-labs/tools-rolldown": "^2.3.0"
51
52
  },
52
53
  "peerDependencies": {
53
- "@pyreon/core": "^0.14.0",
54
- "@pyreon/document": "^0.14.0"
54
+ "@pyreon/core": "^0.15.0",
55
+ "@pyreon/document": "^0.15.0"
55
56
  },
56
57
  "engines": {
57
58
  "node": ">= 22"
@@ -1 +0,0 @@
1
- {"version":3,"file":"index2.d.ts","names":[],"sources":["../../src/cssValueParser.ts","../../src/extractDocumentTree.ts","../../src/resolveStyles.ts"],"mappings":";;;;;;AAiBA;;;;;AAyBC;iBAzBe,iBAAA,CACd,KAAA,sCACA,QAAA;AAAA,KAyBG,cAAA;;;AAWL;;;;;;;iBAAgB,aAAA,CACd,KAAA,+BACA,QAAA,YACC,cAAA;;AAyBH;;iBAAgB,eAAA,CACd,KAAA;;;AAaF;iBAAgB,eAAA,CACd,KAAA,+BACA,QAAA;;;;UC/Fe,cAAA;EACf,aAAA,EAAe,QAAA;AAAA;AAAA,UAGA,cAAA;EDUf;ECRA,QAAA;EDkCG;EChCH,aAAA;AAAA;;;AD2CF;;;;;;;;;AA4BA;iBCmLgB,mBAAA,CAAoB,KAAA,WAAgB,OAAA,GAAS,cAAA,GAAsB,OAAA;;;;;ADrPnF;;;;;iBEGgB,aAAA,CAAc,WAAA,EAAa,MAAA,mBAAyB,QAAA,YAAgB,cAAA"}
package/lib/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/cssValueParser.ts","../src/resolveStyles.ts","../src/extractDocumentTree.ts"],"sourcesContent":["const PX_RE = /^(-?\\d+(?:\\.\\d+)?)px$/\nconst REM_RE = /^(-?\\d+(?:\\.\\d+)?)rem$/\nconst EM_RE = /^(-?\\d+(?:\\.\\d+)?)em$/\nconst PT_RE = /^(-?\\d+(?:\\.\\d+)?)pt$/\nconst NUMBER_RE = /^-?\\d+(?:\\.\\d+)?$/\n\nconst DEFAULT_ROOT_SIZE = 16\n\n/**\n * Parse a CSS dimension value to a number.\n *\n * - `14` → `14`\n * - `'14px'` → `14`\n * - `'1.5rem'` → `24` (with rootSize=16)\n * - `'12pt'` → `16` (pt × 1.333)\n * - `'auto'` → `undefined`\n */\nexport function parseCssDimension(\n value: string | number | null | undefined,\n rootSize = DEFAULT_ROOT_SIZE,\n): number | undefined {\n if (value == null) return undefined\n if (typeof value === 'number') return value\n if (typeof value !== 'string') return undefined\n\n const trimmed = value.trim()\n\n const pxMatch = PX_RE.exec(trimmed)\n if (pxMatch?.[1]) return Number.parseFloat(pxMatch[1])\n\n const remMatch = REM_RE.exec(trimmed)\n if (remMatch?.[1]) return Number.parseFloat(remMatch[1]) * rootSize\n\n const emMatch = EM_RE.exec(trimmed)\n if (emMatch?.[1]) return Number.parseFloat(emMatch[1]) * rootSize\n\n const ptMatch = PT_RE.exec(trimmed)\n if (ptMatch?.[1]) return Number.parseFloat(ptMatch[1]) * (4 / 3)\n\n if (NUMBER_RE.test(trimmed)) return Number.parseFloat(trimmed)\n\n return undefined\n}\n\ntype BoxModelResult = number | [number, number] | [number, number, number, number] | undefined\n\n/**\n * Parse a CSS padding/margin shorthand to document tuple format.\n *\n * - `8` → `8`\n * - `'8px'` → `8`\n * - `'8px 16px'` → `[8, 16]`\n * - `'8px 16px 8px 16px'` → `[8, 16, 8, 16]`\n * - `'8px 16px 12px'` → `[8, 16, 12, 16]` (CSS 3-value shorthand)\n */\nexport function parseBoxModel(\n value: string | number | undefined,\n rootSize = DEFAULT_ROOT_SIZE,\n): BoxModelResult {\n if (value == null) return undefined\n if (typeof value === 'number') return value\n\n const parts = value\n .trim()\n .split(/\\s+/)\n .map((p) => parseCssDimension(p, rootSize))\n\n const nums = parts.filter((p): p is number => p != null)\n if (nums.length !== parts.length) return undefined\n\n if (nums.length === 1) return nums[0]\n if (nums.length === 2) return [nums[0], nums[1]] as [number, number]\n if (nums.length === 3)\n return [nums[0], nums[1], nums[2], nums[1]] as [number, number, number, number]\n if (nums.length === 4)\n return [nums[0], nums[1], nums[2], nums[3]] as [number, number, number, number]\n\n return undefined\n}\n\n/**\n * Parse a CSS font-weight value.\n */\nexport function parseFontWeight(\n value: string | number | undefined,\n): 'normal' | 'bold' | number | undefined {\n if (value == null) return undefined\n if (typeof value === 'number') return value\n if (value === 'normal' || value === 'bold') return value\n const num = Number.parseInt(value, 10)\n if (!Number.isNaN(num)) return num\n return undefined\n}\n\n/**\n * Parse a CSS line-height value to a unitless number.\n */\nexport function parseLineHeight(\n value: string | number | undefined,\n rootSize = DEFAULT_ROOT_SIZE,\n): number | undefined {\n if (value == null) return undefined\n if (typeof value === 'number') return value\n if (value === 'normal') return undefined\n\n const dim = parseCssDimension(value, rootSize)\n if (dim != null) return dim\n\n return undefined\n}\n","import {\n parseBoxModel,\n parseCssDimension,\n parseFontWeight,\n parseLineHeight,\n} from './cssValueParser'\nimport type { ResolvedStyles } from './types'\n\nconst TEXT_ALIGN_VALUES = new Set(['left', 'center', 'right', 'justify'])\nconst FONT_STYLE_VALUES = new Set(['normal', 'italic'])\nconst TEXT_DECORATION_VALUES = new Set(['none', 'underline', 'line-through'])\nconst BORDER_STYLE_VALUES = new Set(['solid', 'dashed', 'dotted'])\n\n/**\n * Convert a rocketstyle `$rocketstyle` theme object into a `ResolvedStyles`\n * object compatible with `@pyreon/document`.\n *\n * Only extracts properties that `ResolvedStyles` supports — everything else\n * (transitions, cursor, display, etc.) is silently ignored.\n */\nexport function resolveStyles(rocketstyle: Record<string, unknown>, rootSize = 16): ResolvedStyles {\n const styles: ResolvedStyles = {}\n\n // Typography\n const fontSize = parseCssDimension(rocketstyle.fontSize as string | number, rootSize)\n if (fontSize != null) styles.fontSize = fontSize\n\n if (typeof rocketstyle.fontFamily === 'string') styles.fontFamily = rocketstyle.fontFamily\n\n const fontWeight = parseFontWeight(rocketstyle.fontWeight as string | number | undefined)\n if (fontWeight != null) styles.fontWeight = fontWeight\n\n if (typeof rocketstyle.fontStyle === 'string' && FONT_STYLE_VALUES.has(rocketstyle.fontStyle))\n styles.fontStyle = rocketstyle.fontStyle as 'normal' | 'italic'\n\n if (\n typeof rocketstyle.textDecoration === 'string' &&\n TEXT_DECORATION_VALUES.has(rocketstyle.textDecoration)\n )\n styles.textDecoration = rocketstyle.textDecoration as 'none' | 'underline' | 'line-through'\n\n if (typeof rocketstyle.color === 'string') styles.color = rocketstyle.color\n\n if (typeof rocketstyle.backgroundColor === 'string')\n styles.backgroundColor = rocketstyle.backgroundColor\n\n if (typeof rocketstyle.textAlign === 'string' && TEXT_ALIGN_VALUES.has(rocketstyle.textAlign))\n styles.textAlign = rocketstyle.textAlign as 'left' | 'center' | 'right' | 'justify'\n\n const lineHeight = parseLineHeight(\n rocketstyle.lineHeight as string | number | undefined,\n rootSize,\n )\n if (lineHeight != null) styles.lineHeight = lineHeight\n\n const letterSpacing = parseCssDimension(rocketstyle.letterSpacing as string | number, rootSize)\n if (letterSpacing != null) styles.letterSpacing = letterSpacing\n\n // Box model\n const padding = parseBoxModel(rocketstyle.padding as string | number | undefined, rootSize)\n if (padding != null) styles.padding = padding\n\n const margin = parseBoxModel(rocketstyle.margin as string | number | undefined, rootSize)\n if (margin != null) styles.margin = margin\n\n // Border\n const borderRadius = parseCssDimension(rocketstyle.borderRadius as string | number, rootSize)\n if (borderRadius != null) styles.borderRadius = borderRadius\n\n const borderWidth = parseCssDimension(rocketstyle.borderWidth as string | number, rootSize)\n if (borderWidth != null) styles.borderWidth = borderWidth\n\n if (typeof rocketstyle.borderColor === 'string') styles.borderColor = rocketstyle.borderColor\n\n if (\n typeof rocketstyle.borderStyle === 'string' &&\n BORDER_STYLE_VALUES.has(rocketstyle.borderStyle)\n )\n styles.borderStyle = rocketstyle.borderStyle as 'solid' | 'dashed' | 'dotted'\n\n // Sizing\n if (rocketstyle.width != null) {\n const w = parseCssDimension(rocketstyle.width as string | number, rootSize)\n styles.width = w ?? (rocketstyle.width as string)\n }\n\n if (rocketstyle.height != null) {\n const h = parseCssDimension(rocketstyle.height as string | number, rootSize)\n styles.height = h ?? (rocketstyle.height as string)\n }\n\n if (rocketstyle.maxWidth != null) {\n const mw = parseCssDimension(rocketstyle.maxWidth as string | number, rootSize)\n styles.maxWidth = mw ?? (rocketstyle.maxWidth as string)\n }\n\n // Opacity\n if (typeof rocketstyle.opacity === 'number') styles.opacity = rocketstyle.opacity\n\n return styles\n}\n","import { resolveStyles } from './resolveStyles'\nimport type { DocChild, DocNode, NodeType } from './types'\n\n/** Marker interface: components with _documentType are extractable. */\nexport interface DocumentMarker {\n _documentType: NodeType\n}\n\nexport interface ExtractOptions {\n /** Root font size for rem→px conversion. Default: 16. */\n rootSize?: number\n /** Include resolved styles from $rocketstyle. Default: true. */\n includeStyles?: boolean\n}\n\ntype VNodeLike = {\n type: string | ((...args: any[]) => any)\n props: Record<string, any>\n children: unknown[]\n}\n\nfunction isVNode(value: unknown): value is VNodeLike {\n return value != null && typeof value === 'object' && 'type' in value && 'props' in value\n}\n\nfunction getDocumentType(fn: unknown): NodeType | undefined {\n if (typeof fn !== 'function') return undefined\n const meta = (fn as any).meta\n if (meta?._documentType) return meta._documentType as NodeType\n // Fallback: check directly on function (non-rocketstyle components)\n if ('_documentType' in fn) return (fn as any)._documentType as NodeType\n return undefined\n}\n\nfunction flattenChildren(children: unknown[]): unknown[] {\n const result: unknown[] = []\n for (const child of children) {\n if (Array.isArray(child)) {\n result.push(...flattenChildren(child))\n } else if (typeof child === 'function') {\n // Reactive getter — call to resolve\n const resolved = child()\n if (Array.isArray(resolved)) {\n result.push(...flattenChildren(resolved))\n } else {\n result.push(resolved)\n }\n } else {\n result.push(child)\n }\n }\n return result\n}\n\nfunction extractChildren(children: unknown[], options: ExtractOptions): DocChild[] {\n const flat = flattenChildren(children)\n const result: DocChild[] = []\n\n for (const child of flat) {\n if (child == null || child === false || child === true) continue\n\n if (typeof child === 'string') {\n result.push(child)\n continue\n }\n\n if (typeof child === 'number') {\n result.push(String(child))\n continue\n }\n\n if (isVNode(child)) {\n const extracted = extractNode(child, options)\n if (Array.isArray(extracted)) {\n result.push(...extracted)\n } else if (extracted != null) {\n result.push(extracted)\n }\n }\n }\n\n return result\n}\n\nfunction extractNode(vnode: VNodeLike, options: ExtractOptions): DocNode | DocChild[] | null {\n const { type, props, children } = vnode\n const includeStyles = options.includeStyles !== false\n const rootSize = options.rootSize ?? 16\n\n // Component function with _documentType marker (via .statics() or direct)\n const docType = getDocumentType(type)\n if (docType) {\n // ── _documentProps resolution ────────────────────────────────────\n //\n // Three paths to find `_documentProps` on a documentType vnode,\n // tried in order:\n //\n // (A) **Pre-resolved on the JSX vnode itself** — used by test\n // fixtures that hand-construct vnodes with `_documentProps`\n // baked in. Cheapest path; tried first.\n //\n // (C) **Hoisted-attrs fast path (T3.1, PR #321)** — when the\n // component is a real rocketstyle primitive, it exposes\n // `__rs_attrs` (the accumulated `.attrs()` callback chain)\n // as a typed static. We run the chain DIRECTLY with the\n // JSX vnode's props — `chain.reduce(Object.assign, {})` —\n // and read `_documentProps` from the result. No styled\n // wrapper invocation, no JSX tree creation, no dimension\n // resolution. This is the production path for every real\n // Pyreon doc-primitive (DocDocument, DocHeading, etc.).\n //\n // (B) **Full component invocation (legacy fallback)** — only\n // fires when neither A nor C applies. Used by hand-rolled\n // test fixtures that mark a function with `_documentType`\n // but don't go through rocketstyle (so `__rs_attrs` is\n // absent). Calls the component with the JSX props and\n // reads `_documentProps` from the post-call vnode.\n //\n // Why three paths instead of one: (A) is for test fixtures that\n // hardcode `_documentProps` directly on the JSX vnode — a pattern\n // that pre-dates the attrs HOC. (C) is the real-world path. (B)\n // is what (C) replaced — kept so non-rocketstyle fixtures still\n // work. See PR #197 for the original metadata-drop bug and\n // PR #321 (T3.1) for the architectural fast path.\n //\n // **Function values in _documentProps are resolved at this\n // point** — primitives like DocDocument can store accessor\n // thunks (`() => string`) for reactive metadata, and the\n // export pipeline reads the LIVE value on each extraction.\n\n let rawDocProps: Record<string, unknown> | undefined\n let extractedFromCall: VNodeLike | null = null\n\n // Path A: pre-resolved on the JSX vnode (test fixtures)\n if (props._documentProps && typeof props._documentProps === 'object') {\n rawDocProps = props._documentProps as Record<string, unknown>\n } else if (typeof type === 'function') {\n // ── Path C (T3.1 fast path) ─────────────────────────────────────\n //\n // Rocketstyle exposes the accumulated `.attrs()` callback chain\n // as `__rs_attrs` on the component function. Run the chain\n // directly with the JSX vnode's props to get the post-attrs\n // result — no full component invocation, no styling work, no\n // wrapped JSX tree creation. Just the user-supplied attrs\n // callback(s) folded into a single props object.\n //\n // This eliminates the per-export cost of Path B for every real\n // rocketstyle primitive (DocDocument, DocHeading, etc.). The\n // idempotence assumption is now structural rather than implicit:\n // we never call the component, so it cannot have side effects\n // that affect the second extraction.\n const rsAttrs = (type as { __rs_attrs?: Array<(p: Record<string, unknown>) => Record<string, unknown>> }).__rs_attrs\n if (rsAttrs && rsAttrs.length > 0) {\n const mergedProps = { ...props }\n if (children && children.length > 0) {\n mergedProps.children = children.length === 1 ? children[0] : children\n }\n const attrsResult = rsAttrs.reduce<Record<string, unknown>>(\n (acc, fn) => Object.assign(acc, fn(mergedProps)),\n {},\n )\n if (attrsResult._documentProps && typeof attrsResult._documentProps === 'object') {\n rawDocProps = attrsResult._documentProps as Record<string, unknown>\n }\n } else {\n // Path B (fallback for non-rocketstyle docComponents):\n // invoke the component to get the post-attrs vnode. Used by\n // hand-rolled test fixtures that don't go through rocketstyle.\n const mergedProps = { ...props }\n if (children && children.length > 0) {\n mergedProps.children = children.length === 1 ? children[0] : children\n }\n const result = (type as (p: Record<string, unknown>) => unknown)(mergedProps)\n if (isVNode(result)) {\n extractedFromCall = result\n const innerProps = (result as { props?: Record<string, unknown> }).props\n if (innerProps?._documentProps && typeof innerProps._documentProps === 'object') {\n rawDocProps = innerProps._documentProps as Record<string, unknown>\n }\n }\n }\n }\n\n // Resolve function values (accessors) at extraction time\n const docProps: Record<string, unknown> = {}\n if (rawDocProps) {\n for (const [key, value] of Object.entries(rawDocProps)) {\n docProps[key] = typeof value === 'function' ? (value as () => unknown)() : value\n }\n }\n\n // Resolve styles from $rocketstyle. Look on the JSX vnode props\n // first; if the call result has its own $rocketstyle (because the\n // post-attrs vnode carries it down), use that as a fallback.\n const stylesSource =\n props.$rocketstyle ??\n (extractedFromCall as { props?: Record<string, unknown> } | null)?.props?.$rocketstyle\n const styles =\n includeStyles && stylesSource\n ? resolveStyles(stylesSource as Record<string, unknown>, rootSize)\n : undefined\n\n // Children: prefer the JSX vnode's children (the user-supplied\n // tree). The post-attrs call might wrap children in additional\n // styled elements that aren't part of the document tree.\n const docChildren = extractChildren(children ?? [], options)\n\n const node: DocNode = {\n type: docType,\n props: docProps,\n children: docChildren,\n }\n\n if (styles && Object.keys(styles).length > 0) {\n node.styles = styles\n }\n\n return node\n }\n\n // Component function WITHOUT _documentType — call it to get its VNode output\n if (typeof type === 'function') {\n const mergedProps = { ...props }\n if (children && children.length > 0) {\n mergedProps.children = children.length === 1 ? children[0] : children\n }\n\n const result = type(mergedProps)\n\n if (isVNode(result)) {\n return extractNode(result, options)\n }\n\n // The component returned a primitive or null\n if (typeof result === 'string') return [result]\n if (typeof result === 'number') return [String(result)]\n return null\n }\n\n // DOM element (string type like 'div', 'span') — transparent, extract children\n if (typeof type === 'string') {\n const docChildren = extractChildren(children ?? [], options)\n // If there's text content in the DOM element, collect it\n if (docChildren.length > 0) return docChildren\n return null\n }\n\n return null\n}\n\n/**\n * Walk a Pyreon VNode tree and extract a `DocNode` tree for `@pyreon/document`.\n *\n * For each VNode whose component has a `_documentType` marker:\n * 1. Read `_documentType` → `DocNode.type`\n * 2. Read `_documentProps` → `DocNode.props`\n * 3. Read `$rocketstyle` → `resolveStyles()` → `DocNode.styles`\n * 4. Recurse into children\n *\n * VNodes without `_documentType` are transparent — their children\n * are flattened into the parent's children list.\n */\nexport function extractDocumentTree(vnode: unknown, options: ExtractOptions = {}): DocNode {\n if (isVNode(vnode)) {\n const result = extractNode(vnode, options)\n if (result && !Array.isArray(result)) return result\n\n // Wrap loose children in a document node\n const children = Array.isArray(result) ? result : []\n return { type: 'document', props: {}, children }\n }\n\n // If passed a component function directly, call it\n if (typeof vnode === 'function') {\n const result = (vnode as () => unknown)()\n return extractDocumentTree(result, options)\n }\n\n return { type: 'document', props: {}, children: [] }\n}\n"],"mappings":"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"}