بنقرة واحدة
dataqueue-react
React SDK and Dashboard patterns for DataQueue — useJob hook, DataqueueProvider, admin dashboard.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
React SDK and Dashboard patterns for DataQueue — useJob hook, DataqueueProvider, admin dashboard.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
Advanced DataQueue patterns — job dependencies, step memoization, waits, tokens, cron, timeouts, tags, idempotency.
Core patterns for using @nicnocquee/dataqueue — typed PayloadMap, init, handlers, adding and processing jobs.
استنادا إلى تصنيف SOC المهني
| name | dataqueue-react |
| description | React SDK and Dashboard patterns for DataQueue — useJob hook, DataqueueProvider, admin dashboard. |
npm install @nicnocquee/dataqueue-react
Requires React 18+.
Poll a job's status and progress from the browser.
'use client';
import { useJob } from '@nicnocquee/dataqueue-react';
function JobTracker({ jobId }: { jobId: number }) {
const { status, progress, data, isLoading, error } = useJob(jobId, {
fetcher: (id) =>
fetch(`/api/jobs/${id}`)
.then((r) => r.json())
.then((d) => d.job),
pollingInterval: 1000,
onComplete: (job) => toast.success('Done!'),
onFailed: (job) => toast.error('Failed'),
onStatusChange: (newStatus, oldStatus) => {
console.log(`${oldStatus} → ${newStatus}`);
},
});
if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error: {error.message}</p>;
return (
<div>
<p>Status: {status}</p>
<progress value={progress ?? 0} max={100} />
</div>
);
}
Polling stops automatically on terminal statuses (completed, failed, cancelled).
Avoid repeating fetcher and pollingInterval by wrapping your app in a provider.
'use client';
import { DataqueueProvider } from '@nicnocquee/dataqueue-react';
const fetcher = (id: number) =>
fetch(`/api/jobs/${id}`)
.then((r) => r.json())
.then((d) => d.job);
export function Providers({ children }: { children: React.ReactNode }) {
return (
<DataqueueProvider fetcher={fetcher} pollingInterval={2000}>
{children}
</DataqueueProvider>
);
}
Then use useJob without config:
const { status, progress } = useJob(jobId);
// app/api/jobs/[id]/route.ts
import { getJobQueue } from '@/lib/queue';
import { NextResponse } from 'next/server';
export async function GET(
_request: Request,
{ params }: { params: Promise<{ id: string }> },
) {
const { id } = await params;
const jobQueue = getJobQueue();
const job = await jobQueue.getJob(Number(id));
if (!job) {
return NextResponse.json({ error: 'Job not found' }, { status: 404 });
}
return NextResponse.json({ job });
}
| Field | Type | Description |
|---|---|---|
data | JobData | null | Latest job data from fetcher |
status | JobStatus | null | Current job status |
progress | number | null | Progress percentage (0–100) |
output | unknown | null | Handler output from ctx.setOutput() or return value |
isLoading | boolean | True until first fetch resolves |
error | Error | null | Last fetch error |
npm install @nicnocquee/dataqueue-dashboard
Create a single catch-all route:
// app/admin/dataqueue/[[...path]]/route.ts
import { createDataqueueDashboard } from '@nicnocquee/dataqueue-dashboard/next';
import { getJobQueue, jobHandlers } from '@/lib/queue';
const { GET, POST } = createDataqueueDashboard({
jobQueue: getJobQueue(),
jobHandlers,
basePath: '/admin/dataqueue',
});
export { GET, POST };
Visit /admin/dataqueue to open the dashboard.
The basePath must match the route file directory. For example, app/jobs/dashboard/[[...path]]/route.ts requires basePath: '/jobs/dashboard'.
Wrap the handlers with your auth logic:
const dashboard = createDataqueueDashboard({
jobQueue: getJobQueue(),
jobHandlers,
basePath: '/admin/dataqueue',
});
export async function GET(req: Request, ctx: any) {
const session = await auth();
if (!session?.user?.isAdmin) {
return new Response('Unauthorized', { status: 401 });
}
return dashboard.GET(req, ctx);
}
export async function POST(req: Request, ctx: any) {
const session = await auth();
if (!session?.user?.isAdmin) {
return new Response('Unauthorized', { status: 401 });
}
return dashboard.POST(req, ctx);
}
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.
const handler = async (payload, signal, ctx) => {
for (let i = 0; i < chunks.length; i++) {
await processChunk(chunks[i]);
await ctx.setProgress(Math.round(((i + 1) / chunks.length) * 100));
}
};
Store results via ctx.setOutput(data) or by returning a value from the handler. Exposed via getJob() (output field) and the useJob hook's output property. If both are used, ctx.setOutput() takes precedence.
const handler = async (payload, signal, ctx) => {
const result = await doWork(payload);
return { url: result.downloadUrl }; // stored as output
};