almostnode 0.1.0 → 0.2.0

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.
@@ -0,0 +1,56 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
4
+
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const url = require('url');
8
+
9
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
10
+ function _interopNamespaceDefault(e) {
11
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
12
+ if (e) {
13
+ for (const k in e) {
14
+ if (k !== 'default') {
15
+ const d = Object.getOwnPropertyDescriptor(e, k);
16
+ Object.defineProperty(n, k, d.get ? d : {
17
+ enumerable: true,
18
+ get: () => e[k]
19
+ });
20
+ }
21
+ }
22
+ }
23
+ n.default = e;
24
+ return Object.freeze(n);
25
+ }
26
+
27
+ const fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
28
+ const path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
29
+
30
+ const __dirname$1 = path__namespace.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('next-plugin.cjs', document.baseURI).href))));
31
+ function getServiceWorkerContent() {
32
+ let swFilePath = path__namespace.join(__dirname$1, "__sw__.js");
33
+ if (!fs__namespace.existsSync(swFilePath)) {
34
+ swFilePath = path__namespace.join(__dirname$1, "../dist/__sw__.js");
35
+ }
36
+ if (!fs__namespace.existsSync(swFilePath)) {
37
+ throw new Error("Service worker file not found. Make sure almostnode is built.");
38
+ }
39
+ return fs__namespace.readFileSync(swFilePath, "utf-8");
40
+ }
41
+ function getServiceWorkerPath() {
42
+ let swFilePath = path__namespace.join(__dirname$1, "__sw__.js");
43
+ if (!fs__namespace.existsSync(swFilePath)) {
44
+ swFilePath = path__namespace.join(__dirname$1, "../dist/__sw__.js");
45
+ }
46
+ if (!fs__namespace.existsSync(swFilePath)) {
47
+ throw new Error("Service worker file not found. Make sure almostnode is built.");
48
+ }
49
+ return swFilePath;
50
+ }
51
+ const nextPlugin = { getServiceWorkerContent, getServiceWorkerPath };
52
+
53
+ exports.default = nextPlugin;
54
+ exports.getServiceWorkerContent = getServiceWorkerContent;
55
+ exports.getServiceWorkerPath = getServiceWorkerPath;
56
+ //# sourceMappingURL=next-plugin.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next-plugin.cjs","sources":["../src/next-plugin.ts"],"sourcesContent":["/**\n * Next.js Plugin for almostnode\n *\n * Provides utilities for serving the service worker file in Next.js applications.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { fileURLToPath } from 'url';\n\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore - import.meta.url is available in ESM\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n/**\n * Get the contents of the almostnode service worker file.\n * Use this in a Next.js API route or middleware to serve the service worker.\n *\n * @example\n * ```typescript\n * // app/api/__sw__/route.ts (App Router)\n * import { getServiceWorkerContent } from 'almostnode/next';\n *\n * export async function GET() {\n * const content = getServiceWorkerContent();\n * return new Response(content, {\n * headers: {\n * 'Content-Type': 'application/javascript',\n * 'Cache-Control': 'no-cache',\n * },\n * });\n * }\n * ```\n *\n * @example\n * ```typescript\n * // pages/api/__sw__.ts (Pages Router)\n * import { getServiceWorkerContent } from 'almostnode/next';\n * import type { NextApiRequest, NextApiResponse } from 'next';\n *\n * export default function handler(req: NextApiRequest, res: NextApiResponse) {\n * const content = getServiceWorkerContent();\n * res.setHeader('Content-Type', 'application/javascript');\n * res.setHeader('Cache-Control', 'no-cache');\n * res.send(content);\n * }\n * ```\n */\nexport function getServiceWorkerContent(): string {\n // The service worker file is in the dist directory relative to this file\n // In src: ../dist/__sw__.js\n // In dist: ./__sw__.js\n let swFilePath = path.join(__dirname, '__sw__.js');\n\n // If running from src directory during development, look in dist\n if (!fs.existsSync(swFilePath)) {\n swFilePath = path.join(__dirname, '../dist/__sw__.js');\n }\n\n if (!fs.existsSync(swFilePath)) {\n throw new Error('Service worker file not found. Make sure almostnode is built.');\n }\n\n return fs.readFileSync(swFilePath, 'utf-8');\n}\n\n/**\n * Get the path to the almostnode service worker file.\n * Useful if you want to copy it to your public directory.\n *\n * @example\n * ```javascript\n * // scripts/copy-sw.js\n * const { getServiceWorkerPath } = require('almostnode/next');\n * const fs = require('fs');\n * const path = require('path');\n *\n * const swPath = getServiceWorkerPath();\n * fs.copyFileSync(swPath, path.join(__dirname, '../public/__sw__.js'));\n * ```\n */\nexport function getServiceWorkerPath(): string {\n let swFilePath = path.join(__dirname, '__sw__.js');\n\n if (!fs.existsSync(swFilePath)) {\n swFilePath = path.join(__dirname, '../dist/__sw__.js');\n }\n\n if (!fs.existsSync(swFilePath)) {\n throw new Error('Service worker file not found. Make sure almostnode is built.');\n }\n\n return swFilePath;\n}\n\nexport default { getServiceWorkerContent, getServiceWorkerPath };\n"],"names":["__dirname","path","fileURLToPath","fs"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAYA,MAAMA,cAAYC,eAAA,CAAK,OAAA,CAAQC,iBAAA,CAAc,iQAAe,CAAC,CAAA;AAoCtD,SAAS,uBAAA,GAAkC;AAIhD,EAAA,IAAI,UAAA,GAAaD,eAAA,CAAK,IAAA,CAAKD,WAAA,EAAW,WAAW,CAAA;AAGjD,EAAA,IAAI,CAACG,aAAA,CAAG,UAAA,CAAW,UAAU,CAAA,EAAG;AAC9B,IAAA,UAAA,GAAaF,eAAA,CAAK,IAAA,CAAKD,WAAA,EAAW,mBAAmB,CAAA;AAAA,EACvD;AAEA,EAAA,IAAI,CAACG,aAAA,CAAG,UAAA,CAAW,UAAU,CAAA,EAAG;AAC9B,IAAA,MAAM,IAAI,MAAM,+DAA+D,CAAA;AAAA,EACjF;AAEA,EAAA,OAAOA,aAAA,CAAG,YAAA,CAAa,UAAA,EAAY,OAAO,CAAA;AAC5C;AAiBO,SAAS,oBAAA,GAA+B;AAC7C,EAAA,IAAI,UAAA,GAAaF,eAAA,CAAK,IAAA,CAAKD,WAAA,EAAW,WAAW,CAAA;AAEjD,EAAA,IAAI,CAACG,aAAA,CAAG,UAAA,CAAW,UAAU,CAAA,EAAG;AAC9B,IAAA,UAAA,GAAaF,eAAA,CAAK,IAAA,CAAKD,WAAA,EAAW,mBAAmB,CAAA;AAAA,EACvD;AAEA,EAAA,IAAI,CAACG,aAAA,CAAG,UAAA,CAAW,UAAU,CAAA,EAAG;AAC9B,IAAA,MAAM,IAAI,MAAM,+DAA+D,CAAA;AAAA,EACjF;AAEA,EAAA,OAAO,UAAA;AACT;AAEA,mBAAe,EAAE,yBAAyB,oBAAA,EAAqB;;;;;;"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Next.js Plugin for almostnode
3
+ *
4
+ * Provides utilities for serving the service worker file in Next.js applications.
5
+ */
6
+ /**
7
+ * Get the contents of the almostnode service worker file.
8
+ * Use this in a Next.js API route or middleware to serve the service worker.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * // app/api/__sw__/route.ts (App Router)
13
+ * import { getServiceWorkerContent } from 'almostnode/next';
14
+ *
15
+ * export async function GET() {
16
+ * const content = getServiceWorkerContent();
17
+ * return new Response(content, {
18
+ * headers: {
19
+ * 'Content-Type': 'application/javascript',
20
+ * 'Cache-Control': 'no-cache',
21
+ * },
22
+ * });
23
+ * }
24
+ * ```
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * // pages/api/__sw__.ts (Pages Router)
29
+ * import { getServiceWorkerContent } from 'almostnode/next';
30
+ * import type { NextApiRequest, NextApiResponse } from 'next';
31
+ *
32
+ * export default function handler(req: NextApiRequest, res: NextApiResponse) {
33
+ * const content = getServiceWorkerContent();
34
+ * res.setHeader('Content-Type', 'application/javascript');
35
+ * res.setHeader('Cache-Control', 'no-cache');
36
+ * res.send(content);
37
+ * }
38
+ * ```
39
+ */
40
+ export declare function getServiceWorkerContent(): string;
41
+ /**
42
+ * Get the path to the almostnode service worker file.
43
+ * Useful if you want to copy it to your public directory.
44
+ *
45
+ * @example
46
+ * ```javascript
47
+ * // scripts/copy-sw.js
48
+ * const { getServiceWorkerPath } = require('almostnode/next');
49
+ * const fs = require('fs');
50
+ * const path = require('path');
51
+ *
52
+ * const swPath = getServiceWorkerPath();
53
+ * fs.copyFileSync(swPath, path.join(__dirname, '../public/__sw__.js'));
54
+ * ```
55
+ */
56
+ export declare function getServiceWorkerPath(): string;
57
+ declare const _default: {
58
+ getServiceWorkerContent: typeof getServiceWorkerContent;
59
+ getServiceWorkerPath: typeof getServiceWorkerPath;
60
+ };
61
+ export default _default;
62
+ //# sourceMappingURL=next-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next-plugin.d.ts","sourceRoot":"","sources":["../src/next-plugin.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAgBhD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAY7C;;;;;AAED,wBAAiE"}
@@ -0,0 +1,30 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import { fileURLToPath } from "url";
4
+ const __dirname$1 = path.dirname(fileURLToPath(import.meta.url));
5
+ function getServiceWorkerContent() {
6
+ let swFilePath = path.join(__dirname$1, "__sw__.js");
7
+ if (!fs.existsSync(swFilePath)) {
8
+ swFilePath = path.join(__dirname$1, "../dist/__sw__.js");
9
+ }
10
+ if (!fs.existsSync(swFilePath)) {
11
+ throw new Error("Service worker file not found. Make sure almostnode is built.");
12
+ }
13
+ return fs.readFileSync(swFilePath, "utf-8");
14
+ }
15
+ function getServiceWorkerPath() {
16
+ let swFilePath = path.join(__dirname$1, "__sw__.js");
17
+ if (!fs.existsSync(swFilePath)) {
18
+ swFilePath = path.join(__dirname$1, "../dist/__sw__.js");
19
+ }
20
+ if (!fs.existsSync(swFilePath)) {
21
+ throw new Error("Service worker file not found. Make sure almostnode is built.");
22
+ }
23
+ return swFilePath;
24
+ }
25
+ const nextPlugin = { getServiceWorkerContent, getServiceWorkerPath };
26
+ export {
27
+ nextPlugin as default,
28
+ getServiceWorkerContent,
29
+ getServiceWorkerPath
30
+ };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next-plugin.mjs","sources":["../src/next-plugin.ts"],"sourcesContent":["/**\n * Next.js Plugin for almostnode\n *\n * Provides utilities for serving the service worker file in Next.js applications.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { fileURLToPath } from 'url';\n\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore - import.meta.url is available in ESM\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n/**\n * Get the contents of the almostnode service worker file.\n * Use this in a Next.js API route or middleware to serve the service worker.\n *\n * @example\n * ```typescript\n * // app/api/__sw__/route.ts (App Router)\n * import { getServiceWorkerContent } from 'almostnode/next';\n *\n * export async function GET() {\n * const content = getServiceWorkerContent();\n * return new Response(content, {\n * headers: {\n * 'Content-Type': 'application/javascript',\n * 'Cache-Control': 'no-cache',\n * },\n * });\n * }\n * ```\n *\n * @example\n * ```typescript\n * // pages/api/__sw__.ts (Pages Router)\n * import { getServiceWorkerContent } from 'almostnode/next';\n * import type { NextApiRequest, NextApiResponse } from 'next';\n *\n * export default function handler(req: NextApiRequest, res: NextApiResponse) {\n * const content = getServiceWorkerContent();\n * res.setHeader('Content-Type', 'application/javascript');\n * res.setHeader('Cache-Control', 'no-cache');\n * res.send(content);\n * }\n * ```\n */\nexport function getServiceWorkerContent(): string {\n // The service worker file is in the dist directory relative to this file\n // In src: ../dist/__sw__.js\n // In dist: ./__sw__.js\n let swFilePath = path.join(__dirname, '__sw__.js');\n\n // If running from src directory during development, look in dist\n if (!fs.existsSync(swFilePath)) {\n swFilePath = path.join(__dirname, '../dist/__sw__.js');\n }\n\n if (!fs.existsSync(swFilePath)) {\n throw new Error('Service worker file not found. Make sure almostnode is built.');\n }\n\n return fs.readFileSync(swFilePath, 'utf-8');\n}\n\n/**\n * Get the path to the almostnode service worker file.\n * Useful if you want to copy it to your public directory.\n *\n * @example\n * ```javascript\n * // scripts/copy-sw.js\n * const { getServiceWorkerPath } = require('almostnode/next');\n * const fs = require('fs');\n * const path = require('path');\n *\n * const swPath = getServiceWorkerPath();\n * fs.copyFileSync(swPath, path.join(__dirname, '../public/__sw__.js'));\n * ```\n */\nexport function getServiceWorkerPath(): string {\n let swFilePath = path.join(__dirname, '__sw__.js');\n\n if (!fs.existsSync(swFilePath)) {\n swFilePath = path.join(__dirname, '../dist/__sw__.js');\n }\n\n if (!fs.existsSync(swFilePath)) {\n throw new Error('Service worker file not found. Make sure almostnode is built.');\n }\n\n return swFilePath;\n}\n\nexport default { getServiceWorkerContent, getServiceWorkerPath };\n"],"names":["__dirname"],"mappings":";;;;AAYA,MAAMA,cAAY,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAC,CAAA;AAoCtD,SAAS,uBAAA,GAAkC;AAIhD,EAAA,IAAI,UAAA,GAAa,IAAA,CAAK,IAAA,CAAKA,WAAA,EAAW,WAAW,CAAA;AAGjD,EAAA,IAAI,CAAC,EAAA,CAAG,UAAA,CAAW,UAAU,CAAA,EAAG;AAC9B,IAAA,UAAA,GAAa,IAAA,CAAK,IAAA,CAAKA,WAAA,EAAW,mBAAmB,CAAA;AAAA,EACvD;AAEA,EAAA,IAAI,CAAC,EAAA,CAAG,UAAA,CAAW,UAAU,CAAA,EAAG;AAC9B,IAAA,MAAM,IAAI,MAAM,+DAA+D,CAAA;AAAA,EACjF;AAEA,EAAA,OAAO,EAAA,CAAG,YAAA,CAAa,UAAA,EAAY,OAAO,CAAA;AAC5C;AAiBO,SAAS,oBAAA,GAA+B;AAC7C,EAAA,IAAI,UAAA,GAAa,IAAA,CAAK,IAAA,CAAKA,WAAA,EAAW,WAAW,CAAA;AAEjD,EAAA,IAAI,CAAC,EAAA,CAAG,UAAA,CAAW,UAAU,CAAA,EAAG;AAC9B,IAAA,UAAA,GAAa,IAAA,CAAK,IAAA,CAAKA,WAAA,EAAW,mBAAmB,CAAA;AAAA,EACvD;AAEA,EAAA,IAAI,CAAC,EAAA,CAAG,UAAA,CAAW,UAAU,CAAA,EAAG;AAC9B,IAAA,MAAM,IAAI,MAAM,+DAA+D,CAAA;AAAA,EACjF;AAEA,EAAA,OAAO,UAAA;AACT;AAEA,mBAAe,EAAE,yBAAyB,oBAAA,EAAqB;;;;"}
@@ -4,36 +4,59 @@
4
4
  * The sandbox runs on a different origin (e.g., myapp-sandbox.vercel.app)
5
5
  * to provide browser-enforced isolation from the main application.
6
6
  */
7
+ export interface SandboxHtmlOptions {
8
+ /**
9
+ * URL to load almostnode from (e.g., unpkg, jsdelivr, or your CDN)
10
+ * @default 'https://unpkg.com/almostnode/dist/index.js'
11
+ */
12
+ almostnodeUrl?: string;
13
+ /**
14
+ * Whether to include service worker registration for dev server support.
15
+ * When true, the sandbox can run ViteDevServer/NextDevServer with URL access.
16
+ * @default true
17
+ */
18
+ includeServiceWorker?: boolean;
19
+ }
7
20
  /**
8
21
  * HTML template for the sandbox page.
9
22
  * This loads almostnode and handles postMessage communication with the parent.
10
23
  *
11
- * @param justNodeUrl - URL to load almostnode from (e.g., unpkg, jsdelivr, or your CDN)
24
+ * @param options - Configuration options or legacy URL string
12
25
  */
13
- export declare function getSandboxHtml(justNodeUrl?: string): string;
26
+ export declare function getSandboxHtml(options?: SandboxHtmlOptions | string): string;
14
27
  /**
15
28
  * Get vercel.json configuration for the sandbox.
16
29
  * Sets up CORS headers to allow embedding as a cross-origin iframe.
17
30
  */
18
31
  export declare function getSandboxVercelConfig(): object;
32
+ export interface GenerateSandboxFilesOptions extends SandboxHtmlOptions {
33
+ }
19
34
  /**
20
- * Generate all files needed for deploying a sandbox to Vercel.
35
+ * Generate all files needed for deploying a sandbox to Vercel or other platforms.
21
36
  *
22
- * @param justNodeUrl - URL to load almostnode from
37
+ * @param options - Configuration options or legacy URL string
23
38
  * @returns Object with file names as keys and content as values
24
39
  *
25
40
  * @example
26
41
  * ```typescript
27
- * import { generateSandboxFiles } from 'almostnode/sandbox-helpers';
42
+ * import { generateSandboxFiles } from 'almostnode';
43
+ * import fs from 'fs';
28
44
  *
29
45
  * const files = generateSandboxFiles();
46
+ *
30
47
  * // Write files to sandbox/ directory
48
+ * fs.mkdirSync('sandbox', { recursive: true });
49
+ * for (const [filename, content] of Object.entries(files)) {
50
+ * fs.writeFileSync(`sandbox/${filename}`, content);
51
+ * }
52
+ *
31
53
  * // Deploy to Vercel: cd sandbox && vercel --prod
32
54
  * ```
33
55
  */
34
- export declare function generateSandboxFiles(justNodeUrl?: string): {
56
+ export declare function generateSandboxFiles(options?: GenerateSandboxFilesOptions | string): {
35
57
  'index.html': string;
36
58
  'vercel.json': string;
59
+ '__sw__.js'?: string;
37
60
  };
38
61
  /**
39
62
  * Instructions for setting up a sandbox on Vercel.
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox-helpers.d.ts","sourceRoot":"","sources":["../src/sandbox-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,WAAW,SAA+C,GAAG,MAAM,CA2FjG;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAY/C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG;IAC1D,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB,CAKA;AAED;;;GAGG;AACH,eAAO,MAAM,0BAA0B,QAmB/B,CAAC"}
1
+ {"version":3,"file":"sandbox-helpers.d.ts","sourceRoot":"","sources":["../src/sandbox-helpers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgCH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,kBAAkB,GAAG,MAAW,GAAG,MAAM,CA6GhF;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAY/C;AAED,MAAM,WAAW,2BAA4B,SAAQ,kBAAkB;CAEtE;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,GAAE,2BAA2B,GAAG,MAAW,GAAG;IACxF,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAuBA;AAED;;;GAGG;AACH,eAAO,MAAM,0BAA0B,QAmB/B,CAAC"}
@@ -26,6 +26,13 @@ export interface BridgeOptions {
26
26
  baseUrl?: string;
27
27
  onServerReady?: (port: number, url: string) => void;
28
28
  }
29
+ export interface InitServiceWorkerOptions {
30
+ /**
31
+ * The URL path to the service worker file
32
+ * @default '/__sw__.js'
33
+ */
34
+ swUrl?: string;
35
+ }
29
36
  /**
30
37
  * Server Bridge manages virtual HTTP servers and routes requests
31
38
  */
@@ -58,8 +65,10 @@ export declare class ServerBridge extends EventEmitter {
58
65
  handleRequest(port: number, method: string, url: string, headers: Record<string, string>, body?: ArrayBuffer): Promise<ResponseData>;
59
66
  /**
60
67
  * Initialize Service Worker communication
68
+ * @param options - Configuration options for the service worker
69
+ * @param options.swUrl - Custom URL path to the service worker file (default: '/__sw__.js')
61
70
  */
62
- initServiceWorker(): Promise<void>;
71
+ initServiceWorker(options?: InitServiceWorkerOptions): Promise<void>;
63
72
  /**
64
73
  * Handle messages from Service Worker
65
74
  */
@@ -1 +1 @@
1
- {"version":3,"file":"server-bridge.d.ts","sourceRoot":"","sources":["../src/server-bridge.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,MAAM,EACN,YAAY,EAIb,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACpE,aAAa,CACX,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GACrB,OAAO,CAAC,YAAY,CAAC,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,GAAG,cAAc,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,YAAY;IAC5C,OAAO,CAAC,OAAO,CAAyC;IACxD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,kBAAkB,CAAkB;gBAEhC,OAAO,GAAE,aAAkB;IAqBvC;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAkB,GAAG,IAAI;IAejG;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKpC;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIlC;;OAEG;IACH,cAAc,IAAI,MAAM,EAAE;IAI1B;;OAEG;IACG,aAAa,CACjB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,YAAY,CAAC;IA0BxB;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IA0CxC;;OAEG;YACW,0BAA0B;IAyDxC;;OAEG;YACW,sBAAsB;IA+FpC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;OAEG;IACH,kBAAkB,IAAI,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC;CA0C9D;AAKD;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,YAAY,CAKrE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"server-bridge.d.ts","sourceRoot":"","sources":["../src/server-bridge.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,MAAM,EACN,YAAY,EAIb,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACpE,aAAa,CACX,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GACrB,OAAO,CAAC,YAAY,CAAC,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,GAAG,cAAc,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD;AAED,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,YAAY;IAC5C,OAAO,CAAC,OAAO,CAAyC;IACxD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,kBAAkB,CAAkB;gBAEhC,OAAO,GAAE,aAAkB;IAqBvC;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAkB,GAAG,IAAI;IAejG;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAKpC;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIlC;;OAEG;IACH,cAAc,IAAI,MAAM,EAAE;IAI1B;;OAEG;IACG,aAAa,CACjB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,YAAY,CAAC;IA0BxB;;;;OAIG;IACG,iBAAiB,CAAC,OAAO,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IA4C1E;;OAEG;YACW,0BAA0B;IAyDxC;;OAEG;YACW,sBAAsB;IA+FpC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAM3B;;OAEG;IACH,kBAAkB,IAAI,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC;CA0C9D;AAKD;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,YAAY,CAKrE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED,eAAe,YAAY,CAAC"}
@@ -0,0 +1,56 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
4
+
5
+ const fs = require('fs');
6
+ const path = require('path');
7
+ const url = require('url');
8
+
9
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
10
+ function _interopNamespaceDefault(e) {
11
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
12
+ if (e) {
13
+ for (const k in e) {
14
+ if (k !== 'default') {
15
+ const d = Object.getOwnPropertyDescriptor(e, k);
16
+ Object.defineProperty(n, k, d.get ? d : {
17
+ enumerable: true,
18
+ get: () => e[k]
19
+ });
20
+ }
21
+ }
22
+ }
23
+ n.default = e;
24
+ return Object.freeze(n);
25
+ }
26
+
27
+ const fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
28
+ const path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
29
+
30
+ const __dirname$1 = path__namespace.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('vite-plugin.cjs', document.baseURI).href))));
31
+ function almostnodePlugin(options = {}) {
32
+ const swPath = options.swPath || "/__sw__.js";
33
+ return {
34
+ name: "almostnode",
35
+ configureServer(server) {
36
+ server.middlewares.use(swPath, (_req, res) => {
37
+ let swFilePath = path__namespace.join(__dirname$1, "__sw__.js");
38
+ if (!fs__namespace.existsSync(swFilePath)) {
39
+ swFilePath = path__namespace.join(__dirname$1, "../dist/__sw__.js");
40
+ }
41
+ if (!fs__namespace.existsSync(swFilePath)) {
42
+ res.statusCode = 404;
43
+ res.end("Service worker file not found. Make sure almostnode is built.");
44
+ return;
45
+ }
46
+ res.setHeader("Content-Type", "application/javascript");
47
+ res.setHeader("Cache-Control", "no-cache");
48
+ res.end(fs__namespace.readFileSync(swFilePath));
49
+ });
50
+ }
51
+ };
52
+ }
53
+
54
+ exports.almostnodePlugin = almostnodePlugin;
55
+ exports.default = almostnodePlugin;
56
+ //# sourceMappingURL=vite-plugin.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite-plugin.cjs","sources":["../src/vite-plugin.ts"],"sourcesContent":["/**\n * Vite Plugin for almostnode\n *\n * Serves the service worker file from the package's dist directory,\n * enabling seamless integration when almostnode is installed as an npm package.\n */\n\nimport type { Plugin, ViteDevServer } from 'vite';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { fileURLToPath } from 'url';\n\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore - import.meta.url is available in ESM\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nexport interface AlmostnodePluginOptions {\n /**\n * The URL path where the service worker will be served\n * @default '/__sw__.js'\n */\n swPath?: string;\n}\n\n/**\n * Vite plugin that serves the almostnode service worker file.\n *\n * When almostnode is installed as an npm package, the service worker file\n * is located at node_modules/almostnode/dist/__sw__.js but the browser\n * tries to load it from the root URL (/__sw__.js). This plugin intercepts\n * requests to the service worker path and serves the file from the correct location.\n *\n * @example\n * ```typescript\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { almostnodePlugin } from 'almostnode/vite';\n *\n * export default defineConfig({\n * plugins: [almostnodePlugin()]\n * });\n * ```\n */\nexport function almostnodePlugin(options: AlmostnodePluginOptions = {}): Plugin {\n const swPath = options.swPath || '/__sw__.js';\n\n return {\n name: 'almostnode',\n\n configureServer(server: ViteDevServer) {\n server.middlewares.use(swPath, (_req, res) => {\n // The service worker file is in the dist directory relative to this file\n // In src: ../dist/__sw__.js\n // In dist: ./__sw__.js\n let swFilePath = path.join(__dirname, '__sw__.js');\n\n // If running from src directory during development, look in dist\n if (!fs.existsSync(swFilePath)) {\n swFilePath = path.join(__dirname, '../dist/__sw__.js');\n }\n\n if (!fs.existsSync(swFilePath)) {\n res.statusCode = 404;\n res.end('Service worker file not found. Make sure almostnode is built.');\n return;\n }\n\n res.setHeader('Content-Type', 'application/javascript');\n res.setHeader('Cache-Control', 'no-cache');\n res.end(fs.readFileSync(swFilePath));\n });\n },\n };\n}\n\nexport default almostnodePlugin;\n"],"names":["__dirname","path","fileURLToPath","fs"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,MAAMA,cAAYC,eAAA,CAAK,OAAA,CAAQC,iBAAA,CAAc,iQAAe,CAAC,CAAA;AA6BtD,SAAS,gBAAA,CAAiB,OAAA,GAAmC,EAAC,EAAW;AAC9E,EAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,IAAU,YAAA;AAEjC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,YAAA;AAAA,IAEN,gBAAgB,MAAA,EAAuB;AACrC,MAAA,MAAA,CAAO,WAAA,CAAY,GAAA,CAAI,MAAA,EAAQ,CAAC,MAAM,GAAA,KAAQ;AAI5C,QAAA,IAAI,UAAA,GAAaD,eAAA,CAAK,IAAA,CAAKD,WAAA,EAAW,WAAW,CAAA;AAGjD,QAAA,IAAI,CAACG,aAAA,CAAG,UAAA,CAAW,UAAU,CAAA,EAAG;AAC9B,UAAA,UAAA,GAAaF,eAAA,CAAK,IAAA,CAAKD,WAAA,EAAW,mBAAmB,CAAA;AAAA,QACvD;AAEA,QAAA,IAAI,CAACG,aAAA,CAAG,UAAA,CAAW,UAAU,CAAA,EAAG;AAC9B,UAAA,GAAA,CAAI,UAAA,GAAa,GAAA;AACjB,UAAA,GAAA,CAAI,IAAI,+DAA+D,CAAA;AACvE,UAAA;AAAA,QACF;AAEA,QAAA,GAAA,CAAI,SAAA,CAAU,gBAAgB,wBAAwB,CAAA;AACtD,QAAA,GAAA,CAAI,SAAA,CAAU,iBAAiB,UAAU,CAAA;AACzC,QAAA,GAAA,CAAI,GAAA,CAAIA,aAAA,CAAG,YAAA,CAAa,UAAU,CAAC,CAAA;AAAA,MACrC,CAAC,CAAA;AAAA,IACH;AAAA,GACF;AACF;;;;;"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Vite Plugin for almostnode
3
+ *
4
+ * Serves the service worker file from the package's dist directory,
5
+ * enabling seamless integration when almostnode is installed as an npm package.
6
+ */
7
+ import type { Plugin } from 'vite';
8
+ export interface AlmostnodePluginOptions {
9
+ /**
10
+ * The URL path where the service worker will be served
11
+ * @default '/__sw__.js'
12
+ */
13
+ swPath?: string;
14
+ }
15
+ /**
16
+ * Vite plugin that serves the almostnode service worker file.
17
+ *
18
+ * When almostnode is installed as an npm package, the service worker file
19
+ * is located at node_modules/almostnode/dist/__sw__.js but the browser
20
+ * tries to load it from the root URL (/__sw__.js). This plugin intercepts
21
+ * requests to the service worker path and serves the file from the correct location.
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * // vite.config.ts
26
+ * import { defineConfig } from 'vite';
27
+ * import { almostnodePlugin } from 'almostnode/vite';
28
+ *
29
+ * export default defineConfig({
30
+ * plugins: [almostnodePlugin()]
31
+ * });
32
+ * ```
33
+ */
34
+ export declare function almostnodePlugin(options?: AlmostnodePluginOptions): Plugin;
35
+ export default almostnodePlugin;
36
+ //# sourceMappingURL=vite-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AASlD,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B,GAAG,MAAM,CA8B9E;AAED,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import { fileURLToPath } from "url";
4
+ const __dirname$1 = path.dirname(fileURLToPath(import.meta.url));
5
+ function almostnodePlugin(options = {}) {
6
+ const swPath = options.swPath || "/__sw__.js";
7
+ return {
8
+ name: "almostnode",
9
+ configureServer(server) {
10
+ server.middlewares.use(swPath, (_req, res) => {
11
+ let swFilePath = path.join(__dirname$1, "__sw__.js");
12
+ if (!fs.existsSync(swFilePath)) {
13
+ swFilePath = path.join(__dirname$1, "../dist/__sw__.js");
14
+ }
15
+ if (!fs.existsSync(swFilePath)) {
16
+ res.statusCode = 404;
17
+ res.end("Service worker file not found. Make sure almostnode is built.");
18
+ return;
19
+ }
20
+ res.setHeader("Content-Type", "application/javascript");
21
+ res.setHeader("Cache-Control", "no-cache");
22
+ res.end(fs.readFileSync(swFilePath));
23
+ });
24
+ }
25
+ };
26
+ }
27
+ export {
28
+ almostnodePlugin,
29
+ almostnodePlugin as default
30
+ };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite-plugin.mjs","sources":["../src/vite-plugin.ts"],"sourcesContent":["/**\n * Vite Plugin for almostnode\n *\n * Serves the service worker file from the package's dist directory,\n * enabling seamless integration when almostnode is installed as an npm package.\n */\n\nimport type { Plugin, ViteDevServer } from 'vite';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { fileURLToPath } from 'url';\n\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore - import.meta.url is available in ESM\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nexport interface AlmostnodePluginOptions {\n /**\n * The URL path where the service worker will be served\n * @default '/__sw__.js'\n */\n swPath?: string;\n}\n\n/**\n * Vite plugin that serves the almostnode service worker file.\n *\n * When almostnode is installed as an npm package, the service worker file\n * is located at node_modules/almostnode/dist/__sw__.js but the browser\n * tries to load it from the root URL (/__sw__.js). This plugin intercepts\n * requests to the service worker path and serves the file from the correct location.\n *\n * @example\n * ```typescript\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { almostnodePlugin } from 'almostnode/vite';\n *\n * export default defineConfig({\n * plugins: [almostnodePlugin()]\n * });\n * ```\n */\nexport function almostnodePlugin(options: AlmostnodePluginOptions = {}): Plugin {\n const swPath = options.swPath || '/__sw__.js';\n\n return {\n name: 'almostnode',\n\n configureServer(server: ViteDevServer) {\n server.middlewares.use(swPath, (_req, res) => {\n // The service worker file is in the dist directory relative to this file\n // In src: ../dist/__sw__.js\n // In dist: ./__sw__.js\n let swFilePath = path.join(__dirname, '__sw__.js');\n\n // If running from src directory during development, look in dist\n if (!fs.existsSync(swFilePath)) {\n swFilePath = path.join(__dirname, '../dist/__sw__.js');\n }\n\n if (!fs.existsSync(swFilePath)) {\n res.statusCode = 404;\n res.end('Service worker file not found. Make sure almostnode is built.');\n return;\n }\n\n res.setHeader('Content-Type', 'application/javascript');\n res.setHeader('Cache-Control', 'no-cache');\n res.end(fs.readFileSync(swFilePath));\n });\n },\n };\n}\n\nexport default almostnodePlugin;\n"],"names":["__dirname"],"mappings":";;;;AAcA,MAAMA,cAAY,IAAA,CAAK,OAAA,CAAQ,aAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAC,CAAA;AA6BtD,SAAS,gBAAA,CAAiB,OAAA,GAAmC,EAAC,EAAW;AAC9E,EAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,IAAU,YAAA;AAEjC,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,YAAA;AAAA,IAEN,gBAAgB,MAAA,EAAuB;AACrC,MAAA,MAAA,CAAO,WAAA,CAAY,GAAA,CAAI,MAAA,EAAQ,CAAC,MAAM,GAAA,KAAQ;AAI5C,QAAA,IAAI,UAAA,GAAa,IAAA,CAAK,IAAA,CAAKA,WAAA,EAAW,WAAW,CAAA;AAGjD,QAAA,IAAI,CAAC,EAAA,CAAG,UAAA,CAAW,UAAU,CAAA,EAAG;AAC9B,UAAA,UAAA,GAAa,IAAA,CAAK,IAAA,CAAKA,WAAA,EAAW,mBAAmB,CAAA;AAAA,QACvD;AAEA,QAAA,IAAI,CAAC,EAAA,CAAG,UAAA,CAAW,UAAU,CAAA,EAAG;AAC9B,UAAA,GAAA,CAAI,UAAA,GAAa,GAAA;AACjB,UAAA,GAAA,CAAI,IAAI,+DAA+D,CAAA;AACvE,UAAA;AAAA,QACF;AAEA,QAAA,GAAA,CAAI,SAAA,CAAU,gBAAgB,wBAAwB,CAAA;AACtD,QAAA,GAAA,CAAI,SAAA,CAAU,iBAAiB,UAAU,CAAA;AACzC,QAAA,GAAA,CAAI,GAAA,CAAI,EAAA,CAAG,YAAA,CAAa,UAAU,CAAC,CAAA;AAAA,MACrC,CAAC,CAAA;AAAA,IACH;AAAA,GACF;AACF;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "almostnode",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Node.js in your browser. Just like that.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -40,6 +40,26 @@
40
40
  "types": "./dist/index.d.ts",
41
41
  "default": "./dist/index.cjs"
42
42
  }
43
+ },
44
+ "./vite": {
45
+ "import": {
46
+ "types": "./dist/vite-plugin.d.ts",
47
+ "default": "./dist/vite-plugin.mjs"
48
+ },
49
+ "require": {
50
+ "types": "./dist/vite-plugin.d.ts",
51
+ "default": "./dist/vite-plugin.cjs"
52
+ }
53
+ },
54
+ "./next": {
55
+ "import": {
56
+ "types": "./dist/next-plugin.d.ts",
57
+ "default": "./dist/next-plugin.mjs"
58
+ },
59
+ "require": {
60
+ "types": "./dist/next-plugin.d.ts",
61
+ "default": "./dist/next-plugin.cjs"
62
+ }
43
63
  }
44
64
  },
45
65
  "files": [
@@ -1846,8 +1846,8 @@ export class NextDevServer extends DevServer {
1846
1846
  React.useEffect(() => {
1847
1847
  const handlePopState = () => {
1848
1848
  setCurrentPath(window.location.pathname);
1849
- // Re-render the page component
1850
- window.location.reload();
1849
+ // Defer reload outside React's update cycle
1850
+ setTimeout(() => window.location.reload(), 0);
1851
1851
  };
1852
1852
 
1853
1853
  window.addEventListener('popstate', handlePopState);
package/src/index.ts CHANGED
@@ -27,6 +27,7 @@ export * as util from './shims/util';
27
27
  export * as npm from './npm';
28
28
  export { PackageManager, install } from './npm';
29
29
  export { ServerBridge, getServerBridge, resetServerBridge } from './server-bridge';
30
+ export type { InitServiceWorkerOptions } from './server-bridge';
30
31
  // Dev servers
31
32
  export { DevServer } from './dev-server';
32
33
  export type { DevServerOptions, ResponseData, HMRUpdate } from './dev-server';
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Next.js Plugin for almostnode
3
+ *
4
+ * Provides utilities for serving the service worker file in Next.js applications.
5
+ */
6
+
7
+ import * as fs from 'fs';
8
+ import * as path from 'path';
9
+ import { fileURLToPath } from 'url';
10
+
11
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
12
+ // @ts-ignore - import.meta.url is available in ESM
13
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
14
+
15
+ /**
16
+ * Get the contents of the almostnode service worker file.
17
+ * Use this in a Next.js API route or middleware to serve the service worker.
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * // app/api/__sw__/route.ts (App Router)
22
+ * import { getServiceWorkerContent } from 'almostnode/next';
23
+ *
24
+ * export async function GET() {
25
+ * const content = getServiceWorkerContent();
26
+ * return new Response(content, {
27
+ * headers: {
28
+ * 'Content-Type': 'application/javascript',
29
+ * 'Cache-Control': 'no-cache',
30
+ * },
31
+ * });
32
+ * }
33
+ * ```
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * // pages/api/__sw__.ts (Pages Router)
38
+ * import { getServiceWorkerContent } from 'almostnode/next';
39
+ * import type { NextApiRequest, NextApiResponse } from 'next';
40
+ *
41
+ * export default function handler(req: NextApiRequest, res: NextApiResponse) {
42
+ * const content = getServiceWorkerContent();
43
+ * res.setHeader('Content-Type', 'application/javascript');
44
+ * res.setHeader('Cache-Control', 'no-cache');
45
+ * res.send(content);
46
+ * }
47
+ * ```
48
+ */
49
+ export function getServiceWorkerContent(): string {
50
+ // The service worker file is in the dist directory relative to this file
51
+ // In src: ../dist/__sw__.js
52
+ // In dist: ./__sw__.js
53
+ let swFilePath = path.join(__dirname, '__sw__.js');
54
+
55
+ // If running from src directory during development, look in dist
56
+ if (!fs.existsSync(swFilePath)) {
57
+ swFilePath = path.join(__dirname, '../dist/__sw__.js');
58
+ }
59
+
60
+ if (!fs.existsSync(swFilePath)) {
61
+ throw new Error('Service worker file not found. Make sure almostnode is built.');
62
+ }
63
+
64
+ return fs.readFileSync(swFilePath, 'utf-8');
65
+ }
66
+
67
+ /**
68
+ * Get the path to the almostnode service worker file.
69
+ * Useful if you want to copy it to your public directory.
70
+ *
71
+ * @example
72
+ * ```javascript
73
+ * // scripts/copy-sw.js
74
+ * const { getServiceWorkerPath } = require('almostnode/next');
75
+ * const fs = require('fs');
76
+ * const path = require('path');
77
+ *
78
+ * const swPath = getServiceWorkerPath();
79
+ * fs.copyFileSync(swPath, path.join(__dirname, '../public/__sw__.js'));
80
+ * ```
81
+ */
82
+ export function getServiceWorkerPath(): string {
83
+ let swFilePath = path.join(__dirname, '__sw__.js');
84
+
85
+ if (!fs.existsSync(swFilePath)) {
86
+ swFilePath = path.join(__dirname, '../dist/__sw__.js');
87
+ }
88
+
89
+ if (!fs.existsSync(swFilePath)) {
90
+ throw new Error('Service worker file not found. Make sure almostnode is built.');
91
+ }
92
+
93
+ return swFilePath;
94
+ }
95
+
96
+ export default { getServiceWorkerContent, getServiceWorkerPath };