// lib/activePointer.js // Active-pointer write: persist -> re-register -> propagate -> refresh assets (ARCHITECTURE.md 5.5) const Plugin = require("@saltcorn/data/models/plugin"); const { getState } = require("@saltcorn/data/db/state"); const db = require("@saltcorn/data/db"); const { PLUGIN_NAME } = require("./constants"); // Resolve the install-name row defensively: _sc_plugins.name is the INSTALL name, which // is NOT guaranteed to equal plugin_name. Try the canonical name, then fall back to scanning // for the row whose module resolves to plugin_name. (folded review fix: read/write name-space split) async function findPluginRow() { let p = await Plugin.findOne({ name: PLUGIN_NAME }); if (p) return p; const all = await Plugin.find({}); return all.find((r) => { const mod = getState().plugins[PLUGIN_NAME]; return mod && (getState().plugin_module_names[r.name] === PLUGIN_NAME || r.name === PLUGIN_NAME); }) || null; } async function setActivePointer(patch /* {activeThemeId?|activeByRole?|activeHash?} */) { const plugin = await findPluginRow(); if (!plugin) throw new Error("theme-builder plugin row not found"); plugin.configuration = { ...(plugin.configuration || {}), ...patch }; await plugin.upsert(); // _sc_plugins (plugin.ts:104-119) await Plugin.loadPlugin(plugin); // re-register -> re-run headers(cfg) await getState().refresh_views(); // REBUILD assets_by_role (Fix 1) getState().processSend({ refresh_plugin_cfg: PLUGIN_NAME, tenant: db.getTenantSchema() }); return plugin.configuration; } // READ: live merged cfg, no DB hit. function getActivePointer() { const cfg = getState().plugin_cfgs[PLUGIN_NAME] || {}; return { activeThemeId: cfg.activeThemeId || null, activeByRole: cfg.activeByRole || {}, activeHash: cfg.activeHash || "0" }; } // Remove every activeByRole entry whose value === id, then persist the scrubbed map. async function dropRoleRefs(id) { const { activeByRole } = getActivePointer(); const scrubbed = {}; for (const role of Object.keys(activeByRole)) { if (activeByRole[role] !== id) scrubbed[role] = activeByRole[role]; } return setActivePointer({ activeByRole: scrubbed }); } module.exports = { setActivePointer, getActivePointer, findPluginRow, dropRoleRefs };