UNPKG

@statezero/core

Version:

The type-safe frontend client for StateZero - connect directly to your backend models with zero boilerplate

93 lines (92 loc) 3.06 kB
import Handlebars from 'handlebars'; import superjson from 'superjson'; // Simple map to store temporary PK to real PK mappings export const tempPkMap = new Map(); // Callbacks to notify when a temp pk is resolved to a real pk const onResolveCallbacks = new Set(); /** * Register a callback to be notified when a temp pk is resolved to a real pk * @param {Function} callback - Called with (tempPk, realPk) when resolved * @returns {Function} - Unsubscribe function */ export function onTempPkResolved(callback) { onResolveCallbacks.add(callback); return () => onResolveCallbacks.delete(callback); } /** * Check if a string contains a temporary PK template * @param {string} str - The string to check * @returns {boolean} - True if the string contains a TempPK tag */ export function containsTempPk(str) { return (typeof str === 'string' && /\{\{\s*TempPK_[^}\s]+\s*\}\}/.test(str)); } /** * Create a temporary PK with handlebars syntax */ export function createTempPk(uuid) { const tempPk = `{{TempPK_${uuid}}}`; return tempPk; } /** * Register a real PK for a temporary PK */ export function setRealPk(uuid, realPk) { const tempPk = `{{TempPK_${uuid}}}`; const key = `"TempPK_${uuid}"`; const value = typeof realPk === 'string' ? `"${realPk}"` : String(realPk); tempPkMap.set(key, value); // Notify listeners so they can migrate cache entries for (const cb of onResolveCallbacks) { try { cb(tempPk, realPk); } catch (e) { console.warn('[tempPk] onResolve callback error:', e); } } } /** * Get the real PK for a temp PK if it exists in the registry * @param {any} pk - The pk to resolve (may be temp or real) * @returns {any} - The real pk if found, otherwise the original pk */ export function resolveToRealPk(pk) { if (!containsTempPk(String(pk))) return pk; // Extract the uuid from {{TempPK_uuid}} const match = String(pk).match(/\{\{\s*TempPK_([^}\s]+)\s*\}\}/); if (!match) return pk; const key = `"TempPK_${match[1]}"`; const realPkStr = tempPkMap.get(key); if (!realPkStr) return pk; // Parse the real pk (remove quotes if string, parse if number) if (realPkStr.startsWith('"') && realPkStr.endsWith('"')) { return realPkStr.slice(1, -1); } return parseInt(realPkStr, 10); } /** * Replace all temporary PKs in an object (or string) with their real values */ export function replaceTempPks(payload) { if (tempPkMap.size === 0) return payload; const context = Object.fromEntries(tempPkMap); try { if (typeof payload === 'string') { const template = Handlebars.compile(payload, { noEscape: true }); return template(context); } const str = superjson.stringify(payload); const template = Handlebars.compile(str, { noEscape: true }); const replaced = template(context); return superjson.parse(replaced); } catch (error) { return payload; } }