Initial Commit
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
import VCLight, { VCLightApp, VCLightRequest, VCLightResponse } from "vclight";
|
||||
import router from "./router";
|
||||
import "./initRouter";
|
||||
|
||||
const app = new VCLight();
|
||||
app.use(router);
|
||||
app.use({
|
||||
async post(request: VCLightRequest, response: VCLightResponse, app: VCLightApp) {},
|
||||
async process(request: VCLightRequest, response: VCLightResponse, app: VCLightApp) {
|
||||
response.headers["access-control-allow-origin"] = "*";
|
||||
response.headers["access-control-allow-headers"] = "*";
|
||||
}
|
||||
});
|
||||
export default app;
|
||||
@@ -0,0 +1,45 @@
|
||||
import Poll from "../../utils/poll";
|
||||
import CONST from "../../const";
|
||||
|
||||
type Polls<T> = { value: Poll<T>[]; cache: T };
|
||||
|
||||
export const coursePolls: Polls<CoursePollData> = {
|
||||
value: [],
|
||||
cache: {
|
||||
questionID: "",
|
||||
answer: "",
|
||||
flag: false
|
||||
}
|
||||
};
|
||||
export const deepSeekPolls: Polls<DeepSeekPollData> = {
|
||||
value: [],
|
||||
cache: {
|
||||
questionID: "",
|
||||
question: "",
|
||||
flag: false
|
||||
}
|
||||
};
|
||||
|
||||
export interface CoursePollData {
|
||||
questionID: string;
|
||||
answer: string;
|
||||
flag: boolean;
|
||||
}
|
||||
|
||||
export interface DeepSeekPollData {
|
||||
questionID: string;
|
||||
question: string;
|
||||
flag: boolean;
|
||||
}
|
||||
|
||||
export function pollCourse() {
|
||||
const poll = new Poll<CoursePollData>(CONST.pollInterval);
|
||||
coursePolls.value.push(poll);
|
||||
return poll.wait();
|
||||
}
|
||||
|
||||
export function pollDeepSeek() {
|
||||
const poll = new Poll<DeepSeekPollData>(CONST.pollInterval);
|
||||
deepSeekPolls.value.push(poll);
|
||||
return poll.wait();
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
import "./routers/answer";
|
||||
import "./routers/polling";
|
||||
import "./routers/question";
|
||||
import "./routers/test";
|
||||
@@ -0,0 +1,4 @@
|
||||
import VCLightRouter from "@vclight/router";
|
||||
|
||||
const router = new VCLightRouter();
|
||||
export default router;
|
||||
@@ -0,0 +1,27 @@
|
||||
import router from "../router";
|
||||
import { coursePolls } from "../data/polls";
|
||||
|
||||
router.on("/answer", async function (data, response) {
|
||||
console.log(data.body);
|
||||
const { questionID, answer } = data.body;
|
||||
response.contentType = "application/json";
|
||||
if (typeof questionID != "string" || typeof answer != "string") {
|
||||
response.response = {
|
||||
status: "error",
|
||||
message: "questionID and answer are required"
|
||||
};
|
||||
return;
|
||||
}
|
||||
console.log("Received answer", questionID, answer);
|
||||
const polls = coursePolls.value;
|
||||
const pollData = {
|
||||
questionID: questionID,
|
||||
answer: answer,
|
||||
flag: true
|
||||
};
|
||||
coursePolls.value = [];
|
||||
polls.forEach((poll) => {
|
||||
poll.resolve(pollData);
|
||||
});
|
||||
coursePolls.cache = pollData;
|
||||
});
|
||||
@@ -0,0 +1,48 @@
|
||||
import router from "../router";
|
||||
import {
|
||||
CoursePollData,
|
||||
coursePolls,
|
||||
DeepSeekPollData,
|
||||
deepSeekPolls,
|
||||
pollCourse,
|
||||
pollDeepSeek
|
||||
} from "../data/polls";
|
||||
import Poll from "../../utils/poll";
|
||||
|
||||
router.on("/polling", async function (data, response) {
|
||||
if (data.method == "OPTIONS") {
|
||||
return;
|
||||
}
|
||||
if (data.query.env == "course" || data.query.env == "deepseek") {
|
||||
const polls = data.query.env == "course" ? coursePolls : deepSeekPolls;
|
||||
|
||||
if (polls.cache.flag) {
|
||||
response.response = {
|
||||
status: "success",
|
||||
data: JSON.parse(JSON.stringify(polls.cache))
|
||||
};
|
||||
polls.cache.flag = false;
|
||||
console.log("Polling cache", polls.cache);
|
||||
return;
|
||||
}
|
||||
|
||||
let pollData: CoursePollData | DeepSeekPollData | typeof Poll.TIMEOUT = await (data.query
|
||||
.env == "course"
|
||||
? pollCourse()
|
||||
: pollDeepSeek());
|
||||
response.contentType = "application/json";
|
||||
if (pollData == Poll.TIMEOUT) {
|
||||
response.response = {
|
||||
status: "nothing"
|
||||
};
|
||||
return;
|
||||
}
|
||||
pollData = <CoursePollData | DeepSeekPollData>pollData;
|
||||
pollData.flag = false;
|
||||
response.response = {
|
||||
status: "success",
|
||||
data: pollData
|
||||
};
|
||||
console.log("Polling data", pollData);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
import router from "../router";
|
||||
import { coursePolls, deepSeekPolls } from "../data/polls";
|
||||
|
||||
router.on("/question", async function (data, response) {
|
||||
const { question } = data.body;
|
||||
const questionId = Math.random().toString(16).slice(2, 8);
|
||||
response.contentType = "application/json";
|
||||
if (typeof question != "string") {
|
||||
response.response = {
|
||||
status: "error",
|
||||
message: "questionId is required"
|
||||
};
|
||||
return;
|
||||
}
|
||||
console.log("Received question", question);
|
||||
const polls = deepSeekPolls.value;
|
||||
coursePolls.value = [];
|
||||
const pollData = {
|
||||
questionID: questionId,
|
||||
question: question,
|
||||
flag: true
|
||||
};
|
||||
polls.forEach((poll) => {
|
||||
poll.resolve(pollData);
|
||||
});
|
||||
deepSeekPolls.cache = pollData;
|
||||
response.response = {
|
||||
status: "success",
|
||||
data: {
|
||||
questionId: questionId
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
import router from "../router";
|
||||
import { coursePolls, deepSeekPolls } from "../data/polls";
|
||||
|
||||
router.on("/test", async function (data, response) {
|
||||
const question = "What is your name?";
|
||||
const questionId = Math.random().toString(16).slice(2, 8);
|
||||
response.contentType = "application/json";
|
||||
console.log("Test question", question);
|
||||
const polls = deepSeekPolls.value;
|
||||
coursePolls.value = [];
|
||||
if (polls.length == 0) {
|
||||
deepSeekPolls.cache = {
|
||||
questionID: questionId,
|
||||
question: question,
|
||||
flag: true
|
||||
};
|
||||
}
|
||||
polls.forEach((poll) => {
|
||||
poll.resolve({
|
||||
questionID: questionId,
|
||||
question: question,
|
||||
flag: true
|
||||
});
|
||||
});
|
||||
response.response = {
|
||||
status: "success",
|
||||
data: {
|
||||
questionId: questionId
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -0,0 +1,5 @@
|
||||
const CONST = {
|
||||
pollInterval: 10000
|
||||
};
|
||||
|
||||
export default CONST;
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
import * as http from "http";
|
||||
import app from "./app/app";
|
||||
|
||||
const server = http.createServer();
|
||||
|
||||
server.on("request", app.httpHandler());
|
||||
|
||||
server.listen(3000, () => {
|
||||
console.log("VCLight serve");
|
||||
console.log("> Ready! Available at http://localhost:3000");
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
export default class Poll<T> {
|
||||
protected inner: Promise<T>;
|
||||
protected timer: Promise<typeof Poll.TIMEOUT>;
|
||||
protected resolver: (value: T | PromiseLike<T>) => void;
|
||||
static TIMEOUT = class Timeout {};
|
||||
|
||||
constructor(protected timeout: number) {
|
||||
let resolver: (value: T | PromiseLike<T>) => void;
|
||||
this.inner = new Promise<T>((r) => {
|
||||
resolver = r;
|
||||
});
|
||||
this.resolver = resolver!;
|
||||
this.timer = new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve(Poll.TIMEOUT);
|
||||
}, timeout);
|
||||
});
|
||||
}
|
||||
|
||||
public resolve(value: T | PromiseLike<T>) {
|
||||
this.resolver(value);
|
||||
}
|
||||
|
||||
public async wait(): Promise<T | typeof Poll.TIMEOUT> {
|
||||
return Promise.race([this.inner, this.timer]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user