Skip to content

Commit 0725913

Browse files
author
DevBot
committed
feat(release,www,ui,docs): stable 0.41.0 preparation — freeze scope, migration guide, content truths
- adapter-vite: prune 10 internal subpaths from exports at the freeze (app-vite, build-context, head-injection, i18n-plugin, plugin, generated-data-resolver, plugin-mdx, route-manifest, cli/build-client, cli/build-ssg); PACKAGE_SURFACE records the prune and the ADR-0119 defineApp freeze boundary; snapshot + export-files regenerated - migration: aggregate alpha-line -> 0.41.0 guide in docs/release/v0.41.0-migration.md plus a bilingual /guide/migration page (ui radius geometry breaking noted); history-surface exemption in the www-truth gate for version-dense migration content - ui consumers evidence: deno-desktop-reader (open-button/card/input + tokens) and deno-desktop-mastodon (open-theme-toggle + tokens) recorded in packages/ui README for the v0.46 decision - www: zh homepage content (locale-aware home), new dispatch 'Three audits later, the stable line' featured on /blog (index now sorts by date desc), stale #390 remnants in roadmap artifact panel already corrected - design: retire the broken indigo mockup pipeline (generate.mjs, v2/v3, old SVGs); v4 is the mockup set of record; CJK serif decision recorded - #37 gate text refreshed (0.41.0 subset, RC-soak -> seven-day P0 watch)
1 parent 8c50ac5 commit 0725913

89 files changed

Lines changed: 448 additions & 14301 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/current/PACKAGE_SURFACE.md

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ promise and are not application-authoring surface.
5656
},
5757
"@openelement/adapter-vite": {
5858
"supported": [".", "nitro-mount", "cli/build", "sitemap"],
59-
"internal": ["app-vite", "build-context", "head-injection", "i18n-plugin", "plugin", "generated-data-resolver", "plugin-mdx", "route-manifest", "cli/build-client", "cli/build-ssg"]
59+
"internal": []
6060
},
6161
"@openelement/create": {
6262
"supported": ["."],
@@ -94,9 +94,25 @@ promise and are not application-authoring surface.
9494
`SpaAppInstance` / `SpaAppOptions`.
9595
- `@openelement/adapter-vite` internal subpaths (`app-vite`, `build-context`,
9696
`head-injection`, `i18n-plugin`, `plugin`, `generated-data-resolver`,
97-
`plugin-mdx`, `route-manifest`, `cli/build-client`, `cli/build-ssg`) serve
98-
the build pipeline and generated code; they may be pruned at the v0.41
99-
freeze.
97+
`plugin-mdx`, `route-manifest`, `cli/build-client`, `cli/build-ssg`) were
98+
pruned at the 0.41.0 freeze (ADR-0119): they had zero consumer specifiers —
99+
the build pipeline and generated code import only relatively or through the
100+
supported root, `nitro-mount`, `cli/build` and `sitemap` subpaths. The module
101+
files remain inside the package for internal relative imports only.
102+
103+
## 0.41.0 interface freeze boundary (ADR-0119)
104+
105+
Frozen at 0.41.0: `defineElement`, `definePage`, `buildApp`, the five-package
106+
graph, the supported subpaths above, and the static/SPA semantics of
107+
`defineApp` as shipped — file routes, `tagName` route elements, island
108+
configuration (`ssr`/`dsd`/`hydrate`), DSD output, and the SPA-mode
109+
loader/action chain.
110+
111+
Explicitly not frozen: request-time data, forms, sessions and cache
112+
semantics (0.42 WC Application Loop and 0.44 Production Runtime scope), the
113+
`@openelement/ui` stable scope (decided at v0.46), and everything marked
114+
internal in the map above. Post-freeze changes to the frozen surface require
115+
a major-version ADR.
100116
- `@openelement/ui` supported subpaths: `open-badge`, `open-button`,
101117
`open-callout`, `open-card`, `open-code-block`, `open-dialog`,
102118
`open-dropdown`, `open-input`, `open-props-tokens`, `open-tabs`,

docs/release/v0.41.0-interface-snapshot.json

Lines changed: 0 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -114,18 +114,8 @@
114114
"name": "@openelement/adapter-vite",
115115
"exports": {
116116
".": "./src/index.ts",
117-
"./app-vite": "./src/app-vite.ts",
118-
"./build-context": "./src/build-context.ts",
119117
"./cli/build": "./src/cli/build.ts",
120-
"./cli/build-client": "./src/cli/build-client.ts",
121-
"./cli/build-ssg": "./src/cli/build-ssg.ts",
122-
"./generated-data-resolver": "./src/generated-data-resolver.ts",
123-
"./head-injection": "./src/head-injection.ts",
124-
"./i18n-plugin": "./src/i18n-plugin.ts",
125118
"./nitro-mount": "./src/nitro-mount.ts",
126-
"./plugin": "./src/plugin.ts",
127-
"./plugin-mdx": "./src/plugin-mdx.ts",
128-
"./route-manifest": "./src/route-manifest.ts",
129119
"./sitemap": "./src/sitemap.ts"
130120
},
131121
"declarations": {
@@ -141,64 +131,10 @@
141131
"export type { OpenMdxPluginOptions } from './plugin-mdx.ts';"
142132
]
143133
},
144-
"./app-vite": {
145-
"sha256": "fbc9bbfd9964bfab9465a1f572ee12ee430b99fa0c216aa2937a8e7a2cfc5ad2",
146-
"publicDeclarations": [
147-
"export interface OpenElementOptions extends FrameworkOptions {",
148-
"export function openElement(options: OpenElementOptions = {}): Plugin[] {"
149-
]
150-
},
151-
"./build-context": {
152-
"sha256": "a77770942f8fd2e1ea5acf4b5e66545e9cf54373a2c312193f317dbe274c3bcf",
153-
"publicDeclarations": [
154-
"export type Phase = 1 | 2 | 3;",
155-
"export class Phase1Meta {",
156-
"export class Phase3Meta {",
157-
"export class OpenElementBuildContext {"
158-
]
159-
},
160134
"./cli/build": {
161135
"sha256": "19b817d8d114f0b107b7708675754de3fdc12c76c85c4dd3333814b6643894bd",
162136
"publicDeclarations": []
163137
},
164-
"./cli/build-client": {
165-
"sha256": "e4ec975531f3d39eef603901e5a034b89e86436ae042f6a40b8d3a344583d175",
166-
"publicDeclarations": []
167-
},
168-
"./cli/build-ssg": {
169-
"sha256": "10fdc527b3a19974af767a71516d5957475be84f551a57c635488cdbe16b937f",
170-
"publicDeclarations": [
171-
"export interface SsgEntryDescriptorInputs {",
172-
"export function buildSsgEntryDescriptor("
173-
]
174-
},
175-
"./generated-data-resolver": {
176-
"sha256": "d18395cfa3eca7cd72f2e5481b24a0e76d49284d717a9c08274c085adf80788c",
177-
"publicDeclarations": [
178-
"export const GENERATED_NAV_ID = '@openelement/generated/nav';",
179-
"export const GENERATED_BLOG_DATA_ID = '@openelement/generated/blog-data';",
180-
"export const GENERATED_I18N_ID = '@openelement/generated/i18n';",
181-
"export type GeneratedDataResolverOptions = {",
182-
"export function generatedDataPath(",
183-
"export function createGeneratedDataResolverPlugin("
184-
]
185-
},
186-
"./head-injection": {
187-
"sha256": "28dab8f1b72b612847e1a158869ad8afc8fe89a242684ffffb44997c022a66e0",
188-
"publicDeclarations": [
189-
"export function assertNoScriptTags(html: string, context: string): void {",
190-
"export function validateSafeUrl(url: string, context: string): string {",
191-
"export interface HeadExtrasResult {",
192-
"export function buildHeadExtras(options: FrameworkOptions): HeadExtrasResult {"
193-
]
194-
},
195-
"./i18n-plugin": {
196-
"sha256": "b24544efcdc71ff563a6a5ad4745bbfa3c3152a4694d42bdae2ec929a5f47cb3",
197-
"publicDeclarations": [
198-
"export function writeI18nDataModule(locales: string[], defaultLocale: string): string {",
199-
"export function openI18n("
200-
]
201-
},
202138
"./nitro-mount": {
203139
"sha256": "33056a4b4e9c291ea90532ad68268aaa9ad7be1a7f4897986847bd4e54926c47",
204140
"publicDeclarations": [
@@ -208,28 +144,6 @@
208144
"export function createOpenElementNitroHandler<"
209145
]
210146
},
211-
"./plugin": {
212-
"sha256": "ce53992a9feb7490df8cf62a22cb97d53ffcf2842176010f79a1a3b2092e907a",
213-
"publicDeclarations": [
214-
"export function optionalPackageStubsPlugin(): Plugin {",
215-
"export function createOpenPlugin("
216-
]
217-
},
218-
"./plugin-mdx": {
219-
"sha256": "d935ba8f764d12bb95cacbe38e1d88ddb3c647560af5d293f0cccb84ecd85601",
220-
"publicDeclarations": [
221-
"export interface OpenMdxPluginOptions {",
222-
"export function mdxPlugin(options: OpenMdxPluginOptions = {}): Plugin {"
223-
]
224-
},
225-
"./route-manifest": {
226-
"sha256": "383a1fdf94c5df10b62fbbdcc3e9d021dfbab222e7c232c3358718d8a866a8f8",
227-
"publicDeclarations": [
228-
"export interface GenerateRouteManifestOptions {",
229-
"export const routeManifest = {} as const;",
230-
"export const routeManifest = {"
231-
]
232-
},
233147
"./sitemap": {
234148
"sha256": "2c24151329624e9adde127f4762580ff3ac75fff4a66818fc83d7100d91a9135",
235149
"publicDeclarations": [

docs/release/v0.41.0-migration.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Migrating to 0.41.0 from the 0.41 alpha line (and 0.40.x)
2+
3+
This is the aggregate migration guide for the 0.41.0 stable release. It covers
4+
every breaking change since `0.40.x`, grouped by the version that shipped it.
5+
Versions not listed are non-breaking.
6+
7+
## From 0.40.x (the eleven-package era)
8+
9+
- The consumer graph is five packages: `@openelement/element`, `/app`,
10+
`/adapter-vite`, `/create`, `/ui`. The retired packages (`@openelement/core`,
11+
`signal`, `router`, `protocol`, `content`, `ssg`) are not supported imports;
12+
their functionality moved into the five packages.
13+
- Author with `defineElement`, `definePage`, `defineApp` and build with
14+
`buildApp()` (adapter-vite root). The plugin-style build entries are gone.
15+
- `defineLayout` was removed; layouts use `defineElement` with the same
16+
definition object.
17+
- Distribution is npm-first (JSR is no longer a release channel).
18+
19+
## alpha.17
20+
21+
- Build-time helpers moved from the `@openelement/element` root to
22+
`@openelement/element/build-utils` (`transformIslandSource`,
23+
`createIsrCacheKey`, `formatJson`, `pathToTagName`, `normalizeSeparators`,
24+
`SsrRenderError`, `createRuntimeAdapter`, runtime handler types). Update
25+
imports: `from '@openelement/element'``from '@openelement/element/build-utils'`.
26+
- App root no longer exports router types (`RouteConfig`, `RouterInstance`,
27+
`RouterMode`). Derive them from `SpaAppInstance` / `SpaAppOptions`.
28+
- Adapter-vite's `ExternalManifest` type and `SsgPageOutput.hydrationHints`
29+
were removed.
30+
31+
## alpha.18
32+
33+
- Dead exports, fields and scripts were removed (element root build helpers,
34+
island-manifest types, `openMdx` alias, unused ui `*TagName` re-exports).
35+
- `renderIntent.streaming` and `PageStreamingMode` were removed; delete the
36+
option from page definitions (it was never implemented).
37+
- Dynamic-route render failures now fail the build by default. Opt out with
38+
`SsgBehaviorOptions.dynamicRouteFailure: 'warn'` if a route is allowed to
39+
fail loudly without stopping the build.
40+
41+
## alpha.19
42+
43+
- The element root no longer carries `export type *` seams; the public type
44+
surface is an explicit export list. `SafeHtml`, `UnsafeHtml` and
45+
`StyleSheetRule` are no longer exported from the root (their alpha.18
46+
removal claim is now true).
47+
- Element internal subpaths `open-element-render` and `open-element-hydration`
48+
were removed from exports. Tooling must not import them.
49+
- `renderDsdStream`/`createRenderDsdStreamMetrics`, `bindHydrateEvents` and
50+
`generateHonoEntryCode` were removed as unused internals.
51+
- ui: the remaining `openDialogTagName`/`openDropdownTagName`/`openTabsTagName`
52+
re-exports were removed; ui controls are squared
53+
(`--btn-radius`/`--badge-radius`/`--ui-control-radius` changed from
54+
`--radius-round` to `--radius-1`, 6px). If your CSS or screenshots assumed
55+
pill-shaped buttons/badges, update them.
56+
57+
## 0.41.0
58+
59+
- Adapter-vite internal subpaths were pruned from exports: `app-vite`,
60+
`build-context`, `head-injection`, `i18n-plugin`, `plugin`,
61+
`generated-data-resolver`, `plugin-mdx`, `route-manifest`, `cli/build-client`,
62+
`cli/build-ssg`. They had no consumer specifiers; the build pipeline imports
63+
them relatively. Migrate to the supported entries: adapter-vite root
64+
(`openElement`, `buildApp`), `nitro-mount`, `cli/build`, `sitemap`.
65+
- The interface freeze (ADR-0119): `defineElement`, `definePage`, `buildApp`,
66+
the five-package graph, the supported subpaths and the static/SPA semantics
67+
of `defineApp` are frozen. Post-freeze changes to that surface require a
68+
major-version ADR — pin with confidence.
69+
70+
## Verify after upgrading
71+
72+
1. `deno install --frozen` and re-run your build; static output must render
73+
identically (dynamic 500s now fail builds by default, see alpha.18).
74+
2. Grep for removed imports: `renderIntent.streaming`, `open-element-render`,
75+
`open-element-hydration`, `app-vite`, `build-context`, `head-injection`,
76+
`plugin-mdx`, `route-manifest`, `SafeHtml`, `UnsafeHtml`, `StyleSheetRule`,
77+
`*TagName`.
78+
3. If you snapshot visual output, re-record baselines after the ui control
79+
geometry change (alpha.19).

packages/adapter-vite/deno.json

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,9 @@
33
"version": "0.41.0-alpha.19",
44
"exports": {
55
".": "./src/index.ts",
6-
"./app-vite": "./src/app-vite.ts",
7-
"./build-context": "./src/build-context.ts",
8-
"./head-injection": "./src/head-injection.ts",
9-
"./i18n-plugin": "./src/i18n-plugin.ts",
106
"./nitro-mount": "./src/nitro-mount.ts",
11-
"./plugin": "./src/plugin.ts",
12-
"./generated-data-resolver": "./src/generated-data-resolver.ts",
13-
"./plugin-mdx": "./src/plugin-mdx.ts",
14-
"./route-manifest": "./src/route-manifest.ts",
157
"./sitemap": "./src/sitemap.ts",
16-
"./cli/build": "./src/cli/build.ts",
17-
"./cli/build-client": "./src/cli/build-client.ts",
18-
"./cli/build-ssg": "./src/cli/build-ssg.ts"
8+
"./cli/build": "./src/cli/build.ts"
199
},
2010
"imports": {
2111
"@mdx-js/rollup": "npm:@mdx-js/rollup@^3.1.1",

packages/adapter-vite/src/generated-export-files.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,8 @@
44
export const OPENELEMENT_EXPORT_FILES: Record<string, Record<string, string>> = {
55
'adapter-vite': {
66
'.': 'src/index.ts',
7-
'app-vite': 'src/app-vite.ts',
8-
'build-context': 'src/build-context.ts',
97
'cli/build': 'src/cli/build.ts',
10-
'cli/build-client': 'src/cli/build-client.ts',
11-
'cli/build-ssg': 'src/cli/build-ssg.ts',
12-
'generated-data-resolver': 'src/generated-data-resolver.ts',
13-
'head-injection': 'src/head-injection.ts',
14-
'i18n-plugin': 'src/i18n-plugin.ts',
158
'nitro-mount': 'src/nitro-mount.ts',
16-
'plugin': 'src/plugin.ts',
17-
'plugin-mdx': 'src/plugin-mdx.ts',
18-
'route-manifest': 'src/route-manifest.ts',
199
'sitemap': 'src/sitemap.ts',
2010
},
2111
'app': {

tools/check-www-current-truth.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,11 @@ if (await exists('www/content/guide')) {
6666

6767
async function checkFile(file: string): Promise<void> {
6868
const text = await Deno.readTextFile(file);
69+
// Version-dense history surfaces (the migration guide, changelog) may name
70+
// retired prereleases without it being a stale current claim.
71+
const isHistorySurface = /(?:routes\/guide\/migration\.tsx|CHANGELOG\.md)$/.test(file);
6972
for (const { name, re } of forbidden) {
73+
if (isHistorySurface && name === 'retired prerelease current claim') continue;
7074
if (re.test(text)) issues.push({ file, text: name });
7175
}
7276
if (
@@ -120,9 +124,16 @@ await checkFile('www/vite.config.ts');
120124
if (Deno.args.includes('--artifacts')) {
121125
for await (const file of walk('www/dist', { skip: ['blog'] })) {
122126
// The root-level history indexes (blog.html, changelog.html or their
123-
// /blog//changelog route index.html) hold historical copy that is
124-
// intentionally outside the current-surface rule.
125-
if (/(?:^|\/)(?:blog|changelog)(?:\.html|\/index\.html)$/.test(file)) continue;
127+
// /blog//changelog route index.html) and the version-dense migration
128+
// guide hold historical copy that is intentionally outside the
129+
// current-surface rule.
130+
if (
131+
/(?:^|\/)(?:(?:blog|changelog)(?:\.html|\/index\.html)|guide\/migration\/index\.html)$/.test(
132+
file,
133+
)
134+
) {
135+
continue;
136+
}
126137
if (/\.html$/.test(file)) await checkFile(file);
127138
}
128139
}

www/app/data/_generated-nav.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ export const navSections = [
170170
"label": "Configuration",
171171
"order": 70
172172
},
173+
{
174+
"path": "/guide/migration",
175+
"label": "Migration",
176+
"order": 75
177+
},
173178
{
174179
"path": "/guide/error-handling",
175180
"label": "Error Handling",

www/app/routes/blog/index.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,11 @@ routeSheet.replaceSync(`
220220
}
221221
`);
222222

223-
const visiblePosts = posts.filter((post) => post.frontmatter.type !== 'adr');
223+
// The dispatch index leads with the newest story: sort by frontmatter date
224+
// descending before picking featured and rows.
225+
const visiblePosts = posts
226+
.filter((post) => post.frontmatter.type !== 'adr')
227+
.sort((a, b) => b.frontmatter.date.localeCompare(a.frontmatter.date));
224228

225229
function postTags(post: typeof posts[number]): string[] {
226230
return post.frontmatter.tags ?? [];

www/app/routes/guide/configuration.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const content: Record<'en' | 'zh', GuideContent> = {
2727
{ id: 'package-config', label: 'Package config', level: 3 },
2828
],
2929
previous: { href: '/guide/api', label: 'API Routes' },
30-
next: { href: '/guide/error-handling', label: 'Error Handling' },
30+
next: { href: '/guide/migration', label: 'Migration' },
3131
cards: [
3232
{
3333
id: 'route-config',
@@ -56,7 +56,7 @@ const content: Record<'en' | 'zh', GuideContent> = {
5656
{ id: 'package-config', label: 'Package 配置', level: 3 },
5757
],
5858
previous: { href: '/guide/api', label: 'API 路由' },
59-
next: { href: '/guide/error-handling', label: '错误处理' },
59+
next: { href: '/guide/migration', label: '迁移' },
6060
cards: [
6161
{
6262
id: 'route-config',

www/app/routes/guide/error-handling.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const content: Record<'en' | 'zh', GuideContent> = {
2626
{ id: 'component-errors', label: 'Component errors', level: 3 },
2727
{ id: 'build-errors', label: 'Build errors', level: 3 },
2828
],
29-
previous: { href: '/guide/configuration', label: 'Configuration' },
29+
previous: { href: '/guide/migration', label: 'Migration' },
3030
next: { href: '/guide/islands-and-ssr', label: 'Islands and SSR' },
3131
cards: [
3232
{
@@ -55,7 +55,7 @@ const content: Record<'en' | 'zh', GuideContent> = {
5555
{ id: 'component-errors', label: '组件错误', level: 3 },
5656
{ id: 'build-errors', label: '构建错误', level: 3 },
5757
],
58-
previous: { href: '/guide/configuration', label: '配置' },
58+
previous: { href: '/guide/migration', label: '迁移' },
5959
next: { href: '/guide/islands-and-ssr', label: 'Islands 与 SSR' },
6060
cards: [
6161
{

0 commit comments

Comments
 (0)