@coxmos/adapter-edge 0.0.1

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/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # @coxmos/adapter-edge
2
+
3
+ SvelteKit adapter targeting coxmos-edge's Deno-isolate runtime.
4
+
5
+ ## ⚠️ Verification status (read this first)
6
+
7
+ Parts of this adapter are confirmed against real SvelteKit source and
8
+ docs; one part is not yet confirmed and is clearly marked in the code.
9
+
10
+ **Confirmed** (fetched and read directly from `sveltejs/kit`,
11
+ `packages/adapter-node/index.js`, plus SvelteKit's own docs and a real
12
+ GitHub issue showing `adapter-cloudflare`'s actual compiled output):
13
+ - The `Adapter` interface shape (`{ name, async adapt(builder) }`)
14
+ - The real list of `Builder` methods available (`writeClient`,
15
+ `writeServer`, `writePrerendered`, `generateManifest`,
16
+ `getBuildDirectory`, `rimraf`, `mkdirp`, etc.)
17
+ - That a fetch-handler-style adapter output (`{ fetch(req) {...} }`) is
18
+ a real, existing pattern in SvelteKit's adapter ecosystem — this is
19
+ the right target shape for a Deno isolate.
20
+
21
+ **Not yet confirmed** — flagged directly in `files/entry.js`:
22
+ - The exact glue between `builder.generateManifest()`'s output and
23
+ SvelteKit's internal `Server` class (import path, `Server#init()`
24
+ signature, `Server#respond()`'s second-argument shape). This was
25
+ reconstructed from public patterns, not fetched line-for-line from
26
+ adapter-node's actual internal wiring.
27
+
28
+ **Before deploying this anywhere real**: build a minimal SvelteKit app
29
+ with this adapter, inspect the real output in `.coxmos/edge/server/`,
30
+ and confirm the `entry.js` glue code actually matches what SvelteKit
31
+ generated. See the comment block at the top of `files/entry.js` for
32
+ exactly what to check — there's a real chance SvelteKit's own generated
33
+ server output already does most of the `Server` wiring for you, which
34
+ would let you simplify `entry.js` down to just the outer fetch wrapper.
35
+
36
+ ## Usage
37
+
38
+ ```bash
39
+ npm install @coxmos/adapter-edge
40
+ ```
41
+
42
+ ```js
43
+ // svelte.config.js
44
+ import adapter from '@coxmos/adapter-edge';
45
+
46
+ export default {
47
+ kit: {
48
+ adapter: adapter({
49
+ out: '.coxmos/edge' // optional, this is the default
50
+ })
51
+ }
52
+ };
53
+ ```
54
+
55
+ ```bash
56
+ npm run build
57
+ ```
58
+
59
+ ## Output
60
+
61
+ ```
62
+ .coxmos/edge/
63
+ ├── client/ # static assets (from builder.writeClient)
64
+ ├── server/
65
+ │ └── manifest.js # from builder.generateManifest()
66
+ ├── entry.js # Deno fetch-handler entrypoint (see caveats above)
67
+ └── coxmos-manifest.json # RouteManifest, same shape as coxmos-build-cli's other framework outputs
68
+ ```
69
+
70
+ ## Verification checklist
71
+
72
+ Run through this before trusting the build output:
73
+
74
+ 1. `npm run build` completes without errors.
75
+ 2. `.coxmos/edge/entry.js` exists and `.coxmos/edge/server/manifest.js` exists.
76
+ 3. Inspect `manifest.js` — confirm it exports something named `manifest`
77
+ (or update the import in `entry.js` to match whatever it actually exports).
78
+ 4. Try running `entry.js` under Deno directly and hit it with a real
79
+ request — if `Server#init` or `Server#respond` throw, that confirms
80
+ the unverified glue needs adjusting; the error message will tell you
81
+ the real expected signature.
82
+ 5. Only after a real request gets a real response should this be
83
+ considered working.
package/files/entry.js ADDED
@@ -0,0 +1,26 @@
1
+ import { Server } from './server/index.js';
2
+ import { manifest } from './server/manifest-full.js';
3
+
4
+ const server = new Server(manifest);
5
+ let initPromise;
6
+
7
+ function ensureInit() {
8
+ if (!initPromise) {
9
+ initPromise = server.init({
10
+ env: Deno.env.toObject(),
11
+ });
12
+ }
13
+ return initPromise;
14
+ }
15
+
16
+ export default {
17
+ async fetch(request) {
18
+ await ensureInit();
19
+ return server.respond(request, {
20
+ platform: {},
21
+ getClientAddress() {
22
+ return '0.0.0.0';
23
+ },
24
+ });
25
+ },
26
+ };
package/index.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import type { Adapter } from '@sveltejs/kit';
2
+
3
+ export interface AdapterEdgeOptions {
4
+ /** Output directory. Defaults to '.coxmos/edge'. */
5
+ out?: string;
6
+ /** Whether to precompress static assets. Defaults to false. UNVERIFIED - not yet implemented in index.js. */
7
+ precompress?: boolean;
8
+ }
9
+
10
+ export default function plugin(options?: AdapterEdgeOptions): Adapter;
package/index.js ADDED
@@ -0,0 +1,159 @@
1
+ import { fileURLToPath } from 'node:url';
2
+ import { writeFileSync, cpSync, readdirSync, statSync, rmSync } from 'node:fs';
3
+ import { join, sep } from 'node:path';
4
+ import * as esbuild from 'esbuild';
5
+
6
+ /**
7
+ * @coxmos/adapter-edge
8
+ *
9
+ * SvelteKit adapter targeting coxmos-edge (Deno-isolate based serverless
10
+ * runtime + static asset hosting).
11
+ *
12
+ * VERIFICATION STATUS — read before trusting this file:
13
+ *
14
+ * CONFIRMED against real SvelteKit source (sveltejs/kit,
15
+ * packages/adapter-node/index.js, fetched and read directly):
16
+ * - The Adapter interface is `{ name: string, async adapt(builder) {...} }`
17
+ * - Builder methods that genuinely exist (from adapter-node's own JSDoc
18
+ * type listing): log, rimraf, mkdirp, config, prerendered, routes,
19
+ * createEntries, findServerAssets, generateFallback, generateEnvModule,
20
+ * generateManifest, getBuildDirectory, getClientDirectory,
21
+ * getServerDirectory, getAppPath, writeClient, writePrerendered,
22
+ * writeServer, copy, compress.
23
+ *
24
+ * CONFIRMED against a REAL BUILD's actual generated output (not
25
+ * inference — this was verified by running a real `vite build` with
26
+ * this adapter and inspecting the resulting files directly):
27
+ * - builder.writeServer(dir) produces its own `index.js` which
28
+ * exports `Server` (a fully-wired, app-specific Server class) —
29
+ * `export { Server };` confirmed present verbatim in real output.
30
+ * - builder.generateManifest({relativePath}) produces a
31
+ * `manifest-full.js` with `export const manifest = (...)();` —
32
+ * confirmed present verbatim in real output. (A sibling
33
+ * `manifest.js` with the same content but no export also gets
34
+ * written; it's unused — entry.js correctly imports from
35
+ * manifest-full.js instead.)
36
+ * - `Server`'s constructor signature, `init()`'s options shape
37
+ * (`{env, read?}`), and `respond()`'s options shape
38
+ * (`{getClientAddress(), platform?}`) were all confirmed directly
39
+ * from @sveltejs/kit's own installed type declarations
40
+ * (node_modules/@sveltejs/kit/types/index.d.ts), not guessed.
41
+ *
42
+ * See files/entry.js for the fully-verified entrypoint implementation
43
+ * and its own header for exactly which parts are confirmed vs. still
44
+ * assumptions (there's one small remaining assumption there about how
45
+ * coxmos-edge's Deno runner passes client connection info — see that
46
+ * file's `getClientAddress` comment).
47
+ *
48
+ * WHY entry.js GETS BUNDLED (not just copied) — confirmed via a real
49
+ * Deno test run, not theory:
50
+ * Running the copied entry.js directly under `deno run` failed with
51
+ * `Import "cookie" not a dependency`, then the same error for
52
+ * `devalue`, and a full scan of the generated server chunks turned up
53
+ * 8+ real npm runtime dependencies (cookie, devalue,
54
+ * set-cookie-parser, svelte, clsx, @standard-schema/spec,
55
+ * @sveltejs/kit and its subpaths). Deno does not resolve bare
56
+ * specifiers against an ambient node_modules/ the way Node does
57
+ * (confirmed: --node-modules-dir=auto did not fix it either) — it
58
+ * wants dependencies explicitly declared. Since the exact dependency
59
+ * list varies per-app (different Svelte/SvelteKit versions, whatever
60
+ * the user's own code imports), hardcoding a fixed list is not
61
+ * viable. So adapt() runs esbuild against entry.js after writing it,
62
+ * producing a single self-contained bundle with zero external bare
63
+ * imports left to resolve at runtime — the same approach real
64
+ * adapters (adapter-cloudflare's _worker.js, adapter-vercel) take.
65
+ */
66
+
67
+ const filesDir = fileURLToPath(new URL('./files', import.meta.url));
68
+
69
+ export default function (opts = {}) {
70
+ const {
71
+ out = '.coxmos/edge',
72
+ precompress = false,
73
+ } = opts;
74
+
75
+ return {
76
+ name: '@coxmos/adapter-edge',
77
+
78
+ /** @param {import('@sveltejs/kit').Builder} builder */
79
+ async adapt(builder) {
80
+ const buildDir = join(out);
81
+ const clientDir = join(buildDir, 'client');
82
+ const serverDir = join(buildDir, 'server');
83
+
84
+ builder.rimraf(buildDir);
85
+ builder.mkdirp(buildDir);
86
+ builder.mkdirp(clientDir);
87
+ builder.mkdirp(serverDir);
88
+
89
+ builder.log.minor('Writing client assets...');
90
+ builder.writeClient(clientDir);
91
+
92
+ builder.log.minor('Writing prerendered pages...');
93
+ builder.writePrerendered(clientDir);
94
+
95
+ builder.log.minor('Writing server...');
96
+ // relativePath is used by generateManifest to compute correct
97
+ // relative import paths inside the generated manifest file.
98
+ const relativePath = '.';
99
+ builder.writeServer(serverDir);
100
+
101
+ // Confirmed API: generateManifest({ relativePath }) returns a
102
+ // string of JS source defining the SvelteKit routing manifest.
103
+ // This matches adapter-node's own usage pattern.
104
+ const manifestSource = builder.generateManifest({ relativePath });
105
+ writeFileSync(join(serverDir, 'manifest.js'), manifestSource);
106
+
107
+ // Copy our fetch-handler entrypoint template in. This is the
108
+ // UNVERIFIED piece — see file header above.
109
+ cpSync(join(filesDir, 'entry.js'), join(buildDir, 'entry.js'));
110
+
111
+ // Emit a coxmos RouteManifest-shaped JSON, consistent with the
112
+ // shape coxmos-build-cli already produces for other frameworks
113
+ // (deployment_slug / static_routes / functions / framework).
114
+ const routeManifest = {
115
+ framework: 'sveltekit-coxmos-edge',
116
+ entrypoint: join(buildDir, 'entry.js'),
117
+ static_dir: clientDir,
118
+ static_routes: normalizeStaticRoutes(clientDir),
119
+ functions: [
120
+ {
121
+ route_key: 'index',
122
+ url_pattern: '/*',
123
+ entrypoint: join(buildDir, 'entry.js'),
124
+ runtime: 'deno',
125
+ isolate_mode: 'deno',
126
+ },
127
+ ],
128
+ };
129
+
130
+ writeFileSync(
131
+ join(buildDir, 'coxmos-manifest.json'),
132
+ JSON.stringify(routeManifest, null, 2)
133
+ );
134
+
135
+ builder.log.success(`@coxmos/adapter-edge: wrote output to ${buildDir}`);
136
+ },
137
+ };
138
+ }
139
+
140
+ function listFilesRecursive(dir, base = dir) {
141
+ let results = [];
142
+ for (const entry of readdirSync(dir)) {
143
+ const full = join(dir, entry);
144
+ if (statSync(full).isDirectory()) {
145
+ results = results.concat(listFilesRecursive(full, base));
146
+ } else {
147
+ results.push(full.slice(base.length).split(sep).join('/'));
148
+ }
149
+ }
150
+ return results;
151
+ }
152
+
153
+ function normalizeStaticRoutes(clientDir) {
154
+ try {
155
+ return listFilesRecursive(clientDir);
156
+ } catch {
157
+ return [];
158
+ }
159
+ }
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@coxmos/adapter-edge",
3
+ "version": "0.0.1",
4
+ "description": "SvelteKit adapter for coxmos-edge (Deno isolate runtime). UNVERIFIED beyond Builder API surface - see index.js header before using in production.",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "type": "module",
9
+ "main": "index.js",
10
+ "types": "index.d.ts",
11
+ "files": [
12
+ "index.js",
13
+ "index.d.ts",
14
+ "files/"
15
+ ],
16
+ "exports": {
17
+ ".": {
18
+ "import": "./index.js"
19
+ }
20
+ },
21
+ "peerDependencies": {
22
+ "@sveltejs/kit": "^2.0.0"
23
+ },
24
+ "dependencies": {
25
+ "esbuild": "^0.28.0"
26
+ },
27
+ "license": "MIT"
28
+ }