@hypen-space/web 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/dist/canvas/accessibility.d.ts +47 -0
  2. package/dist/canvas/events.d.ts +87 -0
  3. package/dist/canvas/index.d.ts +11 -0
  4. package/dist/canvas/index.js +19 -13
  5. package/dist/canvas/index.js.map +6 -6
  6. package/dist/canvas/input.d.ts +56 -0
  7. package/dist/canvas/layout.d.ts +10 -0
  8. package/dist/canvas/layout.js +17 -12
  9. package/dist/canvas/layout.js.map +4 -4
  10. package/dist/canvas/paint.d.ts +14 -0
  11. package/dist/canvas/paint.js +3 -2
  12. package/dist/canvas/paint.js.map +4 -4
  13. package/dist/canvas/renderer.d.ts +99 -0
  14. package/dist/canvas/renderer.js +19 -13
  15. package/dist/canvas/renderer.js.map +6 -6
  16. package/dist/canvas/text.d.ts +22 -0
  17. package/dist/canvas/text.js +2 -2
  18. package/dist/canvas/text.js.map +2 -2
  19. package/dist/canvas/types.d.ts +96 -0
  20. package/dist/canvas/utils.d.ts +44 -0
  21. package/dist/client.d.ts +19 -0
  22. package/dist/client.js +46 -21
  23. package/dist/client.js.map +12 -11
  24. package/dist/dom/applicators/advanced-layout.d.ts +5 -0
  25. package/dist/dom/applicators/advanced-layout.js +1 -114
  26. package/dist/dom/applicators/advanced-layout.js.map +4 -5
  27. package/dist/dom/applicators/background.d.ts +5 -0
  28. package/dist/dom/applicators/border.d.ts +5 -0
  29. package/dist/dom/applicators/color.d.ts +5 -0
  30. package/dist/dom/applicators/display.d.ts +5 -0
  31. package/dist/dom/applicators/effects.d.ts +5 -0
  32. package/dist/dom/applicators/events.d.ts +8 -0
  33. package/dist/dom/applicators/events.js +3 -2
  34. package/dist/dom/applicators/events.js.map +3 -3
  35. package/dist/dom/applicators/font.d.ts +29 -0
  36. package/dist/dom/applicators/index.d.ts +76 -0
  37. package/dist/dom/applicators/index.js +3 -8
  38. package/dist/dom/applicators/index.js.map +4 -4
  39. package/dist/dom/applicators/layout.d.ts +10 -0
  40. package/dist/dom/applicators/margin.d.ts +11 -0
  41. package/dist/dom/applicators/padding.d.ts +11 -0
  42. package/dist/dom/applicators/size.d.ts +14 -0
  43. package/dist/dom/applicators/transform.d.ts +5 -0
  44. package/dist/dom/applicators/transition.d.ts +5 -0
  45. package/dist/dom/applicators/types.d.ts +6 -0
  46. package/dist/dom/applicators/typography.d.ts +5 -0
  47. package/dist/dom/canvas/index.d.ts +12 -0
  48. package/dist/dom/components/app.d.ts +8 -0
  49. package/dist/dom/components/app.js +55 -0
  50. package/dist/dom/components/app.js.map +10 -0
  51. package/dist/dom/components/audio.d.ts +5 -0
  52. package/dist/dom/components/avatar.d.ts +5 -0
  53. package/dist/dom/components/badge.d.ts +5 -0
  54. package/dist/dom/components/button.d.ts +9 -0
  55. package/dist/dom/components/card.d.ts +5 -0
  56. package/dist/dom/components/center.d.ts +9 -0
  57. package/dist/dom/components/checkbox.d.ts +5 -0
  58. package/dist/dom/components/column.d.ts +8 -0
  59. package/dist/dom/components/container.d.ts +5 -0
  60. package/dist/dom/components/divider.d.ts +5 -0
  61. package/dist/dom/components/grid.d.ts +7 -0
  62. package/dist/dom/components/heading.d.ts +5 -0
  63. package/dist/dom/components/hypenapp.d.ts +19 -0
  64. package/dist/dom/components/hypenapp.js +2 -4
  65. package/dist/dom/components/hypenapp.js.map +3 -3
  66. package/dist/dom/components/image.d.ts +5 -0
  67. package/dist/dom/components/index.d.ts +29 -0
  68. package/dist/dom/components/index.js +29 -5
  69. package/dist/dom/components/index.js.map +7 -6
  70. package/dist/dom/components/input.d.ts +5 -0
  71. package/dist/dom/components/link.d.ts +5 -0
  72. package/dist/dom/components/list.d.ts +5 -0
  73. package/dist/dom/components/paragraph.d.ts +5 -0
  74. package/dist/dom/components/progressbar.d.ts +5 -0
  75. package/dist/dom/components/route.d.ts +6 -0
  76. package/dist/dom/components/route.js +2 -2
  77. package/dist/dom/components/route.js.map +2 -2
  78. package/dist/dom/components/router.d.ts +5 -0
  79. package/dist/dom/components/row.d.ts +7 -0
  80. package/dist/dom/components/select.d.ts +5 -0
  81. package/dist/dom/components/slider.d.ts +5 -0
  82. package/dist/dom/components/spacer.d.ts +5 -0
  83. package/dist/dom/components/spinner.d.ts +5 -0
  84. package/dist/dom/components/stack.d.ts +5 -0
  85. package/dist/dom/components/switch.d.ts +5 -0
  86. package/dist/dom/components/text.d.ts +5 -0
  87. package/dist/dom/components/textarea.d.ts +5 -0
  88. package/dist/dom/components/video.d.ts +5 -0
  89. package/dist/dom/debug.d.ts +63 -0
  90. package/dist/dom/debug.js +2 -2
  91. package/dist/dom/debug.js.map +2 -2
  92. package/dist/dom/element-data.d.ts +94 -0
  93. package/dist/dom/events.d.ts +39 -0
  94. package/dist/dom/events.js +2 -2
  95. package/dist/dom/events.js.map +2 -2
  96. package/dist/dom/index.d.ts +10 -0
  97. package/dist/dom/index.js +46 -21
  98. package/dist/dom/index.js.map +12 -11
  99. package/dist/dom/renderer.d.ts +115 -0
  100. package/dist/dom/renderer.js +45 -20
  101. package/dist/dom/renderer.js.map +11 -10
  102. package/dist/hypen.d.ts +140 -0
  103. package/dist/hypen.js +46 -21
  104. package/dist/hypen.js.map +12 -11
  105. package/dist/index.d.ts +28 -0
  106. package/dist/index.js +64 -33
  107. package/dist/index.js.map +16 -15
  108. package/package.json +3 -2
  109. package/src/dom/components/index.ts +2 -0
  110. package/src/dom/renderer.ts +18 -6
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Text Rendering System
3
+ *
4
+ * Text measurement, wrapping, and rendering
5
+ */
6
+ import type { FontStyle, TextMetrics, TextStyle } from "./types.js";
7
+ /**
8
+ * Measure text dimensions
9
+ */
10
+ export declare function measureText(ctx: CanvasRenderingContext2D, text: string, fontStyle: FontStyle, maxWidth?: number): TextMetrics;
11
+ /**
12
+ * Render text with style
13
+ */
14
+ export declare function renderText(ctx: CanvasRenderingContext2D, text: string, x: number, y: number, width: number, height: number, style: TextStyle): void;
15
+ /**
16
+ * Clear text metrics cache
17
+ */
18
+ export declare function clearTextCache(): void;
19
+ /**
20
+ * Preload font to ensure it's available
21
+ */
22
+ export declare function loadFont(fontFamily: string, fontWeight?: string | number): Promise<void>;
@@ -151,7 +151,7 @@ function getAbsoluteBounds(node) {
151
151
  }
152
152
 
153
153
  // src/canvas/text.ts
154
- import { frameworkLoggers } from "@hypen-space/core";
154
+ import { frameworkLoggers } from "@hypen-space/core/logger";
155
155
  var log = frameworkLoggers.canvas;
156
156
  var textMetricsCache = new Map;
157
157
  function getCacheKey(text, fontStyle, maxWidth) {
@@ -262,4 +262,4 @@ export {
262
262
  clearTextCache
263
263
  };
264
264
 
265
- //# debugId=3230AB00A2D208E764756E2164756E21
265
+ //# debugId=C3D9BC7EE728E43964756E2164756E21
@@ -3,9 +3,9 @@
3
3
  "sources": ["../src/canvas/utils.ts", "../src/canvas/text.ts"],
4
4
  "sourcesContent": [
5
5
  "/**\n * Canvas Renderer Utilities\n *\n * Common utility functions\n */\n\nimport type { BoxSpacing, Rectangle, Point, VirtualNode } from \"./types.js\";\n\n/**\n * Parse spacing value (margin, padding)\n * Supports: number, \"10\", \"10 20\", \"10 20 30 40\"\n */\nexport function parseSpacing(value: any): BoxSpacing {\n if (typeof value === \"number\") {\n return { top: value, right: value, bottom: value, left: value };\n }\n\n if (typeof value === \"string\") {\n const parts = value.split(/\\s+/).map((v) => parseFloat(v) || 0);\n if (parts.length === 1) {\n return { top: parts[0], right: parts[0], bottom: parts[0], left: parts[0] };\n }\n if (parts.length === 2) {\n return { top: parts[0], right: parts[1], bottom: parts[0], left: parts[1] };\n }\n if (parts.length === 4) {\n return { top: parts[0], right: parts[1], bottom: parts[2], left: parts[3] };\n }\n }\n\n if (typeof value === \"object\" && value !== null) {\n return {\n top: parseFloat(value.top) || 0,\n right: parseFloat(value.right) || 0,\n bottom: parseFloat(value.bottom) || 0,\n left: parseFloat(value.left) || 0,\n };\n }\n\n return { top: 0, right: 0, bottom: 0, left: 0 };\n}\n\n/**\n * Parse size value (width, height)\n * Returns pixel value or null for \"auto\"\n */\nexport function parseSize(value: any): number | null {\n if (typeof value === \"number\") return value;\n if (typeof value === \"string\") {\n if (value === \"auto\") return null;\n const num = parseFloat(value);\n return isNaN(num) ? null : num;\n }\n return null;\n}\n\n/**\n * Check if point is inside rectangle\n */\nexport function isPointInRect(point: Point, rect: Rectangle): boolean {\n return (\n point.x >= rect.x &&\n point.x <= rect.x + rect.width &&\n point.y >= rect.y &&\n point.y <= rect.y + rect.height\n );\n}\n\n/**\n * Check if point is inside rounded rectangle\n */\nexport function isPointInRoundedRect(\n point: Point,\n rect: Rectangle,\n radius: number\n): boolean {\n const { x, y, width, height } = rect;\n\n // Quick reject if outside bounding box\n if (!isPointInRect(point, rect)) return false;\n\n // No radius means simple rectangle\n if (radius <= 0) return true;\n\n const px = point.x;\n const py = point.y;\n\n // Check corners\n // Top-left\n if (px < x + radius && py < y + radius) {\n return Math.pow(px - (x + radius), 2) + Math.pow(py - (y + radius), 2) <= Math.pow(radius, 2);\n }\n\n // Top-right\n if (px > x + width - radius && py < y + radius) {\n return (\n Math.pow(px - (x + width - radius), 2) + Math.pow(py - (y + radius), 2) <=\n Math.pow(radius, 2)\n );\n }\n\n // Bottom-left\n if (px < x + radius && py > y + height - radius) {\n return (\n Math.pow(px - (x + radius), 2) + Math.pow(py - (y + height - radius), 2) <=\n Math.pow(radius, 2)\n );\n }\n\n // Bottom-right\n if (px > x + width - radius && py > y + height - radius) {\n return (\n Math.pow(px - (x + width - radius), 2) + Math.pow(py - (y + height - radius), 2) <=\n Math.pow(radius, 2)\n );\n }\n\n // Inside rectangle\n return true;\n}\n\n/**\n * Merge rectangles into bounding box\n */\nexport function mergeRects(rects: Rectangle[]): Rectangle | null {\n if (rects.length === 0) return null;\n if (rects.length === 1) return rects[0];\n\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n\n for (const rect of rects) {\n minX = Math.min(minX, rect.x);\n minY = Math.min(minY, rect.y);\n maxX = Math.max(maxX, rect.x + rect.width);\n maxY = Math.max(maxY, rect.y + rect.height);\n }\n\n return {\n x: minX,\n y: minY,\n width: maxX - minX,\n height: maxY - minY,\n };\n}\n\n/**\n * Create a canvas font string from font style\n */\nexport function createFontString(\n fontSize: number,\n fontWeight: string | number,\n fontFamily: string\n): string {\n return `${fontWeight} ${fontSize}px ${fontFamily}`;\n}\n\n/**\n * Walk tree depth-first\n */\nexport function walkTree(node: VirtualNode, callback: (node: VirtualNode) => void): void {\n callback(node);\n for (const child of node.children) {\n walkTree(child, callback);\n }\n}\n\n/**\n * Find node by ID in tree\n */\nexport function findNodeById(root: VirtualNode, id: string): VirtualNode | null {\n if (root.id === id) return root;\n\n for (const child of root.children) {\n const found = findNodeById(child, id);\n if (found) return found;\n }\n\n return null;\n}\n\n/**\n * Get absolute bounds of node (including transformations)\n */\nexport function getAbsoluteBounds(node: VirtualNode): Rectangle | null {\n if (!node.layout) return null;\n\n let x = node.layout.x;\n let y = node.layout.y;\n\n // Walk up tree to accumulate offsets\n let current = node.parent;\n while (current && current.layout) {\n x += current.layout.contentX;\n y += current.layout.contentY;\n current = current.parent;\n }\n\n return {\n x,\n y,\n width: node.layout.width,\n height: node.layout.height,\n };\n}\n\n\n\n\n\n\n\n\n\n\n\n",
6
- "/**\n * Text Rendering System\n *\n * Text measurement, wrapping, and rendering\n */\n\nimport type { FontStyle, TextMetrics, TextStyle } from \"./types.js\";\nimport { createFontString } from \"./utils.js\";\nimport { frameworkLoggers } from \"@hypen-space/core\";\n\nconst log = frameworkLoggers.canvas;\n\n/**\n * Text metrics cache\n */\nconst textMetricsCache = new Map<string, TextMetrics>();\n\n/**\n * Get cache key for text metrics\n */\nfunction getCacheKey(text: string, fontStyle: FontStyle, maxWidth?: number): string {\n return `${text}|${fontStyle.fontSize}|${fontStyle.fontWeight}|${fontStyle.fontFamily}|${maxWidth || \"auto\"}`;\n}\n\n/**\n * Measure text dimensions\n */\nexport function measureText(\n ctx: CanvasRenderingContext2D,\n text: string,\n fontStyle: FontStyle,\n maxWidth?: number\n): TextMetrics {\n const cacheKey = getCacheKey(text, fontStyle, maxWidth);\n const cached = textMetricsCache.get(cacheKey);\n if (cached) return cached;\n\n const font = createFontString(fontStyle.fontSize, fontStyle.fontWeight, fontStyle.fontFamily);\n ctx.save();\n ctx.font = font;\n\n const lineHeight = fontStyle.lineHeight || fontStyle.fontSize * 1.2;\n\n // No wrapping needed\n if (!maxWidth) {\n const metrics = ctx.measureText(text);\n const result: TextMetrics = {\n width: metrics.width,\n height: lineHeight,\n lines: [text],\n lineHeight,\n };\n ctx.restore();\n textMetricsCache.set(cacheKey, result);\n return result;\n }\n\n // Wrap text\n const lines = wrapText(ctx, text, maxWidth);\n const width = Math.max(...lines.map((line) => ctx.measureText(line).width));\n const height = lines.length * lineHeight;\n\n const result: TextMetrics = {\n width,\n height,\n lines,\n lineHeight,\n };\n\n ctx.restore();\n textMetricsCache.set(cacheKey, result);\n return result;\n}\n\n/**\n * Wrap text to fit within maxWidth\n */\nfunction wrapText(ctx: CanvasRenderingContext2D, text: string, maxWidth: number): string[] {\n const lines: string[] = [];\n const paragraphs = text.split(\"\\n\");\n\n for (const paragraph of paragraphs) {\n const words = paragraph.split(\" \");\n let currentLine = \"\";\n\n for (const word of words) {\n const testLine = currentLine ? `${currentLine} ${word}` : word;\n const metrics = ctx.measureText(testLine);\n\n if (metrics.width > maxWidth && currentLine) {\n lines.push(currentLine);\n currentLine = word;\n } else {\n currentLine = testLine;\n }\n }\n\n if (currentLine) {\n lines.push(currentLine);\n }\n }\n\n return lines.length > 0 ? lines : [\"\"];\n}\n\n/**\n * Render text with style\n */\nexport function renderText(\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n width: number,\n height: number,\n style: TextStyle\n): void {\n const font = createFontString(style.fontSize, style.fontWeight, style.fontFamily);\n ctx.save();\n ctx.font = font;\n ctx.fillStyle = style.color;\n ctx.textBaseline = \"top\";\n\n const metrics = measureText(ctx, text, style, width);\n\n // Calculate starting Y based on vertical alignment\n let startY = y;\n if (style.verticalAlign === \"middle\") {\n startY = y + (height - metrics.height) / 2;\n } else if (style.verticalAlign === \"bottom\") {\n startY = y + height - metrics.height;\n }\n\n // Render each line\n for (let i = 0; i < metrics.lines.length; i++) {\n const line = metrics.lines[i];\n const lineY = startY + i * metrics.lineHeight;\n\n // Calculate X based on text alignment\n let lineX = x;\n if (style.textAlign === \"center\") {\n const lineWidth = ctx.measureText(line).width;\n lineX = x + (width - lineWidth) / 2;\n } else if (style.textAlign === \"right\") {\n const lineWidth = ctx.measureText(line).width;\n lineX = x + width - lineWidth;\n }\n\n ctx.fillText(line, lineX, lineY);\n }\n\n ctx.restore();\n}\n\n/**\n * Clear text metrics cache\n */\nexport function clearTextCache(): void {\n textMetricsCache.clear();\n}\n\n/**\n * Preload font to ensure it's available\n */\nexport async function loadFont(fontFamily: string, fontWeight: string | number = \"normal\"): Promise<void> {\n if (!(\"fonts\" in document)) return;\n\n const font = `${fontWeight} 16px ${fontFamily}`;\n try {\n await document.fonts.load(font);\n } catch (error) {\n log.warn(`Failed to load font: ${font}`, error);\n }\n}\n\n\n\n\n\n\n\n\n\n\n\n"
6
+ "/**\n * Text Rendering System\n *\n * Text measurement, wrapping, and rendering\n */\n\nimport type { FontStyle, TextMetrics, TextStyle } from \"./types.js\";\nimport { createFontString } from \"./utils.js\";\nimport { frameworkLoggers } from \"@hypen-space/core/logger\";\n\nconst log = frameworkLoggers.canvas;\n\n/**\n * Text metrics cache\n */\nconst textMetricsCache = new Map<string, TextMetrics>();\n\n/**\n * Get cache key for text metrics\n */\nfunction getCacheKey(text: string, fontStyle: FontStyle, maxWidth?: number): string {\n return `${text}|${fontStyle.fontSize}|${fontStyle.fontWeight}|${fontStyle.fontFamily}|${maxWidth || \"auto\"}`;\n}\n\n/**\n * Measure text dimensions\n */\nexport function measureText(\n ctx: CanvasRenderingContext2D,\n text: string,\n fontStyle: FontStyle,\n maxWidth?: number\n): TextMetrics {\n const cacheKey = getCacheKey(text, fontStyle, maxWidth);\n const cached = textMetricsCache.get(cacheKey);\n if (cached) return cached;\n\n const font = createFontString(fontStyle.fontSize, fontStyle.fontWeight, fontStyle.fontFamily);\n ctx.save();\n ctx.font = font;\n\n const lineHeight = fontStyle.lineHeight || fontStyle.fontSize * 1.2;\n\n // No wrapping needed\n if (!maxWidth) {\n const metrics = ctx.measureText(text);\n const result: TextMetrics = {\n width: metrics.width,\n height: lineHeight,\n lines: [text],\n lineHeight,\n };\n ctx.restore();\n textMetricsCache.set(cacheKey, result);\n return result;\n }\n\n // Wrap text\n const lines = wrapText(ctx, text, maxWidth);\n const width = Math.max(...lines.map((line) => ctx.measureText(line).width));\n const height = lines.length * lineHeight;\n\n const result: TextMetrics = {\n width,\n height,\n lines,\n lineHeight,\n };\n\n ctx.restore();\n textMetricsCache.set(cacheKey, result);\n return result;\n}\n\n/**\n * Wrap text to fit within maxWidth\n */\nfunction wrapText(ctx: CanvasRenderingContext2D, text: string, maxWidth: number): string[] {\n const lines: string[] = [];\n const paragraphs = text.split(\"\\n\");\n\n for (const paragraph of paragraphs) {\n const words = paragraph.split(\" \");\n let currentLine = \"\";\n\n for (const word of words) {\n const testLine = currentLine ? `${currentLine} ${word}` : word;\n const metrics = ctx.measureText(testLine);\n\n if (metrics.width > maxWidth && currentLine) {\n lines.push(currentLine);\n currentLine = word;\n } else {\n currentLine = testLine;\n }\n }\n\n if (currentLine) {\n lines.push(currentLine);\n }\n }\n\n return lines.length > 0 ? lines : [\"\"];\n}\n\n/**\n * Render text with style\n */\nexport function renderText(\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n width: number,\n height: number,\n style: TextStyle\n): void {\n const font = createFontString(style.fontSize, style.fontWeight, style.fontFamily);\n ctx.save();\n ctx.font = font;\n ctx.fillStyle = style.color;\n ctx.textBaseline = \"top\";\n\n const metrics = measureText(ctx, text, style, width);\n\n // Calculate starting Y based on vertical alignment\n let startY = y;\n if (style.verticalAlign === \"middle\") {\n startY = y + (height - metrics.height) / 2;\n } else if (style.verticalAlign === \"bottom\") {\n startY = y + height - metrics.height;\n }\n\n // Render each line\n for (let i = 0; i < metrics.lines.length; i++) {\n const line = metrics.lines[i];\n const lineY = startY + i * metrics.lineHeight;\n\n // Calculate X based on text alignment\n let lineX = x;\n if (style.textAlign === \"center\") {\n const lineWidth = ctx.measureText(line).width;\n lineX = x + (width - lineWidth) / 2;\n } else if (style.textAlign === \"right\") {\n const lineWidth = ctx.measureText(line).width;\n lineX = x + width - lineWidth;\n }\n\n ctx.fillText(line, lineX, lineY);\n }\n\n ctx.restore();\n}\n\n/**\n * Clear text metrics cache\n */\nexport function clearTextCache(): void {\n textMetricsCache.clear();\n}\n\n/**\n * Preload font to ensure it's available\n */\nexport async function loadFont(fontFamily: string, fontWeight: string | number = \"normal\"): Promise<void> {\n if (!(\"fonts\" in document)) return;\n\n const font = `${fontWeight} 16px ${fontFamily}`;\n try {\n await document.fonts.load(font);\n } catch (error) {\n log.warn(`Failed to load font: ${font}`, error);\n }\n}\n\n\n\n\n\n\n\n\n\n\n\n"
7
7
  ],
8
8
  "mappings": "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",
9
- "debugId": "3230AB00A2D208E764756E2164756E21",
9
+ "debugId": "C3D9BC7EE728E43964756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Canvas Renderer Types
3
+ *
4
+ * Shared type definitions for the canvas renderer
5
+ */
6
+ export interface VirtualNode {
7
+ id: string;
8
+ type: string;
9
+ props: Record<string, any>;
10
+ children: VirtualNode[];
11
+ parent: VirtualNode | null;
12
+ layout?: Layout;
13
+ visible: boolean;
14
+ opacity: number;
15
+ clickable: boolean;
16
+ hoverable: boolean;
17
+ focusable: boolean;
18
+ focused: boolean;
19
+ hovered: boolean;
20
+ }
21
+ export interface Layout {
22
+ x: number;
23
+ y: number;
24
+ width: number;
25
+ height: number;
26
+ margin: BoxSpacing;
27
+ padding: BoxSpacing;
28
+ border: BorderStyle;
29
+ contentX: number;
30
+ contentY: number;
31
+ contentWidth: number;
32
+ contentHeight: number;
33
+ }
34
+ export interface BoxSpacing {
35
+ top: number;
36
+ right: number;
37
+ bottom: number;
38
+ left: number;
39
+ }
40
+ export interface BorderStyle {
41
+ width: number;
42
+ color: string;
43
+ radius: number;
44
+ }
45
+ export interface Rectangle {
46
+ x: number;
47
+ y: number;
48
+ width: number;
49
+ height: number;
50
+ }
51
+ export interface Point {
52
+ x: number;
53
+ y: number;
54
+ }
55
+ export interface FontStyle {
56
+ fontFamily: string;
57
+ fontSize: number;
58
+ fontWeight: string | number;
59
+ lineHeight?: number;
60
+ }
61
+ export interface TextStyle extends FontStyle {
62
+ color: string;
63
+ textAlign: "left" | "center" | "right";
64
+ verticalAlign: "top" | "middle" | "bottom";
65
+ }
66
+ export interface TextMetrics {
67
+ width: number;
68
+ height: number;
69
+ lines: string[];
70
+ lineHeight: number;
71
+ }
72
+ export interface CanvasRendererOptions {
73
+ devicePixelRatio?: number;
74
+ backgroundColor?: string;
75
+ enableAccessibility?: boolean;
76
+ enableHitTesting?: boolean;
77
+ enableInputOverlay?: boolean;
78
+ enableDirtyRects?: boolean;
79
+ enableLayerCaching?: boolean;
80
+ maxLayerCacheSize?: number;
81
+ showLayoutBounds?: boolean;
82
+ showDirtyRects?: boolean;
83
+ logPerformance?: boolean;
84
+ }
85
+ export interface PainterFunction {
86
+ (ctx: CanvasRenderingContext2D, node: VirtualNode): void;
87
+ }
88
+ export interface LayoutFunction {
89
+ (node: VirtualNode, availableWidth: number, availableHeight: number): {
90
+ width: number;
91
+ height: number;
92
+ };
93
+ }
94
+ export interface DirtyRect extends Rectangle {
95
+ frameId: number;
96
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Canvas Renderer Utilities
3
+ *
4
+ * Common utility functions
5
+ */
6
+ import type { BoxSpacing, Rectangle, Point, VirtualNode } from "./types.js";
7
+ /**
8
+ * Parse spacing value (margin, padding)
9
+ * Supports: number, "10", "10 20", "10 20 30 40"
10
+ */
11
+ export declare function parseSpacing(value: any): BoxSpacing;
12
+ /**
13
+ * Parse size value (width, height)
14
+ * Returns pixel value or null for "auto"
15
+ */
16
+ export declare function parseSize(value: any): number | null;
17
+ /**
18
+ * Check if point is inside rectangle
19
+ */
20
+ export declare function isPointInRect(point: Point, rect: Rectangle): boolean;
21
+ /**
22
+ * Check if point is inside rounded rectangle
23
+ */
24
+ export declare function isPointInRoundedRect(point: Point, rect: Rectangle, radius: number): boolean;
25
+ /**
26
+ * Merge rectangles into bounding box
27
+ */
28
+ export declare function mergeRects(rects: Rectangle[]): Rectangle | null;
29
+ /**
30
+ * Create a canvas font string from font style
31
+ */
32
+ export declare function createFontString(fontSize: number, fontWeight: string | number, fontFamily: string): string;
33
+ /**
34
+ * Walk tree depth-first
35
+ */
36
+ export declare function walkTree(node: VirtualNode, callback: (node: VirtualNode) => void): void;
37
+ /**
38
+ * Find node by ID in tree
39
+ */
40
+ export declare function findNodeById(root: VirtualNode, id: string): VirtualNode | null;
41
+ /**
42
+ * Get absolute bounds of node (including transformations)
43
+ */
44
+ export declare function getAbsoluteBounds(node: VirtualNode): Rectangle | null;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * @hypen-space/web/client - Client-side rendering with WASM engine
3
+ *
4
+ * This entry point includes the Hypen orchestrator which connects the
5
+ * BrowserEngine (WASM) with the DOM renderer. Use this when you want
6
+ * to run the engine client-side in the browser.
7
+ *
8
+ * For remote UI (server-side engine, no WASM in browser), use the
9
+ * default import from "@hypen-space/web" instead.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * import { render } from "@hypen-space/web/client";
14
+ *
15
+ * await render("Counter", "#app");
16
+ * ```
17
+ */
18
+ export { Hypen, render, renderWithComponents } from "./hypen.js";
19
+ export type { HypenConfig } from "./hypen.js";
package/dist/client.js CHANGED
@@ -1011,7 +1011,7 @@ var exports_route = {};
1011
1011
  __export(exports_route, {
1012
1012
  routeHandler: () => routeHandler
1013
1013
  });
1014
- import { frameworkLoggers } from "@hypen-space/core";
1014
+ import { frameworkLoggers } from "@hypen-space/core/logger";
1015
1015
  var log, routeHandler;
1016
1016
  var init_route = __esm(() => {
1017
1017
  log = frameworkLoggers.router;
@@ -1046,7 +1046,7 @@ __export(exports_hypenapp, {
1046
1046
  disconnectHypenApp: () => disconnectHypenApp
1047
1047
  });
1048
1048
  import { RemoteEngine } from "@hypen-space/core/remote/client";
1049
- import { frameworkLoggers as frameworkLoggers2 } from "@hypen-space/core";
1049
+ import { frameworkLoggers as frameworkLoggers2 } from "@hypen-space/core/logger";
1050
1050
  function applyPatches(container, nodes, patches, engine, onRoot) {
1051
1051
  for (const patch of patches) {
1052
1052
  switch (patch.type) {
@@ -1202,8 +1202,6 @@ function applyProp(el, name, value) {
1202
1202
  border: "border",
1203
1203
  gap: "gap",
1204
1204
  flex: "flex",
1205
- alignItems: "alignItems",
1206
- justifyContent: "justifyContent",
1207
1205
  opacity: "opacity",
1208
1206
  overflow: "overflow"
1209
1207
  };
@@ -1301,6 +1299,26 @@ var init_hypenapp = __esm(() => {
1301
1299
  };
1302
1300
  });
1303
1301
 
1302
+ // src/dom/components/app.ts
1303
+ var exports_app = {};
1304
+ __export(exports_app, {
1305
+ appHandler: () => appHandler
1306
+ });
1307
+ var appHandler;
1308
+ var init_app = __esm(() => {
1309
+ appHandler = {
1310
+ create() {
1311
+ const el = document.createElement("div");
1312
+ el.style.display = "flex";
1313
+ el.style.flexDirection = "column";
1314
+ el.style.minHeight = "100vh";
1315
+ el.style.width = "100%";
1316
+ el.dataset.hypenType = "app";
1317
+ return el;
1318
+ }
1319
+ };
1320
+ });
1321
+
1304
1322
  // src/dom/components/index.ts
1305
1323
  class ComponentRegistry {
1306
1324
  handlers = new Map;
@@ -1311,9 +1329,13 @@ class ComponentRegistry {
1311
1329
  this.handlers.set(type.toLowerCase(), handler);
1312
1330
  }
1313
1331
  get(type) {
1332
+ if (!type)
1333
+ return;
1314
1334
  return this.handlers.get(type.toLowerCase());
1315
1335
  }
1316
1336
  createElement(type, props = {}) {
1337
+ if (!type)
1338
+ return null;
1317
1339
  const handler = this.get(type);
1318
1340
  if (!handler)
1319
1341
  return null;
@@ -1355,6 +1377,8 @@ class ComponentRegistry {
1355
1377
  const { routerHandler: routerHandler2 } = (init_router(), __toCommonJS(exports_router));
1356
1378
  const { routeHandler: routeHandler2 } = (init_route(), __toCommonJS(exports_route));
1357
1379
  const { hypenAppHandler: hypenAppHandler2 } = (init_hypenapp(), __toCommonJS(exports_hypenapp));
1380
+ const { appHandler: appHandler2 } = (init_app(), __toCommonJS(exports_app));
1381
+ this.register("app", appHandler2);
1358
1382
  this.register("column", columnHandler2);
1359
1383
  this.register("row", rowHandler2);
1360
1384
  this.register("text", textHandler2);
@@ -2038,7 +2062,7 @@ import {
2038
2062
  disposableListener,
2039
2063
  disposableTimeout
2040
2064
  } from "@hypen-space/core/disposable";
2041
- import { frameworkLoggers as frameworkLoggers3 } from "@hypen-space/core";
2065
+ import { frameworkLoggers as frameworkLoggers3 } from "@hypen-space/core/logger";
2042
2066
  var log3 = frameworkLoggers3.events;
2043
2067
  function toPlainObject(value) {
2044
2068
  if (value instanceof Map) {
@@ -2323,6 +2347,7 @@ var eventHandlers = {
2323
2347
  extractPayload: scrollPayload
2324
2348
  }),
2325
2349
  onLongClick: createLongClickHandler(500),
2350
+ onLongPress: createLongClickHandler(500),
2326
2351
  onFocus: createEventHandler("focus", { extractPayload: focusPayload }),
2327
2352
  onBlur: createEventHandler("blur", { extractPayload: focusPayload }),
2328
2353
  onMouseEnter: createEventHandler("mouseenter", { extractPayload: mousePayload }),
@@ -2584,12 +2609,6 @@ var advancedLayoutHandlers = {
2584
2609
  flexBasis: (el, value) => {
2585
2610
  el.style.flexBasis = typeof value === "number" ? `${value}px` : String(value);
2586
2611
  },
2587
- justifyContent: (el, value) => {
2588
- el.style.justifyContent = mapAlignmentValue(String(value));
2589
- },
2590
- alignItems: (el, value) => {
2591
- el.style.alignItems = mapAlignmentValue(String(value));
2592
- },
2593
2612
  alignContent: (el, value) => {
2594
2613
  el.style.alignContent = String(value);
2595
2614
  },
@@ -3127,7 +3146,7 @@ var canvasApplicators = {
3127
3146
  };
3128
3147
 
3129
3148
  // src/dom/debug.ts
3130
- import { frameworkLoggers as frameworkLoggers4 } from "@hypen-space/core";
3149
+ import { frameworkLoggers as frameworkLoggers4 } from "@hypen-space/core/logger";
3131
3150
  var log4 = frameworkLoggers4.debug;
3132
3151
  var defaultDebugConfig = {
3133
3152
  enabled: false,
@@ -3290,7 +3309,7 @@ class RerenderTracker {
3290
3309
  }
3291
3310
 
3292
3311
  // src/dom/renderer.ts
3293
- import { frameworkLoggers as frameworkLoggers5 } from "@hypen-space/core";
3312
+ import { frameworkLoggers as frameworkLoggers5 } from "@hypen-space/core/logger";
3294
3313
  var log5 = frameworkLoggers5.renderer;
3295
3314
 
3296
3315
  class DOMRenderer {
@@ -3363,24 +3382,30 @@ class DOMRenderer {
3363
3382
  });
3364
3383
  }
3365
3384
  applyPatch(patch) {
3385
+ const p = patch;
3386
+ const id = patch.id ?? p.id;
3387
+ const elementType = patch.elementType ?? p.element_type;
3388
+ const parentId = patch.parentId ?? p.parent_id;
3389
+ const beforeId = patch.beforeId ?? p.before_id;
3390
+ const eventName = patch.eventName ?? p.event_name;
3366
3391
  switch (patch.type) {
3367
3392
  case "create":
3368
- this.onCreate(patch.id, patch.elementType, patch.props || {});
3393
+ this.onCreate(id, elementType ?? "container", patch.props || {});
3369
3394
  break;
3370
3395
  case "setProp":
3371
- this.onSetProp(patch.id, patch.name, patch.value);
3396
+ this.onSetProp(id, patch.name, patch.value);
3372
3397
  break;
3373
3398
  case "setText":
3374
- this.onSetText(patch.id, patch.text);
3399
+ this.onSetText(id, patch.text);
3375
3400
  break;
3376
3401
  case "insert":
3377
- this.onInsert(patch.parentId, patch.id, patch.beforeId);
3402
+ this.onInsert(parentId, id, beforeId);
3378
3403
  break;
3379
3404
  case "move":
3380
- this.onMove(patch.parentId, patch.id, patch.beforeId);
3405
+ this.onMove(parentId, id, beforeId);
3381
3406
  break;
3382
3407
  case "remove":
3383
- this.onRemove(patch.id);
3408
+ this.onRemove(id);
3384
3409
  break;
3385
3410
  }
3386
3411
  }
@@ -3517,7 +3542,7 @@ import { HypenRouter } from "@hypen-space/core/router";
3517
3542
  import { HypenGlobalContext } from "@hypen-space/core/context";
3518
3543
  import { componentLoader } from "@hypen-space/core/loader";
3519
3544
  import { Router, Route, Link } from "@hypen-space/core/components";
3520
- import { frameworkLoggers as frameworkLoggers6, setDebugMode } from "@hypen-space/core";
3545
+ import { frameworkLoggers as frameworkLoggers6, setDebugMode } from "@hypen-space/core/logger";
3521
3546
  var log6 = frameworkLoggers6.hypen;
3522
3547
 
3523
3548
  class Hypen {
@@ -3816,4 +3841,4 @@ export {
3816
3841
  Hypen
3817
3842
  };
3818
3843
 
3819
- //# debugId=2F6AEA497E33207F64756E2164756E21
3844
+ //# debugId=12790505428577C564756E2164756E21