Skip to content

Commit a6cae8e

Browse files
committed
Squashed commit of the following:
commit a5dcc79 Author: justinvdm <justinvderm@gmail.com> Date: Thu Sep 25 04:28:50 2025 +0200 Implement HMR for use client and use server directives. commit e353495 Author: justinvdm <justinvderm@gmail.com> Date: Thu Sep 25 03:14:32 2025 +0200 tests: Temporarily remove yarn classic from build matrix for E2E We are still covered by smoke tests for it. commit be1d1d2 Author: justinvdm <justinvderm@gmail.com> Date: Thu Sep 25 03:08:56 2025 +0200 tests: Avoid dev e2e tests waiting on deployments and vice versa commit 3bf3c6f Author: Justin van der Merwe <justinvderm@gmail.com> Date: Thu Sep 25 02:16:17 2025 +0200 fix: CI failures (#778) * **Concurrent Test Execution**: The test harness now provisions dev and deployment environments concurrently within the `beforeAll` hook. The `testDev` and `testDeploy` helpers were updated to use `test.concurrent`. * **Shared Browser Instance**: A `globalSetup` file was added to the Vitest configuration. It launches a single browser instance and writes its WebSocket endpoint to a temporary file. Tests now connect to this shared instance. * **Server Readiness Polling**: The `runDevServer` and `createDeployment` functions now poll their respective server URLs after the process is spawned. The functions only return after a successful `fetch` response is received. * **Refactored Polling Utility**: The `poll` function was moved to its own module and refactored to accept an options object. A `minTries` parameter was added, and all call sites were updated to use the new signature. commit adf0427 Author: justinvdm <justinvderm@gmail.com> Date: Wed Sep 24 17:32:41 2025 +0200 Remove retry script from e2e tests. commit ad7fa16 Author: Justin van der Merwe <justinvderm@gmail.com> Date: Wed Sep 24 15:30:19 2025 +0200 docs: Document API Stability and Compatibility (#757) To prepare for a 1.0 beta release, we need to communicate which parts of the SDK are stable and which are experimental. This update establishes a system for marking experimental APIs directly within the documentation. We've implemented a convention where experimental pages or specific functions are marked with an 'Experimental' badge. This is handled by adding an `experimental: true` flag to the frontmatter of relevant documentation pages, which then conditionally renders the badge in the page title. This provides clear, inline guidance to users about the stability of different features. commit 57c99a9 Author: justinvdm <justinvderm@gmail.com> Date: Wed Sep 24 14:06:02 2025 +0200 Configure vitest with concurrency and timeout settings. commit 5b91076 Author: justinvdm <justinvderm@gmail.com> Date: Wed Sep 24 13:23:02 2025 +0200 tests: Cleanup stale workers on a job
1 parent 51e08cb commit a6cae8e

Some content is hidden

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

57 files changed

+9465
-708
lines changed

.cursor/rules/user/justin.mdc

Lines changed: 121 additions & 0 deletions
Large diffs are not rendered by default.

.github/workflows/playground-e2e-tests.yml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ on:
3838
- pnpm
3939
- npm
4040
- yarn
41-
- yarn-classic
41+
# todo(justinvdm, 25 Sep 2025): Re-enable yarn-classic once E2E tests are fixed
42+
# - yarn-classic
4243

4344
concurrency:
4445
group: ${{ github.workflow }}-${{ github.ref }}
@@ -63,7 +64,8 @@ jobs:
6364
PM_INPUT=${{ github.event.inputs.package-manager }}
6465
6566
[ "$OS_INPUT" == "all" ] && OS_LIST='ubuntu-latest macos-latest' || OS_LIST=$OS_INPUT
66-
[ "$PM_INPUT" == "all" ] && PM_LIST='pnpm npm yarn yarn-classic' || PM_LIST=$PM_INPUT
67+
# todo(justinvdm, 25 Sep 2025): Re-enable yarn-classic once E2E tests are fixed
68+
[ "$PM_INPUT" == "all" ] && PM_LIST='pnpm npm yarn' || PM_LIST=$PM_INPUT
6769
6870
JSON_ARRAY="[]"
6971
for o in $OS_LIST; do
@@ -73,7 +75,8 @@ jobs:
7375
done
7476
echo "matrix={\"include\":${JSON_ARRAY}}" >> $GITHUB_OUTPUT
7577
else
76-
echo 'matrix={"include":[{"os":"ubuntu-latest","package-manager":"pnpm"},{"os":"ubuntu-latest","package-manager":"npm"},{"os":"ubuntu-latest","package-manager":"yarn"},{"os":"ubuntu-latest","package-manager":"yarn-classic"},{"os":"macos-latest","package-manager":"pnpm"},{"os":"macos-latest","package-manager":"npm"},{"os":"macos-latest","package-manager":"yarn"},{"os":"macos-latest","package-manager":"yarn-classic"}]}' >> $GITHUB_OUTPUT
78+
# todo(justinvdm, 25 Sep 2025): Re-enable yarn-classic once E2E tests are fixed
79+
echo 'matrix={"include":[{"os":"ubuntu-latest","package-manager":"pnpm"},{"os":"ubuntu-latest","package-manager":"npm"},{"os":"ubuntu-latest","package-manager":"yarn"},{"os":"macos-latest","package-manager":"pnpm"},{"os":"macos-latest","package-manager":"npm"},{"os":"macos-latest","package-manager":"yarn"}]}' >> $GITHUB_OUTPUT
7780
fi
7881
7982
playground-e2e:
@@ -116,7 +119,7 @@ jobs:
116119
shell: bash
117120
run: |
118121
pnpm install
119-
./scripts/retry.sh pnpm test:e2e
122+
pnpm test:e2e
120123
env:
121124
CI: 1
122125
PACKAGE_MANAGER: ${{ matrix.package-manager }}

.github/workflows/smoke-test-starters.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ jobs:
122122
id: smoke-test
123123
shell: bash
124124
run: |
125-
./scripts/retry.sh ./sdk/scripts/ci-smoke-test.sh --starter "${{ matrix.starter }}" --package-manager "${{ matrix.package-manager }}"
125+
./sdk/scripts/ci-smoke-test.sh --starter "${{ matrix.starter }}" --package-manager "${{ matrix.package-manager }}"
126126
env:
127127
CHROME_BIN: ${{ steps.setup-chrome.outputs.chrome-path }}
128128

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,4 +188,5 @@ smoke-test-artifacts
188188
starters/standard/.cursor/rules/*
189189
starters/standard/.pnpm-store
190190

191+
# Cursor User Rules
191192
.cursor/rules/user
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
# Work Log: 2025-09-20 - Documenting API Stability
2+
3+
## 1. Problem Definition & Goal
4+
5+
The SDK's public APIs lack clear documentation regarding their stability. Users, particularly those considering the SDK for production use, have no way of knowing which features are considered stable and which are experimental and subject to breaking changes. This can lead to user friction and uncertainty.
6+
7+
The goal is to investigate the SDK's public API surface, research best practices for communicating API stability, and implement a clear, maintainable documentation system that explicitly labels features as "Stable" or "Experimental".
8+
9+
## 2. Investigation: Discovering the Public API
10+
11+
The first step was to create a comprehensive list of all public-facing APIs. This was a multi-step process.
12+
13+
### 2.1. `package.json` Exports
14+
15+
I started by analyzing the `exports` map in `sdk/package.json`. This provided the primary, official entry points for the package. I filtered out internal entry points (those prefixed with `__`) to focus on the intended public surface.
16+
17+
### 2.2. Source Code Analysis
18+
19+
I then traced each of these entry points back to their source files in `sdk/src/` to determine exactly what functions, classes, and types were being re-exported. This analysis produced a detailed list of every public API.
20+
21+
## 3. The Solution: A Hybrid Documentation Strategy
22+
23+
After identifying the APIs, the next step was to determine the best way to communicate their stability. The final chosen strategy uses a central page to define stability and inline labels to mark specific experimental APIs.
24+
25+
### 3.1. The Strategy
26+
27+
1. **A Central "API Stability" Page:** A page at `docs/src/content/docs/stability.mdx` defines what "Stable" and "Experimental" mean. It establishes the rule that all APIs are considered stable by default unless marked with an inline "Experimental" label.
28+
2. **Inline Labels:** For APIs classified as experimental, a small, inline `<Badge>` component is placed directly next to the API's title in the documentation. This provides clear, in-context warnings without large, intrusive banners.
29+
30+
### 3.2. Implementation Details
31+
32+
- Created `docs/src/content/docs/stability.mdx`.
33+
- Added a link to the new page in the sidebar in `docs/astro.config.mjs`.
34+
- Added experimental labels to the documentation for `renderToString`, `renderToStream`, `initClientNavigation`, and `Turnstile`.
35+
36+
## 4. Final Public API List & Stability Classification
37+
38+
This is the final, revised list of public APIs based on user feedback, along with their stability and documentation status.
39+
40+
| Entrypoint | API | Stability | Documented? |
41+
| ---------------------- | ------------------------- | -------------- | --------------------------------------------------- |
42+
| **`rwsdk/vite`** | `redwood()` | Stable | Yes |
43+
| **`rwsdk/worker`** | `defineApp()` | Stable | Yes |
44+
| | `renderToString()` | **Experimental** | Yes (`core/react-server-components.mdx`) |
45+
| | `renderToStream()` | **Experimental** | Yes (`core/react-server-components.mdx`) |
46+
| | `registerServerReference` | Internal | No |
47+
| | `rscActionHandler` | Internal | No |
48+
| | `getRequestInfo` | Internal | No |
49+
| **`rwsdk/client`** | `initClient()` | Stable | Yes (`reference/sdk-client.mdx`) |
50+
| | `initClientNavigation()` | **Experimental** | Yes (`guides/frontend/client-side-nav.mdx`) |
51+
| | `createServerReference` | Internal | No |
52+
| **`rwsdk/router`** | (all exports) | Stable | Yes (`core/routing.mdx`, `reference/sdk-router.mdx`)|
53+
| **`rwsdk/auth`** | (all exports) | Stable | Yes (`core/authentication.mdx`) |
54+
| **`rwsdk/turnstile`** | (all exports) | **Experimental** | Yes (`core/authentication.mdx`) |
55+
| **`rwsdk/db`** | (all exports) | **Experimental** | Yes (`core/database.mdx`, `core/database-do.mdx`) |
56+
| **`rwsdk/realtime/*`** | (all exports) | **Experimental** | Yes (`core/realtime.mdx`) |
57+
| **`rwsdk/debug`** | `debug()` | **Experimental** | No |
58+
| **`rwsdk/constants`** | `IS_DEV` | Internal | No |
59+
60+
## 5. Badge Rendering Fix
61+
62+
**Issue**: Badges in page titles were rendering as plain text instead of HTML components.
63+
64+
**Root Cause**: JSX components (`<Badge>`) were placed in frontmatter `title` fields, which are YAML metadata and don't support JSX rendering.
65+
66+
**Solution**: Moved badges from frontmatter titles to H1 headings in the content:
67+
- `database.mdx`: `title: Database (D1) <Badge...>``# Database (D1) <Badge...>`
68+
- `database-do.mdx`: `title: Database (Durable Objects) <Badge...>``# Database (Durable Objects) <Badge...>`
69+
- `realtime.mdx`: `title: Realtime <Badge...>``# Realtime <Badge...>`
70+
71+
This allows the badges to render properly as components while maintaining the visual hierarchy.
72+
73+
## 6. MDX Parsing Error Fix
74+
75+
**Issue**: MDX error in `core/react-server-components.mdx` - "Plugin 'Code caption' caused an error in its 'preprocessCode' hook. Error message: Expected a valid non-empty non-negative number[], but got [-1]"
76+
77+
**Root Cause**: Multiple syntax issues in the MDX file:
78+
1. `---` lines inside code blocks (lines 53-56 and 80-82) breaking the MDX parser
79+
2. Missing experimental badges for `renderToStream()` and `renderToString()`
80+
3. Incomplete code block at the end of the file
81+
82+
**Solution**:
83+
- Moved explanatory text outside of code blocks
84+
- Added experimental badge to the combined `renderToStream()` and `renderToString()` section
85+
- Fixed malformed code block syntax
86+
- Removed stray closing ``` at the end
87+
88+
The page now loads successfully without MDX parsing errors.
89+
90+
## 7. Duplicate Title Fix
91+
92+
**Issue**: Pages with experimental badges were showing duplicate titles (e.g., "Realtime" followed by "Realtime Experimental").
93+
94+
**Root Cause**: Starlight automatically generates an H1 from the frontmatter `title`, and we were adding another H1 with the badge (`# Realtime <Badge>`), creating duplicate headings.
95+
96+
**Solution**: Removed the manual H1 headings and placed the badge as the first element in the content, right after the auto-generated title. This provides clear visual indication without duplication:
97+
- `realtime.mdx`: Removed `# Realtime <Badge>`, kept just `<Badge>` at the top
98+
- `database.mdx`: Removed `# Database (D1) <Badge>`, kept just `<Badge>` at the top
99+
- `database-do.mdx`: Removed `# Database (Durable Objects) <Badge>`, kept just `<Badge>` at the top
100+
101+
All pages now display correctly with single titles and prominent experimental badges.
102+
103+
## 9. Schema Extension Solution
104+
105+
**Issue**: The `experimental` frontmatter field was not being recognized by Starlight, showing as `undefined` in the custom PageTitle component.
106+
107+
**Root Cause**: Starlight's default `docsSchema()` only includes predefined fields. Custom frontmatter fields need to be explicitly defined in the content schema.
108+
109+
**Solution**: Extended Starlight's schema in `content.config.ts`:
110+
```typescript
111+
schema: docsSchema({
112+
extend: z.object({
113+
experimental: z.boolean().optional(),
114+
}),
115+
}),
116+
```
117+
118+
**Result**: The experimental badges now render correctly on all experimental pages:
119+
- `realtime.mdx`: Shows "Realtime Experimental"
120+
- `database.mdx`: Shows "Database (D1) Experimental"
121+
- `database-do.mdx`: Shows "Database (Durable Objects) Experimental"
122+
- Non-experimental pages (e.g., routing) correctly show no badges
123+
124+
The component override system is working perfectly, providing a clean, maintainable solution for marking experimental APIs.
125+
126+
## 8. Proper Badge Integration via Component Override
127+
128+
**Issue**: The previous badge placement approaches (frontmatter titles, manual H1s, separate elements) didn't look quite right visually and weren't integrated properly into Starlight's title rendering.
129+
130+
**Solution**: Implemented Starlight's component override system to customize title rendering:
131+
132+
1. **Created custom PageTitle component** (`src/components/PageTitle.astro`):
133+
- Accesses frontmatter via `Astro.locals.starlightRoute.entry.data`
134+
- Conditionally renders badge when `experimental: true` is set
135+
- Maintains proper styling and accessibility (id="_top")
136+
137+
2. **Configured component override** in `astro.config.mjs`:
138+
- Added `components: { PageTitle: './src/components/PageTitle.astro' }`
139+
- Overrides Starlight's default title rendering
140+
141+
3. **Updated frontmatter approach**:
142+
- Added `experimental: true` field to experimental pages
143+
- Removed manual badge elements from content
144+
- Clean separation of metadata and content
145+
146+
**Result**: Badges now render seamlessly integrated into the page titles, looking natural and professional without duplication or visual inconsistencies. The approach is maintainable and follows Starlight's recommended patterns.
147+
148+
## 10. Missing Import Fix
149+
150+
**Issue**: `authentication.mdx` was throwing a runtime error: "importedCodeStandardWorker is not defined"
151+
152+
**Root Cause**: The file was using `importedCodeStandardWorker` in a code block but missing the import statement.
153+
154+
**Solution**: Added the missing import:
155+
```typescript
156+
import importedCodeStandardWorker from "../../../../../starters/standard/src/worker.tsx?raw";
157+
```
158+
159+
**Result**: Authentication page now loads successfully without runtime errors.
160+
161+
## 11. Improved Badge Placement for Turnstile
162+
163+
**Issue**: The experimental badge for Turnstile was placed inline with the Cloudflare documentation link, making it less contextually clear.
164+
165+
**Solution**: Moved the experimental badge to a more appropriate location:
166+
- **Removed** badge from inline text: `[Cloudflare Turnstile](https://developers.cloudflare.com/turnstile/) <Badge...>`
167+
- **Added** badge to section heading: `## Optional: Bot Protection with Turnstile <Badge text="Experimental" type="caution" />`
168+
169+
**Result**: The experimental badge now clearly indicates that the entire Turnstile feature is experimental, rather than just the documentation link.
170+
171+
## 12. Individual API Method Badge Placement
172+
173+
**Issue**: The experimental badge for `renderToStream()` and `renderToString()` was placed on a combined heading, making it unclear which specific methods were experimental.
174+
175+
**Solution**: Moved experimental badges to individual API method signatures:
176+
- **Changed** from: `### renderToStream() and renderToString() <Badge...>`
177+
- **To**: Individual badges on each method:
178+
- `#### renderToStream(element[, options]): Promise<ReadableStream> <Badge text="Experimental" type="caution" />`
179+
- `#### renderToString(element[, options]): Promise<string> <Badge text="Experimental" type="caution" />`
180+
181+
**Result**: Each API method is now clearly marked as experimental at the point of reference, providing better granular information to developers.
182+
183+
## 13. Missing Import Fix for Compatibility Page
184+
185+
**Issue**: `compatibility.mdx` was throwing a runtime error: "Expected component Aside to be defined: you likely forgot to import, pass, or provide it."
186+
187+
**Root Cause**: The file was using the `<Aside>` component but missing the import statement.
188+
189+
**Solution**: Added the missing import:
190+
```typescript
191+
import { Aside } from "@astrojs/starlight/components";
192+
```
193+
194+
**Result**: Compatibility page now loads successfully without runtime errors.
195+
196+
## PR Description
197+
198+
To prepare for a 1.0 beta release, we need to communicate which parts of the SDK are stable and which are experimental. This update establishes a system for marking experimental APIs directly within the documentation. We've implemented a convention where experimental pages or specific functions are marked with an 'Experimental' badge. This is handled by adding an `experimental: true` flag to the frontmatter of relevant documentation pages, which then conditionally renders the badge in the page title. This provides clear, inline guidance to users about the stability of different features.

0 commit comments

Comments
 (0)