/** * @module helpers.web * * Web-specific helper functions for space-gib. */ import { extractErrorMsg } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs"; import { storageGet } from "@ibgib/web-gib/dist/storage/storage-helpers.web.mjs"; import { initAppStorage } from "@ibgib/web-gib/dist/helpers.web.mjs"; import { getGlobalMetaspace_waitIfNeeded } from "@ibgib/web-gib/dist/helpers.mjs"; import { IbGibDynamicComponentMetaCtorOpts } from "@ibgib/web-gib/dist/ui/component/component-types.mjs"; import { IbGibGlobalThisInfo } from "@ibgib/web-gib/dist/types.mjs"; import { delay } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs"; import { GLOBAL_LOG_A_LOT } from "./constants.mjs"; import { AUTO_GENERATED_VERSION } from "./AUTO-GENERATED-version.mjs"; import { IbGibAmbientContextConfig, IbGibGlobalThis_SpaceGib, IbGibGlobalThis_Common, } from "./types.mjs"; const logalot = GLOBAL_LOG_A_LOT; // --------------------------------------------------------------------------- // Storage initialization // --------------------------------------------------------------------------- export async function initIbGibStorage(config: IbGibAmbientContextConfig): Promise { const lc = `[${initIbGibStorage.name}]`; try { if (logalot) { console.log(`${lc} starting... (I: 1905af1827a34ca8a5507fe0c5085b01)`); } await initAppStorage({ infos: [ { dbName: config.dbName, storeNames: [config.storeName, ...(config.additionalStoreNames ?? [])], }, ], }); } catch (error) { console.error(`${lc} ${extractErrorMsg(error)}`); throw error; } finally { if (logalot) { console.log(`${lc} complete.`); } } } // --------------------------------------------------------------------------- // globalThis initialization // --------------------------------------------------------------------------- export function initIbGibGlobalThis(config: IbGibAmbientContextConfig): void { const lc = `[${initIbGibGlobalThis.name}]`; try { if (logalot) { console.log(`${lc} starting... (I: 7be20d161bb14a498c44a42d3193bec1)`); } if (!(globalThis as any).ibgib) { (globalThis as any).ibgib = { dbName_hack: config.dbName, apiKeyName_hack: config.apiKeyName, storeName_hack: config.storeName, } satisfies IbGibGlobalThisInfo; } if (!(globalThis as any).ibgib.spaceGib) { (globalThis as any).ibgib.spaceGib = { version: AUTO_GENERATED_VERSION, spaceShim: {}, fnDefaultGetAPIKey: async () => { const apiKey = await storageGet({ dbName: config.dbName, storeName: config.storeName, key: config.apiKeyName, }); return apiKey ?? ''; }, dbName_hack: config.dbName, apiKeyName_hack: config.apiKeyName, storeName_hack: config.storeName, } satisfies IbGibGlobalThis_SpaceGib; } } catch (error) { console.error(`${lc} ${extractErrorMsg(error)}`); throw error; } finally { if (logalot) { console.log(`${lc} complete.`); } } } // --------------------------------------------------------------------------- // GlobalThis accessors // --------------------------------------------------------------------------- export function getIbGibGlobalThis_SpaceGib( config?: IbGibAmbientContextConfig ): IbGibGlobalThis_SpaceGib { if (!(globalThis as any).ibgib?.spaceGib) { if (!config) { throw new Error(`Global context not initialized and config not provided.`); } initIbGibGlobalThis(config); } return (globalThis as any).ibgib.spaceGib as IbGibGlobalThis_SpaceGib; } export function getIbGibGlobalThis_Common(): IbGibGlobalThis_Common { const g = (globalThis as any).ibgib?.spaceGib; if (!g) { throw new Error(`(UNEXPECTED) globalThis.ibgib.spaceGib not initialized.`); } return g as IbGibGlobalThis_Common; } // --------------------------------------------------------------------------- // API key helper // --------------------------------------------------------------------------- export function getDefaultFnGetAPIKey(): () => Promise { return async () => { const gb = getIbGibGlobalThis_SpaceGib(); return (await storageGet({ dbName: gb.dbName_hack, storeName: gb.storeName_hack, key: gb.apiKeyName_hack, })) ?? ''; }; } // --------------------------------------------------------------------------- // Dynamic bootstrap loading // --------------------------------------------------------------------------- export async function dynamicallyLoadBootstrapScript(path: string): Promise { const lc = `[${dynamicallyLoadBootstrapScript.name}]`; try { if (logalot) { console.log(`${lc} starting... (I: 3123b18eb29b480bad056a9a029b9ad4)`); } const module = await import(path); await module.bootstrapSpaceGibApp(); } catch (error) { console.error(`${lc} ${extractErrorMsg(error)}`); throw error; } finally { if (logalot) { console.log(`${lc} complete.`); } } } // --------------------------------------------------------------------------- // Component constructor args helper // --------------------------------------------------------------------------- export function getComponentCtorArg(): IbGibDynamicComponentMetaCtorOpts { const fnGetMetaspace = async () => getGlobalMetaspace_waitIfNeeded(); const bootstrapPromiseWrapper = new Promise(async (resolve, reject) => { try { let maxTries = 100_000; let counter = 0; let bootstrapPromise: Promise | undefined; do { bootstrapPromise = getIbGibGlobalThis_SpaceGib()?.bootstrapPromise; counter++; if (counter > maxTries) { break; } await delay(10); } while (bootstrapPromise === undefined); if (!bootstrapPromise) { throw new Error(`Timed out waiting for bootstrapPromise. (E: ceb3ba5261994476900e4a623c0e9d10)`); } await bootstrapPromise; resolve(); } catch (error) { reject(error); } }); return { fnGetMetaspace, bootstrapPromise: bootstrapPromiseWrapper }; }