@b9g/platform-cloudflare 0.1.7 → 0.1.8

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@b9g/platform-cloudflare",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Cloudflare Workers platform adapter for Shovel - already ServiceWorker-based!",
5
5
  "keywords": [
6
6
  "shovel",
@@ -11,14 +11,15 @@
11
11
  "serviceworker"
12
12
  ],
13
13
  "dependencies": {
14
- "@b9g/assets": "^0.1.13",
14
+ "@b9g/assets": "^0.1.14",
15
15
  "@b9g/cache": "^0.1.4",
16
16
  "@b9g/platform": "^0.1.10",
17
17
  "@cloudflare/workers-types": "^4.20241218.0",
18
+ "@logtape/logtape": "^1.2.0",
18
19
  "miniflare": "^4.20251118.1"
19
20
  },
20
21
  "devDependencies": {
21
- "@b9g/libuild": "^0.1.11",
22
+ "@b9g/libuild": "^0.1.18",
22
23
  "bun-types": "latest"
23
24
  },
24
25
  "type": "module",
package/src/index.d.ts CHANGED
@@ -65,7 +65,7 @@ export declare const cloudflareWorkerBanner = "// Cloudflare Worker ES Module wr
65
65
  /**
66
66
  * Generate footer code for ServiceWorker → ES Module conversion
67
67
  */
68
- export declare const cloudflareWorkerFooter = "\n// Export ES Module for Cloudflare Workers\nexport default {\n\tasync fetch(request, env, ctx) {\n\t\ttry {\n\t\t\t// Set up ServiceWorker-like dirs API for bundled deployment\n\t\t\tif (!globalThis.self.dirs) {\n\t\t\t\t// For bundled deployment, assets are served via static middleware\n\t\t\t\t// not through the dirs API\n\t\t\t\tglobalThis.self.dirs = {\n\t\t\t\t\tasync open(directoryName) {\n\t\t\t\t\t\tif (directoryName === 'assets') {\n\t\t\t\t\t\t\t// Return a minimal interface that indicates no files available\n\t\t\t\t\t\t\t// The assets middleware will fall back to dev mode behavior\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tasync getFileHandle(fileName) {\n\t\t\t\t\t\t\t\t\tthrow new Error(`NotFoundError: ${fileName} not found in bundled assets`);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow new Error(`Directory ${directoryName} not available in bundled deployment`);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t\t\n\t\t\t// Set up caches API\n\t\t\tif (!globalThis.self.caches) {\n\t\t\t\tglobalThis.self.caches = globalThis.caches;\n\t\t\t}\n\t\t\t\n\t\t\t// Ensure request.url is a string\n\t\t\tif (typeof request.url !== 'string') {\n\t\t\t\treturn new Response('Invalid request URL: ' + typeof request.url, { status: 500 });\n\t\t\t}\n\t\t\t\n\t\t\t// Create proper FetchEvent-like object\n\t\t\tlet responseReceived = null;\n\t\t\tconst event = { \n\t\t\t\trequest, \n\t\t\t\trespondWith: (response) => { responseReceived = response; }\n\t\t\t};\n\t\t\t\n\t\t\t// Helper for error responses\n\t\t\tconst createErrorResponse = (err) => {\n\t\t\t\tconst isDev = typeof import.meta !== \"undefined\" && import.meta.env?.MODE !== \"production\";\n\t\t\t\tif (isDev) {\n\t\t\t\t\tconst escapeHtml = (str) => str.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\");\n\t\t\t\t\treturn new Response(`<!DOCTYPE html>\n<html>\n<head>\n <title>500 Internal Server Error</title>\n <style>\n body { font-family: system-ui, sans-serif; padding: 2rem; max-width: 800px; margin: 0 auto; }\n h1 { color: #c00; }\n .message { font-size: 1.2em; color: #333; }\n pre { background: #f5f5f5; padding: 1rem; overflow-x: auto; border-radius: 4px; }\n </style>\n</head>\n<body>\n <h1>500 Internal Server Error</h1>\n <p class=\"message\">${escapeHtml(err.message)}</p>\n <pre>${escapeHtml(err.stack || \"No stack trace available\")}</pre>\n</body>\n</html>`, { status: 500, headers: { \"Content-Type\": \"text/html; charset=utf-8\" } });\n\t\t\t\t} else {\n\t\t\t\t\treturn new Response(\"Internal Server Error\", { status: 500, headers: { \"Content-Type\": \"text/plain\" } });\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Dispatch to ServiceWorker fetch handlers\n\t\t\tfor (const handler of fetchHandlers) {\n\t\t\t\ttry {\n\t\t\t\t\tlogger.debug(\"Calling handler\", {url: request.url});\n\t\t\t\t\tawait handler(event);\n\t\t\t\t\tlogger.debug(\"Handler completed\", {hasResponse: !!responseReceived});\n\t\t\t\t\tif (responseReceived) {\n\t\t\t\t\t\treturn responseReceived;\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlogger.error(\"Handler error\", {error});\n\t\t\t\t\tlogger.error(\"Error stack\", {stack: error.stack});\n\t\t\t\t\treturn createErrorResponse(error);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn new Response('No ServiceWorker handler', { status: 404 });\n\t\t} catch (topLevelError) {\n\t\t\tlogger.error(\"Top-level error\", {error: topLevelError});\n\t\t\tconst isDev = typeof import.meta !== \"undefined\" && import.meta.env?.MODE !== \"production\";\n\t\t\tif (isDev) {\n\t\t\t\tconst escapeHtml = (str) => String(str).replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\");\n\t\t\t\treturn new Response(`<!DOCTYPE html>\n<html>\n<head>\n <title>500 Internal Server Error</title>\n <style>\n body { font-family: system-ui, sans-serif; padding: 2rem; max-width: 800px; margin: 0 auto; }\n h1 { color: #c00; }\n .message { font-size: 1.2em; color: #333; }\n pre { background: #f5f5f5; padding: 1rem; overflow-x: auto; border-radius: 4px; }\n </style>\n</head>\n<body>\n <h1>500 Internal Server Error</h1>\n <p class=\"message\">${escapeHtml(topLevelError.message)}</p>\n <pre>${escapeHtml(topLevelError.stack || \"No stack trace available\")}</pre>\n</body>\n</html>`, { status: 500, headers: { \"Content-Type\": \"text/html; charset=utf-8\" } });\n\t\t\t} else {\n\t\t\t\treturn new Response(\"Internal Server Error\", { status: 500, headers: { \"Content-Type\": \"text/plain\" } });\n\t\t\t}\n\t\t}\n\t}\n};";
68
+ export declare const cloudflareWorkerFooter = "\n// Export ES Module for Cloudflare Workers\nexport default {\n\tasync fetch(request, env, ctx) {\n\t\ttry {\n\t\t\t// Set up ServiceWorker-like dirs API for bundled deployment\n\t\t\tif (!globalThis.self.dirs) {\n\t\t\t\t// For bundled deployment, assets are served via static middleware\n\t\t\t\t// not through the dirs API\n\t\t\t\tglobalThis.self.dirs = {\n\t\t\t\t\tasync open(directoryName) {\n\t\t\t\t\t\tif (directoryName === 'assets') {\n\t\t\t\t\t\t\t// Return a minimal interface that indicates no files available\n\t\t\t\t\t\t\t// The assets middleware will fall back to dev mode behavior\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tasync getFileHandle(fileName) {\n\t\t\t\t\t\t\t\t\tthrow new Error(`NotFoundError: ${fileName} not found in bundled assets`);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow new Error(`Directory ${directoryName} not available in bundled deployment`);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t\t\n\t\t\t// Set up caches API\n\t\t\tif (!globalThis.self.caches) {\n\t\t\t\tglobalThis.self.caches = globalThis.caches;\n\t\t\t}\n\t\t\t\n\t\t\t// Ensure request.url is a string\n\t\t\tif (typeof request.url !== 'string') {\n\t\t\t\treturn new Response('Invalid request URL: ' + typeof request.url, { status: 500 });\n\t\t\t}\n\t\t\t\n\t\t\t// Create proper FetchEvent-like object\n\t\t\tlet responseReceived = null;\n\t\t\tconst event = { \n\t\t\t\trequest, \n\t\t\t\trespondWith: (response) => { responseReceived = response; }\n\t\t\t};\n\t\t\t\n\t\t\t// Helper for error responses\n\t\t\tconst createErrorResponse = (err) => {\n\t\t\t\tconst isDev = typeof import.meta !== \"undefined\" && import.meta.env?.MODE !== \"production\";\n\t\t\t\tif (isDev) {\n\t\t\t\t\tconst escapeHtml = (str) => str.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\");\n\t\t\t\t\treturn new Response(`<!DOCTYPE html>\n<html>\n<head>\n <title>500 Internal Server Error</title>\n <style>\n body { font-family: system-ui, sans-serif; padding: 2rem; max-width: 800px; margin: 0 auto; }\n h1 { color: #c00; }\n .message { font-size: 1.2em; color: #333; }\n pre { background: #f5f5f5; padding: 1rem; overflow-x: auto; border-radius: 4px; }\n </style>\n</head>\n<body>\n <h1>500 Internal Server Error</h1>\n <p class=\"message\">${escapeHtml(err.message)}</p>\n <pre>${escapeHtml(err.stack || \"No stack trace available\")}</pre>\n</body>\n</html>`, { status: 500, headers: { \"Content-Type\": \"text/html; charset=utf-8\" } });\n\t\t\t\t} else {\n\t\t\t\t\treturn new Response(\"Internal Server Error\", { status: 500, headers: { \"Content-Type\": \"text/plain\" } });\n\t\t\t\t}\n\t\t\t};\n\n\t\t\t// Dispatch to ServiceWorker fetch handlers\n\t\t\tfor (const handler of fetchHandlers) {\n\t\t\t\ttry {\n\t\t\t\t\tlogger.debug(\"Calling handler\", {url: request.url});\n\t\t\t\t\tawait handler(event);\n\t\t\t\t\tlogger.debug(\"Handler completed\", {hasResponse: !!responseReceived});\n\t\t\t\t\tif (responseReceived) {\n\t\t\t\t\t\treturn responseReceived;\n\t\t\t\t\t}\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlogger.error(\"Handler error: {error}\", {error});\n\t\t\t\t\treturn createErrorResponse(error);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn new Response('No ServiceWorker handler', { status: 404 });\n\t\t} catch (topLevelError) {\n\t\t\tlogger.error(\"Top-level error: {error}\", {error: topLevelError});\n\t\t\tconst isDev = typeof import.meta !== \"undefined\" && import.meta.env?.MODE !== \"production\";\n\t\t\tif (isDev) {\n\t\t\t\tconst escapeHtml = (str) => String(str).replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\");\n\t\t\t\treturn new Response(`<!DOCTYPE html>\n<html>\n<head>\n <title>500 Internal Server Error</title>\n <style>\n body { font-family: system-ui, sans-serif; padding: 2rem; max-width: 800px; margin: 0 auto; }\n h1 { color: #c00; }\n .message { font-size: 1.2em; color: #333; }\n pre { background: #f5f5f5; padding: 1rem; overflow-x: auto; border-radius: 4px; }\n </style>\n</head>\n<body>\n <h1>500 Internal Server Error</h1>\n <p class=\"message\">${escapeHtml(topLevelError.message)}</p>\n <pre>${escapeHtml(topLevelError.stack || \"No stack trace available\")}</pre>\n</body>\n</html>`, { status: 500, headers: { \"Content-Type\": \"text/html; charset=utf-8\" } });\n\t\t\t} else {\n\t\t\t\treturn new Response(\"Internal Server Error\", { status: 500, headers: { \"Content-Type\": \"text/plain\" } });\n\t\t\t}\n\t\t}\n\t}\n};";
69
69
  /**
70
70
  * Default export for easy importing
71
71
  */
package/src/index.js CHANGED
@@ -365,15 +365,14 @@ export default {
365
365
  return responseReceived;
366
366
  }
367
367
  } catch (error) {
368
- logger.error("Handler error", {error});
369
- logger.error("Error stack", {stack: error.stack});
368
+ logger.error("Handler error: {error}", {error});
370
369
  return createErrorResponse(error);
371
370
  }
372
371
  }
373
372
 
374
373
  return new Response('No ServiceWorker handler', { status: 404 });
375
374
  } catch (topLevelError) {
376
- logger.error("Top-level error", {error: topLevelError});
375
+ logger.error("Top-level error: {error}", {error: topLevelError});
377
376
  const isDev = typeof import.meta !== "undefined" && import.meta.env?.MODE !== "production";
378
377
  if (isDev) {
379
378
  const escapeHtml = (str) => String(str).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");