@constela/server 5.0.1 → 6.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 +26 -0
  2. package/dist/index.js +16 -0
  3. package/package.json +3 -3
package/README.md CHANGED
@@ -38,6 +38,32 @@ JSON program → HTML string
38
38
 
39
39
  ## Features
40
40
 
41
+ ### String Concatenation (concat)
42
+
43
+ Build dynamic strings during SSR:
44
+
45
+ ```json
46
+ {
47
+ "kind": "element",
48
+ "tag": "a",
49
+ "props": {
50
+ "href": {
51
+ "expr": "concat",
52
+ "items": [
53
+ { "expr": "lit", "value": "/posts/" },
54
+ { "expr": "data", "name": "post", "path": "slug" }
55
+ ]
56
+ }
57
+ }
58
+ }
59
+ ```
60
+
61
+ ↓ SSR
62
+
63
+ ```html
64
+ <a href="/posts/hello-world">...</a>
65
+ ```
66
+
41
67
  ### Markdown Rendering
42
68
 
43
69
  ```json
package/dist/index.js CHANGED
@@ -371,6 +371,8 @@ async function renderNode(node, ctx) {
371
371
  return await renderCode(node, ctx);
372
372
  case "slot":
373
373
  return "";
374
+ case "localState":
375
+ return await renderLocalState(node, ctx);
374
376
  default: {
375
377
  const _exhaustiveCheck = node;
376
378
  throw new Error(`Unknown node kind: ${JSON.stringify(_exhaustiveCheck)}`);
@@ -461,6 +463,20 @@ async function renderCode(node, ctx) {
461
463
  const copyButton = `<button class="constela-copy-btn absolute right-3 top-3 z-10 flex h-8 w-8 items-center justify-center rounded-md border border-border bg-background/80 opacity-0 transition-opacity hover:bg-muted group-hover:opacity-100" data-copy-target="code" aria-label="Copy code"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="h-4 w-4"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg></button>`;
462
464
  return `<div class="constela-code" data-code-content="${escapeHtml(content)}"><div class="group relative">${languageBadge}${copyButton}${highlightedCode}</div></div>`;
463
465
  }
466
+ async function renderLocalState(node, ctx) {
467
+ const localStateValues = {};
468
+ for (const [name, field] of Object.entries(node.state)) {
469
+ localStateValues[name] = field.initial;
470
+ }
471
+ const childCtx = {
472
+ ...ctx,
473
+ locals: {
474
+ ...ctx.locals,
475
+ ...localStateValues
476
+ }
477
+ };
478
+ return await renderNode(node.child, childCtx);
479
+ }
464
480
  async function renderToString(program, options) {
465
481
  const state = /* @__PURE__ */ new Map();
466
482
  for (const [name, field] of Object.entries(program.state)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@constela/server",
3
- "version": "5.0.1",
3
+ "version": "6.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.9.1"
18
+ "@constela/compiler": "^0.10.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.9.1"
31
+ "@constela/compiler": "0.10.0"
32
32
  },
33
33
  "engines": {
34
34
  "node": ">=20.0.0"