@constela/server 3.0.1 → 4.0.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.
Files changed (3) hide show
  1. package/README.md +112 -88
  2. package/dist/index.js +6 -0
  3. package/package.json +3 -3
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @constela/server
2
2
 
3
- Server-side rendering (SSR) for the Constela UI framework.
3
+ Server-side rendering (SSR) for Constela JSON programs.
4
4
 
5
5
  ## Installation
6
6
 
@@ -11,76 +11,85 @@ npm install @constela/server
11
11
  **Peer Dependencies:**
12
12
  - `@constela/compiler` ^0.7.0
13
13
 
14
- ## Overview
15
-
16
- This package provides SSR capabilities for Constela applications. Features:
17
-
18
- - **HTML Generation** - Render programs to HTML strings
19
- - **Route Context** - Pass route params and query strings
20
- - **Markdown & Code** - Server-side Markdown and syntax highlighting
21
- - **Dual Theme** - Light and dark theme code blocks
14
+ ## How It Works
15
+
16
+ JSON program HTML string
17
+
18
+ ```json
19
+ {
20
+ "version": "1.0",
21
+ "state": { "name": { "type": "string", "initial": "World" } },
22
+ "view": {
23
+ "kind": "element",
24
+ "tag": "h1",
25
+ "children": [
26
+ { "kind": "text", "value": { "expr": "lit", "value": "Hello, " } },
27
+ { "kind": "text", "value": { "expr": "state", "name": "name" } }
28
+ ]
29
+ }
30
+ }
31
+ ```
22
32
 
23
- ## API Reference
33
+ SSR
24
34
 
25
- ### renderToString
35
+ ```html
36
+ <h1>Hello, World</h1>
37
+ ```
26
38
 
27
- Main SSR function that renders a compiled program to HTML.
39
+ ## Features
28
40
 
29
- ```typescript
30
- import { renderToString } from '@constela/server';
41
+ ### Markdown Rendering
31
42
 
32
- const html = await renderToString(compiledProgram, {
33
- route: {
34
- params: { id: '123' },
35
- query: { tab: 'overview' },
36
- path: '/users/123',
37
- },
38
- imports: {
39
- config: { siteName: 'My Site' },
40
- },
41
- });
43
+ ```json
44
+ {
45
+ "kind": "markdown",
46
+ "content": { "expr": "data", "name": "article", "path": "content" }
47
+ }
42
48
  ```
43
49
 
44
- **Parameters:**
45
- - `program: CompiledProgram` - Compiled program from `@constela/compiler`
46
- - `options?: RenderOptions` - Optional render configuration
50
+ Rendered with async parsing and Shiki syntax highlighting.
47
51
 
48
- **RenderOptions:**
49
- ```typescript
50
- interface RenderOptions {
51
- route?: {
52
- params?: Record<string, string>;
53
- query?: Record<string, string>;
54
- path?: string;
55
- };
56
- imports?: Record<string, unknown>;
52
+ ### Code Highlighting
53
+
54
+ ```json
55
+ {
56
+ "kind": "code",
57
+ "code": { "expr": "lit", "value": "const x = 1;" },
58
+ "language": { "expr": "lit", "value": "typescript" }
57
59
  }
58
60
  ```
59
61
 
60
- **Returns:** `Promise<string>` - Complete HTML string
62
+ Features:
63
+ - Dual theme support (github-light, github-dark)
64
+ - CSS custom properties for theme switching
65
+ - Preloaded languages: javascript, typescript, json, html, css, python, rust, go, java, bash, markdown
61
66
 
62
- ## Internal Features
67
+ ### Route Context
63
68
 
64
- The package internally handles:
69
+ Pass route parameters for dynamic pages:
65
70
 
66
- **Markdown Rendering:**
67
- - Async parsing with Shiki syntax highlighting
68
- - Sanitization via DOMPurify
71
+ ```json
72
+ {
73
+ "route": { "path": "/users/:id" },
74
+ "view": {
75
+ "kind": "text",
76
+ "value": { "expr": "route", "name": "id", "source": "param" }
77
+ }
78
+ }
79
+ ```
69
80
 
70
- **Code Highlighting:**
71
- - Dual theme support (github-light, github-dark)
72
- - CSS custom properties for theme switching
73
- - Preloaded languages: javascript, typescript, json, html, css, python, rust, go, java, bash, markdown
81
+ ### Import Data
74
82
 
75
- **CSS Variables:** Code blocks use CSS custom properties:
76
- ```css
77
- /* Light mode */
78
- .shiki { background-color: var(--shiki-light-bg); }
79
- .shiki span { color: var(--shiki-light); }
83
+ Pass external data at render time:
80
84
 
81
- /* Dark mode */
82
- .dark .shiki { background-color: var(--shiki-dark-bg); }
83
- .dark .shiki span { color: var(--shiki-dark); }
85
+ ```json
86
+ {
87
+ "imports": { "config": "./data/config.json" },
88
+ "view": {
89
+ "kind": "text",
90
+ "value": { "expr": "import", "name": "config", "path": "siteName" }
91
+ }
92
+ }
84
93
  ```
85
94
 
86
95
  ## Output Structure
@@ -91,23 +100,23 @@ The package internally handles:
91
100
  <div class="constela-code" data-code-content="...">
92
101
  <div class="group relative">
93
102
  <div class="language-badge">typescript</div>
94
- <button class="constela-copy-btn">
95
- <!-- Copy icon SVG -->
96
- </button>
103
+ <button class="constela-copy-btn"><!-- Copy icon --></button>
97
104
  <pre><code class="shiki">...</code></pre>
98
105
  </div>
99
106
  </div>
100
107
  ```
101
108
 
102
- The `data-code-content` attribute contains the raw code for copy functionality.
109
+ ### CSS Variables
103
110
 
104
- ## Expression Evaluation
105
-
106
- SSR evaluates expressions server-side with some limitations:
111
+ ```css
112
+ /* Light mode */
113
+ .shiki { background-color: var(--shiki-light-bg); }
114
+ .shiki span { color: var(--shiki-light); }
107
115
 
108
- - **No DOM refs** - `ref` expressions return `null`
109
- - **No safe globals** - Limited to basic operations
110
- - **Static only** - No reactive updates
116
+ /* Dark mode */
117
+ .dark .shiki { background-color: var(--shiki-dark-bg); }
118
+ .dark .shiki span { color: var(--shiki-dark); }
119
+ ```
111
120
 
112
121
  ## Security
113
122
 
@@ -115,29 +124,37 @@ SSR evaluates expressions server-side with some limitations:
115
124
  - **DOMPurify** - Markdown content is sanitized
116
125
  - **Prototype Pollution Prevention** - Same as runtime
117
126
 
118
- ## Example
127
+ ## Internal API
128
+
129
+ > For framework developers only. End users should use the CLI.
130
+
131
+ ### renderToString
119
132
 
120
133
  ```typescript
121
- import { compile } from '@constela/compiler';
122
134
  import { renderToString } from '@constela/server';
123
135
 
124
- const program = compile({
125
- version: '1.0',
126
- state: { name: { type: 'string', initial: 'World' } },
127
- actions: [],
128
- view: {
129
- kind: 'element',
130
- tag: 'h1',
131
- children: [
132
- { kind: 'text', value: { expr: 'lit', value: 'Hello, ' } },
133
- { kind: 'text', value: { expr: 'state', name: 'name' } },
134
- ],
136
+ const html = await renderToString(compiledProgram, {
137
+ route: {
138
+ params: { id: '123' },
139
+ query: { tab: 'overview' },
140
+ path: '/users/123',
141
+ },
142
+ imports: {
143
+ config: { siteName: 'My Site' },
135
144
  },
136
145
  });
146
+ ```
147
+
148
+ **RenderOptions:**
137
149
 
138
- if (program.ok) {
139
- const html = await renderToString(program.program);
140
- console.log(html); // '<h1>Hello, World</h1>'
150
+ ```typescript
151
+ interface RenderOptions {
152
+ route?: {
153
+ params?: Record<string, string>;
154
+ query?: Record<string, string>;
155
+ path?: string;
156
+ };
157
+ imports?: Record<string, unknown>;
141
158
  }
142
159
  ```
143
160
 
@@ -145,14 +162,21 @@ if (program.ok) {
145
162
 
146
163
  Server-rendered HTML can be hydrated on the client:
147
164
 
148
- ```typescript
149
- // Server
150
- import { renderToString } from '@constela/server';
151
- const html = await renderToString(program, { route, imports });
152
-
153
- // Client
154
- import { hydrateApp } from '@constela/runtime';
155
- hydrateApp({ program, mount, route, imports });
165
+ ```json
166
+ {
167
+ "version": "1.0",
168
+ "lifecycle": { "onMount": "initializeClient" },
169
+ "state": { ... },
170
+ "actions": [
171
+ {
172
+ "name": "initializeClient",
173
+ "steps": [
174
+ { "do": "storage", "operation": "get", "key": { "expr": "lit", "value": "preferences" }, ... }
175
+ ]
176
+ }
177
+ ],
178
+ "view": { ... }
179
+ }
156
180
  ```
157
181
 
158
182
  ## License
package/dist/index.js CHANGED
@@ -213,6 +213,12 @@ function evaluate(expr, ctx) {
213
213
  if (typeof key === "string" && forbiddenKeys.has(key)) return void 0;
214
214
  return base[key];
215
215
  }
216
+ case "param": {
217
+ return void 0;
218
+ }
219
+ case "style": {
220
+ return "";
221
+ }
216
222
  default: {
217
223
  const _exhaustiveCheck = expr;
218
224
  throw new Error(`Unknown expression type: ${JSON.stringify(_exhaustiveCheck)}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constela/server",
3
- "version": "3.0.1",
3
+ "version": "4.0.0",
4
4
  "description": "Server-side rendering for Constela UI framework",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -15,7 +15,7 @@
15
15
  "dist"
16
16
  ],
17
17
  "peerDependencies": {
18
- "@constela/compiler": "^0.7.0"
18
+ "@constela/compiler": "^0.8.0"
19
19
  },
20
20
  "dependencies": {
21
21
  "isomorphic-dompurify": "^2.35.0",
@@ -28,7 +28,7 @@
28
28
  "tsup": "^8.0.0",
29
29
  "typescript": "^5.3.0",
30
30
  "vitest": "^2.0.0",
31
- "@constela/compiler": "0.7.0"
31
+ "@constela/compiler": "0.8.0"
32
32
  },
33
33
  "engines": {
34
34
  "node": ">=20.0.0"