@epic-web/workshop-utils 6.15.0 → 6.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/esm/apps.server.d.ts +244 -244
  2. package/dist/esm/apps.server.d.ts.map +1 -1
  3. package/dist/esm/apps.server.js +2 -5
  4. package/dist/esm/apps.server.js.map +1 -1
  5. package/dist/esm/cache.server.d.ts +27 -27
  6. package/dist/esm/cache.server.d.ts.map +1 -1
  7. package/dist/esm/cache.server.js +3 -1
  8. package/dist/esm/cache.server.js.map +1 -1
  9. package/dist/esm/compile-mdx.server.d.ts +1 -0
  10. package/dist/esm/compile-mdx.server.d.ts.map +1 -1
  11. package/dist/esm/compile-mdx.server.js +1 -0
  12. package/dist/esm/compile-mdx.server.js.map +1 -1
  13. package/dist/esm/config.server.d.ts +6 -7
  14. package/dist/esm/config.server.d.ts.map +1 -1
  15. package/dist/esm/config.server.js +4 -3
  16. package/dist/esm/config.server.js.map +1 -1
  17. package/dist/esm/db.server.d.ts +1 -0
  18. package/dist/esm/db.server.d.ts.map +1 -1
  19. package/dist/esm/db.server.js +1 -0
  20. package/dist/esm/db.server.js.map +1 -1
  21. package/dist/esm/diff.server.d.ts.map +1 -1
  22. package/dist/esm/diff.server.js +2 -0
  23. package/dist/esm/diff.server.js.map +1 -1
  24. package/dist/esm/env.server.d.ts +6 -0
  25. package/dist/esm/env.server.d.ts.map +1 -1
  26. package/dist/esm/env.server.js +6 -0
  27. package/dist/esm/env.server.js.map +1 -1
  28. package/dist/esm/epic-api.server.d.ts +2 -2
  29. package/dist/esm/epic-api.server.d.ts.map +1 -1
  30. package/dist/esm/epic-api.server.js +2 -0
  31. package/dist/esm/epic-api.server.js.map +1 -1
  32. package/dist/esm/git.server.d.ts +1 -0
  33. package/dist/esm/git.server.d.ts.map +1 -1
  34. package/dist/esm/git.server.js +1 -0
  35. package/dist/esm/git.server.js.map +1 -1
  36. package/dist/esm/init-env.d.ts +16 -0
  37. package/dist/esm/init-env.d.ts.map +1 -0
  38. package/dist/esm/init-env.js +6 -0
  39. package/dist/esm/init-env.js.map +1 -0
  40. package/dist/esm/modified-time.server.d.ts +1 -0
  41. package/dist/esm/modified-time.server.d.ts.map +1 -1
  42. package/dist/esm/modified-time.server.js +1 -0
  43. package/dist/esm/modified-time.server.js.map +1 -1
  44. package/dist/esm/notifications.server.d.ts +3 -3
  45. package/dist/esm/notifications.server.d.ts.map +1 -1
  46. package/dist/esm/notifications.server.js +2 -0
  47. package/dist/esm/notifications.server.js.map +1 -1
  48. package/dist/esm/playwright.server.d.ts +1 -0
  49. package/dist/esm/playwright.server.d.ts.map +1 -1
  50. package/dist/esm/playwright.server.js +1 -0
  51. package/dist/esm/playwright.server.js.map +1 -1
  52. package/dist/esm/process-manager.server.d.ts +1 -0
  53. package/dist/esm/process-manager.server.d.ts.map +1 -1
  54. package/dist/esm/process-manager.server.js +1 -0
  55. package/dist/esm/process-manager.server.js.map +1 -1
  56. package/dist/esm/request-context.server.d.ts +1 -0
  57. package/dist/esm/request-context.server.d.ts.map +1 -1
  58. package/dist/esm/request-context.server.js +1 -0
  59. package/dist/esm/request-context.server.js.map +1 -1
  60. package/dist/esm/timing.server.d.ts +1 -0
  61. package/dist/esm/timing.server.d.ts.map +1 -1
  62. package/dist/esm/timing.server.js +1 -0
  63. package/dist/esm/timing.server.js.map +1 -1
  64. package/dist/esm/user.server.d.ts.map +1 -1
  65. package/dist/esm/user.server.js +2 -0
  66. package/dist/esm/user.server.js.map +1 -1
  67. package/dist/esm/utils.d.ts +1 -0
  68. package/dist/esm/utils.d.ts.map +1 -1
  69. package/dist/esm/utils.js +1 -0
  70. package/dist/esm/utils.js.map +1 -1
  71. package/dist/esm/utils.server.d.ts +1 -0
  72. package/dist/esm/utils.server.d.ts.map +1 -1
  73. package/dist/esm/utils.server.js +1 -0
  74. package/dist/esm/utils.server.js.map +1 -1
  75. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"process-manager.server.js","sourceRoot":"","sources":["../../src/process-manager.server.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn, type ChildProcess } from 'child_process'\nimport net from 'node:net'\nimport { remember } from '@epic-web/remember'\nimport chalk from 'chalk'\nimport closeWithGrace from 'close-with-grace'\nimport findProcess from 'find-process'\nimport fkill from 'fkill'\nimport { type App } from './apps.server.js'\nimport { getWorkshopUrl } from './config.server.js'\nimport { getErrorMessage } from './utils.js'\n\nconst isDeployed =\n\tprocess.env.EPICSHOP_DEPLOYED === 'true' ||\n\tprocess.env.EPICSHOP_DEPLOYED === '1'\n\ntype DevProcessesMap = Map<\n\tstring,\n\t{\n\t\tcolor: (typeof colors)[number]\n\t\tprocess: ChildProcess\n\t\tport: number\n\t}\n>\n\ntype OutputLine = {\n\ttype: 'stdout' | 'stderr'\n\tcontent: string\n\ttimestamp: number\n}\n\ntype TestProcessEntry = {\n\tprocess: ChildProcess | null\n\toutput: Array<OutputLine>\n\texitCode?: number | null\n}\n\ntype TestProcessesMap = Map<string, TestProcessEntry>\ndeclare global {\n\tvar __process_dev_close_with_grace_return__: ReturnType<\n\t\t\ttypeof closeWithGrace\n\t\t>,\n\t\t__process_test_close_with_grace_return__: ReturnType<typeof closeWithGrace>\n}\n\nconst devProcesses = remember('dev_processes', getDevProcessesMap)\nconst testProcesses = remember('test_processes', getTestProcessesMap)\n\nfunction getDevProcessesMap() {\n\tconst procs: DevProcessesMap = new Map()\n\n\tglobal.__process_dev_close_with_grace_return__?.uninstall()\n\n\tglobal.__process_dev_close_with_grace_return__ = closeWithGrace(async () => {\n\t\tfor (const [name, proc] of procs.entries()) {\n\t\t\tconsole.log('closing', name)\n\t\t\tproc.process.kill()\n\t\t}\n\t})\n\treturn procs\n}\n\nfunction getTestProcessesMap() {\n\tconst procs: TestProcessesMap = new Map()\n\n\tglobal.__process_test_close_with_grace_return__?.uninstall()\n\n\tglobal.__process_test_close_with_grace_return__ = closeWithGrace(async () => {\n\t\tfor (const [id, proc] of procs.entries()) {\n\t\t\tif (proc.process) {\n\t\t\t\tconsole.log('closing', id)\n\t\t\t\tproc.process.kill()\n\t\t\t}\n\t\t}\n\t})\n\treturn procs\n}\n\nconst colors = [\n\t'blue',\n\t'green',\n\t'yellow',\n\t'red',\n\t'magenta',\n\t'redBright',\n\t'greenBright',\n\t'yellowBright',\n\t'blueBright',\n\t'magentaBright',\n] as const\n\nexport async function runAppDev(app: App) {\n\tif (isDeployed) throw new Error('cannot run apps in deployed mode')\n\tconst key = app.name\n\t// if the app is already running, don't start it again\n\tif (devProcesses.has(key)) {\n\t\treturn { status: 'process-running', running: true } as const\n\t}\n\n\tif (app.dev.type !== 'script') {\n\t\treturn { status: 'error', error: 'no-server' } as const\n\t}\n\n\tconst { portNumber } = app.dev\n\tif (!(await isPortAvailable(portNumber))) {\n\t\treturn { status: 'port-unavailable', running: false, portNumber } as const\n\t}\n\tconst availableColors = colors.filter((color) =>\n\t\tArray.from(devProcesses.values()).every((p) => p.color !== color),\n\t)\n\tconst color =\n\t\tavailableColors[devProcesses.size % availableColors.length] ?? 'blue'\n\tconst appProcess = spawn('npm', ['run', 'dev', '--silent'], {\n\t\tcwd: app.fullPath,\n\t\tshell: true,\n\t\tstdio: ['ignore', 'pipe', 'pipe'],\n\t\tenv: {\n\t\t\t...process.env,\n\t\t\t// TODO: support specifying the env\n\t\t\tNODE_ENV: 'development',\n\t\t\t// TODO: support specifying the port\n\t\t\tPORT: String(portNumber),\n\t\t\tAPP_SERVER_PORT: String(portNumber),\n\t\t\t// let it pick a random port...\n\t\t\tREMIX_DEV_SERVER_WS_PORT: '',\n\t\t},\n\t})\n\tconst prefix = chalk[color](\n\t\t`[${app.name.replace(/^exercises\\./, '')}:${portNumber}]`,\n\t)\n\tfunction handleStdOutData(data: Buffer) {\n\t\tconsole.log(\n\t\t\tdata\n\t\t\t\t.toString('utf-8')\n\t\t\t\t.split('\\n')\n\t\t\t\t.map((line) => `${prefix} ${line}`)\n\t\t\t\t.join('\\n'),\n\t\t)\n\t}\n\tappProcess.stdout.on('data', handleStdOutData)\n\tfunction handleStdErrData(data: Buffer) {\n\t\tconsole.error(\n\t\t\tdata\n\t\t\t\t.toString('utf-8')\n\t\t\t\t.split('\\n')\n\t\t\t\t.map((line) => `${prefix} ${line}`)\n\t\t\t\t.join('\\n'),\n\t\t)\n\t}\n\tappProcess.stderr.on('data', handleStdErrData)\n\tdevProcesses.set(key, { color, process: appProcess, port: portNumber })\n\tappProcess.on('exit', (code) => {\n\t\tappProcess.stdout.off('data', handleStdOutData)\n\t\tappProcess.stderr.off('data', handleStdErrData)\n\t\tconsole.log(`${prefix} exited (${code})`)\n\t\tdevProcesses.delete(key)\n\t})\n\n\treturn { status: 'process-started', running: true } as const\n}\n\nexport async function runAppTests(app: App) {\n\tif (isDeployed) throw new Error('cannot run tests in deployed mode')\n\tconst key = app.name\n\n\tif (app.test.type !== 'script') {\n\t\treturn { status: 'error', error: 'no-test' } as const\n\t}\n\n\tconst testProcess = spawn('npm', ['run', 'test', '--silent'], {\n\t\tcwd: app.fullPath,\n\t\tshell: true,\n\t\tstdio: ['ignore', 'pipe', 'pipe'],\n\t\tenv: {\n\t\t\t...process.env,\n\t\t\t// TODO: support specifying the env\n\t\t\tNODE_ENV: 'development',\n\t\t\t// TODO: support specifying the port\n\t\t\tPORT: app.dev.type === 'script' ? String(app.dev.portNumber) : undefined,\n\t\t\tAPP_SERVER_PORT:\n\t\t\t\tapp.dev.type === 'script' ? String(app.dev.portNumber) : undefined,\n\t\t\t// let it pick a random port...\n\t\t\tREMIX_DEV_SERVER_WS_PORT: '',\n\t\t},\n\t})\n\tconst output: Array<OutputLine> = []\n\tconst entry: TestProcessEntry = { process: testProcess, output }\n\tfunction handleStdOutData(data: Buffer) {\n\t\toutput.push({\n\t\t\ttype: 'stdout',\n\t\t\tcontent: data.toString('utf-8'),\n\t\t\ttimestamp: Date.now(),\n\t\t})\n\t}\n\ttestProcess.stdout.on('data', handleStdOutData)\n\tfunction handleStdErrData(data: Buffer) {\n\t\toutput.push({\n\t\t\ttype: 'stderr',\n\t\t\tcontent: data.toString('utf-8'),\n\t\t\ttimestamp: Date.now(),\n\t\t})\n\t}\n\ttestProcess.stderr.on('data', handleStdErrData)\n\ttestProcess.on('exit', (code) => {\n\t\ttestProcess.stdout.off('data', handleStdOutData)\n\t\ttestProcess.stderr.off('data', handleStdErrData)\n\t\tentry.process = null\n\t\tentry.exitCode = code\n\t})\n\ttestProcesses.set(key, entry)\n\treturn testProcess\n}\n\nexport async function waitOnApp(app: App) {\n\tif (app.dev.type === 'script') {\n\t\tconst startTime = Date.now()\n\n\t\tconst retryInterval = 100\n\t\tconst timeout = 20_000\n\t\tlet lastError: unknown\n\t\twhile (Date.now() - startTime < timeout) {\n\t\t\ttry {\n\t\t\t\tconst url = getWorkshopUrl(app.dev.portNumber)\n\t\t\t\tawait fetch(url, {\n\t\t\t\t\tmethod: 'HEAD',\n\t\t\t\t\theaders: { Accept: '*/*' },\n\t\t\t\t})\n\t\t\t\treturn { status: 'success' } as const\n\t\t\t} catch (error) {\n\t\t\t\tlastError = error\n\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, retryInterval))\n\t\t\t}\n\t\t}\n\n\t\treturn { status: 'error', error: getErrorMessage(lastError) } as const\n\t}\n\treturn null\n}\n\nexport function isPortAvailable(port: number | string): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst server = net.createServer()\n\t\tserver.unref()\n\t\tserver.on('error', () => resolve(false))\n\n\t\tserver.listen(Number(port), () => {\n\t\t\tserver.close(() => {\n\t\t\t\tresolve(true)\n\t\t\t})\n\t\t})\n\t})\n}\n\nexport async function isAppRunning(app: { name: string }) {\n\ttry {\n\t\tconst devProcess = devProcesses.get(app.name)\n\t\tif (!devProcess?.process.pid) return false\n\t\tconst found = await findProcess('pid', devProcess.process.pid)\n\t\treturn found.length > 0\n\t} catch {\n\t\treturn false\n\t}\n}\n\nexport function isTestRunning(app: { name: string }) {\n\ttry {\n\t\tconst testProcess = testProcesses.get(app.name)\n\t\tif (!testProcess) return false\n\t\tif (testProcess.process === null) return false\n\t\ttestProcess.process.kill(0)\n\t\treturn true\n\t} catch {\n\t\treturn false\n\t}\n}\n\nexport function getTestProcessEntry(app: { name: string }) {\n\treturn testProcesses.get(app.name)\n}\n\nexport function clearTestProcessEntry(app: { name: string }) {\n\treturn testProcesses.delete(app.name)\n}\n\nexport function getProcesses() {\n\treturn { devProcesses, testProcesses }\n}\n\nexport async function closeProcess(key: string) {\n\tif (isDeployed) throw new Error('cannot close processes in deployed mode')\n\tconst proc = devProcesses.get(key)\n\tif (proc) {\n\t\tconst exitedPromise = new Promise((resolve) =>\n\t\t\tproc.process.on('exit', resolve),\n\t\t)\n\t\tif (process.platform === 'win32') {\n\t\t\tconst { execa } = await import('execa')\n\t\t\tawait execa('taskkill', ['/pid', String(proc.process.pid), '/f', '/t'])\n\t\t} else {\n\t\t\tproc.process.kill()\n\t\t}\n\t\tawait Promise.race([\n\t\t\tnew Promise((resolve) => setTimeout(resolve, 500)),\n\t\t\texitedPromise,\n\t\t])\n\t\tawait stopPort(proc.port) // just in case 🤷‍♂️\n\t\tdevProcesses.delete(key)\n\t}\n}\n\nconst sleep = (t: number) => new Promise((resolve) => setTimeout(resolve, t))\n\nexport async function stopPort(port: string | number) {\n\tif (isDeployed) throw new Error('cannot stop ports in deployed mode')\n\tawait fkill(`:${port}`, { force: true, silent: true })\n\tawait waitForPortToBeAvailable(port)\n}\n\nexport async function waitForPortToBeAvailable(port: string | number) {\n\t// wait for the port to become available again\n\tconst timeout = Date.now() + 10_000\n\tlet portAvailable = false\n\tdo {\n\t\tportAvailable = await isPortAvailable(port)\n\t\tawait sleep(100)\n\t} while (!portAvailable && Date.now() < timeout)\n\tif (!portAvailable) {\n\t\tconsole.error('Timed out waiting for the port to become available')\n\t}\n}\n"]}
1
+ {"version":3,"file":"process-manager.server.js","sourceRoot":"","sources":["../../src/process-manager.server.ts"],"names":[],"mappings":"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","sourcesContent":["import './init-env.js'\n\nimport { spawn, type ChildProcess } from 'child_process'\nimport net from 'node:net'\nimport { remember } from '@epic-web/remember'\nimport chalk from 'chalk'\nimport closeWithGrace from 'close-with-grace'\nimport findProcess from 'find-process'\nimport fkill from 'fkill'\nimport { type App } from './apps.server.js'\nimport { getWorkshopUrl } from './config.server.js'\nimport { getErrorMessage } from './utils.js'\n\nconst isDeployed =\n\tprocess.env.EPICSHOP_DEPLOYED === 'true' ||\n\tprocess.env.EPICSHOP_DEPLOYED === '1'\n\ntype DevProcessesMap = Map<\n\tstring,\n\t{\n\t\tcolor: (typeof colors)[number]\n\t\tprocess: ChildProcess\n\t\tport: number\n\t}\n>\n\ntype OutputLine = {\n\ttype: 'stdout' | 'stderr'\n\tcontent: string\n\ttimestamp: number\n}\n\ntype TestProcessEntry = {\n\tprocess: ChildProcess | null\n\toutput: Array<OutputLine>\n\texitCode?: number | null\n}\n\ntype TestProcessesMap = Map<string, TestProcessEntry>\ndeclare global {\n\tvar __process_dev_close_with_grace_return__: ReturnType<\n\t\t\ttypeof closeWithGrace\n\t\t>,\n\t\t__process_test_close_with_grace_return__: ReturnType<typeof closeWithGrace>\n}\n\nconst devProcesses = remember('dev_processes', getDevProcessesMap)\nconst testProcesses = remember('test_processes', getTestProcessesMap)\n\nfunction getDevProcessesMap() {\n\tconst procs: DevProcessesMap = new Map()\n\n\tglobal.__process_dev_close_with_grace_return__?.uninstall()\n\n\tglobal.__process_dev_close_with_grace_return__ = closeWithGrace(async () => {\n\t\tfor (const [name, proc] of procs.entries()) {\n\t\t\tconsole.log('closing', name)\n\t\t\tproc.process.kill()\n\t\t}\n\t})\n\treturn procs\n}\n\nfunction getTestProcessesMap() {\n\tconst procs: TestProcessesMap = new Map()\n\n\tglobal.__process_test_close_with_grace_return__?.uninstall()\n\n\tglobal.__process_test_close_with_grace_return__ = closeWithGrace(async () => {\n\t\tfor (const [id, proc] of procs.entries()) {\n\t\t\tif (proc.process) {\n\t\t\t\tconsole.log('closing', id)\n\t\t\t\tproc.process.kill()\n\t\t\t}\n\t\t}\n\t})\n\treturn procs\n}\n\nconst colors = [\n\t'blue',\n\t'green',\n\t'yellow',\n\t'red',\n\t'magenta',\n\t'redBright',\n\t'greenBright',\n\t'yellowBright',\n\t'blueBright',\n\t'magentaBright',\n] as const\n\nexport async function runAppDev(app: App) {\n\tif (isDeployed) throw new Error('cannot run apps in deployed mode')\n\tconst key = app.name\n\t// if the app is already running, don't start it again\n\tif (devProcesses.has(key)) {\n\t\treturn { status: 'process-running', running: true } as const\n\t}\n\n\tif (app.dev.type !== 'script') {\n\t\treturn { status: 'error', error: 'no-server' } as const\n\t}\n\n\tconst { portNumber } = app.dev\n\tif (!(await isPortAvailable(portNumber))) {\n\t\treturn { status: 'port-unavailable', running: false, portNumber } as const\n\t}\n\tconst availableColors = colors.filter((color) =>\n\t\tArray.from(devProcesses.values()).every((p) => p.color !== color),\n\t)\n\tconst color =\n\t\tavailableColors[devProcesses.size % availableColors.length] ?? 'blue'\n\tconst appProcess = spawn('npm', ['run', 'dev', '--silent'], {\n\t\tcwd: app.fullPath,\n\t\tshell: true,\n\t\tstdio: ['ignore', 'pipe', 'pipe'],\n\t\tenv: {\n\t\t\t...process.env,\n\t\t\t// TODO: support specifying the env\n\t\t\tNODE_ENV: 'development',\n\t\t\t// TODO: support specifying the port\n\t\t\tPORT: String(portNumber),\n\t\t\tAPP_SERVER_PORT: String(portNumber),\n\t\t\t// let it pick a random port...\n\t\t\tREMIX_DEV_SERVER_WS_PORT: '',\n\t\t},\n\t})\n\tconst prefix = chalk[color](\n\t\t`[${app.name.replace(/^exercises\\./, '')}:${portNumber}]`,\n\t)\n\tfunction handleStdOutData(data: Buffer) {\n\t\tconsole.log(\n\t\t\tdata\n\t\t\t\t.toString('utf-8')\n\t\t\t\t.split('\\n')\n\t\t\t\t.map((line) => `${prefix} ${line}`)\n\t\t\t\t.join('\\n'),\n\t\t)\n\t}\n\tappProcess.stdout.on('data', handleStdOutData)\n\tfunction handleStdErrData(data: Buffer) {\n\t\tconsole.error(\n\t\t\tdata\n\t\t\t\t.toString('utf-8')\n\t\t\t\t.split('\\n')\n\t\t\t\t.map((line) => `${prefix} ${line}`)\n\t\t\t\t.join('\\n'),\n\t\t)\n\t}\n\tappProcess.stderr.on('data', handleStdErrData)\n\tdevProcesses.set(key, { color, process: appProcess, port: portNumber })\n\tappProcess.on('exit', (code) => {\n\t\tappProcess.stdout.off('data', handleStdOutData)\n\t\tappProcess.stderr.off('data', handleStdErrData)\n\t\tconsole.log(`${prefix} exited (${code})`)\n\t\tdevProcesses.delete(key)\n\t})\n\n\treturn { status: 'process-started', running: true } as const\n}\n\nexport async function runAppTests(app: App) {\n\tif (isDeployed) throw new Error('cannot run tests in deployed mode')\n\tconst key = app.name\n\n\tif (app.test.type !== 'script') {\n\t\treturn { status: 'error', error: 'no-test' } as const\n\t}\n\n\tconst testProcess = spawn('npm', ['run', 'test', '--silent'], {\n\t\tcwd: app.fullPath,\n\t\tshell: true,\n\t\tstdio: ['ignore', 'pipe', 'pipe'],\n\t\tenv: {\n\t\t\t...process.env,\n\t\t\t// TODO: support specifying the env\n\t\t\tNODE_ENV: 'development',\n\t\t\t// TODO: support specifying the port\n\t\t\tPORT: app.dev.type === 'script' ? String(app.dev.portNumber) : undefined,\n\t\t\tAPP_SERVER_PORT:\n\t\t\t\tapp.dev.type === 'script' ? String(app.dev.portNumber) : undefined,\n\t\t\t// let it pick a random port...\n\t\t\tREMIX_DEV_SERVER_WS_PORT: '',\n\t\t},\n\t})\n\tconst output: Array<OutputLine> = []\n\tconst entry: TestProcessEntry = { process: testProcess, output }\n\tfunction handleStdOutData(data: Buffer) {\n\t\toutput.push({\n\t\t\ttype: 'stdout',\n\t\t\tcontent: data.toString('utf-8'),\n\t\t\ttimestamp: Date.now(),\n\t\t})\n\t}\n\ttestProcess.stdout.on('data', handleStdOutData)\n\tfunction handleStdErrData(data: Buffer) {\n\t\toutput.push({\n\t\t\ttype: 'stderr',\n\t\t\tcontent: data.toString('utf-8'),\n\t\t\ttimestamp: Date.now(),\n\t\t})\n\t}\n\ttestProcess.stderr.on('data', handleStdErrData)\n\ttestProcess.on('exit', (code) => {\n\t\ttestProcess.stdout.off('data', handleStdOutData)\n\t\ttestProcess.stderr.off('data', handleStdErrData)\n\t\tentry.process = null\n\t\tentry.exitCode = code\n\t})\n\ttestProcesses.set(key, entry)\n\treturn testProcess\n}\n\nexport async function waitOnApp(app: App) {\n\tif (app.dev.type === 'script') {\n\t\tconst startTime = Date.now()\n\n\t\tconst retryInterval = 100\n\t\tconst timeout = 20_000\n\t\tlet lastError: unknown\n\t\twhile (Date.now() - startTime < timeout) {\n\t\t\ttry {\n\t\t\t\tconst url = getWorkshopUrl(app.dev.portNumber)\n\t\t\t\tawait fetch(url, {\n\t\t\t\t\tmethod: 'HEAD',\n\t\t\t\t\theaders: { Accept: '*/*' },\n\t\t\t\t})\n\t\t\t\treturn { status: 'success' } as const\n\t\t\t} catch (error) {\n\t\t\t\tlastError = error\n\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, retryInterval))\n\t\t\t}\n\t\t}\n\n\t\treturn { status: 'error', error: getErrorMessage(lastError) } as const\n\t}\n\treturn null\n}\n\nexport function isPortAvailable(port: number | string): Promise<boolean> {\n\treturn new Promise((resolve) => {\n\t\tconst server = net.createServer()\n\t\tserver.unref()\n\t\tserver.on('error', () => resolve(false))\n\n\t\tserver.listen(Number(port), () => {\n\t\t\tserver.close(() => {\n\t\t\t\tresolve(true)\n\t\t\t})\n\t\t})\n\t})\n}\n\nexport async function isAppRunning(app: { name: string }) {\n\ttry {\n\t\tconst devProcess = devProcesses.get(app.name)\n\t\tif (!devProcess?.process.pid) return false\n\t\tconst found = await findProcess('pid', devProcess.process.pid)\n\t\treturn found.length > 0\n\t} catch {\n\t\treturn false\n\t}\n}\n\nexport function isTestRunning(app: { name: string }) {\n\ttry {\n\t\tconst testProcess = testProcesses.get(app.name)\n\t\tif (!testProcess) return false\n\t\tif (testProcess.process === null) return false\n\t\ttestProcess.process.kill(0)\n\t\treturn true\n\t} catch {\n\t\treturn false\n\t}\n}\n\nexport function getTestProcessEntry(app: { name: string }) {\n\treturn testProcesses.get(app.name)\n}\n\nexport function clearTestProcessEntry(app: { name: string }) {\n\treturn testProcesses.delete(app.name)\n}\n\nexport function getProcesses() {\n\treturn { devProcesses, testProcesses }\n}\n\nexport async function closeProcess(key: string) {\n\tif (isDeployed) throw new Error('cannot close processes in deployed mode')\n\tconst proc = devProcesses.get(key)\n\tif (proc) {\n\t\tconst exitedPromise = new Promise((resolve) =>\n\t\t\tproc.process.on('exit', resolve),\n\t\t)\n\t\tif (process.platform === 'win32') {\n\t\t\tconst { execa } = await import('execa')\n\t\t\tawait execa('taskkill', ['/pid', String(proc.process.pid), '/f', '/t'])\n\t\t} else {\n\t\t\tproc.process.kill()\n\t\t}\n\t\tawait Promise.race([\n\t\t\tnew Promise((resolve) => setTimeout(resolve, 500)),\n\t\t\texitedPromise,\n\t\t])\n\t\tawait stopPort(proc.port) // just in case 🤷‍♂️\n\t\tdevProcesses.delete(key)\n\t}\n}\n\nconst sleep = (t: number) => new Promise((resolve) => setTimeout(resolve, t))\n\nexport async function stopPort(port: string | number) {\n\tif (isDeployed) throw new Error('cannot stop ports in deployed mode')\n\tawait fkill(`:${port}`, { force: true, silent: true })\n\tawait waitForPortToBeAvailable(port)\n}\n\nexport async function waitForPortToBeAvailable(port: string | number) {\n\t// wait for the port to become available again\n\tconst timeout = Date.now() + 10_000\n\tlet portAvailable = false\n\tdo {\n\t\tportAvailable = await isPortAvailable(port)\n\t\tawait sleep(100)\n\t} while (!portAvailable && Date.now() < timeout)\n\tif (!portAvailable) {\n\t\tconsole.error('Timed out waiting for the port to become available')\n\t}\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import './init-env.js';
1
2
  import { AsyncLocalStorage } from 'node:async_hooks';
2
3
  export type RequestContextStore = {
3
4
  getExercisesPromise?: Promise<any>;
@@ -1 +1 @@
1
- {"version":3,"file":"request-context.server.d.ts","sourceRoot":"","sources":["../../src/request-context.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAGpD,MAAM,MAAM,mBAAmB,GAAG;IAEjC,mBAAmB,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,CAAA;IAClC,cAAc,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,CAAA;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACtB,CAAA;AAID,eAAO,MAAM,cAAc,wCAG1B,CAAA;AAED,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,EAC3E,EAAE,EAAE,CAAC,EACL,GAAG,CAAC,EAAE,MAAM,GACV,CAAC,CAWH"}
1
+ {"version":3,"file":"request-context.server.d.ts","sourceRoot":"","sources":["../../src/request-context.server.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAEtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAGpD,MAAM,MAAM,mBAAmB,GAAG;IAEjC,mBAAmB,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,CAAA;IAClC,cAAc,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,CAAA;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACtB,CAAA;AAID,eAAO,MAAM,cAAc,wCAG1B,CAAA;AAED,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,EAC3E,EAAE,EAAE,CAAC,EACL,GAAG,CAAC,EAAE,MAAM,GACV,CAAC,CAWH"}
@@ -1,3 +1,4 @@
1
+ import './init-env.js';
1
2
  import { AsyncLocalStorage } from 'node:async_hooks';
2
3
  import { remember } from '@epic-web/remember';
3
4
  // this is important to make it global so even if somehow we have two versions of the workshop-utils,
@@ -1 +1 @@
1
- {"version":3,"file":"request-context.server.js","sourceRoot":"","sources":["../../src/request-context.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAS7C,qGAAqG;AACrG,2CAA2C;AAC3C,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ,CACrC,gBAAgB,EAChB,GAAG,EAAE,CAAC,IAAI,iBAAiB,EAAuB,CAClD,CAAA;AAED,MAAM,UAAU,iBAAiB,CAChC,EAAK,EACL,GAAY;IAEZ,MAAM,UAAU,GAAG,GAAG,IAAI,EAAE,CAAC,IAAI,CAAA;IACjC,OAAO,UAAU,GAAG,IAAW;QAC9B,MAAM,KAAK,GAAG,cAAc,CAAC,QAAQ,EAAE,CAAA;QACvC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC,UAAU,CAAC,CAAA;QACzB,CAAC;QACD,MAAM,OAAO,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAA;QAC3B,IAAI,KAAK;YAAE,KAAK,CAAC,UAAU,CAAC,GAAG,OAAO,CAAA;QACtC,OAAO,OAAO,CAAA;IACf,CAAM,CAAA;AACP,CAAC","sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\nimport { remember } from '@epic-web/remember'\n\nexport type RequestContextStore = {\n\t// Add more keys for other per-request caches as needed\n\tgetExercisesPromise?: Promise<any>\n\tgetAppsPromise?: Promise<any>\n\t[key: string]: unknown\n}\n\n// this is important to make it global so even if somehow we have two versions of the workshop-utils,\n// they will share the same request context\nexport const requestContext = remember(\n\t'requestContext',\n\t() => new AsyncLocalStorage<RequestContextStore>(),\n)\n\nexport function requestStorageify<T extends (...args: any[]) => Promise<any>>(\n\tfn: T,\n\tkey?: string,\n): T {\n\tconst storageKey = key ?? fn.name\n\treturn function (...args: any[]) {\n\t\tconst store = requestContext.getStore()\n\t\tif (store?.[storageKey]) {\n\t\t\treturn store[storageKey]\n\t\t}\n\t\tconst promise = fn(...args)\n\t\tif (store) store[storageKey] = promise\n\t\treturn promise\n\t} as T\n}\n"]}
1
+ {"version":3,"file":"request-context.server.js","sourceRoot":"","sources":["../../src/request-context.server.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAEtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAS7C,qGAAqG;AACrG,2CAA2C;AAC3C,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ,CACrC,gBAAgB,EAChB,GAAG,EAAE,CAAC,IAAI,iBAAiB,EAAuB,CAClD,CAAA;AAED,MAAM,UAAU,iBAAiB,CAChC,EAAK,EACL,GAAY;IAEZ,MAAM,UAAU,GAAG,GAAG,IAAI,EAAE,CAAC,IAAI,CAAA;IACjC,OAAO,UAAU,GAAG,IAAW;QAC9B,MAAM,KAAK,GAAG,cAAc,CAAC,QAAQ,EAAE,CAAA;QACvC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC,UAAU,CAAC,CAAA;QACzB,CAAC;QACD,MAAM,OAAO,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAA;QAC3B,IAAI,KAAK;YAAE,KAAK,CAAC,UAAU,CAAC,GAAG,OAAO,CAAA;QACtC,OAAO,OAAO,CAAA;IACf,CAAM,CAAA;AACP,CAAC","sourcesContent":["import './init-env.js'\n\nimport { AsyncLocalStorage } from 'node:async_hooks'\nimport { remember } from '@epic-web/remember'\n\nexport type RequestContextStore = {\n\t// Add more keys for other per-request caches as needed\n\tgetExercisesPromise?: Promise<any>\n\tgetAppsPromise?: Promise<any>\n\t[key: string]: unknown\n}\n\n// this is important to make it global so even if somehow we have two versions of the workshop-utils,\n// they will share the same request context\nexport const requestContext = remember(\n\t'requestContext',\n\t() => new AsyncLocalStorage<RequestContextStore>(),\n)\n\nexport function requestStorageify<T extends (...args: any[]) => Promise<any>>(\n\tfn: T,\n\tkey?: string,\n): T {\n\tconst storageKey = key ?? fn.name\n\treturn function (...args: any[]) {\n\t\tconst store = requestContext.getStore()\n\t\tif (store?.[storageKey]) {\n\t\t\treturn store[storageKey]\n\t\t}\n\t\tconst promise = fn(...args)\n\t\tif (store) store[storageKey] = promise\n\t\treturn promise\n\t} as T\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import './init-env.js';
1
2
  import { type CreateReporter } from '@epic-web/cachified';
2
3
  export type Timings = Record<string, Array<{
3
4
  desc?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"timing.server.d.ts","sourceRoot":"","sources":["../../src/timing.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEzD,MAAM,MAAM,OAAO,GAAG,MAAM,CAC3B,MAAM,EACN,KAAK,CACJ;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,CACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GAC/B;IAAE,IAAI,CAAC,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CACjC,CACD,CACD,CAAA;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,WAWtD;AAgBD,wBAAsB,IAAI,CAAC,UAAU,EACpC,EAAE,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,EAClE,EACC,IAAI,EACJ,IAAI,EACJ,OAAO,GACP,EAAE;IACF,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,OAAO,CAAA;CACjB,GACC,OAAO,CAAC,UAAU,CAAC,CASrB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,OAAO,UAuBpD;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,UAIxE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAC5C,OAAO,CAAC,EAAE,OAAO,EACjB,SAAS,CAAC,EAAE,MAAM,GAChB,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,CA6BnC"}
1
+ {"version":3,"file":"timing.server.d.ts","sourceRoot":"","sources":["../../src/timing.server.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAEtB,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEzD,MAAM,MAAM,OAAO,GAAG,MAAM,CAC3B,MAAM,EACN,KAAK,CACJ;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,CACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,GAC/B;IAAE,IAAI,CAAC,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CACjC,CACD,CACD,CAAA;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,WAWtD;AAgBD,wBAAsB,IAAI,CAAC,UAAU,EACpC,EAAE,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,EAClE,EACC,IAAI,EACJ,IAAI,EACJ,OAAO,GACP,EAAE;IACF,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,OAAO,CAAA;CACjB,GACC,OAAO,CAAC,UAAU,CAAC,CASrB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,OAAO,UAuBpD;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,UAIxE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAC5C,OAAO,CAAC,EAAE,OAAO,EACjB,SAAS,CAAC,EAAE,MAAM,GAChB,SAAS,GAAG,cAAc,CAAC,KAAK,CAAC,CA6BnC"}
@@ -1,3 +1,4 @@
1
+ import './init-env.js';
1
2
  export function makeTimings(type, desc) {
2
3
  const timings = {
3
4
  [type]: [{ desc, start: performance.now() }],
@@ -1 +1 @@
1
- {"version":3,"file":"timing.server.js","sourceRoot":"","sources":["../../src/timing.server.ts"],"names":[],"mappings":"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","sourcesContent":["import { type CreateReporter } from '@epic-web/cachified'\n\nexport type Timings = Record<\n\tstring,\n\tArray<\n\t\t{ desc?: string } & (\n\t\t\t| { time: number; start?: never }\n\t\t\t| { time?: never; start: number }\n\t\t)\n\t>\n>\n\nexport function makeTimings(type: string, desc?: string) {\n\tconst timings: Timings = {\n\t\t[type]: [{ desc, start: performance.now() }],\n\t}\n\tObject.defineProperty(timings, 'toString', {\n\t\tvalue() {\n\t\t\treturn getServerTimeHeader(timings)\n\t\t},\n\t\tenumerable: false,\n\t})\n\treturn timings\n}\n\nfunction createTimer(type: string, desc?: string) {\n\tconst start = performance.now()\n\treturn {\n\t\tend(timings: Timings) {\n\t\t\tlet timingType = timings[type]\n\n\t\t\tif (!timingType) {\n\t\t\t\ttimingType = timings[type] = []\n\t\t\t}\n\t\t\ttimingType.push({ desc, time: performance.now() - start })\n\t\t},\n\t}\n}\n\nexport async function time<ReturnType>(\n\tfn: Promise<ReturnType> | (() => ReturnType | Promise<ReturnType>),\n\t{\n\t\ttype,\n\t\tdesc,\n\t\ttimings,\n\t}: {\n\t\ttype: string\n\t\tdesc?: string\n\t\ttimings?: Timings\n\t},\n): Promise<ReturnType> {\n\tconst timer = createTimer(type, desc)\n\tconst promise = typeof fn === 'function' ? fn() : fn\n\tif (!timings) return promise\n\n\tconst result = await promise\n\n\ttimer.end(timings)\n\treturn result\n}\n\nexport function getServerTimeHeader(timings?: Timings) {\n\tif (!timings) return ''\n\treturn Object.entries(timings)\n\t\t.map(([key, timingInfos]) => {\n\t\t\tconst dur = timingInfos\n\t\t\t\t.reduce((acc, timingInfo) => {\n\t\t\t\t\tconst time = timingInfo.time ?? performance.now() - timingInfo.start\n\t\t\t\t\treturn acc + time\n\t\t\t\t}, 0)\n\t\t\t\t.toFixed(1)\n\t\t\tconst desc = timingInfos\n\t\t\t\t.map((t) => t.desc)\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.join(' & ')\n\t\t\treturn [\n\t\t\t\tkey.replaceAll(/(:| |@|=|;|,|\\/|\\\\|\\{|\\})/g, '_'),\n\t\t\t\tdesc ? `desc=${JSON.stringify(desc)}` : null,\n\t\t\t\t`dur=${dur}`,\n\t\t\t]\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.join(';')\n\t\t})\n\t\t.join(',')\n}\n\nexport function combineServerTimings(headers1: Headers, headers2: Headers) {\n\tconst newHeaders = new Headers(headers1)\n\tnewHeaders.append('Server-Timing', headers2.get('Server-Timing') ?? '')\n\treturn newHeaders.get('Server-Timing') ?? ''\n}\n\nexport function cachifiedTimingReporter<Value>(\n\ttimings?: Timings,\n\ttimingKey?: string,\n): undefined | CreateReporter<Value> {\n\tif (!timings) return\n\n\treturn ({ key }) => {\n\t\ttimingKey = timingKey ?? key\n\t\tconst cacheRetrievalTimer = createTimer(\n\t\t\t`cache:${timingKey}`,\n\t\t\t`${timingKey} cache retrieval`,\n\t\t)\n\t\tlet getFreshValueTimer: ReturnType<typeof createTimer> | undefined\n\t\treturn (event) => {\n\t\t\tswitch (event.name) {\n\t\t\t\tcase 'getFreshValueStart':\n\t\t\t\t\tgetFreshValueTimer = createTimer(\n\t\t\t\t\t\t`getFreshValue:${timingKey}`,\n\t\t\t\t\t\t`request forced to wait for a fresh ${timingKey} value`,\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'getFreshValueSuccess':\n\t\t\t\t\tgetFreshValueTimer?.end(timings)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'done':\n\t\t\t\t\tcacheRetrievalTimer.end(timings)\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"timing.server.js","sourceRoot":"","sources":["../../src/timing.server.ts"],"names":[],"mappings":"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","sourcesContent":["import './init-env.js'\n\nimport { type CreateReporter } from '@epic-web/cachified'\n\nexport type Timings = Record<\n\tstring,\n\tArray<\n\t\t{ desc?: string } & (\n\t\t\t| { time: number; start?: never }\n\t\t\t| { time?: never; start: number }\n\t\t)\n\t>\n>\n\nexport function makeTimings(type: string, desc?: string) {\n\tconst timings: Timings = {\n\t\t[type]: [{ desc, start: performance.now() }],\n\t}\n\tObject.defineProperty(timings, 'toString', {\n\t\tvalue() {\n\t\t\treturn getServerTimeHeader(timings)\n\t\t},\n\t\tenumerable: false,\n\t})\n\treturn timings\n}\n\nfunction createTimer(type: string, desc?: string) {\n\tconst start = performance.now()\n\treturn {\n\t\tend(timings: Timings) {\n\t\t\tlet timingType = timings[type]\n\n\t\t\tif (!timingType) {\n\t\t\t\ttimingType = timings[type] = []\n\t\t\t}\n\t\t\ttimingType.push({ desc, time: performance.now() - start })\n\t\t},\n\t}\n}\n\nexport async function time<ReturnType>(\n\tfn: Promise<ReturnType> | (() => ReturnType | Promise<ReturnType>),\n\t{\n\t\ttype,\n\t\tdesc,\n\t\ttimings,\n\t}: {\n\t\ttype: string\n\t\tdesc?: string\n\t\ttimings?: Timings\n\t},\n): Promise<ReturnType> {\n\tconst timer = createTimer(type, desc)\n\tconst promise = typeof fn === 'function' ? fn() : fn\n\tif (!timings) return promise\n\n\tconst result = await promise\n\n\ttimer.end(timings)\n\treturn result\n}\n\nexport function getServerTimeHeader(timings?: Timings) {\n\tif (!timings) return ''\n\treturn Object.entries(timings)\n\t\t.map(([key, timingInfos]) => {\n\t\t\tconst dur = timingInfos\n\t\t\t\t.reduce((acc, timingInfo) => {\n\t\t\t\t\tconst time = timingInfo.time ?? performance.now() - timingInfo.start\n\t\t\t\t\treturn acc + time\n\t\t\t\t}, 0)\n\t\t\t\t.toFixed(1)\n\t\t\tconst desc = timingInfos\n\t\t\t\t.map((t) => t.desc)\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.join(' & ')\n\t\t\treturn [\n\t\t\t\tkey.replaceAll(/(:| |@|=|;|,|\\/|\\\\|\\{|\\})/g, '_'),\n\t\t\t\tdesc ? `desc=${JSON.stringify(desc)}` : null,\n\t\t\t\t`dur=${dur}`,\n\t\t\t]\n\t\t\t\t.filter(Boolean)\n\t\t\t\t.join(';')\n\t\t})\n\t\t.join(',')\n}\n\nexport function combineServerTimings(headers1: Headers, headers2: Headers) {\n\tconst newHeaders = new Headers(headers1)\n\tnewHeaders.append('Server-Timing', headers2.get('Server-Timing') ?? '')\n\treturn newHeaders.get('Server-Timing') ?? ''\n}\n\nexport function cachifiedTimingReporter<Value>(\n\ttimings?: Timings,\n\ttimingKey?: string,\n): undefined | CreateReporter<Value> {\n\tif (!timings) return\n\n\treturn ({ key }) => {\n\t\ttimingKey = timingKey ?? key\n\t\tconst cacheRetrievalTimer = createTimer(\n\t\t\t`cache:${timingKey}`,\n\t\t\t`${timingKey} cache retrieval`,\n\t\t)\n\t\tlet getFreshValueTimer: ReturnType<typeof createTimer> | undefined\n\t\treturn (event) => {\n\t\t\tswitch (event.name) {\n\t\t\t\tcase 'getFreshValueStart':\n\t\t\t\t\tgetFreshValueTimer = createTimer(\n\t\t\t\t\t\t`getFreshValue:${timingKey}`,\n\t\t\t\t\t\t`request forced to wait for a fresh ${timingKey} value`,\n\t\t\t\t\t)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'getFreshValueSuccess':\n\t\t\t\t\tgetFreshValueTimer?.end(timings)\n\t\t\t\t\tbreak\n\t\t\t\tcase 'done':\n\t\t\t\t\tcacheRetrievalTimer.end(timings)\n\t\t\t\t\tbreak\n\t\t\t\tdefault:\n\t\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"user.server.d.ts","sourceRoot":"","sources":["../../src/user.server.ts"],"names":[],"mappings":"AAIA,wBAAsB,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE;;;;;;;;;;;;GAiChE;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,UAE1D"}
1
+ {"version":3,"file":"user.server.d.ts","sourceRoot":"","sources":["../../src/user.server.ts"],"names":[],"mappings":"AAOA,wBAAsB,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE;;;;;;;;;;;;GAiChE;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,UAE1D"}
@@ -1,3 +1,5 @@
1
+ // eslint-disable-next-line import/order -- this must be first
2
+ import { ENV } from './init-env.js';
1
3
  import { createId as cuid } from '@paralleldrive/cuid2';
2
4
  import * as cookie from 'cookie';
3
5
  import { getAuthInfo, getClientId } from './db.server.js';
@@ -1 +1 @@
1
- {"version":3,"file":"user.server.js","sourceRoot":"","sources":["../../src/user.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,IAAI,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAA;AAChC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEzD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,EAAE,OAAO,EAAwB;IAChE,IAAI,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAC3B,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAClD,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC,CAAA;QAEpD,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;YAC1B,OAAO;gBACN,EAAE,EAAE,WAAW,CAAC,QAAQ;gBACxB,IAAI,EAAE,iBAAiB;aACd,CAAA;QACX,CAAC;aAAM,CAAC;YACP,MAAM,KAAK,GAAG,IAAI,EAAE,CAAA;YACpB,OAAO;gBACN,EAAE,EAAE,KAAK;gBACT,IAAI,EAAE,iBAAiB;aACd,CAAA;QACX,CAAC;IACF,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,WAAW,EAAE,CAAA;IAEpC,IAAI,QAAQ,EAAE,EAAE,EAAE,CAAC;QAClB,OAAO;YACN,EAAE,EAAE,QAAQ,CAAC,EAAE;YACf,IAAI,EAAE,aAAa;SACV,CAAA;IACX,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,WAAW,EAAE,CAAA;IACpC,OAAO;QACN,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,aAAa;KACV,CAAA;AACX,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,QAAgB;IAC1D,OAAO,YAAY,QAAQ,kCAAkC,CAAA;AAC9D,CAAC","sourcesContent":["import { createId as cuid } from '@paralleldrive/cuid2'\nimport * as cookie from 'cookie'\nimport { getAuthInfo, getClientId } from './db.server.js'\n\nexport async function getUserId({ request }: { request: Request }) {\n\tif (ENV.EPICSHOP_DEPLOYED) {\n\t\tconst cookieHeader = request.headers.get('cookie')\n\t\tconst cookieValue = cookie.parse(cookieHeader ?? '')\n\n\t\tif (cookieValue.clientId) {\n\t\t\treturn {\n\t\t\t\tid: cookieValue.clientId,\n\t\t\t\ttype: 'cookie.clientId',\n\t\t\t} as const\n\t\t} else {\n\t\t\tconst newId = cuid()\n\t\t\treturn {\n\t\t\t\tid: newId,\n\t\t\t\ttype: 'cookie.randomId',\n\t\t\t} as const\n\t\t}\n\t}\n\n\tconst authInfo = await getAuthInfo()\n\n\tif (authInfo?.id) {\n\t\treturn {\n\t\t\tid: authInfo.id,\n\t\t\ttype: 'db.authInfo',\n\t\t} as const\n\t}\n\n\tconst clientId = await getClientId()\n\treturn {\n\t\tid: clientId,\n\t\ttype: 'db.clientId',\n\t} as const\n}\n\nexport function getSetClientIdCookieHeader(clientId: string) {\n\treturn `clientId=${clientId}; Path=/; HttpOnly; SameSite=Lax`\n}\n"]}
1
+ {"version":3,"file":"user.server.js","sourceRoot":"","sources":["../../src/user.server.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAA;AAEnC,OAAO,EAAE,QAAQ,IAAI,IAAI,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAA;AAChC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEzD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,EAAE,OAAO,EAAwB;IAChE,IAAI,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAC3B,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAClD,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC,CAAA;QAEpD,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;YAC1B,OAAO;gBACN,EAAE,EAAE,WAAW,CAAC,QAAQ;gBACxB,IAAI,EAAE,iBAAiB;aACd,CAAA;QACX,CAAC;aAAM,CAAC;YACP,MAAM,KAAK,GAAG,IAAI,EAAE,CAAA;YACpB,OAAO;gBACN,EAAE,EAAE,KAAK;gBACT,IAAI,EAAE,iBAAiB;aACd,CAAA;QACX,CAAC;IACF,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,WAAW,EAAE,CAAA;IAEpC,IAAI,QAAQ,EAAE,EAAE,EAAE,CAAC;QAClB,OAAO;YACN,EAAE,EAAE,QAAQ,CAAC,EAAE;YACf,IAAI,EAAE,aAAa;SACV,CAAA;IACX,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,WAAW,EAAE,CAAA;IACpC,OAAO;QACN,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,aAAa;KACV,CAAA;AACX,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,QAAgB;IAC1D,OAAO,YAAY,QAAQ,kCAAkC,CAAA;AAC9D,CAAC","sourcesContent":["// eslint-disable-next-line import/order -- this must be first\nimport { ENV } from './init-env.js'\n\nimport { createId as cuid } from '@paralleldrive/cuid2'\nimport * as cookie from 'cookie'\nimport { getAuthInfo, getClientId } from './db.server.js'\n\nexport async function getUserId({ request }: { request: Request }) {\n\tif (ENV.EPICSHOP_DEPLOYED) {\n\t\tconst cookieHeader = request.headers.get('cookie')\n\t\tconst cookieValue = cookie.parse(cookieHeader ?? '')\n\n\t\tif (cookieValue.clientId) {\n\t\t\treturn {\n\t\t\t\tid: cookieValue.clientId,\n\t\t\t\ttype: 'cookie.clientId',\n\t\t\t} as const\n\t\t} else {\n\t\t\tconst newId = cuid()\n\t\t\treturn {\n\t\t\t\tid: newId,\n\t\t\t\ttype: 'cookie.randomId',\n\t\t\t} as const\n\t\t}\n\t}\n\n\tconst authInfo = await getAuthInfo()\n\n\tif (authInfo?.id) {\n\t\treturn {\n\t\t\tid: authInfo.id,\n\t\t\ttype: 'db.authInfo',\n\t\t} as const\n\t}\n\n\tconst clientId = await getClientId()\n\treturn {\n\t\tid: clientId,\n\t\ttype: 'db.clientId',\n\t} as const\n}\n\nexport function getSetClientIdCookieHeader(clientId: string) {\n\treturn `clientId=${clientId}; Path=/; HttpOnly; SameSite=Lax`\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import './init-env.js';
1
2
  export declare function getErrorMessage(error: unknown): string;
2
3
  export declare function handleGitHubRepoAndRoot({ githubRepo, githubRoot, }: {
3
4
  githubRepo?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,UAY7C;AAED,wBAAgB,uBAAuB,CAAC,EACvC,UAAU,EACV,UAAU,GACV,EAAE;IACF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;CACnB;;;EAYA"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAEtB,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,UAY7C;AAED,wBAAgB,uBAAuB,CAAC,EACvC,UAAU,EACV,UAAU,GACV,EAAE;IACF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;CACnB;;;EAYA"}
package/dist/esm/utils.js CHANGED
@@ -1,3 +1,4 @@
1
+ import './init-env.js';
1
2
  export function getErrorMessage(error) {
2
3
  if (typeof error === 'string')
3
4
  return error;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,eAAe,CAAC,KAAc;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,IACC,KAAK;QACL,OAAO,KAAK,KAAK,QAAQ;QACzB,SAAS,IAAI,KAAK;QAClB,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,EAChC,CAAC;QACF,OAAO,KAAK,CAAC,OAAO,CAAA;IACrB,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAA;IAC7D,OAAO,eAAe,CAAA;AACvB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,EACvC,UAAU,EACV,UAAU,GAIV;IACA,IAAI,UAAU,EAAE,CAAC;QAChB,UAAU,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAA;IAC1D,CAAC;SAAM,IAAI,UAAU,EAAE,CAAC;QACvB,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAA;QACzD,UAAU,GAAG,GAAG,UAAU,YAAY,CAAA;IACvC,CAAC;SAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACd,sJAAsJ,CACtJ,CAAA;IACF,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,CAAA;AAClC,CAAC","sourcesContent":["export function getErrorMessage(error: unknown) {\n\tif (typeof error === 'string') return error\n\tif (\n\t\terror &&\n\t\ttypeof error === 'object' &&\n\t\t'message' in error &&\n\t\ttypeof error.message === 'string'\n\t) {\n\t\treturn error.message\n\t}\n\tconsole.error('Unable to get error message for error', error)\n\treturn 'Unknown Error'\n}\n\nexport function handleGitHubRepoAndRoot({\n\tgithubRepo,\n\tgithubRoot,\n}: {\n\tgithubRepo?: string\n\tgithubRoot?: string\n}) {\n\tif (githubRepo) {\n\t\tgithubRoot = `${githubRepo.replace(/\\/$/, '')}/tree/main`\n\t} else if (githubRoot) {\n\t\tgithubRepo = githubRoot.replace(/\\/(blob|tree)\\/.*$/, '')\n\t\tgithubRoot = `${githubRepo}/tree/main`\n\t} else {\n\t\tthrow new Error(\n\t\t\t`Either githubRepo or githubRoot is required. Please ensure your epicshop package.json config includes either githubRepo or githubRoot configuration.`,\n\t\t)\n\t}\n\treturn { githubRepo, githubRoot }\n}\n"]}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAEtB,MAAM,UAAU,eAAe,CAAC,KAAc;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3C,IACC,KAAK;QACL,OAAO,KAAK,KAAK,QAAQ;QACzB,SAAS,IAAI,KAAK;QAClB,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,EAChC,CAAC;QACF,OAAO,KAAK,CAAC,OAAO,CAAA;IACrB,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAA;IAC7D,OAAO,eAAe,CAAA;AACvB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,EACvC,UAAU,EACV,UAAU,GAIV;IACA,IAAI,UAAU,EAAE,CAAC;QAChB,UAAU,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAA;IAC1D,CAAC;SAAM,IAAI,UAAU,EAAE,CAAC;QACvB,UAAU,GAAG,UAAU,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAA;QACzD,UAAU,GAAG,GAAG,UAAU,YAAY,CAAA;IACvC,CAAC;SAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACd,sJAAsJ,CACtJ,CAAA;IACF,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,CAAA;AAClC,CAAC","sourcesContent":["import './init-env.js'\n\nexport function getErrorMessage(error: unknown) {\n\tif (typeof error === 'string') return error\n\tif (\n\t\terror &&\n\t\ttypeof error === 'object' &&\n\t\t'message' in error &&\n\t\ttypeof error.message === 'string'\n\t) {\n\t\treturn error.message\n\t}\n\tconsole.error('Unable to get error message for error', error)\n\treturn 'Unknown Error'\n}\n\nexport function handleGitHubRepoAndRoot({\n\tgithubRepo,\n\tgithubRoot,\n}: {\n\tgithubRepo?: string\n\tgithubRoot?: string\n}) {\n\tif (githubRepo) {\n\t\tgithubRoot = `${githubRepo.replace(/\\/$/, '')}/tree/main`\n\t} else if (githubRoot) {\n\t\tgithubRepo = githubRoot.replace(/\\/(blob|tree)\\/.*$/, '')\n\t\tgithubRoot = `${githubRepo}/tree/main`\n\t} else {\n\t\tthrow new Error(\n\t\t\t`Either githubRepo or githubRoot is required. Please ensure your epicshop package.json config includes either githubRepo or githubRoot configuration.`,\n\t\t)\n\t}\n\treturn { githubRepo, githubRoot }\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import './init-env.js';
1
2
  import dayjsLib from 'dayjs';
2
3
  import { type Timings } from './timing.server.js';
3
4
  export declare const dayjs: typeof dayjsLib;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.server.d.ts","sourceRoot":"","sources":["../../src/utils.server.ts"],"names":[],"mappings":"AACA,OAAO,QAAQ,MAAM,OAAO,CAAA;AAK5B,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAEjD,eAAO,MAAM,KAAK,iBAKhB,CAAA;AAEF,wBAAsB,eAAe,qBASpC;AAED,wBAAsB,qBAAqB,CAAC,EAC3C,OAAO,EACP,OAAO,GACP,GAAE;IACF,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;CACZ,oBAmBL"}
1
+ {"version":3,"file":"utils.server.d.ts","sourceRoot":"","sources":["../../src/utils.server.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAGtB,OAAO,QAAQ,MAAM,OAAO,CAAA;AAK5B,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAEjD,eAAO,MAAM,KAAK,iBAKhB,CAAA;AAEF,wBAAsB,eAAe,qBASpC;AAED,wBAAsB,qBAAqB,CAAC,EAC3C,OAAO,EACP,OAAO,GACP,GAAE;IACF,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;CACZ,oBAmBL"}
@@ -1,3 +1,4 @@
1
+ import './init-env.js';
1
2
  import { remember } from '@epic-web/remember';
2
3
  import dayjsLib from 'dayjs';
3
4
  import relativeTimePlugin from 'dayjs/plugin/relativeTime.js';
@@ -1 +1 @@
1
- {"version":3,"file":"utils.server.js","sourceRoot":"","sources":["../../src/utils.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,QAAQ,MAAM,OAAO,CAAA;AAC5B,OAAO,kBAAkB,MAAM,8BAA8B,CAAA;AAC7D,OAAO,cAAc,MAAM,0BAA0B,CAAA;AACrD,OAAO,SAAS,MAAM,qBAAqB,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAG9D,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IAC3C,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IAC1B,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;IAC/B,QAAQ,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAA;IACnC,OAAO,QAAQ,CAAA;AAChB,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,KAAK,UAAU,eAAe;IACpC,IAAI,CAAC;QACJ,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,4BAA4B,EAAE;YAC1D,MAAM,EAAE,MAAM;SACd,CAAC,CAAA;QACF,OAAO,QAAQ,CAAC,EAAE,CAAA;IACnB,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAA;IACb,CAAC;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,EAC3C,OAAO,EACP,OAAO,MAIJ,EAAE;IACL,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC;QAChC,KAAK,EAAE,eAAe;QACtB,OAAO;QACP,OAAO;QACP,GAAG,EAAE,WAAW;QAChB,GAAG,EAAE,IAAI,GAAG,EAAE;QACd,KAAK,CAAC,aAAa,CAAC,OAAO;YAC1B,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE,CAAA;YACtC,IAAI,MAAM,EAAE,CAAC;gBACZ,OAAO,CAAC,QAAQ,CAAC,GAAG,GAAG,IAAI,GAAG,EAAE,CAAA;gBAChC,OAAO,CAAC,QAAQ,CAAC,GAAG,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,CAAA;gBACrC,OAAO,IAAI,CAAA;YACZ,CAAC;iBAAM,CAAC;gBACP,OAAO,KAAK,CAAA;YACb,CAAC;QACF,CAAC;KACD,CAAC,CAAA;IACF,OAAO,QAAQ,CAAA;AAChB,CAAC","sourcesContent":["import { remember } from '@epic-web/remember'\nimport dayjsLib from 'dayjs'\nimport relativeTimePlugin from 'dayjs/plugin/relativeTime.js'\nimport timeZonePlugin from 'dayjs/plugin/timezone.js'\nimport utcPlugin from 'dayjs/plugin/utc.js'\nimport { cachified, connectionCache } from './cache.server.js'\nimport { type Timings } from './timing.server.js'\n\nexport const dayjs = remember('dayjs', () => {\n\tdayjsLib.extend(utcPlugin)\n\tdayjsLib.extend(timeZonePlugin)\n\tdayjsLib.extend(relativeTimePlugin)\n\treturn dayjsLib\n})\n\nexport async function checkConnection() {\n\ttry {\n\t\tconst response = await fetch('https://www.cloudflare.com', {\n\t\t\tmethod: 'HEAD',\n\t\t})\n\t\treturn response.ok\n\t} catch {\n\t\treturn false\n\t}\n}\n\nexport async function checkConnectionCached({\n\trequest,\n\ttimings,\n}: {\n\trequest?: Request\n\ttimings?: Timings\n} = {}) {\n\tconst isOnline = await cachified({\n\t\tcache: connectionCache,\n\t\trequest,\n\t\ttimings,\n\t\tkey: 'connected',\n\t\tttl: 1000 * 10,\n\t\tasync getFreshValue(context) {\n\t\t\tconst result = await checkConnection()\n\t\t\tif (result) {\n\t\t\t\tcontext.metadata.ttl = 1000 * 60\n\t\t\t\tcontext.metadata.swr = 1000 * 60 * 30\n\t\t\t\treturn true\n\t\t\t} else {\n\t\t\t\treturn false\n\t\t\t}\n\t\t},\n\t})\n\treturn isOnline\n}\n"]}
1
+ {"version":3,"file":"utils.server.js","sourceRoot":"","sources":["../../src/utils.server.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AAEtB,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,QAAQ,MAAM,OAAO,CAAA;AAC5B,OAAO,kBAAkB,MAAM,8BAA8B,CAAA;AAC7D,OAAO,cAAc,MAAM,0BAA0B,CAAA;AACrD,OAAO,SAAS,MAAM,qBAAqB,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAG9D,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IAC3C,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IAC1B,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;IAC/B,QAAQ,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAA;IACnC,OAAO,QAAQ,CAAA;AAChB,CAAC,CAAC,CAAA;AAEF,MAAM,CAAC,KAAK,UAAU,eAAe;IACpC,IAAI,CAAC;QACJ,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,4BAA4B,EAAE;YAC1D,MAAM,EAAE,MAAM;SACd,CAAC,CAAA;QACF,OAAO,QAAQ,CAAC,EAAE,CAAA;IACnB,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAA;IACb,CAAC;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,EAC3C,OAAO,EACP,OAAO,MAIJ,EAAE;IACL,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC;QAChC,KAAK,EAAE,eAAe;QACtB,OAAO;QACP,OAAO;QACP,GAAG,EAAE,WAAW;QAChB,GAAG,EAAE,IAAI,GAAG,EAAE;QACd,KAAK,CAAC,aAAa,CAAC,OAAO;YAC1B,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE,CAAA;YACtC,IAAI,MAAM,EAAE,CAAC;gBACZ,OAAO,CAAC,QAAQ,CAAC,GAAG,GAAG,IAAI,GAAG,EAAE,CAAA;gBAChC,OAAO,CAAC,QAAQ,CAAC,GAAG,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,CAAA;gBACrC,OAAO,IAAI,CAAA;YACZ,CAAC;iBAAM,CAAC;gBACP,OAAO,KAAK,CAAA;YACb,CAAC;QACF,CAAC;KACD,CAAC,CAAA;IACF,OAAO,QAAQ,CAAA;AAChB,CAAC","sourcesContent":["import './init-env.js'\n\nimport { remember } from '@epic-web/remember'\nimport dayjsLib from 'dayjs'\nimport relativeTimePlugin from 'dayjs/plugin/relativeTime.js'\nimport timeZonePlugin from 'dayjs/plugin/timezone.js'\nimport utcPlugin from 'dayjs/plugin/utc.js'\nimport { cachified, connectionCache } from './cache.server.js'\nimport { type Timings } from './timing.server.js'\n\nexport const dayjs = remember('dayjs', () => {\n\tdayjsLib.extend(utcPlugin)\n\tdayjsLib.extend(timeZonePlugin)\n\tdayjsLib.extend(relativeTimePlugin)\n\treturn dayjsLib\n})\n\nexport async function checkConnection() {\n\ttry {\n\t\tconst response = await fetch('https://www.cloudflare.com', {\n\t\t\tmethod: 'HEAD',\n\t\t})\n\t\treturn response.ok\n\t} catch {\n\t\treturn false\n\t}\n}\n\nexport async function checkConnectionCached({\n\trequest,\n\ttimings,\n}: {\n\trequest?: Request\n\ttimings?: Timings\n} = {}) {\n\tconst isOnline = await cachified({\n\t\tcache: connectionCache,\n\t\trequest,\n\t\ttimings,\n\t\tkey: 'connected',\n\t\tttl: 1000 * 10,\n\t\tasync getFreshValue(context) {\n\t\t\tconst result = await checkConnection()\n\t\t\tif (result) {\n\t\t\t\tcontext.metadata.ttl = 1000 * 60\n\t\t\t\tcontext.metadata.swr = 1000 * 60 * 30\n\t\t\t\treturn true\n\t\t\t} else {\n\t\t\t\treturn false\n\t\t\t}\n\t\t},\n\t})\n\treturn isOnline\n}\n"]}
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@epic-web/workshop-utils","version":"6.15.0","publishConfig":{"access":"public"},"type":"module","tshy":{"project":"./tsconfig.build.json","dialects":["esm"],"exports":{"./package.json":"./package.json","./apps.server":"./src/apps.server.ts","./diff.server":"./src/diff.server.ts","./env.server":"./src/env.server.ts","./epic-api.server":"./src/epic-api.server.ts","./user.server":"./src/user.server.ts","./cache.server":"./src/cache.server.ts","./config.server":"./src/config.server.ts","./db.server":"./src/db.server.ts","./timing.server":"./src/timing.server.ts","./modified-time.server":"./src/modified-time.server.ts","./compile-mdx.server":"./src/compile-mdx.server.ts","./git.server":"./src/git.server.ts","./iframe-sync":"./src/iframe-sync.ts","./playwright.server":"./src/playwright.server.ts","./notifications.server":"./src/notifications.server.ts","./process-manager.server":"./src/process-manager.server.ts","./test":"./src/test.ts","./request-context.server":"./src/request-context.server.ts","./utils.server":"./src/utils.server.ts","./utils":"./src/utils.ts"}},"exports":{"./package.json":"./package.json","./apps.server":{"import":{"types":"./dist/esm/apps.server.d.ts","default":"./dist/esm/apps.server.js"}},"./diff.server":{"import":{"types":"./dist/esm/diff.server.d.ts","default":"./dist/esm/diff.server.js"}},"./env.server":{"import":{"types":"./dist/esm/env.server.d.ts","default":"./dist/esm/env.server.js"}},"./epic-api.server":{"import":{"types":"./dist/esm/epic-api.server.d.ts","default":"./dist/esm/epic-api.server.js"}},"./user.server":{"import":{"types":"./dist/esm/user.server.d.ts","default":"./dist/esm/user.server.js"}},"./cache.server":{"import":{"types":"./dist/esm/cache.server.d.ts","default":"./dist/esm/cache.server.js"}},"./config.server":{"import":{"types":"./dist/esm/config.server.d.ts","default":"./dist/esm/config.server.js"}},"./db.server":{"import":{"types":"./dist/esm/db.server.d.ts","default":"./dist/esm/db.server.js"}},"./timing.server":{"import":{"types":"./dist/esm/timing.server.d.ts","default":"./dist/esm/timing.server.js"}},"./modified-time.server":{"import":{"types":"./dist/esm/modified-time.server.d.ts","default":"./dist/esm/modified-time.server.js"}},"./compile-mdx.server":{"import":{"types":"./dist/esm/compile-mdx.server.d.ts","default":"./dist/esm/compile-mdx.server.js"}},"./git.server":{"import":{"types":"./dist/esm/git.server.d.ts","default":"./dist/esm/git.server.js"}},"./iframe-sync":{"import":{"types":"./dist/esm/iframe-sync.d.ts","default":"./dist/esm/iframe-sync.js"}},"./playwright.server":{"import":{"types":"./dist/esm/playwright.server.d.ts","default":"./dist/esm/playwright.server.js"}},"./notifications.server":{"import":{"types":"./dist/esm/notifications.server.d.ts","default":"./dist/esm/notifications.server.js"}},"./process-manager.server":{"import":{"types":"./dist/esm/process-manager.server.d.ts","default":"./dist/esm/process-manager.server.js"}},"./test":{"import":{"types":"./dist/esm/test.d.ts","default":"./dist/esm/test.js"}},"./request-context.server":{"import":{"types":"./dist/esm/request-context.server.d.ts","default":"./dist/esm/request-context.server.js"}},"./utils.server":{"import":{"types":"./dist/esm/utils.server.d.ts","default":"./dist/esm/utils.server.js"}},"./utils":{"import":{"types":"./dist/esm/utils.d.ts","default":"./dist/esm/utils.js"}}},"files":["dist"],"scripts":{"typecheck":"tsc --noEmit","build":"tshy","build:watch":"nx watch --projects=@epic-web/workshop-utils -- nx run \\$NX_PROJECT_NAME:build"},"dependencies":{"@epic-web/cachified":"^5.6.0","@epic-web/invariant":"^1.0.0","@epic-web/remember":"^1.1.0","@kentcdodds/md-temp":"^10.0.1","@mdx-js/mdx":"^3.1.0","@paralleldrive/cuid2":"^2.2.2","@playwright/test":"^1.53.2","@react-router/node":"^7.6.3","@sentry/react-router":"^9.40.0","@testing-library/dom":"^10.4.0","@testing-library/jest-dom":"^6.6.3","@total-typescript/ts-reset":"^0.6.1","@types/chai":"^5.2.2","@types/chai-dom":"^1.11.3","@vitest/expect":"^3.2.4","chai":"^5.2.0","chai-dom":"^1.12.1","chalk":"^5.4.1","chokidar":"^4.0.3","close-with-grace":"^2.2.0","cookie":"^1.0.2","cross-spawn":"^7.0.6","dayjs":"^1.11.13","esbuild":"^0.25.5","execa":"^9.6.0","find-process":"^1.4.10","fkill":"^9.0.0","fs-extra":"^11.3.0","globby":"^14.1.0","ignore":"^7.0.5","json5":"^2.2.3","lru-cache":"^11.1.0","lz-string":"^1.5.0","md5-hex":"^5.0.0","mdast-util-mdx-jsx":"^3.2.0","mdx-bundler":"^10.1.1","p-queue":"^8.1.0","parse-git-diff":"^0.0.19","rehype":"^13.0.2","rehype-autolink-headings":"^7.1.0","remark":"^15.0.1","remark-emoji":"^5.0.1","remark-gfm":"^4.0.1","shiki":"^3.7.0","unified":"^11.0.5","unist-util-remove-position":"^5.0.0","unist-util-visit":"^5.0.0","zod":"^3.25.71"},"devDependencies":{"@types/hast":"^3.0.4","@types/mdast":"^4.0.4","@types/node":"^24.0.10","tshy":"^3.0.2"},"repository":{"type":"git","url":"https://github.com/epicweb-dev/epicshop.git","directory":"packages/workshop-utils"}}
1
+ {"name":"@epic-web/workshop-utils","version":"6.15.2","publishConfig":{"access":"public"},"type":"module","tshy":{"project":"./tsconfig.build.json","dialects":["esm"],"exports":{"./package.json":"./package.json","./apps.server":"./src/apps.server.ts","./diff.server":"./src/diff.server.ts","./env.server":"./src/env.server.ts","./epic-api.server":"./src/epic-api.server.ts","./user.server":"./src/user.server.ts","./cache.server":"./src/cache.server.ts","./config.server":"./src/config.server.ts","./db.server":"./src/db.server.ts","./timing.server":"./src/timing.server.ts","./modified-time.server":"./src/modified-time.server.ts","./compile-mdx.server":"./src/compile-mdx.server.ts","./git.server":"./src/git.server.ts","./iframe-sync":"./src/iframe-sync.ts","./init-env":"./src/init-env.ts","./playwright.server":"./src/playwright.server.ts","./notifications.server":"./src/notifications.server.ts","./process-manager.server":"./src/process-manager.server.ts","./test":"./src/test.ts","./request-context.server":"./src/request-context.server.ts","./utils.server":"./src/utils.server.ts","./utils":"./src/utils.ts"}},"exports":{"./package.json":"./package.json","./apps.server":{"import":{"types":"./dist/esm/apps.server.d.ts","default":"./dist/esm/apps.server.js"}},"./diff.server":{"import":{"types":"./dist/esm/diff.server.d.ts","default":"./dist/esm/diff.server.js"}},"./env.server":{"import":{"types":"./dist/esm/env.server.d.ts","default":"./dist/esm/env.server.js"}},"./epic-api.server":{"import":{"types":"./dist/esm/epic-api.server.d.ts","default":"./dist/esm/epic-api.server.js"}},"./user.server":{"import":{"types":"./dist/esm/user.server.d.ts","default":"./dist/esm/user.server.js"}},"./cache.server":{"import":{"types":"./dist/esm/cache.server.d.ts","default":"./dist/esm/cache.server.js"}},"./config.server":{"import":{"types":"./dist/esm/config.server.d.ts","default":"./dist/esm/config.server.js"}},"./db.server":{"import":{"types":"./dist/esm/db.server.d.ts","default":"./dist/esm/db.server.js"}},"./timing.server":{"import":{"types":"./dist/esm/timing.server.d.ts","default":"./dist/esm/timing.server.js"}},"./modified-time.server":{"import":{"types":"./dist/esm/modified-time.server.d.ts","default":"./dist/esm/modified-time.server.js"}},"./compile-mdx.server":{"import":{"types":"./dist/esm/compile-mdx.server.d.ts","default":"./dist/esm/compile-mdx.server.js"}},"./git.server":{"import":{"types":"./dist/esm/git.server.d.ts","default":"./dist/esm/git.server.js"}},"./iframe-sync":{"import":{"types":"./dist/esm/iframe-sync.d.ts","default":"./dist/esm/iframe-sync.js"}},"./init-env":{"import":{"types":"./dist/esm/init-env.d.ts","default":"./dist/esm/init-env.js"}},"./playwright.server":{"import":{"types":"./dist/esm/playwright.server.d.ts","default":"./dist/esm/playwright.server.js"}},"./notifications.server":{"import":{"types":"./dist/esm/notifications.server.d.ts","default":"./dist/esm/notifications.server.js"}},"./process-manager.server":{"import":{"types":"./dist/esm/process-manager.server.d.ts","default":"./dist/esm/process-manager.server.js"}},"./test":{"import":{"types":"./dist/esm/test.d.ts","default":"./dist/esm/test.js"}},"./request-context.server":{"import":{"types":"./dist/esm/request-context.server.d.ts","default":"./dist/esm/request-context.server.js"}},"./utils.server":{"import":{"types":"./dist/esm/utils.server.d.ts","default":"./dist/esm/utils.server.js"}},"./utils":{"import":{"types":"./dist/esm/utils.d.ts","default":"./dist/esm/utils.js"}}},"files":["dist"],"scripts":{"typecheck":"tsc --noEmit","build":"tshy","build:watch":"nx watch --projects=@epic-web/workshop-utils -- nx run \\$NX_PROJECT_NAME:build"},"dependencies":{"@epic-web/cachified":"^5.6.0","@epic-web/invariant":"^1.0.0","@epic-web/remember":"^1.1.0","@kentcdodds/md-temp":"^10.0.1","@mdx-js/mdx":"^3.1.0","@paralleldrive/cuid2":"^2.2.2","@playwright/test":"^1.53.2","@react-router/node":"^7.6.3","@sentry/react-router":"^9.40.0","@testing-library/dom":"^10.4.0","@testing-library/jest-dom":"^6.6.3","@total-typescript/ts-reset":"^0.6.1","@types/chai":"^5.2.2","@types/chai-dom":"^1.11.3","@vitest/expect":"^3.2.4","chai":"^5.2.0","chai-dom":"^1.12.1","chalk":"^5.4.1","chokidar":"^4.0.3","close-with-grace":"^2.2.0","cookie":"^1.0.2","cross-spawn":"^7.0.6","dayjs":"^1.11.13","esbuild":"^0.25.5","execa":"^9.6.0","find-process":"^1.4.10","fkill":"^9.0.0","fs-extra":"^11.3.0","globby":"^14.1.0","ignore":"^7.0.5","json5":"^2.2.3","lru-cache":"^11.1.0","lz-string":"^1.5.0","md5-hex":"^5.0.0","mdast-util-mdx-jsx":"^3.2.0","mdx-bundler":"^10.1.1","p-queue":"^8.1.0","parse-git-diff":"^0.0.19","rehype":"^13.0.2","rehype-autolink-headings":"^7.1.0","remark":"^15.0.1","remark-emoji":"^5.0.1","remark-gfm":"^4.0.1","shiki":"^3.7.0","unified":"^11.0.5","unist-util-remove-position":"^5.0.0","unist-util-visit":"^5.0.0","zod":"^3.25.71"},"devDependencies":{"@types/hast":"^3.0.4","@types/mdast":"^4.0.4","@types/node":"^24.0.10","tshy":"^3.0.2"},"repository":{"type":"git","url":"https://github.com/epicweb-dev/epicshop.git","directory":"packages/workshop-utils"}}