/** * Entry point for seitime-bridge. Registers settings, wires hooks, and * exposes the public API on `globalThis.seitimeBridge` for use from * Foundry macros and the F12 console. * * All push operations are gated to the primary connected GM * (`game.users.activeGM`) so that worlds with multiple GMs don't * duplicate webhook calls. */ import { MODULE_ID } from "./constants.js"; import { registerSettings } from "./settings.js"; import { pushManifest, testConnection } from "./api.js"; let manifestTimerId = null; function isPrimaryGM() { return game.user.isGM && game.users.activeGM?.id === game.user.id; } function safePushManifest(reason) { if (!isPrimaryGM()) return; pushManifest().catch((err) => { console.warn(`[${MODULE_ID}] manifest push (${reason}) failed:`, err); }); } Hooks.once("init", () => { registerSettings(); }); Hooks.once("ready", () => { const mod = game.modules.get(MODULE_ID); const api = { pushManifest, testConnection }; mod.api = api; globalThis.seitimeBridge = api; console.log(`[${MODULE_ID}] ready. Call seitimeBridge.testConnection() to verify config.`); safePushManifest("ready"); const intervalMin = game.settings.get(MODULE_ID, "manifestSyncIntervalMinutes"); if (intervalMin > 0) { manifestTimerId = setInterval(() => safePushManifest("periodic"), intervalMin * 60 * 1000); } }); Hooks.on("createActor", (actor) => { if (actor.type !== "character") return; safePushManifest("createActor"); }); Hooks.on("deleteActor", (actor) => { if (actor.type !== "character") return; safePushManifest("deleteActor"); });