@rangojs/router 0.0.0-experimental.110 → 0.0.0-experimental.111

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.
@@ -2049,7 +2049,7 @@ import { resolve } from "node:path";
2049
2049
  // package.json
2050
2050
  var package_default = {
2051
2051
  name: "@rangojs/router",
2052
- version: "0.0.0-experimental.110",
2052
+ version: "0.0.0-experimental.111",
2053
2053
  description: "Django-inspired RSC router with composable URL patterns",
2054
2054
  keywords: [
2055
2055
  "react",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rangojs/router",
3
- "version": "0.0.0-experimental.110",
3
+ "version": "0.0.0-experimental.111",
4
4
  "description": "Django-inspired RSC router with composable URL patterns",
5
5
  "keywords": [
6
6
  "react",
@@ -132,6 +132,15 @@
132
132
  "access": "public",
133
133
  "tag": "experimental"
134
134
  },
135
+ "scripts": {
136
+ "build": "pnpm dlx esbuild src/vite/index.ts --bundle --format=esm --outfile=dist/vite/index.js --platform=node --packages=external && mkdir -p dist/vite/plugins && cp src/vite/plugins/cloudflare-protocol-loader-hook.mjs dist/vite/plugins/cloudflare-protocol-loader-hook.mjs && pnpm dlx esbuild src/bin/rango.ts --bundle --format=esm --outfile=dist/bin/rango.js --platform=node --packages=external --banner:js='#!/usr/bin/env node' && chmod +x dist/bin/rango.js",
137
+ "prepublishOnly": "pnpm build",
138
+ "typecheck": "tsc --noEmit && tsc -p tsconfig.strict-check.json --noEmit && tsc -p tsconfig.augment-check.json --noEmit",
139
+ "test": "playwright test",
140
+ "test:ui": "playwright test --ui",
141
+ "test:unit": "vitest run",
142
+ "test:unit:watch": "vitest"
143
+ },
135
144
  "dependencies": {
136
145
  "@types/debug": "^4.1.12",
137
146
  "@vitejs/plugin-rsc": "^0.5.26",
@@ -143,12 +152,12 @@
143
152
  "devDependencies": {
144
153
  "@playwright/test": "^1.49.1",
145
154
  "@types/node": "^24.10.1",
146
- "@types/react": "^19.2.7",
147
- "@types/react-dom": "^19.2.3",
155
+ "@types/react": "catalog:",
156
+ "@types/react-dom": "catalog:",
148
157
  "esbuild": "^0.27.0",
149
158
  "jiti": "^2.6.1",
150
- "react": "^19.2.6",
151
- "react-dom": "^19.2.6",
159
+ "react": "catalog:",
160
+ "react-dom": "catalog:",
152
161
  "tinyexec": "^0.3.2",
153
162
  "typescript": "^5.3.0",
154
163
  "vitest": "^4.0.0"
@@ -167,13 +176,5 @@
167
176
  "vite": {
168
177
  "optional": true
169
178
  }
170
- },
171
- "scripts": {
172
- "build": "pnpm dlx esbuild src/vite/index.ts --bundle --format=esm --outfile=dist/vite/index.js --platform=node --packages=external && mkdir -p dist/vite/plugins && cp src/vite/plugins/cloudflare-protocol-loader-hook.mjs dist/vite/plugins/cloudflare-protocol-loader-hook.mjs && pnpm dlx esbuild src/bin/rango.ts --bundle --format=esm --outfile=dist/bin/rango.js --platform=node --packages=external --banner:js='#!/usr/bin/env node' && chmod +x dist/bin/rango.js",
173
- "typecheck": "tsc --noEmit && tsc -p tsconfig.strict-check.json --noEmit && tsc -p tsconfig.augment-check.json --noEmit",
174
- "test": "playwright test",
175
- "test:ui": "playwright test --ui",
176
- "test:unit": "vitest run",
177
- "test:unit:watch": "vitest"
178
179
  }
179
- }
180
+ }
@@ -297,7 +297,7 @@ QuickViewModal.use = () => [
297
297
 
298
298
  ## `loading()` is a single-assignment item — scope it correctly
299
299
 
300
- Most `use` items accumulate when merged: `handler.use` `middleware()` runs _and_ explicit `middleware()` runs; both `loader()` registrations apply. `loading()` is different — it mutates `entry.loading` directly, last call wins ([dsl-helpers.ts `loadingFn`](../../src/route-definition/dsl-helpers.ts)).
300
+ Most `use` items accumulate when merged: `handler.use` `middleware()` runs _and_ explicit `middleware()` runs; both `loader()` registrations apply. `loading()` is different — it mutates `entry.loading` directly, last call wins ([dsl-helpers.ts `loading`](../../src/route-definition/dsl-helpers.ts)).
301
301
 
302
302
  For pages, layouts, and intercepts that's straightforward: explicit `loading()` at the mount site replaces any `loading()` from `handler.use`. The merge order is `handler.use → explicit`, so the explicit one is the last writer and wins.
303
303
 
@@ -142,6 +142,18 @@ by reference with `ctx.isAction(Action)` (rename-safe, where `CartActions` is an
142
142
  `import * as CartActions from "./actions/cart"`); see `/typesafety` → "Stable
143
143
  identity".
144
144
 
145
+ The predicate arg carries the action's full context, not just its identity. Match
146
+ _which_ action with `ctx.isAction(addToCart)` (rename-safe); branch on _what it
147
+ returned_ with `ctx.actionResult` — the value your `"use server"` function
148
+ returned, for outcome-conditional revalidation. The arg also exposes `actionId`
149
+ (raw `path#export`), `actionUrl`, `formData`, `method`, and `stale` (cross-tab
150
+ `_rsc_stale` signal). All are `undefined` on plain navigation (no action).
151
+
152
+ ```ts
153
+ // re-render only when checkout actually succeeded; defer otherwise
154
+ revalidate((ctx) => (ctx.isAction(checkout) && ctx.actionResult?.ok) || undefined),
155
+ ```
156
+
145
157
  **The source is the source of truth.** Structure, types, and update policy are
146
158
  visible and local in the tree — read top-down, no hidden global model to hold in
147
159
  your head. A snippet earns its place only if, from the code alone, you can answer:
@@ -150,6 +162,14 @@ without leaving the call site?_ (type-safety), _what re-renders after this
150
162
  action?_ (partial rendering). If any answer needs another file, it isn't legible
151
163
  yet.
152
164
 
165
+ **Reading Rango's own source.** Rango is consumed as raw TypeScript — the
166
+ `exports` map resolves `@rangojs/router` and its subpaths to `./src/*.ts` for
167
+ both types and runtime, so a consuming app bundles Rango straight from source.
168
+ Only the `./vite` plugin entry and the CLI `bin` load from `dist/`. To confirm
169
+ any runtime or type detail against an installed copy, read the resolved source
170
+ under `node_modules/@rangojs/router/src/`, not `dist/` — the runtime does not
171
+ resolve `dist/` outside `./vite`, and it may lag `src/`.
172
+
153
173
  ## Skills
154
174
 
155
175
  Grouped by concern — read when you need to…
package/src/errors.ts CHANGED
@@ -109,6 +109,24 @@ export class BuildError extends Error {
109
109
  }
110
110
  }
111
111
 
112
+ /**
113
+ * Thrown when a route-definition DSL helper (route/layout/loader/cache/…) is
114
+ * called outside an active urls()/map() builder, so there is no
115
+ * AsyncLocalStorage build context to attach to. The message names the specific
116
+ * helper and how to fix it; the `cause` records the mechanical reason so the
117
+ * failure mode is identifiable (not conflated with an unrelated throw).
118
+ */
119
+ export class DslContextError extends Error {
120
+ name = "DslContextError" as const;
121
+ cause?: unknown;
122
+
123
+ constructor(message: string, options?: ErrorOptions) {
124
+ super(message);
125
+ Object.setPrototypeOf(this, DslContextError.prototype);
126
+ this.cause = options?.cause;
127
+ }
128
+ }
129
+
112
130
  /**
113
131
  * Thrown when a network request fails (server unreachable, no internet, etc.)
114
132
  * This error triggers the root error boundary with retry capability.
package/src/index.rsc.ts CHANGED
@@ -18,6 +18,7 @@ export {
18
18
  MiddlewareError,
19
19
  HandlerError,
20
20
  BuildError,
21
+ DslContextError,
21
22
  InvalidHandlerError,
22
23
  RouterError,
23
24
  Skip,
package/src/index.ts CHANGED
@@ -18,6 +18,7 @@ export {
18
18
  MiddlewareError,
19
19
  HandlerError,
20
20
  BuildError,
21
+ DslContextError,
21
22
  InvalidHandlerError,
22
23
  RouterError,
23
24
  Skip,