Files
TaroTime/app/app-runtime.js

205 lines
5.6 KiB
JavaScript
Raw Permalink Normal View History

2026-03-07 05:17:50 -08:00
(function () {
"use strict";
let config = {
calendar: null,
baseWeekOptions: null,
defaultSettings: null,
latEl: null,
lngEl: null,
nowElements: null,
calendarVisualsUi: null,
homeUi: null,
onStatus: null,
services: {},
ensure: {}
};
let referenceData = null;
let magickDataset = null;
let currentGeo = null;
let nowInterval = null;
let centeredDayKey = "";
let renderInProgress = false;
let currentTimeFormat = "minutes";
let currentSettings = null;
function setStatus(text) {
config.onStatus?.(text);
}
function getReferenceData() {
return referenceData;
}
function getMagickDataset() {
return magickDataset;
}
function getCurrentGeo() {
return currentGeo;
}
function getCurrentTimeFormat() {
return currentTimeFormat;
}
function getCurrentSettings() {
return currentSettings ? { ...currentSettings } : null;
}
function parseGeoInput() {
const latitude = Number(config.latEl?.value);
const longitude = Number(config.lngEl?.value);
if (Number.isNaN(latitude) || Number.isNaN(longitude)) {
throw new Error("Latitude/Longitude must be valid numbers.");
}
return { latitude, longitude };
}
function applyCenteredWeekWindow(date) {
const startDayOfWeek = config.services.getCenteredWeekStartDay?.(date) ?? 0;
config.calendar?.setOptions?.({
week: {
...(config.baseWeekOptions || {}),
startDayOfWeek
}
});
config.calendarVisualsUi?.applyTimeFormatTemplates?.();
config.calendar?.changeView?.("week");
config.calendar?.setDate?.(date);
}
function startNowTicker() {
if (nowInterval) {
clearInterval(nowInterval);
}
2026-03-08 22:24:34 -07:00
const tick = async () => {
2026-03-07 05:17:50 -08:00
if (!referenceData || !currentGeo || renderInProgress) {
return;
}
const now = new Date();
config.homeUi?.syncNowPanelTheme?.(now);
const currentDayKey = config.services.getDateKey?.(now) || "";
if (currentDayKey !== centeredDayKey) {
centeredDayKey = currentDayKey;
void renderWeek();
return;
}
2026-03-08 22:24:34 -07:00
try {
await config.services.updateNowPanel?.(referenceData, currentGeo, config.nowElements, currentTimeFormat);
config.calendarVisualsUi?.applyDynamicNowIndicatorVisual?.(now);
} catch (_error) {
}
2026-03-07 05:17:50 -08:00
};
2026-03-08 22:24:34 -07:00
void tick();
nowInterval = setInterval(() => {
void tick();
}, 1000);
2026-03-07 05:17:50 -08:00
}
async function renderWeek() {
if (renderInProgress) {
return;
}
renderInProgress = true;
try {
currentGeo = parseGeoInput();
config.homeUi?.syncNowPanelTheme?.(new Date());
config.homeUi?.syncNowSkyBackground?.(currentGeo);
if (!referenceData || !magickDataset) {
setStatus("Loading planetary, sign and decan tarot correspondences...");
const [loadedReference, loadedMagick] = await Promise.all([
referenceData ? Promise.resolve(referenceData) : config.services.loadReferenceData?.(),
magickDataset
? Promise.resolve(magickDataset)
: config.services.loadMagickDataset?.().catch(() => null)
]);
referenceData = loadedReference;
magickDataset = loadedMagick;
}
config.ensure.ensureTarotSection?.(referenceData, magickDataset);
config.ensure.ensurePlanetSection?.(referenceData, magickDataset);
config.ensure.ensureCyclesSection?.(referenceData);
config.ensure.ensureIChingSection?.(referenceData);
config.ensure.ensureCalendarSection?.(referenceData, magickDataset);
config.ensure.ensureHolidaySection?.(referenceData, magickDataset);
config.ensure.ensureNatalPanel?.(referenceData);
config.ensure.ensureQuizSection?.(referenceData, magickDataset);
const anchorDate = new Date();
centeredDayKey = config.services.getDateKey?.(anchorDate) || "";
applyCenteredWeekWindow(anchorDate);
2026-03-08 22:24:34 -07:00
const events = await config.services.buildWeekEvents?.(currentGeo, referenceData, anchorDate) || [];
2026-03-07 05:17:50 -08:00
config.calendar?.clear?.();
config.calendar?.createEvents?.(events);
config.calendarVisualsUi?.applySunRulerGradient?.(anchorDate);
config.calendarVisualsUi?.updateMonthStrip?.();
requestAnimationFrame(() => {
config.calendarVisualsUi?.updateMonthStrip?.();
});
setStatus(`Rendered ${events.length} planetary + tarot events for lat ${currentGeo.latitude}, lng ${currentGeo.longitude}.`);
startNowTicker();
} catch (error) {
setStatus(error?.message || "Failed to render calendar.");
} finally {
renderInProgress = false;
}
}
function applySettings(settings) {
currentTimeFormat = settings?.timeFormat || "minutes";
currentSettings = settings ? { ...settings } : { ...(config.defaultSettings || {}) };
}
function init(nextConfig = {}) {
config = {
...config,
...nextConfig,
services: {
...(config.services || {}),
...(nextConfig.services || {})
},
ensure: {
...(config.ensure || {}),
...(nextConfig.ensure || {})
}
};
if (!currentSettings) {
currentSettings = { ...(config.defaultSettings || {}) };
currentTimeFormat = currentSettings.timeFormat || "minutes";
}
centeredDayKey = config.services.getDateKey?.(new Date()) || centeredDayKey;
}
window.TarotAppRuntime = {
...(window.TarotAppRuntime || {}),
init,
parseGeoInput,
applyCenteredWeekWindow,
renderWeek,
applySettings,
getReferenceData,
getMagickDataset,
getCurrentGeo,
getCurrentTimeFormat,
getCurrentSettings
};
})();