@uniweb/runtime 0.2.11 → 0.2.12

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": "@uniweb/runtime",
3
- "version": "0.2.11",
3
+ "version": "0.2.12",
4
4
  "description": "Minimal runtime for loading Uniweb foundations",
5
5
  "type": "module",
6
6
  "exports": {
@@ -29,7 +29,7 @@
29
29
  "node": ">=20.19"
30
30
  },
31
31
  "dependencies": {
32
- "@uniweb/core": "0.1.8"
32
+ "@uniweb/core": "0.1.11"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "react": "^18.0.0 || ^19.0.0",
@@ -2,10 +2,11 @@
2
2
  * BlockRenderer
3
3
  *
4
4
  * Bridges Block data to foundation components.
5
- * Handles theming and wrapper props.
5
+ * Handles theming, wrapper props, and runtime guarantees.
6
6
  */
7
7
 
8
8
  import React from 'react'
9
+ import { prepareProps, getComponentMeta } from '../prepare-props.js'
9
10
 
10
11
  /**
11
12
  * Convert hex color to rgba
@@ -82,34 +83,40 @@ export default function BlockRenderer({ block, pure = false, extra = {} }) {
82
83
  )
83
84
  }
84
85
 
85
- // Build content for component
86
- // Components expect content as a simple object with all data
86
+ // Build content and params with runtime guarantees
87
87
  // Sources:
88
88
  // 1. parsedContent.raw - simple PoC format (hardcoded content)
89
89
  // 2. parsedContent - semantic parser output (main.header, main.body, items, etc.)
90
90
  // 3. block.properties - params from frontmatter (theme, alignment, etc.)
91
- let content
91
+ // 4. meta - defaults from component meta.js
92
+ let content, params
92
93
 
93
94
  if (block.parsedContent?.raw) {
94
95
  // Simple PoC format - content was passed directly
95
96
  content = block.parsedContent.raw
97
+ params = block.properties
96
98
  } else {
97
- // Collected content - merge parsed content with frontmatter params
98
- // Parsed content goes first so components can access content.main.header, etc.
99
- // Frontmatter params overlay for things like content.title from YAML
99
+ // Get runtime metadata for this component (has defaults, data binding, etc.)
100
+ const meta = getComponentMeta(block.type)
101
+
102
+ // Prepare props with runtime guarantees:
103
+ // - Apply param defaults from meta.js
104
+ // - Guarantee content structure exists
105
+ const prepared = prepareProps(block, meta)
106
+ params = prepared.params
107
+
108
+ // Merge prepared content with raw access for components that need it
100
109
  content = {
101
- ...block.parsedContent, // Semantic parser output (main, items, etc.)
102
- ...block.properties, // Frontmatter params overlay
110
+ ...prepared.content,
111
+ ...block.properties, // Frontmatter params overlay (legacy support)
103
112
  _prosemirror: block.parsedContent // Keep original for components that need raw access
104
113
  }
105
114
  }
106
115
 
107
116
  const componentProps = {
108
117
  content,
109
- params: block.properties,
118
+ params,
110
119
  block,
111
- page: globalThis.uniweb?.activeWebsite?.activePage,
112
- website: globalThis.uniweb?.activeWebsite,
113
120
  input: block.input
114
121
  }
115
122
 
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Props Preparation for Runtime Guarantees
3
+ *
4
+ * Prepares props for foundation components with:
5
+ * - Param defaults from runtime schema
6
+ * - Guaranteed content structure (no null checks needed)
7
+ *
8
+ * This enables simpler component code by ensuring predictable prop shapes.
9
+ */
10
+
11
+ /**
12
+ * Guarantee content structure exists
13
+ * Returns a content object with all standard paths guaranteed to exist
14
+ *
15
+ * @param {Object} parsedContent - Raw parsed content from semantic parser
16
+ * @returns {Object} Content with guaranteed structure
17
+ */
18
+ export function guaranteeContentStructure(parsedContent) {
19
+ const content = parsedContent || {}
20
+
21
+ return {
22
+ // Main content section
23
+ main: {
24
+ header: {
25
+ title: content.main?.header?.title || '',
26
+ pretitle: content.main?.header?.pretitle || '',
27
+ subtitle: content.main?.header?.subtitle || '',
28
+ },
29
+ body: {
30
+ paragraphs: content.main?.body?.paragraphs || [],
31
+ links: content.main?.body?.links || [],
32
+ imgs: content.main?.body?.imgs || [],
33
+ lists: content.main?.body?.lists || [],
34
+ icons: content.main?.body?.icons || [],
35
+ },
36
+ },
37
+ // Content items (H3 sections)
38
+ items: content.items || [],
39
+ // Preserve any additional fields from parser
40
+ ...content,
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Apply param defaults from runtime schema
46
+ *
47
+ * @param {Object} params - Params from frontmatter
48
+ * @param {Object} defaults - Default values from runtime schema
49
+ * @returns {Object} Merged params with defaults applied
50
+ */
51
+ export function applyDefaults(params, defaults) {
52
+ if (!defaults || Object.keys(defaults).length === 0) {
53
+ return params || {}
54
+ }
55
+
56
+ return {
57
+ ...defaults,
58
+ ...(params || {}),
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Prepare props for a component with runtime guarantees
64
+ *
65
+ * @param {Object} block - The block instance
66
+ * @param {Object} meta - Runtime metadata for the component (from meta[componentName])
67
+ * @returns {Object} Prepared props: { content, params }
68
+ */
69
+ export function prepareProps(block, meta) {
70
+ // Apply param defaults
71
+ const defaults = meta?.defaults || {}
72
+ const params = applyDefaults(block.properties, defaults)
73
+
74
+ // Guarantee content structure
75
+ const content = guaranteeContentStructure(block.parsedContent)
76
+
77
+ return { content, params }
78
+ }
79
+
80
+ /**
81
+ * Get runtime metadata for a component from the global uniweb instance
82
+ *
83
+ * @param {string} componentName
84
+ * @returns {Object|null}
85
+ */
86
+ export function getComponentMeta(componentName) {
87
+ return globalThis.uniweb?.getComponentMeta?.(componentName) || null
88
+ }
89
+
90
+ /**
91
+ * Get default param values for a component
92
+ *
93
+ * @param {string} componentName
94
+ * @returns {Object}
95
+ */
96
+ export function getComponentDefaults(componentName) {
97
+ return globalThis.uniweb?.getComponentDefaults?.(componentName) || {}
98
+ }