diff options
Diffstat (limited to 'examples/hello-next/bun-framework-next/page-loader.ts')
-rw-r--r-- | examples/hello-next/bun-framework-next/page-loader.ts | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/examples/hello-next/bun-framework-next/page-loader.ts b/examples/hello-next/bun-framework-next/page-loader.ts new file mode 100644 index 000000000..03ee3e5ed --- /dev/null +++ b/examples/hello-next/bun-framework-next/page-loader.ts @@ -0,0 +1,142 @@ +import NextPageLoader from "next/dist/client/page-loader"; +import getAssetPathFromRoute from "next/dist/shared/lib/router/utils/get-asset-path-from-route"; +// import createRouteLoader from "./route-loader"; + +function insertStyleSheet(url: string) { + if (document.querySelector(`link[href="${url}"]`)) { + return Promise.resolve(); + } + + return new Promise((resolve, reject) => { + const link = document.createElement("link"); + link.rel = "stylesheet"; + + link.onload = () => resolve(); + link.onerror = () => reject(); + + link.href = url; + document.head.appendChild(link); + }); +} + +export default class PageLoader extends NextPageLoader { + public routeLoader: RouteLoader; + + constructor(_, __, pages) { + super(_, __); + + // TODO: assetPrefix? + // this.routeLoader = {}; //createRouteLoader(""); + + // Rewrite the pages object to omit the entry script + // At this point, the entry point has been loaded so we don't want to do that again. + for (let name in pages) { + for (let i = 0; i < pages[name].length; i += 1) { + const lastDot = pages[name][i].lastIndexOf("."); + if (lastDot == -1) continue; + if ( + pages[name][i].substring(lastDot - ".entry".length, lastDot) !== + ".entry" + ) + continue; + + pages[name][i] = + pages[name][i].substring(0, lastDot - ".entry".length) + + pages[name][i].substring(lastDot); + } + } + + this.pages = pages; + this.pageList = Object.keys(this.pages); + } + + pageList: string[]; + pages: Record<string, string[]>; + + getPageList() { + return this.pageList; + } + + cssQueue = []; + + onImportCSS = (event) => { + this.cssQueue.push( + insertStyleSheet(event.detail).then( + () => {}, + () => {} + ) + ); + }; + + prefetch(route) { + return Promise.resolve({}); + } + + async loadPage(route: string): Promise<GoodPageCache> { + const assets = + this.pages[route] || this.pages[getAssetPathFromRoute(route)]; + + var src; + console.log(getAssetPathFromRoute(route), assets); + for (let asset of assets) { + if (!asset.endsWith(".css")) { + src = asset; + break; + } + } + console.assert(src, "Invalid or unknown route passed to loadPage"); + + document.removeEventListener("onimportcss", this.onImportCSS); + this.cssQueue.length = 0; + document.addEventListener("onimportcss", this.onImportCSS, { + passive: true, + }); + + try { + const res = await import(src); + + if (this.cssQueue.length > 0) { + await Promise.all(this.cssQueue); + this.cssQueue.length = 0; + } + + document.removeEventListener("onimportcss", this.onImportCSS); + + if (this.cssQueue.length > 0) { + await Promise.all(this.cssQueue); + + this.cssQueue.length = 0; + } + + return { + page: res.default, + mod: res, + styleSheets: [], + __N_SSG: false, + __N_SSP: false, + }; + } catch (exception) { + console.error({ exception }); + } + + // return this.routeLoader.loadRoute(route).then((res) => { + // debugger; + // if ("component" in res) { + // return { + // page: res.component, + // mod: res.exports, + // styleSheets: res.styles.map((o) => ({ + // href: o.href, + // text: o.content, + // })), + // }; + // } + // throw res.error; + // }); + } + + // not used in development! + // prefetch(route: string): Promise<void> { + // return this.routeLoader.prefetch(route); + // } +} |