Something went wrong. Try again.
a tiny pet with a GPT-2 brain, living in your browser
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129import { BRAINS, cachedBrains, loadBrain, stopBrain, updateStorage } from "./brain.ts";import { CFG } from "./config.ts";import { playEffect } from "./animation.ts";import { pump } from "./conversation.ts";import { afterChanges, startEngine } from "./engine.ts";import { startAcceptedGame, stopGameControls } from "./game.ts";import { planAlerts } from "./pwa.ts";import { catchUp } from "./simulation.ts";import { cancelSave, fresh, KEY, load } from "./storage.ts";import { brain, emit, store } from "./store.ts";import { canRunLocally, isRemote, releaseRecoveredCopy, resumeRemote, stopRemote, stopPendingStops,} from "./hosting.ts";
let releaseTab: (() => void) | null = null;
function requestTab(steal: boolean): Promise<boolean> { if (!navigator.locks) return Promise.resolve(true); return new Promise((resolve) => { navigator.locks .request(KEY, steal ? { steal: true } : { ifAvailable: true }, (lock) => { resolve(!!lock); return lock ? new Promise<void>((release) => { releaseTab = release; }) : undefined; }) .catch(() => { resolve(false); lostTab(); }); });}export async function claimTab(steal: boolean): Promise<boolean> { // A reload can request its new lock before the old document's release reaches // the lock manager. Retry briefly without stealing from another live tab. for (let attempt = 0; attempt < 3; attempt++) { if (await requestTab(steal && attempt === 0)) return true; if (attempt < 2) await new Promise((resolve) => setTimeout(resolve, 100)); } return false;}export function lostTab() { store.tabOwned = false; cancelSave(); stopBrain(); stopRemote(); stopPendingStops(); stopGameControls(); emit();}export function takeOver() { try { sessionStorage.setItem("tokenling.steal", "1"); } catch { /* optional */ } location.reload();}export async function boot() { let steal = false; try { steal = sessionStorage.getItem("tokenling.steal") === "1"; sessionStorage.removeItem("tokenling.steal"); } catch { /* optional */ } store.tabOwned = await claimTab(steal); startEngine(store.tabOwned ? load() : fresh(), CFG.weatherSeed || ""); if (!store.tabOwned) return; // After every change: animate its effects; locally, also start a game the // pet accepted and run the turns it wants. afterChanges((effects) => { for (const effect of effects) playEffect(effect); if (!canRunLocally()) return; startAcceptedGame(); setTimeout(pump, 0); }); addEventListener("pagehide", () => { void planAlerts(); lostTab(); releaseTab?.(); releaseTab = null; }); addEventListener("pageshow", (event) => { if (event.persisted) location.reload(); }); if (store.badEgg) return; catchUp(); document.addEventListener("visibilitychange", () => { if (document.hidden) stopGameControls(); if (!store.tabOwned) return; if (!document.hidden) { if (isRemote()) void resumeRemote(); else catchUp(); emit(); } void planAlerts(); }); addEventListener("blur", stopGameControls); addEventListener("online", () => { if (isRemote()) void resumeRemote(); void releaseRecoveredCopy(); }); void planAlerts(); void updateStorage();}export async function resumeBrain() { if (!store.tabOwned || store.badEgg) return; void releaseRecoveredCopy(); if (isRemote()) { await resumeRemote(); return; } const have = await cachedBrains(); const selected = BRAINS.some((b) => b.id === store.state.hosting.brainId) ? store.state.hosting.brainId : null; if (store.state.egg && store.state.owner) void loadBrain(selected || CFG.modelId); else if (store.state.pet && have.length && !brain.worker) void loadBrain(selected && have.includes(selected) ? selected : have[0]);}