LPDoctor's picture
Add cloudflare worker
c0dd699
import { OpenAPIRoute } from 'chanfana';
import { Context } from 'hono';
import { z } from 'zod';
import { Bindings, TaskStatus, Variables } from '../types';
export class FetchTaskSSE extends OpenAPIRoute {
schema = {
summary: 'θŽ·ε–δ»»εŠ‘ηŠΆζ€ SSE',
description: `θŽ·ε–δ»»εŠ‘ηŠΆζ€οΌŒε¦‚ζžœζˆεŠŸεŒζ—ΆθΏ”ε›žε›Ύη‰‡εœ°ε€.`,
request: {
params: z.object({
id: z.string().nanoid(),
}),
},
};
async handle(c: Context<{ Bindings: Bindings; Variables: Variables }>) {
const data = await this.getValidatedData<typeof this.schema>();
const headers: Record<string, string> = {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
};
Object.keys(headers).forEach((key) => {
c.header(key, headers[key]);
});
const { readable, writable } = new TransformStream();
const enc = new TextEncoder();
const writer = writable.getWriter();
const fetchData = async (writer: WritableStreamDefaultWriter) => {
let interval = 1000; // εˆε§‹ι—΄ιš”ζ—Άι—΄
const increment = 0; // ζ―ζ¬‘ε’žεŠ ηš„ζ—Άι—΄ι—΄ιš”
const maxInterval = 1000; // ζœ€ε€§ι—΄ιš”ζ—Άι—΄
while (true) {
await new Promise((resolve) => setTimeout(resolve, interval));
interval = Math.min(interval + increment, maxInterval);
try {
const result = await c.var.stub.getStatus(data.params.id);
if (!result.id) {
console.log('Task not found');
writer.write(enc.encode('data: {"error": "Task not found"}\n\n'));
return writer.close();
}
console.log('result:', result);
writer.write(enc.encode('data: ' + JSON.stringify(result) + '\n\n'));
if (result.status === TaskStatus.FINISHED || result.status === TaskStatus.FAILED || result.status === TaskStatus.UNKNOWN) {
console.log('Task status: ', result.status);
return writer.close();
} else {
console.log('Task not finished');
}
} catch (error) {
console.error('Error fetching data:', error);
}
}
};
fetchData(writer);
return c.body(readable);
}
}