diff --git a/.vscode/launch.json b/.vscode/launch.json
index 759aa27..a433482 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -63,7 +63,7 @@
"args": [
"--forceExit",
"--runInBand",
- "src/modules/metaServer/lib/page/usePage/spec/useSpaPage.spec.ts",
+ "src/modules/metaServer/contentHandlers/liveShare/spec/liveShare.spec.ts",
],
"pauseForSourceMap": true,
"console": "integratedTerminal",
diff --git a/src/modules/metaServer/contentHandlers/dynamicShare/dynamicShareHandler.ts b/src/modules/metaServer/contentHandlers/dynamicShare/dynamicShareHandler.ts
index 517d055..78bddd2 100644
--- a/src/modules/metaServer/contentHandlers/dynamicShare/dynamicShareHandler.ts
+++ b/src/modules/metaServer/contentHandlers/dynamicShare/dynamicShareHandler.ts
@@ -4,6 +4,7 @@ import Path from 'node:path'
import { assertEx } from '@xylabs/assert'
import { exists } from '@xylabs/exists'
import { asyncHandler } from '@xylabs/sdk-api-express-ecs'
+import { HttpStatusCode } from 'axios'
import { RequestHandler } from 'express'
import {
@@ -26,7 +27,7 @@ import { useIndexAndDynamicPreviewImage } from './lib/index.js'
const indexHtmlMaxAge = 60 * 10
const indexHtmlCacheControlHeader = `public, max-age=${indexHtmlMaxAge}`
-const disableCaching = false
+const enableCaching = false
const getPageHandler = (baseDir: string) => {
// Ensure file containing base HTML exists
@@ -39,28 +40,36 @@ const getPageHandler = (baseDir: string) => {
const pageHandler: RequestHandler = asyncHandler(async (req, res, next) => {
const adjustedPath = getAdjustedPath(req)
if (Path.extname(adjustedPath) === '.html') {
+ const uri = getUriBehindProxy(req)
try {
- const uri = getUriBehindProxy(req)
console.log(`[dynamicShare][pageHandler][${uri}]: called`)
- const cachedHtml = await pageRepository.findFile(adjustedPath)
- if (cachedHtml && !disableCaching) {
- console.log(`[dynamicShare][pageHandler][${uri}]: return cached`)
- const html = arrayBufferToString(await cachedHtml.data)
- res.type('html').set('Cache-Control', indexHtmlCacheControlHeader).send(html)
- return
- } else {
- console.log(`[dynamicShare][pageHandler][${uri}]: rendering`)
- const updatedHtml = await useIndexAndDynamicPreviewImage(uri, indexHtml)
- console.log(`[dynamicShare][pageHandler][${uri}]: caching`)
- const data = stringToArrayBuffer(updatedHtml)
- const file: RepositoryFile = { data, type: 'text/html', uri: adjustedPath }
- await pageRepository.addFile(file)
- console.log(`[dynamicShare][pageHandler][${uri}]: return html`)
- res.type('html').set('Cache-Control', indexHtmlCacheControlHeader).send(updatedHtml)
- return
+ if (enableCaching) {
+ console.log(`[dynamicShare][pageHandler][${uri}]: checking for cached`)
+ const cachedHtml = await pageRepository.findFile(adjustedPath)
+ if (cachedHtml) {
+ console.log(`[dynamicShare][pageHandler][${uri}]: return cached`)
+ const html = arrayBufferToString(await cachedHtml.data)
+ res.type('html').set('Cache-Control', indexHtmlCacheControlHeader).send(html)
+ return
+ }
}
+ console.log(`[dynamicShare][pageHandler][${uri}]: rendering`)
+ const updatedHtml = await useIndexAndDynamicPreviewImage(uri, indexHtml)
+ console.log(`[dynamicShare][pageHandler][${uri}]: caching`)
+ const data = stringToArrayBuffer(updatedHtml)
+ const file: RepositoryFile = { data, type: 'text/html', uri: adjustedPath }
+ await pageRepository.addFile(file)
+ console.log(`[dynamicShare][pageHandler][${uri}]: return html`)
+ res.type('html').set('Cache-Control', indexHtmlCacheControlHeader).send(updatedHtml)
+ return
} catch (error) {
+ const status = HttpStatusCode.ServiceUnavailable
+ console.log(`[dynamicShare][useIndexAndDynamicPreviewImage][${uri}]: error, returning status code ${status}`)
console.log(error)
+ res.status(status)
+ .set('Cache-Control', 'no-store, no-cache, must-revalidate, proxy-revalidate')
+ .set('Retry-After', '60') // Retry after 60 seconds
+ .send()
}
}
next()
diff --git a/src/modules/metaServer/contentHandlers/dynamicShare/lib/image/getImageMeta.ts b/src/modules/metaServer/contentHandlers/dynamicShare/lib/image/getImageMeta.ts
index 60590fd..cb10eef 100644
--- a/src/modules/metaServer/contentHandlers/dynamicShare/lib/image/getImageMeta.ts
+++ b/src/modules/metaServer/contentHandlers/dynamicShare/lib/image/getImageMeta.ts
@@ -1,6 +1,6 @@
import { Meta, OpenGraphMeta, TwitterMeta } from '@xyo-network/sdk-meta'
-import { defaultViewportSize } from '../../../../lib/index.js'
+import { defaultViewportSize } from '../../../../lib/index.ts'
import { getImageUrlFromPage } from './getImageUrlFromPage.ts'
/**
diff --git a/src/modules/metaServer/contentHandlers/dynamicShare/lib/image/getPreviewUrlFromPage.ts b/src/modules/metaServer/contentHandlers/dynamicShare/lib/image/getPreviewUrlFromPage.ts
deleted file mode 100644
index a641a1d..0000000
--- a/src/modules/metaServer/contentHandlers/dynamicShare/lib/image/getPreviewUrlFromPage.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import { assertEx } from '@xylabs/assert'
-import he from 'he'
-const { decode } = he
-
-import { useSpaPage } from '../../../../lib/index.js'
-
-/**
- * The property name of the meta element
- * which contains the preview image URL
- */
-const xyoOgImageProperty = 'xyo:og:image'
-
-// Define the regex pattern to match the meta element
-const xyoOgImageElementRegex = /]*property="xyo:og:image"[^>]*content="([^"]*)"[^>]*>/
-
-/**
- * Returns the URL of the preview image from within the Live Share page's meta tags
- * @param url The URL of the Live Share page
- * @returns The URL of the preview image from within the Live Share page's meta tags
- */
-export const getPreviewUrlFromPage = async (url: string): Promise => {
- // TODO: Optimize this with something like React SSR
- const content = await useSpaPage(url, async (page) => {
- console.log(`[dynamicShare][getPreviewUrlFromPage][${url}]: navigated to ${url}`)
- await page.waitForSelector('head > meta[property="xyo:og:image"]', { timeout: 15_000 })
- console.log(`[dynamicShare][getPreviewUrlFromPage][${url}]: found meta property ${xyoOgImageProperty}`)
- return await page.content()
- })
- const html = assertEx(content, `[dynamicShare][getPreviewUrlFromPage][${url}]: error retrieving html`)
- // Use the regex to extract the expected meta element
- const match = html.match(xyoOgImageElementRegex)
- // Extract the preview image URL from the meta element & decode it
- const previewUrl = decode(
- assertEx(match?.[1], `[dynamicShare][getPreviewUrlFromPage][${url}]: error, missing meta element with ${xyoOgImageProperty} property`),
- )
- return previewUrl
-}
-
-/**
- * Returns the URL of the preview image from within the Live Share page's meta tags
- * or undefined if the preview image URL could not be obtained
- * @param url The URL of the Live Share page
- * @returns The URL of the preview image from within the Live Share page's meta tags
- * or undefined if the preview image URL could not be obtained
- */
-export const tryGetPreviewUrlFromPage = async (url: string): Promise => {
- try {
- return await getPreviewUrlFromPage(url)
- } catch {
- return undefined
- }
-}
diff --git a/src/modules/metaServer/contentHandlers/dynamicShare/lib/image/index.ts b/src/modules/metaServer/contentHandlers/dynamicShare/lib/image/index.ts
index 2f471ed..628c421 100644
--- a/src/modules/metaServer/contentHandlers/dynamicShare/lib/image/index.ts
+++ b/src/modules/metaServer/contentHandlers/dynamicShare/lib/image/index.ts
@@ -1 +1 @@
-export * from './getImageMeta.js'
+export * from './getImageMeta.ts'
diff --git a/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/getRenderedPageHtml/getRenderedPageHtml.ts b/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/getRenderedPageHtml/getRenderedPageHtml.ts
deleted file mode 100644
index 0fa73c0..0000000
--- a/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/getRenderedPageHtml/getRenderedPageHtml.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { usePage } from '../../../../../lib/index.js'
-
-/**
- * Gets the rendered page html
- * @param url The url to navigate to
- * @param navigateToRootFirst Should navigate to the root of the url first, then navigate to the relative path
- * @returns The rendered page html
- */
-export const getRenderedPageHtml = async (url: string): Promise => {
- try {
- console.log(`[dynamicShare][getRenderedPageHtml][${url}]: rendering`)
- const html = await usePage(url, undefined, async (page) => {
- console.log(`[dynamicShare][getRenderedPageHtml][${url}]: navigated to ${url}`)
- return await page.content()
- })
- console.log(`[dynamicShare][getRenderedPageHtml][${url}]: rendered`)
- return html
- } catch (error) {
- console.log(error)
- }
- return undefined
-}
diff --git a/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/getRenderedPageHtml/getRenderedSpaPageHtml.ts b/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/getRenderedPageHtml/getRenderedSpaPageHtml.ts
deleted file mode 100644
index 03c4c6b..0000000
--- a/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/getRenderedPageHtml/getRenderedSpaPageHtml.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { useSpaPage } from '../../../../../lib/index.js'
-
-/**
- * Gets the rendered page html
- * @param url The url to navigate to
- * @param navigateToRootFirst Should navigate to the root of the url first, then navigate to the relative path
- * @returns The rendered page html
- */
-export const getRenderedSpaPageHtml = async (url: string): Promise => {
- try {
- console.log(`[dynamicShare][getRenderedPageHtml][${url}]: rendering`)
- const html = await useSpaPage(url, async (page) => {
- console.log(`[dynamicShare][getRenderedPageHtml][${url}]: navigated to ${url}`)
- return await page.content()
- })
- console.log(`[dynamicShare][getRenderedPageHtml][${url}]: rendered`)
- return html
- } catch (error) {
- console.log(error)
- }
- return undefined
-}
diff --git a/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/getRenderedPageHtml/index.ts b/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/getRenderedPageHtml/index.ts
deleted file mode 100644
index bfff53f..0000000
--- a/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/getRenderedPageHtml/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from './getRenderedPageHtml.js'
-export * from './getRenderedSpaPageHtml.js'
diff --git a/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/getRenderedPageHtml/spec/getRenderedSpaPageHtml.spec.ts b/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/getRenderedPageHtml/spec/getRenderedSpaPageHtml.spec.ts
deleted file mode 100644
index f8959fc..0000000
--- a/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/getRenderedPageHtml/spec/getRenderedSpaPageHtml.spec.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { getRenderedSpaPageHtml } from '../getRenderedSpaPageHtml.js'
-
-describe.skip('getRenderedSpaPageHtml', () => {
- const uri = 'https://xyo.network/brand'
- const expected = 'XYO: Brand Assets & Logos'
- it('gets the page', async () => {
- const result = await getRenderedSpaPageHtml(uri)
- expect(result).toContain(expected)
- })
-})
diff --git a/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/index.ts b/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/index.ts
index a83461a..1e35759 100644
--- a/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/index.ts
+++ b/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/index.ts
@@ -1,2 +1 @@
-export * from './getRenderedPageHtml/index.js'
-export * from './useIndexAndDeferredPreviewImage/index.ts'
+export * from './useIndexAndDynamicPreviewImage/index.ts'
diff --git a/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/useIndexAndDeferredPreviewImage/useIndexAndDynamicPreviewImage.ts b/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/useIndexAndDeferredPreviewImage/useIndexAndDynamicPreviewImage.ts
deleted file mode 100644
index 41afe5c..0000000
--- a/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/useIndexAndDeferredPreviewImage/useIndexAndDynamicPreviewImage.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { metaBuilder } from '@xyo-network/sdk-meta'
-
-import { getImageMeta } from '../../image/index.ts'
-
-export const useIndexAndDynamicPreviewImage = async (url: string, indexHtml: string): Promise => {
- try {
- console.log(`[dynamicShare][useIndexAndDynamicPreviewImage][${url}]: generating preview image meta`)
- const meta = await getImageMeta(url)
- const updatedHtml = metaBuilder(indexHtml, meta)
- console.log(`[dynamicShare][useIndexAndDynamicPreviewImage][${url}]: returning index.html & preview image meta`)
- return updatedHtml
- } catch (error) {
- console.log(error)
- }
- console.log(`[dynamicShare][useIndexAndDynamicPreviewImage][${url}]: error, returning index.html`)
- return indexHtml
-}
diff --git a/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/useIndexAndDeferredPreviewImage/index.ts b/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/useIndexAndDynamicPreviewImage/index.ts
similarity index 100%
rename from src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/useIndexAndDeferredPreviewImage/index.ts
rename to src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/useIndexAndDynamicPreviewImage/index.ts
diff --git a/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/useIndexAndDynamicPreviewImage/useIndexAndDynamicPreviewImage.ts b/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/useIndexAndDynamicPreviewImage/useIndexAndDynamicPreviewImage.ts
new file mode 100644
index 0000000..60662e3
--- /dev/null
+++ b/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/useIndexAndDynamicPreviewImage/useIndexAndDynamicPreviewImage.ts
@@ -0,0 +1,11 @@
+import { metaBuilder } from '@xyo-network/sdk-meta'
+
+import { getImageMeta } from '../../image/index.ts'
+
+export const useIndexAndDynamicPreviewImage = async (url: string, indexHtml: string): Promise => {
+ console.log(`[dynamicShare][useIndexAndDynamicPreviewImage][${url}]: generating preview image meta`)
+ const meta = await getImageMeta(url)
+ const updatedHtml = metaBuilder(indexHtml, meta)
+ console.log(`[dynamicShare][useIndexAndDynamicPreviewImage][${url}]: returning index.html & preview image meta`)
+ return updatedHtml
+}
diff --git a/src/modules/metaServer/contentHandlers/liveShare/lib/pageStrategies/getRenderedPageHtml/getRenderedPageHtml.ts b/src/modules/metaServer/contentHandlers/liveShare/lib/pageStrategies/getRenderedPageHtml/getRenderedPageHtml.ts
deleted file mode 100644
index 3a46894..0000000
--- a/src/modules/metaServer/contentHandlers/liveShare/lib/pageStrategies/getRenderedPageHtml/getRenderedPageHtml.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { usePage } from '../../../../../lib/index.js'
-
-/**
- * Gets the rendered page html
- * @param url The url to navigate to
- * @param navigateToRootFirst Should navigate to the root of the url first, then navigate to the relative path
- * @returns The rendered page html
- */
-export const getRenderedPageHtml = async (url: string): Promise => {
- try {
- console.log(`[liveShare][getRenderedPageHtml][${url}]: rendering`)
- const html = await usePage(url, undefined, async (page) => {
- console.log(`[liveShare][getRenderedPageHtml][${url}]: navigated to ${url}`)
- return await page.content()
- })
- console.log(`[liveShare][getRenderedPageHtml][${url}]: rendered`)
- return html
- } catch (error) {
- console.log(error)
- }
- return undefined
-}
diff --git a/src/modules/metaServer/contentHandlers/liveShare/lib/pageStrategies/getRenderedPageHtml/getRenderedSpaPageHtml.ts b/src/modules/metaServer/contentHandlers/liveShare/lib/pageStrategies/getRenderedPageHtml/getRenderedSpaPageHtml.ts
deleted file mode 100644
index 1f14365..0000000
--- a/src/modules/metaServer/contentHandlers/liveShare/lib/pageStrategies/getRenderedPageHtml/getRenderedSpaPageHtml.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { useSpaPage } from '../../../../../lib/index.js'
-
-/**
- * Gets the rendered page html
- * @param url The url to navigate to
- * @param navigateToRootFirst Should navigate to the root of the url first, then navigate to the relative path
- * @returns The rendered page html
- */
-export const getRenderedSpaPageHtml = async (url: string): Promise => {
- try {
- console.log(`[liveShare][getRenderedPageHtml][${url}]: rendering`)
- const html = await useSpaPage(url, async (page) => {
- console.log(`[liveShare][getRenderedPageHtml][${url}]: navigated to ${url}`)
- return await page.content()
- })
- console.log(`[liveShare][getRenderedPageHtml][${url}]: rendered`)
- return html
- } catch (error) {
- console.log(error)
- }
- return undefined
-}
diff --git a/src/modules/metaServer/contentHandlers/liveShare/lib/pageStrategies/getRenderedPageHtml/index.ts b/src/modules/metaServer/contentHandlers/liveShare/lib/pageStrategies/getRenderedPageHtml/index.ts
deleted file mode 100644
index bfff53f..0000000
--- a/src/modules/metaServer/contentHandlers/liveShare/lib/pageStrategies/getRenderedPageHtml/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from './getRenderedPageHtml.js'
-export * from './getRenderedSpaPageHtml.js'
diff --git a/src/modules/metaServer/contentHandlers/liveShare/lib/pageStrategies/getRenderedPageHtml/spec/getRenderedSpaPageHtml.spec.ts b/src/modules/metaServer/contentHandlers/liveShare/lib/pageStrategies/getRenderedPageHtml/spec/getRenderedSpaPageHtml.spec.ts
deleted file mode 100644
index f8959fc..0000000
--- a/src/modules/metaServer/contentHandlers/liveShare/lib/pageStrategies/getRenderedPageHtml/spec/getRenderedSpaPageHtml.spec.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import { getRenderedSpaPageHtml } from '../getRenderedSpaPageHtml.js'
-
-describe.skip('getRenderedSpaPageHtml', () => {
- const uri = 'https://xyo.network/brand'
- const expected = 'XYO: Brand Assets & Logos'
- it('gets the page', async () => {
- const result = await getRenderedSpaPageHtml(uri)
- expect(result).toContain(expected)
- })
-})
diff --git a/src/modules/metaServer/contentHandlers/liveShare/lib/pageStrategies/getRenderedPageHtml/spec/tsconfig.json b/src/modules/metaServer/contentHandlers/liveShare/lib/pageStrategies/getRenderedPageHtml/spec/tsconfig.json
deleted file mode 100644
index 8208316..0000000
--- a/src/modules/metaServer/contentHandlers/liveShare/lib/pageStrategies/getRenderedPageHtml/spec/tsconfig.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "compilerOptions": {
- "allowImportingTsExtensions": true,
- },
- "extends": "@xylabs/tsconfig-jest"
-}
\ No newline at end of file
diff --git a/src/modules/metaServer/contentHandlers/liveShare/lib/pageStrategies/index.ts b/src/modules/metaServer/contentHandlers/liveShare/lib/pageStrategies/index.ts
index ffc11e3..21a5ffe 100644
--- a/src/modules/metaServer/contentHandlers/liveShare/lib/pageStrategies/index.ts
+++ b/src/modules/metaServer/contentHandlers/liveShare/lib/pageStrategies/index.ts
@@ -1,2 +1 @@
-export * from './getRenderedPageHtml/index.js'
-export * from './useIndexAndDeferredPreviewImage/index.js'
+export * from './useIndexAndDeferredPreviewImage/index.ts'
diff --git a/src/modules/metaServer/contentHandlers/liveShare/liveShareHandlers.ts b/src/modules/metaServer/contentHandlers/liveShare/liveShareHandlers.ts
index 3791d69..dbef52d 100644
--- a/src/modules/metaServer/contentHandlers/liveShare/liveShareHandlers.ts
+++ b/src/modules/metaServer/contentHandlers/liveShare/liveShareHandlers.ts
@@ -54,7 +54,7 @@ const maxImageGenerationWait = 8000
* the environment is fully initialized.
*/
const imageRepository = () => getFileRepository()
-const disableCaching = false
+const enableCaching = true
const getPageHandler = (baseDir: string) => {
// Ensure file containing base HTML exists
@@ -70,23 +70,25 @@ const getPageHandler = (baseDir: string) => {
try {
const uri = getUriBehindProxy(req)
console.log(`[liveShare][pageHandler][${uri}]: called`)
- const cachedHtml = await pageRepository.findFile(adjustedPath)
- if (cachedHtml && !disableCaching) {
- console.log(`[liveShare][pageHandler][${uri}]: return cached`)
- const html = arrayBufferToString(await cachedHtml.data)
- res.type('html').set('Cache-Control', indexHtmlCacheControlHeader).send(html)
- return
- } else {
- console.log(`[liveShare][pageHandler][${uri}]: rendering`)
- const updatedHtml = useIndexAndDeferredPreviewImage(uri, imageRepository(), indexHtml)
- console.log(`[liveShare][pageHandler][${uri}]: caching`)
- const data = stringToArrayBuffer(updatedHtml)
- const file: RepositoryFile = { data, type: 'text/html', uri: adjustedPath }
- await pageRepository.addFile(file)
- console.log(`[liveShare][pageHandler][${uri}]: return html`)
- res.type('html').set('Cache-Control', indexHtmlCacheControlHeader).send(updatedHtml)
- return
+ if (enableCaching) {
+ console.log(`[liveShare][pageHandler][${uri}]: checking for cached`)
+ const cachedHtml = await pageRepository.findFile(adjustedPath)
+ if (cachedHtml) {
+ console.log(`[liveShare][pageHandler][${uri}]: return cached`)
+ const html = arrayBufferToString(await cachedHtml.data)
+ res.type('html').set('Cache-Control', indexHtmlCacheControlHeader).send(html)
+ return
+ }
}
+ console.log(`[liveShare][pageHandler][${uri}]: rendering`)
+ const updatedHtml = useIndexAndDeferredPreviewImage(uri, imageRepository(), indexHtml)
+ console.log(`[liveShare][pageHandler][${uri}]: caching`)
+ const data = stringToArrayBuffer(updatedHtml)
+ const file: RepositoryFile = { data, type: 'text/html', uri: adjustedPath }
+ await pageRepository.addFile(file)
+ console.log(`[liveShare][pageHandler][${uri}]: return html`)
+ res.type('html').set('Cache-Control', indexHtmlCacheControlHeader).send(updatedHtml)
+ return
} catch (error) {
console.log(error)
}
diff --git a/src/modules/metaServer/lib/index.ts b/src/modules/metaServer/lib/index.ts
index ec485d8..2c13672 100644
--- a/src/modules/metaServer/lib/index.ts
+++ b/src/modules/metaServer/lib/index.ts
@@ -4,6 +4,7 @@ export * from './file/index.js'
export * from './head/index.js'
export * from './image/index.js'
export * from './page/index.js'
+export * from './pageHtml/index.js'
export * from './path/index.js'
export * from './repository/index.js'
export * from './socialMedia/index.js'
diff --git a/src/modules/metaServer/lib/logging/ScopedLogFunction.ts b/src/modules/metaServer/lib/logging/ScopedLogFunction.ts
new file mode 100644
index 0000000..ae3fc30
--- /dev/null
+++ b/src/modules/metaServer/lib/logging/ScopedLogFunction.ts
@@ -0,0 +1 @@
+export type ScopedLogFunction = (message: string, scopes: string[]) => void
diff --git a/src/modules/metaServer/lib/logging/index.ts b/src/modules/metaServer/lib/logging/index.ts
new file mode 100644
index 0000000..72cc927
--- /dev/null
+++ b/src/modules/metaServer/lib/logging/index.ts
@@ -0,0 +1,2 @@
+export * from './ScopedLogFunction.ts'
+export * from './scopedLoggers.ts'
diff --git a/src/modules/metaServer/lib/logging/scopedLoggers.ts b/src/modules/metaServer/lib/logging/scopedLoggers.ts
new file mode 100644
index 0000000..22005cc
--- /dev/null
+++ b/src/modules/metaServer/lib/logging/scopedLoggers.ts
@@ -0,0 +1,51 @@
+import { ScopedLogFunction } from './ScopedLogFunction.ts'
+
+type ConsoleLoggerMethod = keyof Pick
+
+/**
+ * Logs a log message to the console
+ * @param message The message to log
+ * @param scopes The scopes to log the message under
+ */
+const scopedLoggerWithVerbosity = (verbosity: ConsoleLoggerMethod): ScopedLogFunction => {
+ const logFunction: ScopedLogFunction = (message: string, scopes: string[] = []) => {
+ const prefix = scopes.length > 0 ? `[${scopes.join('][')}]` : ''
+ console[verbosity](`${prefix}: ${message}`)
+ }
+ return logFunction
+}
+
+/**
+ * Logs a debug message to the console
+ * @param message The message to log
+ * @param scopes The scopes to log the message under
+ */
+export const debug: ScopedLogFunction = scopedLoggerWithVerbosity('debug')
+
+/**
+ * Logs an info message to the console
+ * @param message The message to log
+ * @param scopes The scopes to log the message under
+ */
+export const info: ScopedLogFunction = scopedLoggerWithVerbosity('info')
+
+/**
+ * Logs a log message to the console
+ * @param message The message to log
+ * @param scopes The scopes to log the message under
+ */
+export const log: ScopedLogFunction = scopedLoggerWithVerbosity('log')
+
+/**
+ * Logs a warning message to the console
+ * @param message The message to log
+ * @param scopes The scopes to log the message under
+ */
+export const warn: ScopedLogFunction = scopedLoggerWithVerbosity('warn')
+
+/**
+ * Logs an error message to the console
+ * @param message The message to log
+ * @param scopes The scopes to log the message under
+ */
+export const error: ScopedLogFunction = scopedLoggerWithVerbosity('error')
diff --git a/src/modules/metaServer/lib/page/usePage/spec/usePage.spec.ts b/src/modules/metaServer/lib/page/usePage/spec/usePage.spec.ts
index 3c824dc..ac6e6d8 100644
--- a/src/modules/metaServer/lib/page/usePage/spec/usePage.spec.ts
+++ b/src/modules/metaServer/lib/page/usePage/spec/usePage.spec.ts
@@ -1,24 +1,24 @@
import { usePage } from '../usePage.js'
+const waitForElementToInclude = (selector: string, expectedValue: string) => {
+ const element = document.querySelector(selector)
+ return element && element.textContent?.includes(expectedValue)
+}
+
describe('usePage', () => {
- const uri = 'https://xyo.network/brand'
- const expected = 'XYO: Brand Assets & Logos'
- describe('with navigateToRootFirst=false', () => {
- it('gets the page', async () => {
- const result = await usePage(uri, undefined, async (page) => {
- await page.waitForSelector('title', { timeout: 10_000 })
- return page.content()
- })
- expect(result).toContain(expected)
- }, 60_000)
- })
- describe('with navigateToRootFirst=true', () => {
- it('gets the page', async () => {
- const result = await usePage(uri, undefined, async (page) => {
- await page.waitForSelector('title', { timeout: 10_000 })
- return page.content()
- })
- expect(result).toContain(expected)
- }, 60_000)
- })
+ const uri = 'https://react.dev/learn'
+ const expected = 'Quick Start'
+ it('gets the page', async () => {
+ const result = await usePage(uri, undefined, async (page) => {
+ await page.waitForFunction(waitForElementToInclude,
+ {
+ polling: 100,
+ timeout: 30_000,
+ },
+ 'title',
+ expected)
+ return page.content()
+ })
+ expect(result).toContain(expected)
+ }, 60_000)
})
diff --git a/src/modules/metaServer/lib/page/usePage/spec/useSpaPage.perf.spec.ts b/src/modules/metaServer/lib/page/usePage/spec/useSpaPage.perf.spec.ts
new file mode 100644
index 0000000..e6b2a9c
--- /dev/null
+++ b/src/modules/metaServer/lib/page/usePage/spec/useSpaPage.perf.spec.ts
@@ -0,0 +1,14 @@
+import { useSpaPage } from '../useSpaPage.js'
+
+describe.skip('useSpaPage [perf]', () => {
+ const uri = 'https://react.dev/learn'
+ const expected = 'Quick Start'
+ it('gets the page', async () => {
+ await Promise.all(Array.from({ length: 200 }).map(async () => {
+ const content = await useSpaPage(uri, async (page) => {
+ return await page.content()
+ })
+ expect(content).toContain(expected)
+ }))
+ }, 60_000)
+})
diff --git a/src/modules/metaServer/lib/page/usePage/spec/useSpaPage.spec.ts b/src/modules/metaServer/lib/page/usePage/spec/useSpaPage.spec.ts
index c7a9178..2e07f1d 100644
--- a/src/modules/metaServer/lib/page/usePage/spec/useSpaPage.spec.ts
+++ b/src/modules/metaServer/lib/page/usePage/spec/useSpaPage.spec.ts
@@ -1,26 +1,12 @@
import { useSpaPage } from '../useSpaPage.js'
-const waitForElementToInclude = (selector: string, expectedValue: string) => {
- const element = document.querySelector(selector)
- return element && element.textContent?.includes(expectedValue)
-}
-
describe('useSpaPage', () => {
- const uri = 'https://xyo.network/brand'
- const expected = 'XYO: Brand Assets'
- describe('with navigateToRootFirst=true', () => {
- it('gets the page', async () => {
- const content = await useSpaPage(uri, async (page) => {
- await page.waitForFunction(waitForElementToInclude,
- {
- polling: 100,
- timeout: 30_000,
- },
- 'title',
- expected)
- return page.content()
- })
- expect(content).toContain(expected)
- }, 60_000)
- })
+ const uri = 'https://react.dev/learn'
+ const expected = 'Quick Start'
+ it('gets the page', async () => {
+ const content = await useSpaPage(uri, async (page) => {
+ return await page.content()
+ })
+ expect(content).toContain(expected)
+ }, 60_000)
})
diff --git a/src/modules/metaServer/lib/pageHtml/getRenderedPageHtml.ts b/src/modules/metaServer/lib/pageHtml/getRenderedPageHtml.ts
new file mode 100644
index 0000000..892700c
--- /dev/null
+++ b/src/modules/metaServer/lib/pageHtml/getRenderedPageHtml.ts
@@ -0,0 +1,23 @@
+import { log } from '../logging/index.ts'
+import { usePage } from '../page/index.ts'
+
+/**
+ * Gets the rendered page html
+ * @param url The url to navigate to
+ * @param logScopePrefix The prefix to use for logging
+ * @returns The rendered page html
+ */
+export const getRenderedPageHtml = async (url: string, logScopePrefix: string): Promise => {
+ try {
+ log('rendering', [logScopePrefix, 'getRenderedPageHtml', url])
+ const html = await usePage(url, undefined, async (page) => {
+ log('navigated to url', [logScopePrefix, 'getRenderedPageHtml', url])
+ return await page.content()
+ })
+ log('rendered', [logScopePrefix, 'getRenderedPageHtml', url])
+ return html
+ } catch (error) {
+ console.log(error)
+ }
+ return undefined
+}
diff --git a/src/modules/metaServer/lib/pageHtml/getRenderedSpaPageHtml.ts b/src/modules/metaServer/lib/pageHtml/getRenderedSpaPageHtml.ts
new file mode 100644
index 0000000..824d38b
--- /dev/null
+++ b/src/modules/metaServer/lib/pageHtml/getRenderedSpaPageHtml.ts
@@ -0,0 +1,24 @@
+import { log } from '../logging/index.ts'
+import { useSpaPage } from '../page/index.ts'
+
+/**
+ * Gets the rendered page html by navigating to the root of the url first, then to the relative path, just like a user would
+ * when navigating a SPA
+ * @param url The url to navigate to
+ * @param logScopePrefix The prefix to use for logging
+ * @returns The rendered page html
+ */
+export const getRenderedSpaPageHtml = async (url: string, logScopePrefix: string): Promise => {
+ try {
+ log('rendering', [logScopePrefix, 'getRenderedSpaPageHtml', url])
+ const html = await useSpaPage(url, async (page) => {
+ log('navigated to url', [logScopePrefix, 'getRenderedSpaPageHtml', url])
+ return await page.content()
+ })
+ log('rendered', [logScopePrefix, 'getRenderedSpaPageHtml', url])
+ return html
+ } catch (error) {
+ console.log(error)
+ }
+ return undefined
+}
diff --git a/src/modules/metaServer/lib/pageHtml/index.ts b/src/modules/metaServer/lib/pageHtml/index.ts
new file mode 100644
index 0000000..1afe4ac
--- /dev/null
+++ b/src/modules/metaServer/lib/pageHtml/index.ts
@@ -0,0 +1,2 @@
+export * from './getRenderedPageHtml.ts'
+export * from './getRenderedSpaPageHtml.ts'
diff --git a/src/modules/metaServer/lib/pageHtml/spec/getRenderedPageHtml.spec.ts b/src/modules/metaServer/lib/pageHtml/spec/getRenderedPageHtml.spec.ts
new file mode 100644
index 0000000..ab84aaf
--- /dev/null
+++ b/src/modules/metaServer/lib/pageHtml/spec/getRenderedPageHtml.spec.ts
@@ -0,0 +1,10 @@
+import { getRenderedPageHtml } from '../getRenderedPageHtml.ts'
+
+describe('getRenderedSpaPageHtml', () => {
+ const uri = 'https://react.dev/learn'
+ const expected = 'Quick Start'
+ it('gets the page', async () => {
+ const result = await getRenderedPageHtml(uri, 'test')
+ expect(result).toContain(expected)
+ })
+})
diff --git a/src/modules/metaServer/lib/pageHtml/spec/getRenderedSpaPageHtml.spec.ts b/src/modules/metaServer/lib/pageHtml/spec/getRenderedSpaPageHtml.spec.ts
new file mode 100644
index 0000000..d955f94
--- /dev/null
+++ b/src/modules/metaServer/lib/pageHtml/spec/getRenderedSpaPageHtml.spec.ts
@@ -0,0 +1,10 @@
+import { getRenderedSpaPageHtml } from '../getRenderedSpaPageHtml.ts'
+
+describe('getRenderedSpaPageHtml', () => {
+ const uri = 'https://react.dev/learn'
+ const expected = 'Quick Start'
+ it('gets the page', async () => {
+ const result = await getRenderedSpaPageHtml(uri, 'test')
+ expect(result).toContain(expected)
+ })
+})
diff --git a/src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/getRenderedPageHtml/spec/tsconfig.json b/src/modules/metaServer/lib/pageHtml/spec/tsconfig.json
similarity index 100%
rename from src/modules/metaServer/contentHandlers/dynamicShare/lib/pageStrategies/getRenderedPageHtml/spec/tsconfig.json
rename to src/modules/metaServer/lib/pageHtml/spec/tsconfig.json