Skip to content

Commit cf88369

Browse files
vnphanquangeltigerchinodummdidumm
authored
feat: add support for read in edge environments (#13859)
closes #12446 closes #11674 --------- Co-authored-by: Chew Tee Ming <[email protected]> Co-authored-by: Simon Holthausen <[email protected]>
1 parent 497f616 commit cf88369

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+5900
-414
lines changed

.changeset/moody-birds-help.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@sveltejs/adapter-netlify': minor
3+
'@sveltejs/adapter-vercel': minor
4+
---
5+
6+
feat: add support for `read` imported from `$app/server` in edge functions

.changeset/old-moons-lick.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/adapter-cloudflare': minor
3+
---
4+
5+
feat: add support for `read` imported from `$app/server`

.changeset/weak-pillows-doubt.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': minor
3+
---
4+
5+
feat: support asynchronous `read` implementations from adapters

eslint.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export default [
3333
},
3434
ignores: [
3535
'packages/adapter-cloudflare/test/apps/**/*',
36+
'packages/adapter-netlify/test/apps/**/*',
3637
'packages/adapter-node/rollup.config.js',
3738
'packages/adapter-node/tests/smoke.spec_disabled.js',
3839
'packages/adapter-static/test/apps/**/*',

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,13 @@
3737
},
3838
"pnpm": {
3939
"onlyBuiltDependencies": [
40+
"@parcel/watcher",
4041
"esbuild",
42+
"netlify-cli",
4143
"rolldown",
4244
"sharp",
4345
"svelte-preprocess",
46+
"unix-dgram",
4447
"workerd"
4548
]
4649
}

packages/adapter-cloudflare/index.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1+
import { VERSION } from '@sveltejs/kit';
12
import { copyFileSync, existsSync, writeFileSync } from 'node:fs';
23
import path from 'node:path';
34
import { fileURLToPath } from 'node:url';
45
import { is_building_for_cloudflare_pages } from './utils.js';
56
import { getPlatformProxy, unstable_readConfig } from 'wrangler';
67

8+
const name = '@sveltejs/adapter-cloudflare';
9+
const [kit_major, kit_minor] = VERSION.split('.');
10+
711
/** @type {import('./index.js').default} */
812
export default function (options = {}) {
913
return {
10-
name: '@sveltejs/adapter-cloudflare',
14+
name,
1115
async adapt(builder) {
1216
if (existsSync('_routes.json')) {
1317
throw new Error(
@@ -162,6 +166,18 @@ export default function (options = {}) {
162166
return prerender ? emulated.prerender_platform : emulated.platform;
163167
}
164168
};
169+
},
170+
supports: {
171+
read: ({ route }) => {
172+
// TODO bump peer dep in next adapter major to simplify this
173+
if (kit_major === '2' && kit_minor < '25') {
174+
throw new Error(
175+
`${name}: Cannot use \`read\` from \`$app/server\` in route \`${route.id}\` when using SvelteKit < 2.25.0`
176+
);
177+
}
178+
179+
return true;
180+
}
165181
}
166182
};
167183
}

packages/adapter-cloudflare/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@
3333
"ambient.d.ts"
3434
],
3535
"scripts": {
36-
"build": "esbuild src/worker.js --bundle --outfile=files/worker.js --external:SERVER --external:MANIFEST --format=esm",
36+
"build": "esbuild src/worker.js --bundle --outfile=files/worker.js --external:SERVER --external:MANIFEST --external:cloudflare:workers --format=esm",
3737
"lint": "prettier --check .",
3838
"format": "pnpm lint --write",
3939
"check": "tsc --skipLibCheck",
40-
"prepublishOnly": "pnpm build",
4140
"test:unit": "vitest run",
4241
"test:e2e": "pnpm build && pnpm -r --workspace-concurrency 1 --filter=\"./test/**\" test",
43-
"test": "pnpm test:unit && pnpm test:e2e"
42+
"test": "pnpm test:unit && pnpm test:e2e",
43+
"prepublishOnly": "pnpm build"
4444
},
4545
"dependencies": {
4646
"@cloudflare/workers-types": "^4.20250507.0",

packages/adapter-cloudflare/src/worker.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Server } from 'SERVER';
22
import { manifest, prerendered, base_path } from 'MANIFEST';
3+
import { env } from 'cloudflare:workers';
34
import * as Cache from 'worktop/cfw.cache';
45

56
const server = new Server(manifest);
@@ -9,6 +10,27 @@ const app_path = `/${manifest.appPath}`;
910
const immutable = `${app_path}/immutable/`;
1011
const version_file = `${app_path}/version.json`;
1112

13+
/**
14+
* We don't know the origin until we receive a request, but
15+
* that's guaranteed to happen before we call `read`
16+
* @type {string}
17+
*/
18+
let origin;
19+
20+
const initialized = server.init({
21+
// @ts-expect-error env contains environment variables and bindings
22+
env,
23+
read: async (file) => {
24+
const response = await /** @type {{ ASSETS: { fetch: typeof fetch } }} */ (env).ASSETS.fetch(
25+
`${origin}/${file}`
26+
);
27+
if (!response.ok) {
28+
throw new Error(`Failed to fetch ${file}: ${response.status} ${response.statusText}`);
29+
}
30+
return response.body;
31+
}
32+
});
33+
1234
export default {
1335
/**
1436
* @param {Request} req
@@ -17,10 +39,10 @@ export default {
1739
* @returns {Promise<Response>}
1840
*/
1941
async fetch(req, env, ctx) {
20-
await server.init({
21-
// @ts-expect-error env contains environment variables and bindings
22-
env
23-
});
42+
if (!origin) {
43+
origin = new URL(req.url).origin;
44+
await initialized;
45+
}
2446

2547
// skip cache if "cache-control: no-cache" in request
2648
let pragma = req.headers.get('cache-control') || '';
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { read } from '$app/server';
2+
import file from './file.txt?url';
3+
4+
export function GET() {
5+
return read(file);
6+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Hello! This file is read by `read` from `$app/server`.

0 commit comments

Comments
 (0)