@nicnocquee/dataqueue 1.33.0 → 1.34.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/ai/build-docs-content.ts +96 -0
- package/ai/build-llms-full.ts +42 -0
- package/ai/docs-content.json +278 -0
- package/ai/rules/advanced.md +94 -0
- package/ai/rules/basic.md +90 -0
- package/ai/rules/react-dashboard.md +83 -0
- package/ai/skills/dataqueue-advanced/SKILL.md +211 -0
- package/ai/skills/dataqueue-core/SKILL.md +131 -0
- package/ai/skills/dataqueue-react/SKILL.md +189 -0
- package/dist/cli.cjs +577 -32
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +52 -2
- package/dist/cli.d.ts +52 -2
- package/dist/cli.js +575 -32
- package/dist/cli.js.map +1 -1
- package/dist/mcp-server.cjs +186 -0
- package/dist/mcp-server.cjs.map +1 -0
- package/dist/mcp-server.d.cts +32 -0
- package/dist/mcp-server.d.ts +32 -0
- package/dist/mcp-server.js +175 -0
- package/dist/mcp-server.js.map +1 -0
- package/package.json +10 -4
- package/src/cli.test.ts +65 -0
- package/src/cli.ts +56 -19
- package/src/install-mcp-command.test.ts +216 -0
- package/src/install-mcp-command.ts +185 -0
- package/src/install-rules-command.test.ts +218 -0
- package/src/install-rules-command.ts +233 -0
- package/src/install-skills-command.test.ts +176 -0
- package/src/install-skills-command.ts +124 -0
- package/src/mcp-server.test.ts +162 -0
- package/src/mcp-server.ts +231 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dataqueue-react
|
|
3
|
+
description: React SDK and Dashboard patterns for DataQueue — useJob hook, DataqueueProvider, admin dashboard.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# DataQueue React & Dashboard Patterns
|
|
7
|
+
|
|
8
|
+
## React SDK — @nicnocquee/dataqueue-react
|
|
9
|
+
|
|
10
|
+
### Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @nicnocquee/dataqueue-react
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Requires React 18+.
|
|
17
|
+
|
|
18
|
+
### useJob Hook
|
|
19
|
+
|
|
20
|
+
Poll a job's status and progress from the browser.
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
'use client';
|
|
24
|
+
import { useJob } from '@nicnocquee/dataqueue-react';
|
|
25
|
+
|
|
26
|
+
function JobTracker({ jobId }: { jobId: number }) {
|
|
27
|
+
const { status, progress, data, isLoading, error } = useJob(jobId, {
|
|
28
|
+
fetcher: (id) =>
|
|
29
|
+
fetch(`/api/jobs/${id}`)
|
|
30
|
+
.then((r) => r.json())
|
|
31
|
+
.then((d) => d.job),
|
|
32
|
+
pollingInterval: 1000,
|
|
33
|
+
onComplete: (job) => toast.success('Done!'),
|
|
34
|
+
onFailed: (job) => toast.error('Failed'),
|
|
35
|
+
onStatusChange: (newStatus, oldStatus) => {
|
|
36
|
+
console.log(`${oldStatus} → ${newStatus}`);
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
if (isLoading) return <p>Loading...</p>;
|
|
41
|
+
if (error) return <p>Error: {error.message}</p>;
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<div>
|
|
45
|
+
<p>Status: {status}</p>
|
|
46
|
+
<progress value={progress ?? 0} max={100} />
|
|
47
|
+
</div>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Polling stops automatically on terminal statuses (`completed`, `failed`, `cancelled`).
|
|
53
|
+
|
|
54
|
+
### DataqueueProvider
|
|
55
|
+
|
|
56
|
+
Avoid repeating `fetcher` and `pollingInterval` by wrapping your app in a provider.
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
'use client';
|
|
60
|
+
import { DataqueueProvider } from '@nicnocquee/dataqueue-react';
|
|
61
|
+
|
|
62
|
+
const fetcher = (id: number) =>
|
|
63
|
+
fetch(`/api/jobs/${id}`)
|
|
64
|
+
.then((r) => r.json())
|
|
65
|
+
.then((d) => d.job);
|
|
66
|
+
|
|
67
|
+
export function Providers({ children }: { children: React.ReactNode }) {
|
|
68
|
+
return (
|
|
69
|
+
<DataqueueProvider fetcher={fetcher} pollingInterval={2000}>
|
|
70
|
+
{children}
|
|
71
|
+
</DataqueueProvider>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Then use `useJob` without config:
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
const { status, progress } = useJob(jobId);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### API Route for Job Fetching (Next.js)
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
// app/api/jobs/[id]/route.ts
|
|
86
|
+
import { getJobQueue } from '@/lib/queue';
|
|
87
|
+
import { NextResponse } from 'next/server';
|
|
88
|
+
|
|
89
|
+
export async function GET(
|
|
90
|
+
_request: Request,
|
|
91
|
+
{ params }: { params: Promise<{ id: string }> },
|
|
92
|
+
) {
|
|
93
|
+
const { id } = await params;
|
|
94
|
+
const jobQueue = getJobQueue();
|
|
95
|
+
const job = await jobQueue.getJob(Number(id));
|
|
96
|
+
if (!job) {
|
|
97
|
+
return NextResponse.json({ error: 'Job not found' }, { status: 404 });
|
|
98
|
+
}
|
|
99
|
+
return NextResponse.json({ job });
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### useJob Return Value
|
|
104
|
+
|
|
105
|
+
| Field | Type | Description |
|
|
106
|
+
| ----------- | ------------------- | ------------------------------- |
|
|
107
|
+
| `data` | `JobData \| null` | Latest job data from fetcher |
|
|
108
|
+
| `status` | `JobStatus \| null` | Current job status |
|
|
109
|
+
| `progress` | `number \| null` | Progress percentage (0–100) |
|
|
110
|
+
| `isLoading` | `boolean` | True until first fetch resolves |
|
|
111
|
+
| `error` | `Error \| null` | Last fetch error |
|
|
112
|
+
|
|
113
|
+
## Dashboard — @nicnocquee/dataqueue-dashboard
|
|
114
|
+
|
|
115
|
+
### Installation
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
npm install @nicnocquee/dataqueue-dashboard
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Setup (Next.js App Router)
|
|
122
|
+
|
|
123
|
+
Create a single catch-all route:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
// app/admin/dataqueue/[[...path]]/route.ts
|
|
127
|
+
import { createDataqueueDashboard } from '@nicnocquee/dataqueue-dashboard/next';
|
|
128
|
+
import { getJobQueue, jobHandlers } from '@/lib/queue';
|
|
129
|
+
|
|
130
|
+
const { GET, POST } = createDataqueueDashboard({
|
|
131
|
+
jobQueue: getJobQueue(),
|
|
132
|
+
jobHandlers,
|
|
133
|
+
basePath: '/admin/dataqueue',
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
export { GET, POST };
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Visit `/admin/dataqueue` to open the dashboard.
|
|
140
|
+
|
|
141
|
+
The `basePath` must match the route file directory. For example, `app/jobs/dashboard/[[...path]]/route.ts` requires `basePath: '/jobs/dashboard'`.
|
|
142
|
+
|
|
143
|
+
### Dashboard Features
|
|
144
|
+
|
|
145
|
+
- Jobs list with status filter tabs, pagination, auto-refresh
|
|
146
|
+
- Job detail view with payload, error history, step data, events timeline
|
|
147
|
+
- Inline actions: cancel pending/waiting jobs, retry failed/cancelled jobs
|
|
148
|
+
- Process Jobs button for one-shot processing (useful in dev)
|
|
149
|
+
|
|
150
|
+
### Protecting the Dashboard
|
|
151
|
+
|
|
152
|
+
Wrap the handlers with your auth logic:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
const dashboard = createDataqueueDashboard({
|
|
156
|
+
jobQueue: getJobQueue(),
|
|
157
|
+
jobHandlers,
|
|
158
|
+
basePath: '/admin/dataqueue',
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
export async function GET(req: Request, ctx: any) {
|
|
162
|
+
const session = await auth();
|
|
163
|
+
if (!session?.user?.isAdmin) {
|
|
164
|
+
return new Response('Unauthorized', { status: 401 });
|
|
165
|
+
}
|
|
166
|
+
return dashboard.GET(req, ctx);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export async function POST(req: Request, ctx: any) {
|
|
170
|
+
const session = await auth();
|
|
171
|
+
if (!session?.user?.isAdmin) {
|
|
172
|
+
return new Response('Unauthorized', { status: 401 });
|
|
173
|
+
}
|
|
174
|
+
return dashboard.POST(req, ctx);
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Progress Tracking from Handlers
|
|
179
|
+
|
|
180
|
+
Report progress via `ctx.setProgress(percent)` (0–100). The value persists to the database and is exposed via `getJob()` and the `useJob` hook's `progress` field.
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
const handler = async (payload, signal, ctx) => {
|
|
184
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
185
|
+
await processChunk(chunks[i]);
|
|
186
|
+
await ctx.setProgress(Math.round(((i + 1) / chunks.length) * 100));
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
```
|