fix: support idempotent actions over HTTP
This commit is contained in:
@@ -17,6 +17,32 @@ function csrfToken() {
|
||||
return match ? decodeURIComponent(match[1]) : "";
|
||||
}
|
||||
|
||||
function createIdempotencyKey() {
|
||||
const cryptoApi = globalThis.crypto;
|
||||
if (typeof cryptoApi?.randomUUID === "function") {
|
||||
return cryptoApi.randomUUID();
|
||||
}
|
||||
|
||||
const bytes = new Uint8Array(16);
|
||||
if (typeof cryptoApi?.getRandomValues === "function") {
|
||||
cryptoApi.getRandomValues(bytes);
|
||||
} else {
|
||||
for (let index = 0; index < bytes.length; index += 1) {
|
||||
bytes[index] = Math.floor(Math.random() * 256);
|
||||
}
|
||||
}
|
||||
bytes[6] = (bytes[6] & 0x0f) | 0x40;
|
||||
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
||||
const hex = [...bytes].map((value) => value.toString(16).padStart(2, "0"));
|
||||
return [
|
||||
hex.slice(0, 4).join(""),
|
||||
hex.slice(4, 6).join(""),
|
||||
hex.slice(6, 8).join(""),
|
||||
hex.slice(8, 10).join(""),
|
||||
hex.slice(10).join(""),
|
||||
].join("-");
|
||||
}
|
||||
|
||||
async function api(path, options = {}) {
|
||||
const headers = { Accept: "application/json", ...(options.headers || {}) };
|
||||
if (options.body && typeof options.body !== "string") {
|
||||
@@ -165,7 +191,7 @@ function renderStoryNode(run) {
|
||||
try {
|
||||
const next = await api(`math-life/runs/${run.run_id}/choice/`, {
|
||||
method: "POST",
|
||||
headers: { "Idempotency-Key": crypto.randomUUID() },
|
||||
headers: { "Idempotency-Key": createIdempotencyKey() },
|
||||
body: { choice_index: choice.index },
|
||||
});
|
||||
renderStoryNode(next);
|
||||
@@ -341,7 +367,7 @@ function renderAttempt(attempt) {
|
||||
try {
|
||||
const result = await api(`contests/attempts/${attempt.attempt_id}/submit/`, {
|
||||
method: "POST",
|
||||
headers: { "Idempotency-Key": crypto.randomUUID() },
|
||||
headers: { "Idempotency-Key": createIdempotencyKey() },
|
||||
body: { answers },
|
||||
});
|
||||
renderAttempt(result);
|
||||
|
||||
Reference in New Issue
Block a user