Skip to content

Commit ff50aa0

Browse files
Merge pull request #537 from open-element/dev
feat(create,docs,tools): 0.42.0-alpha.4 — hardening, recipes and starter (ADR-0120)
2 parents 642629f + 7a2dcb0 commit ff50aa0

31 files changed

Lines changed: 561 additions & 36 deletions

CHANGELOG.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,28 @@ Current truth lives in:
1212
Historical changelog details remain available through git history and release
1313
evidence.
1414

15+
## 0.42.0-alpha.4
16+
17+
- Hardening and recipes (TP-5, ADR-0120): the 0.42 line closes with
18+
integration proof instead of new semantics.
19+
- Validation recipes verified in CI: zod (`/register`) and valibot
20+
(`/subscribe`) run inside fixture actions with 422/303 asserted in three
21+
engines — `docs/integrations/validation.md`. better-auth and Drizzle
22+
recipes are published as doc-level (honestly marked unverified):
23+
`docs/integrations/better-auth.md`, `docs/integrations/drizzle.md`.
24+
- The `create` starter gains a request-time `/contact` route exercising
25+
the full loop (`rendering: 'dynamic'` + action + `data-open-enhance`),
26+
so starter consumers get the loop out of the box.
27+
- `PACKAGE_SURFACE.md` records the 0.42 line additions as unfrozen with
28+
their freeze target.
29+
- Performance baseline for 0.44: request-time render on the fixture is
30+
cold 28.6ms, warm p50 1.58ms / p95 2.97ms
31+
(`docs/release/v0.42.0-alpha.4-performance.json`).
32+
- Fix (from alpha.3): the morph could replace an island whose light DOM
33+
carried whitespace-only text around the DSD template, resetting its
34+
state; the comparison now ignores whitespace-only text nodes, covered
35+
by the survival matrix in three engines (42/42).
36+
1537
## 0.42.0-alpha.3
1638

1739
- Revalidation continuity (ADR-0120): enhanced forms (`data-open-enhance`)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Elements are the durable application contract; JSX and Basic Element are the
77
authoring layer; Declarative Shadow DOM is the default server representation;
88
interactive regions upgrade selectively.
99

10-
Published package line: `0.42.0-alpha.3` (`v0.42.0-alpha.3`) — the stable five-package
10+
Published package line: `0.42.0-alpha.4` (`v0.42.0-alpha.4`) — the stable five-package
1111
release under ADR-0119's scoped interface freeze; the abandoned beta naming
1212
is not an active line.
1313

README.zh.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
Elements 是可长期保存的应用组件模型;JSX 与 Basic Element 是作者层;
77
Declarative Shadow DOM 是默认服务端表示;交互区域按需升级。
88

9-
已发布包线为 `0.42.0-alpha.3``v0.42.0-alpha.3`)——ADR-0119 范围化接口冻结下的
9+
已发布包线为 `0.42.0-alpha.4``v0.42.0-alpha.4`)——ADR-0119 范围化接口冻结下的
1010
stable 五包版本;已放弃的 beta 命名不再是当前版本线。
1111

1212
## 当前产品

deno.json

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929
"@shoelace-style/shoelace": "npm:@shoelace-style/shoelace@^2.19.0",
3030
"@material/web/checkbox/checkbox.js": "npm:@material/web@^2.0.0/checkbox/checkbox.js",
3131
"nitro": "npm:nitro@3.0.0",
32-
"@rollup/plugin-terser": "npm:@rollup/plugin-terser@1.0.0"
32+
"@rollup/plugin-terser": "npm:@rollup/plugin-terser@1.0.0",
33+
"zod": "npm:zod@^3.25",
34+
"valibot": "npm:valibot@^1.1"
3335
},
3436
"vendor": true,
3537
"nodeModulesDir": "manual",
@@ -131,8 +133,12 @@
131133
},
132134
"lint": {
133135
"rules": {
134-
"tags": ["recommended"],
135-
"exclude": ["no-sloppy-imports"]
136+
"tags": [
137+
"recommended"
138+
],
139+
"exclude": [
140+
"no-sloppy-imports"
141+
]
136142
},
137143
"exclude": [
138144
"www/content/blog/",
@@ -145,7 +151,12 @@
145151
"compilerOptions": {
146152
"module": "ESNext",
147153
"moduleResolution": "bundler",
148-
"lib": ["ES2022", "DOM", "DOM.Iterable", "deno.ns"],
154+
"lib": [
155+
"ES2022",
156+
"DOM",
157+
"DOM.Iterable",
158+
"deno.ns"
159+
],
149160
"strict": true,
150161
"skipLibCheck": true,
151162
"jsx": "react-jsx",

deno.lock

Lines changed: 18 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/current/PACKAGE_SURFACE.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,18 @@ semantics (0.42 WC Application Loop and 0.44 Production Runtime scope), the
114114
internal in the map above. Post-freeze changes to the frozen surface require
115115
a major-version ADR.
116116

117+
### 0.42 line additions (unfrozen until the 0.42.0 stable decision)
118+
119+
- `definePage({ renderIntent: { mode } })`: `'auto'`/`'static'`/`'dynamic'`
120+
rendering modes; `'dynamic'` routes render per request through the
121+
generated `dist/server/index.js` (0.42.0-alpha.1).
122+
- Route-module `loader`/`action`/`actions` exports with the ADR-0120
123+
protocol: `fail(status, data)` 422 re-render, 303 PRG, named actions via
124+
`formaction='?/name'` (0.42.0-alpha.2).
125+
- `ActionResult` / `ACTION_FETCH_HEADER` wire types and the
126+
`data-open-enhance` / `data-open-preserve` / `data-open-region`
127+
enhancement attributes with morph-based continuity (0.42.0-alpha.3).
128+
117129
- `@openelement/ui` supported subpaths: `open-badge`, `open-button`,
118130
`open-callout`, `open-card`, `open-code-block`, `open-dialog`,
119131
`open-dropdown`, `open-input`, `open-props-tokens`, `open-tabs`,

docs/current/VERSION_PLAN.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# v0.42.0 — WC Application Loop release plan
22

3-
> Current source package line: `v0.42.0-alpha.3`\
4-
> Current npm registry line: `v0.42.0-alpha.3`\
3+
> Current source package line: `v0.42.0-alpha.4`\
4+
> Current npm registry line: `v0.42.0-alpha.4`\
55
> Active release target: `v0.41.1`\
66
> Planning release target: `v0.42.0` (WC Application Loop)\
77
> Next release line: `v0.43.0` (Universal WC SSR)\

docs/governance/PROJECT_WORKFLOW.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ complete because an issue, chat message, or SOP says it is complete. It is
1111
complete only when the repository contains the decision, the execution package,
1212
the implementation, and the gates that prove the claim.
1313

14-
Current execution anchor: published package line `v0.42.0-alpha.3`, completed
15-
implementation anchor `v0.42.0-alpha.3`, and `0.42.0` WC Application Loop planning
14+
Current execution anchor: published package line `v0.42.0-alpha.4`, completed
15+
implementation anchor `v0.42.0-alpha.4`, and `0.42.0` WC Application Loop planning
1616
under ADR-0120 and `docs/current/VERSION_PLAN.md`.
1717
OpenElement is one Web Components-native,
1818
static-first application framework: Basic Element is an authoring mode, not a

docs/integrations/better-auth.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Auth recipe (better-auth)
2+
3+
> Status: **doc-level, not CI-verified** — integration shape, not a tested
4+
> artifact. It will move to verified status when a consumer reproduces it
5+
> (0.42.x recipe follow-up).
6+
7+
openElement does not ship auth. The loop gives better-auth three honest
8+
attachment points, all Web-standard:
9+
10+
1. **Session read in loaders**: a dynamic route's `loader({ request })`
11+
gets the standard `Request`; pass its headers to better-auth's
12+
`auth.api.getSession({ headers: request.headers })` and return the
13+
session as loader data. Render signed-in vs signed-out in DSD.
14+
2. **Auth endpoints**: mount better-auth's handler as an API route (or a
15+
Nitro route) on the same deployment — it owns its URLs; the framework
16+
does not proxy them.
17+
3. **Actions**: in an action, use the session to authorize before
18+
mutating; on failure `redirect('/login')` (303 by protocol) or
19+
`fail(403, { error })` when the form should re-render with an error.
20+
21+
```ts
22+
export async function loader({ request }: LoaderContext) {
23+
const session = await auth.api.getSession({ headers: request.headers });
24+
if (!session) redirect('/login');
25+
return { user: session.user };
26+
}
27+
```
28+
29+
Sessions remain a 0.44 framework topic; until then the cookie/session
30+
wiring is entirely better-auth's, which is the point of the recipe.

docs/integrations/drizzle.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Data recipe (Drizzle)
2+
3+
> Status: **doc-level, not CI-verified** — integration shape, not a tested
4+
> artifact. It will move to verified status when a consumer reproduces it
5+
> (0.42.x recipe follow-up).
6+
7+
openElement does not ship an ORM or a data layer. Drizzle (or any query
8+
builder) runs inside loaders and actions, which are ordinary server
9+
functions on a `rendering: 'dynamic'` route:
10+
11+
1. **Reads**: run queries in `loader`; return plain serializable data. The
12+
page renders it in DSD at request time; pure-static routes keep using
13+
build-time data instead.
14+
2. **Writes**: run mutations in `action` after validation (see the
15+
validation recipe). On conflict or constraint failure,
16+
`return fail(422, { error })` to re-render with the echo; on success,
17+
`redirect()` to the changed resource (303 PRG, revalidation re-runs the
18+
loader for you).
19+
3. **Connection**: create the client once at module scope of a small
20+
`db.ts` and import it from routes. Connection secrets belong to the
21+
deployment environment (`ctx.env`), never to the client bundle —
22+
loaders/actions never ship to the browser.
23+
24+
```ts
25+
// app/db.ts
26+
export const db = drizzle(process.env.DATABASE_URL!);
27+
28+
// app/routes/posts.tsx
29+
export async function loader() {
30+
return { posts: await db.select().from(postsTable).limit(20) };
31+
}
32+
```
33+
34+
Transactions, pooling and migrations stay with Drizzle; the framework
35+
owns only the route-to-interaction loop around them.

0 commit comments

Comments
 (0)