@demokit-ai/remix 0.0.2 → 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 +203 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# @demokit-ai/remix
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+
|
|
6
|
+
Remix adapter for DemoKit - demo-aware loader and action mocking for Remix applications.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @demokit-ai/remix @demokit-ai/core @demokit-ai/react
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- **Demo Loaders** - Wrap loaders to return fixtures in demo mode
|
|
17
|
+
- **Demo Actions** - Wrap actions with method-specific fixtures
|
|
18
|
+
- **Route Configuration** - Apply demo mode to entire route trees
|
|
19
|
+
- **Provider Pattern** - Centralized fixture management
|
|
20
|
+
- **Server-Side Support** - Works with Remix server rendering
|
|
21
|
+
- Full TypeScript support
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
### Wrap Individual Loaders
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
// app/routes/users.tsx
|
|
29
|
+
import { createDemoLoader } from '@demokit-ai/remix'
|
|
30
|
+
|
|
31
|
+
export const loader = createDemoLoader({
|
|
32
|
+
loader: async () => {
|
|
33
|
+
return db.users.findMany()
|
|
34
|
+
},
|
|
35
|
+
isEnabled: () => process.env.DEMO_MODE === 'true',
|
|
36
|
+
fixture: [
|
|
37
|
+
{ id: '1', name: 'Demo User', email: 'demo@example.com' },
|
|
38
|
+
{ id: '2', name: 'Another User', email: 'another@example.com' },
|
|
39
|
+
],
|
|
40
|
+
delay: 100,
|
|
41
|
+
})
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Wrap Individual Actions
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
// app/routes/users.$id.tsx
|
|
48
|
+
import { createDemoAction } from '@demokit-ai/remix'
|
|
49
|
+
|
|
50
|
+
export const action = createDemoAction({
|
|
51
|
+
action: async ({ request, params }) => {
|
|
52
|
+
const formData = await request.formData()
|
|
53
|
+
return db.users.update({
|
|
54
|
+
where: { id: params.id },
|
|
55
|
+
data: Object.fromEntries(formData),
|
|
56
|
+
})
|
|
57
|
+
},
|
|
58
|
+
isEnabled: () => process.env.DEMO_MODE === 'true',
|
|
59
|
+
fixture: {
|
|
60
|
+
PUT: ({ params, formData }) => ({
|
|
61
|
+
id: params.id,
|
|
62
|
+
...Object.fromEntries(formData!),
|
|
63
|
+
updated: true,
|
|
64
|
+
}),
|
|
65
|
+
DELETE: ({ params }) => ({
|
|
66
|
+
id: params.id,
|
|
67
|
+
deleted: true,
|
|
68
|
+
}),
|
|
69
|
+
},
|
|
70
|
+
})
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Route Configuration Wrapping
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
// app/root.tsx
|
|
77
|
+
import { createDemoRoutes, defineLoaderFixtures, defineActionFixtures } from '@demokit-ai/remix'
|
|
78
|
+
|
|
79
|
+
const loaders = defineLoaderFixtures({
|
|
80
|
+
'/users': [
|
|
81
|
+
{ id: '1', name: 'Demo User' },
|
|
82
|
+
{ id: '2', name: 'Another User' },
|
|
83
|
+
],
|
|
84
|
+
'/users/:id': ({ params }) => ({
|
|
85
|
+
id: params.id,
|
|
86
|
+
name: 'Demo User',
|
|
87
|
+
email: 'demo@example.com',
|
|
88
|
+
}),
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
const actions = defineActionFixtures({
|
|
92
|
+
'/users/:id': {
|
|
93
|
+
PUT: ({ formData }) => ({ updated: true }),
|
|
94
|
+
DELETE: ({ params }) => ({ deleted: true, id: params.id }),
|
|
95
|
+
},
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
// Apply to routes
|
|
99
|
+
const routes = createDemoRoutes(originalRoutes, {
|
|
100
|
+
isEnabled: () => process.env.DEMO_MODE === 'true',
|
|
101
|
+
loaders,
|
|
102
|
+
actions,
|
|
103
|
+
delay: 100,
|
|
104
|
+
})
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Provider Pattern
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
// app/root.tsx
|
|
111
|
+
import { DemoRemixProvider, useDemoRemix } from '@demokit-ai/remix'
|
|
112
|
+
|
|
113
|
+
export default function App() {
|
|
114
|
+
return (
|
|
115
|
+
<DemoRemixProvider
|
|
116
|
+
enabled={process.env.DEMO_MODE === 'true'}
|
|
117
|
+
loaders={{
|
|
118
|
+
'/users': [{ id: '1', name: 'Demo User' }],
|
|
119
|
+
}}
|
|
120
|
+
actions={{
|
|
121
|
+
'/users': ({ formData }) => ({ id: '1', ...Object.fromEntries(formData!) }),
|
|
122
|
+
}}
|
|
123
|
+
>
|
|
124
|
+
<Outlet />
|
|
125
|
+
</DemoRemixProvider>
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function DemoControls() {
|
|
130
|
+
const { enabled, toggle, setLoader } = useDemoRemix()
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<div>
|
|
134
|
+
<button onClick={toggle}>Demo: {enabled ? 'ON' : 'OFF'}</button>
|
|
135
|
+
<button onClick={() => setLoader('/custom', () => ({ custom: true }))}>
|
|
136
|
+
Add Custom
|
|
137
|
+
</button>
|
|
138
|
+
</div>
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Server-Side Demo Detection
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
// app/routes/api.users.tsx
|
|
147
|
+
import { isDemoRequest, getDemoScenario } from '@demokit-ai/remix/server'
|
|
148
|
+
|
|
149
|
+
export async function loader({ request }: LoaderFunctionArgs) {
|
|
150
|
+
if (isDemoRequest(request)) {
|
|
151
|
+
const scenario = getDemoScenario(request)
|
|
152
|
+
return json(demoFixtures[scenario])
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return json(await db.users.findMany())
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## API Reference
|
|
160
|
+
|
|
161
|
+
### `createDemoLoader(options)`
|
|
162
|
+
|
|
163
|
+
Create a demo-aware loader function.
|
|
164
|
+
|
|
165
|
+
Options:
|
|
166
|
+
- `loader` - The real loader function
|
|
167
|
+
- `isEnabled` - Function to check if demo mode is enabled
|
|
168
|
+
- `fixture` - Demo fixture (static value or function)
|
|
169
|
+
- `delay` - Simulated delay in milliseconds
|
|
170
|
+
- `onDemo` - Callback when demo mode is used
|
|
171
|
+
|
|
172
|
+
### `createDemoAction(options)`
|
|
173
|
+
|
|
174
|
+
Create a demo-aware action function.
|
|
175
|
+
|
|
176
|
+
Options:
|
|
177
|
+
- `action` - The real action function
|
|
178
|
+
- `isEnabled` - Function to check if demo mode is enabled
|
|
179
|
+
- `fixture` - Demo fixture (static, function, or method-specific handlers)
|
|
180
|
+
- `delay` - Simulated delay in milliseconds
|
|
181
|
+
- `onDemo` - Callback when demo mode is used
|
|
182
|
+
|
|
183
|
+
### `DemoRemixProvider`
|
|
184
|
+
|
|
185
|
+
Props:
|
|
186
|
+
- `enabled` - Whether demo mode is enabled
|
|
187
|
+
- `loaders` - Loader fixtures by path
|
|
188
|
+
- `actions` - Action fixtures by path
|
|
189
|
+
- `delay` - Default delay in milliseconds
|
|
190
|
+
|
|
191
|
+
### `useDemoRemix()`
|
|
192
|
+
|
|
193
|
+
Returns:
|
|
194
|
+
- `enabled` - Whether demo mode is enabled
|
|
195
|
+
- `toggle()` - Toggle demo mode
|
|
196
|
+
- `setLoader(path, handler)` - Set a loader fixture
|
|
197
|
+
- `removeLoader(path)` - Remove a loader fixture
|
|
198
|
+
- `setAction(path, handler)` - Set an action fixture
|
|
199
|
+
- `removeAction(path)` - Remove an action fixture
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
MIT
|