woby
Version:
A high-performance framework with fine-grained observable/signal-based reactivity for building rich applications.
1 lines • 7.29 kB
Source Map (JSON)
{"version":3,"file":"render_to_string-QEFRB-Fu.cjs","sources":["../src/methods/render.ts","../src/components/portal.ts","../src/components/suspense.collector.ts","../src/methods/render_to_string.ts"],"sourcesContent":["\r\n/* IMPORT */\r\n\r\nimport useRoot from '../hooks/use_root'\r\nimport { setChild } from '../utils/setters'\r\nimport type { Child, Disposer } from '../types'\r\nimport { FragmentUtils } from '../utils/fragment'\r\n\r\n/* MAIN */\r\n\r\nconst render = (child: Child, parent?: Element | null): Disposer => {\r\n\r\n if (!parent || !(parent instanceof HTMLElement)) throw new Error('Invalid parent node')\r\n\r\n parent.textContent = ''\r\n\r\n return useRoot((stack, dispose) => {\r\n\r\n setChild(parent, child, FragmentUtils.make(), stack)\r\n\r\n return (): void => {\r\n\r\n dispose(stack)\r\n\r\n parent.textContent = ''\r\n\r\n }\r\n\r\n })\r\n\r\n}\r\n\r\n/* EXPORT */\r\n\r\nexport default render\r\n","\r\n/* IMPORT */\r\n\r\nimport useBoolean from '../hooks/use_boolean'\r\nimport useRenderEffect from '../hooks/use_render_effect'\r\nimport render from '../methods/render'\r\nimport $$ from '../methods/SS'\r\nimport { createHTMLNode } from '../utils/creators'\r\nimport { assign } from '../utils/lang'\r\nimport type { Child, ChildWithMetadata, FunctionMaybe } from '../types'\r\n\r\n/* MAIN */\r\n\r\nconst Portal = ({ when = true, mount, wrapper, children }: { mount?: Child, when?: FunctionMaybe<boolean>, wrapper?: Child, children?: Child }): ChildWithMetadata<{ portal: HTMLElement }> => {\r\n\r\n const portal = $$(wrapper) || createHTMLNode('div')\r\n\r\n if (!(portal instanceof HTMLElement)) throw new Error('Invalid wrapper node')\r\n\r\n const condition = useBoolean(when)\r\n\r\n const stack = new Error()\r\n\r\n useRenderEffect(() => {\r\n\r\n if (!$$(condition)) return\r\n\r\n const parent = $$(mount) || document.body\r\n\r\n if (!(parent instanceof Element)) throw new Error('Invalid mount node')\r\n\r\n parent.insertBefore(portal, null)\r\n\r\n return (): void => {\r\n\r\n parent.removeChild(portal)\r\n\r\n }\r\n\r\n }, stack)\r\n\r\n useRenderEffect(() => {\r\n\r\n if (!$$(condition)) return\r\n\r\n return render(children, portal)\r\n\r\n }, stack)\r\n\r\n return assign(() => $$(condition) || children, { metadata: { portal } })\r\n\r\n}\r\n\r\n/* EXPORT */\r\n\r\nexport default Portal","\r\n/* IMPORT */\r\n\r\nimport { SYMBOL_SUSPENSE_COLLECTOR } from '../constants'\r\nimport useMemo from '../hooks/use_memo'\r\nimport $ from '../methods/S'\r\nimport { context, resolve } from 'soby'\r\nimport type { SuspenseCollectorData, SuspenseData } from '../types'\r\n\r\n/* MAIN */\r\n\r\n// Keeping track of all Suspense instances below it, needed in some cases\r\n\r\nconst SuspenseCollector = {\r\n\r\n create: (): SuspenseCollectorData => { //TODO: Optimize this, some parts are unnecessarily slow, we just need a counter of active suspenses here really\r\n\r\n const parent = SuspenseCollector.get()\r\n const suspenses = $<SuspenseData[]>([])\r\n const active = useMemo(() => suspenses().some(suspense => suspense.active()))\r\n const register = (suspense: SuspenseData) => { parent?.register(suspense); suspenses(prev => [...prev, suspense]) }\r\n const unregister = (suspense: SuspenseData) => { parent?.unregister(suspense); suspenses(prev => prev.filter(other => other !== suspense)) }\r\n const data = { suspenses, active, register, unregister }\r\n\r\n return data\r\n\r\n },\r\n\r\n get: (): SuspenseCollectorData | undefined => {\r\n\r\n return context<SuspenseCollectorData>(SYMBOL_SUSPENSE_COLLECTOR)\r\n\r\n },\r\n\r\n wrap: <T>(fn: (data: SuspenseCollectorData) => T) => {\r\n\r\n const data = SuspenseCollector.create()\r\n\r\n return context({ [SYMBOL_SUSPENSE_COLLECTOR]: data }, () => {\r\n\r\n return resolve(() => fn(data))\r\n\r\n })\r\n\r\n }\r\n\r\n}\r\n\r\n/* EXPORT */\r\n\r\nexport default SuspenseCollector","\r\n/* IMPORT */\r\n\r\nimport Portal from '../components/portal'\r\nimport SuspenseCollector from '../components/suspense.collector'\r\nimport useEffect from '../hooks/use_effect'\r\nimport useRoot from '../hooks/use_root'\r\nimport $$ from '../methods/SS'\r\nimport type { Child } from '../types'\r\n\r\n/* MAIN */\r\n\r\n//TODO: Implement this properly, without relying on JSDOM or stuff like that\r\n\r\nconst renderToString = (child: Child): Promise<string> => {\r\n\r\n return new Promise(resolve => {\r\n\r\n useRoot((stack, dispose) => {\r\n\r\n $$(SuspenseCollector.wrap(suspenses => {\r\n\r\n const { portal } = Portal({ children: child }).metadata\r\n\r\n useEffect((stack) => {\r\n\r\n if (suspenses.active()) return\r\n\r\n resolve(portal.innerHTML)\r\n\r\n dispose(stack)\r\n\r\n }, { suspense: false, stack: stack })\r\n\r\n }))\r\n\r\n })\r\n\r\n })\r\n\r\n}\r\n\r\n/* EXPORT */\r\n\r\nexport default renderToString"],"names":["useRoot","setChild","FragmentUtils","$$","createHTMLNode","useBoolean","useRenderEffect","assign","$","useMemo","context","SYMBOL_SUSPENSE_COLLECTOR","resolve","useEffect","stack"],"mappings":";;;;AAUA,MAAM,SAAS,CAAC,OAAc,WAAsC;AAEhE,MAAI,CAAC,UAAU,EAAE,kBAAkB,aAAc,OAAM,IAAI,MAAM,qBAAqB;AAEtF,SAAO,cAAc;AAErB,SAAOA,KAAAA,KAAQ,CAAC,OAAO,YAAY;AAE/BC,YAAAA,SAAS,QAAQ,OAAOC,QAAAA,cAAc,KAAA,GAAQ,KAAK;AAEnD,WAAO,MAAY;AAEf,cAAQ,KAAK;AAEb,aAAO,cAAc;AAAA,IAEzB;AAAA,EAEJ,CAAC;AAEL;ACjBA,MAAM,SAAS,CAAC,EAAE,OAAO,MAAM,OAAO,SAAS,eAAgJ;AAE3L,QAAM,SAASC,QAAAA,IAAG,OAAO,KAAKC,QAAAA,eAAe,KAAK;AAElD,MAAI,EAAE,kBAAkB,aAAc,OAAM,IAAI,MAAM,sBAAsB;AAE5E,QAAM,YAAYC,YAAAA,QAAW,IAAI;AAEjC,QAAM,QAAQ,IAAI,MAAA;AAElBC,UAAAA,gBAAgB,MAAM;AAElB,QAAI,CAACH,QAAAA,IAAG,SAAS,EAAG;AAEpB,UAAM,SAASA,QAAAA,IAAG,KAAK,KAAK,SAAS;AAErC,QAAI,EAAE,kBAAkB,SAAU,OAAM,IAAI,MAAM,oBAAoB;AAEtE,WAAO,aAAa,QAAQ,IAAI;AAEhC,WAAO,MAAY;AAEf,aAAO,YAAY,MAAM;AAAA,IAE7B;AAAA,EAEJ,GAAG,KAAK;AAERG,UAAAA,gBAAgB,MAAM;AAElB,QAAI,CAACH,QAAAA,IAAG,SAAS,EAAG;AAEpB,WAAO,OAAO,UAAU,MAAM;AAAA,EAElC,GAAG,KAAK;AAER,SAAOI,QAAAA,OAAO,MAAMJ,QAAAA,IAAG,SAAS,KAAK,UAAU,EAAE,UAAU,EAAE,OAAA,GAAU;AAE3E;ACtCA,MAAM,oBAAoB;AAAA,EAExB,QAAQ,MAA6B;AAEnC,UAAM,SAAS,kBAAkB,IAAA;AACjC,UAAM,YAAYK,YAAAA,WAAkB,EAAE;AACtC,UAAM,SAASC,iBAAQ,MAAM,UAAA,EAAY,KAAK,CAAA,aAAY,SAAS,OAAA,CAAQ,CAAC;AAC5E,UAAM,WAAW,CAAC,aAA2B;AAAE,uCAAQ,SAAS;AAAW,gBAAU,CAAA,SAAQ,CAAC,GAAG,MAAM,QAAQ,CAAC;AAAA,IAAE;AAClH,UAAM,aAAa,CAAC,aAA2B;AAAE,uCAAQ,WAAW;AAAW,gBAAU,UAAQ,KAAK,OAAO,CAAA,UAAS,UAAU,QAAQ,CAAC;AAAA,IAAE;AAC3I,UAAM,OAAO,EAAE,WAAW,QAAQ,UAAU,WAAA;AAE5C,WAAO;AAAA,EAET;AAAA,EAEA,KAAK,MAAyC;AAE5C,WAAOC,QAAAA,QAA+BC,QAAAA,yBAAyB;AAAA,EAEjE;AAAA,EAEA,MAAM,CAAI,OAA2C;AAEnD,UAAM,OAAO,kBAAkB,OAAA;AAE/B,WAAOD,QAAAA,QAAQ,EAAE,CAACC,iCAAyB,GAAG,KAAA,GAAQ,MAAM;AAE1D,aAAOC,oBAAQ,MAAM,GAAG,IAAI,CAAC;AAAA,IAE/B,CAAC;AAAA,EAEH;AAEF;AChCA,MAAM,iBAAiB,CAAC,UAAkC;AAExD,SAAO,IAAI,QAAQ,CAAA,YAAW;AAE5BZ,cAAQ,CAAC,OAAO,YAAY;AAE1BG,cAAAA,IAAG,kBAAkB,KAAK,CAAA,cAAa;AAErC,cAAM,EAAE,WAAW,OAAO,EAAE,UAAU,MAAA,CAAO,EAAE;AAE/CU,gBAAAA,OAAU,CAACC,WAAU;AAEnB,cAAI,UAAU,SAAU;AAExB,kBAAQ,OAAO,SAAS;AAExB,kBAAQA,MAAK;AAAA,QAEf,GAAG,EAAE,UAAU,OAAO,OAAc;AAAA,MAEtC,CAAC,CAAC;AAAA,IAEJ,CAAC;AAAA,EAEH,CAAC;AAEH;;;;"}