@gyoll/adapter-solid-router 0.2.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.
- package/README.md +167 -0
- package/build-output/index.cjs +1 -0
- package/build-output/index.d.ts +23 -0
- package/build-output/index.js +1 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# @gyoll/adapter-solid-router
|
|
2
|
+
|
|
3
|
+
Solid Router adapter for Gyoll file-based routing.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @gyoll/adapter-solid-router @gyoll/runtime
|
|
9
|
+
pnpm add solid-js @solidjs/router # peer dependencies
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Usage
|
|
13
|
+
|
|
14
|
+
```javascript
|
|
15
|
+
import { render } from "solid-js/web";
|
|
16
|
+
import { initFileRoutes } from "@gyoll/runtime";
|
|
17
|
+
import { solidRouterAdapter } from "@gyoll/adapter-solid-router";
|
|
18
|
+
import { routes } from "./gyoll-manifest.js";
|
|
19
|
+
|
|
20
|
+
const RouterComponent = await initFileRoutes({
|
|
21
|
+
routes,
|
|
22
|
+
adapter: solidRouterAdapter,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
render(() => <RouterComponent />, document.getElementById("root"));
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## File-Based Routing Conventions
|
|
29
|
+
|
|
30
|
+
### Supported Files
|
|
31
|
+
|
|
32
|
+
- **`page.jsx`** - Route component (lazy-loaded automatically)
|
|
33
|
+
- **`layout.jsx`** - Wraps child routes
|
|
34
|
+
- **Route groups** - `(group)` directories don't affect URLs
|
|
35
|
+
- **Dynamic segments** - `[id]` becomes `:id`
|
|
36
|
+
- **Catch-all routes** - `[...slug]` becomes `*`
|
|
37
|
+
|
|
38
|
+
### Example Structure
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
src/routes/
|
|
42
|
+
├── page.jsx → /
|
|
43
|
+
├── about/
|
|
44
|
+
│ └── page.jsx → /about
|
|
45
|
+
├── blog/
|
|
46
|
+
│ ├── layout.jsx → wraps all /blog/* routes
|
|
47
|
+
│ ├── page.jsx → /blog
|
|
48
|
+
│ └── [slug]/
|
|
49
|
+
│ └── page.jsx → /blog/:slug
|
|
50
|
+
└── (auth)/
|
|
51
|
+
├── login/
|
|
52
|
+
│ └── page.jsx → /login (group doesn't affect URL)
|
|
53
|
+
└── register/
|
|
54
|
+
└── page.jsx → /register
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Framework-Specific Behavior
|
|
58
|
+
|
|
59
|
+
### Error Handling
|
|
60
|
+
|
|
61
|
+
Solid Router does **not** support error boundaries at the route configuration level. Use Solid's `<ErrorBoundary>` component in your layouts or pages:
|
|
62
|
+
|
|
63
|
+
```jsx
|
|
64
|
+
// layout.jsx
|
|
65
|
+
import { ErrorBoundary } from "solid-js";
|
|
66
|
+
|
|
67
|
+
export default function Layout(props) {
|
|
68
|
+
return (
|
|
69
|
+
<ErrorBoundary fallback={(err) => <div>Error: {err.message}</div>}>
|
|
70
|
+
{props.children}
|
|
71
|
+
</ErrorBoundary>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Loading States
|
|
77
|
+
|
|
78
|
+
Solid Router automatically integrates with `<Suspense>` boundaries. All components are lazy-loaded, so wrap your layout with Suspense:
|
|
79
|
+
|
|
80
|
+
```jsx
|
|
81
|
+
// layout.jsx
|
|
82
|
+
import { Suspense } from "solid-js";
|
|
83
|
+
|
|
84
|
+
export default function Layout(props) {
|
|
85
|
+
return (
|
|
86
|
+
<Suspense fallback={<div>Loading...</div>}>
|
|
87
|
+
{props.children}
|
|
88
|
+
</Suspense>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Data Loading
|
|
94
|
+
|
|
95
|
+
Export a `routeData` or `loader` function from your page components:
|
|
96
|
+
|
|
97
|
+
```jsx
|
|
98
|
+
// page.jsx
|
|
99
|
+
export async function routeData() {
|
|
100
|
+
const response = await fetch("/api/data");
|
|
101
|
+
return response.json();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export default function Page(props) {
|
|
105
|
+
const data = props.data; // Access loaded data
|
|
106
|
+
return <div>{data.title}</div>;
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Unsupported Features
|
|
111
|
+
|
|
112
|
+
Due to Solid Router's design, the following Gyoll conventions are **not supported**:
|
|
113
|
+
|
|
114
|
+
- ❌ `error.jsx` - Use `<ErrorBoundary>` components instead
|
|
115
|
+
- ❌ `loading.jsx` - Use `<Suspense>` components instead
|
|
116
|
+
|
|
117
|
+
These are handled at the component level in Solid, not the route configuration level.
|
|
118
|
+
|
|
119
|
+
## API
|
|
120
|
+
|
|
121
|
+
### `solidRouterAdapter`
|
|
122
|
+
|
|
123
|
+
```javascript
|
|
124
|
+
{
|
|
125
|
+
createRouter(routes, options), // Returns Router component
|
|
126
|
+
transformRoutes(routes) // Transforms manifest to Solid format
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Router Options
|
|
131
|
+
|
|
132
|
+
Pass options to Solid Router's `<Router>`:
|
|
133
|
+
|
|
134
|
+
```javascript
|
|
135
|
+
const RouterComponent = await initFileRoutes({
|
|
136
|
+
routes,
|
|
137
|
+
adapter: solidRouterAdapter,
|
|
138
|
+
routerOptions: {
|
|
139
|
+
root: App, // Root component
|
|
140
|
+
base: "/app", // Base path
|
|
141
|
+
// ... other Router props
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Layout Wrapping
|
|
147
|
+
|
|
148
|
+
Layouts automatically wrap their child routes:
|
|
149
|
+
|
|
150
|
+
```jsx
|
|
151
|
+
// routes/dashboard/layout.jsx
|
|
152
|
+
export default function DashboardLayout(props) {
|
|
153
|
+
return (
|
|
154
|
+
<div class="dashboard">
|
|
155
|
+
<nav>Dashboard Nav</nav>
|
|
156
|
+
{props.children}
|
|
157
|
+
</div>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// routes/dashboard/page.jsx
|
|
162
|
+
export default function Dashboard() {
|
|
163
|
+
return <h1>Dashboard Home</h1>;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Result: Dashboard page wrapped in DashboardLayout
|
|
167
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var c=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var f=Object.prototype.hasOwnProperty;var y=(n,o)=>{for(var t in o)c(n,t,{get:o[t],enumerable:!0})},h=(n,o,t,e)=>{if(o&&typeof o=="object"||typeof o=="function")for(let r of d(o))!f.call(n,r)&&r!==t&&c(n,r,{get:()=>o[r],enumerable:!(e=u(o,r))||e.enumerable});return n};var R=n=>h(c({},"__esModule",{value:!0}),n);var g={};y(g,{solidRouterAdapter:()=>w});module.exports=R(g);var a=require("solid-js"),p=require("@solidjs/router");function i(n){return n.map(o=>{let t={path:o.path};if(o.component&&(t.component=(0,a.lazy)(o.component)),o.layout){let e=(0,a.lazy)(o.layout);t.component?t.component=(0,a.lazy)(async()=>{let[s,m]=await Promise.all([o.layout(),o.component()]);return{default:l=>React.createElement(s.default,null,React.createElement(m.default,{...l}))}}):t.component=e}return o.component&&(t.load=async()=>{let e=await o.component();return e.loader||e.routeData}),o.children&&o.children.length>0&&(t.children=i(o.children)),t})}var w={createRouter(n,o={}){return t=>React.createElement(p.Router,{...o},n)},transformRoutes:i,registerRoutes(n,o){throw new Error("Solid Router does not support runtime route registration. Use createRouter() instead.")}};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export namespace solidRouterAdapter {
|
|
2
|
+
/**
|
|
3
|
+
* Creates a Solid Router instance (returns component)
|
|
4
|
+
* @param {Array} routes - Transformed routes
|
|
5
|
+
* @param {object} options - Router options
|
|
6
|
+
* @returns {Function} Router component
|
|
7
|
+
*/
|
|
8
|
+
export function createRouter(routes: any[], options?: object): Function;
|
|
9
|
+
export { transformRoutes };
|
|
10
|
+
/**
|
|
11
|
+
* Register routes with existing router (if needed)
|
|
12
|
+
* @param {object} router - Existing router instance
|
|
13
|
+
* @param {Array} routes - Transformed routes
|
|
14
|
+
*/
|
|
15
|
+
export function registerRoutes(router: object, routes: any[]): never;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Transforms file-routes format to Solid Router format
|
|
19
|
+
* @param {Array} routes - Routes from manifest
|
|
20
|
+
* @returns {Array} Solid Router route objects
|
|
21
|
+
*/
|
|
22
|
+
declare function transformRoutes(routes: any[]): any[];
|
|
23
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{lazy as r}from"solid-js";import{Router as s}from"@solidjs/router";function a(n){return n.map(o=>{let t={path:o.path};if(o.component&&(t.component=r(o.component)),o.layout){let e=r(o.layout);t.component?t.component=r(async()=>{let[c,p]=await Promise.all([o.layout(),o.component()]);return{default:i=>React.createElement(c.default,null,React.createElement(p.default,{...i}))}}):t.component=e}return o.component&&(t.load=async()=>{let e=await o.component();return e.loader||e.routeData}),o.children&&o.children.length>0&&(t.children=a(o.children)),t})}var d={createRouter(n,o={}){return t=>React.createElement(s,{...o},n)},transformRoutes:a,registerRoutes(n,o){throw new Error("Solid Router does not support runtime route registration. Use createRouter() instead.")}};export{d as solidRouterAdapter};
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gyoll/adapter-solid-router",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Solid Router adapter for Gyoll file-based routing",
|
|
6
|
+
"main": "./build-output/index.cjs",
|
|
7
|
+
"module": "./build-output/index.js",
|
|
8
|
+
"types": "./build-output/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./build-output/index.d.ts",
|
|
12
|
+
"import": "./build-output/index.js",
|
|
13
|
+
"require": "./build-output/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"build-output/",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"keywords": [
|
|
22
|
+
"routing",
|
|
23
|
+
"@solidjs/router",
|
|
24
|
+
"solid-js",
|
|
25
|
+
"solid",
|
|
26
|
+
"adapter",
|
|
27
|
+
"gyoll"
|
|
28
|
+
],
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://gitlab.com/scottlindeman/public.git",
|
|
32
|
+
"directory": "01_projects/gyoll/adapters-react-router-dom"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"@gyoll/runtime": "^0.1.0",
|
|
36
|
+
"solid-js": "^1.9.10",
|
|
37
|
+
"@solidjs/router": "latest"
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"typescript": "^5.9.3"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "node build.js",
|
|
47
|
+
"types": "tsc --declaration --emitDeclarationOnly --outDir build-output",
|
|
48
|
+
"test:unit": "vitest run --dir tests/unit",
|
|
49
|
+
"test:integration": "vitest run --dir tests/integration"
|
|
50
|
+
}
|
|
51
|
+
}
|