41 lines
1.2 KiB
TypeScript
41 lines
1.2 KiB
TypeScript
import type { WorldDelta, WorldSnapshot } from "./contracts";
|
|
|
|
export async function fetchWorldSnapshot(signal?: AbortSignal) {
|
|
const response = await fetch("/api/world", { signal });
|
|
if (!response.ok) {
|
|
throw new Error(`World request failed with ${response.status}`);
|
|
}
|
|
return response.json() as Promise<WorldSnapshot>;
|
|
}
|
|
|
|
export function openWorldStream(
|
|
afterSequence: number,
|
|
handlers: {
|
|
onDelta: (delta: WorldDelta, rawBytes: number) => void;
|
|
onOpen?: () => void;
|
|
onError?: () => void;
|
|
},
|
|
) {
|
|
const stream = new EventSource(`/api/world/stream?afterSequence=${afterSequence}`);
|
|
stream.addEventListener("open", () => handlers.onOpen?.());
|
|
stream.addEventListener("error", () => handlers.onError?.());
|
|
stream.addEventListener("world-delta", (event) => {
|
|
const message = event as MessageEvent<string>;
|
|
handlers.onDelta(
|
|
JSON.parse(message.data) as WorldDelta,
|
|
new Blob([message.data]).size,
|
|
);
|
|
});
|
|
return stream;
|
|
}
|
|
|
|
export async function resetWorld() {
|
|
const response = await fetch("/api/world/reset", {
|
|
method: "POST",
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error(`Reset request failed with ${response.status}`);
|
|
}
|
|
return response.json() as Promise<WorldSnapshot>;
|
|
}
|