Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: native support for Websockets #12973

Open
wants to merge 178 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
178 commits
Select commit Hold shift + click to select a range
d0b7f09
example crossws implementation with `hooks.server.js` websocketHooks …
LukeHagar Nov 7, 2024
b69b2e0
Migrated from hooks to server.js export named socket, validated funct…
LukeHagar Nov 8, 2024
aa69e1c
Formatting and fix a test
LukeHagar Nov 8, 2024
38c919c
removed global comment
LukeHagar Nov 8, 2024
2a022b5
regenerated types
LukeHagar Nov 8, 2024
c3a0bf7
removed some log statements
LukeHagar Nov 8, 2024
c86e4e9
cleaning up previous implementation
LukeHagar Nov 8, 2024
5858b49
Thoroughly tested handle implementation
LukeHagar Nov 9, 2024
9d56c50
Cleaning
LukeHagar Nov 9, 2024
46c8682
regenerated types and ran formatter
LukeHagar Nov 9, 2024
7791759
generate types
eltigerchino Nov 11, 2024
70202e3
adjusted implementation to only use responses and the updated crossws…
LukeHagar Jan 23, 2025
92e3e41
corrected example
LukeHagar Jan 23, 2025
db517f6
swapped from browser to onMount
LukeHagar Jan 23, 2025
a43c49b
cleaned log statements
LukeHagar Jan 23, 2025
6469816
added a docs page
LukeHagar Jan 24, 2025
ee0c6ee
updated node adapter
LukeHagar Jan 24, 2025
e737e02
fixed imports and resolve type
LukeHagar Jan 24, 2025
42e2f2d
updating adapters
LukeHagar Jan 24, 2025
0abeb17
Update documentation/docs/30-advanced/15-websockets.md
LukeHagar Jan 24, 2025
2a9971f
Update packages/kit/src/exports/index.js
LukeHagar Jan 24, 2025
cc58820
Update documentation/docs/30-advanced/15-websockets.md
LukeHagar Jan 24, 2025
29fdfec
ditching reject function for existing error
LukeHagar Jan 24, 2025
fda8a68
Update documentation/docs/30-advanced/15-websockets.md
LukeHagar Jan 24, 2025
ff58988
Update documentation/docs/30-advanced/15-websockets.md
LukeHagar Jan 24, 2025
1fed29d
Update documentation/docs/30-advanced/15-websockets.md
LukeHagar Jan 24, 2025
0ea72ab
Update documentation/docs/30-advanced/15-websockets.md
LukeHagar Jan 24, 2025
6408350
moved adapter integration, added response getter to HttpError
LukeHagar Jan 24, 2025
182a666
TABS
LukeHagar Jan 24, 2025
dda7298
corrected package.json versions
LukeHagar Jan 24, 2025
192840a
normalize on error and the response prop
LukeHagar Jan 24, 2025
ec0b797
Merge branch 'main' into crossws
LukeHagar Jan 24, 2025
f3bed08
recreated lockfile
LukeHagar Jan 24, 2025
2f11dca
ran formatter
LukeHagar Jan 24, 2025
3f2679e
fix lint errors
LukeHagar Jan 24, 2025
de37505
Update documentation/docs/25-build-and-deploy/99-writing-adapters.md
LukeHagar Jan 24, 2025
8dfad0c
fix lint errors
LukeHagar Jan 24, 2025
21cb866
added an s
LukeHagar Jan 24, 2025
f70aea1
correcting lockfile issues
LukeHagar Jan 24, 2025
c0a5e3d
regenerated types
LukeHagar Jan 24, 2025
a6bcf60
adjusting types
LukeHagar Jan 25, 2025
d3a48d7
cleaning a log
LukeHagar Jan 27, 2025
fa52645
adding ts comments
LukeHagar Feb 2, 2025
e63dfc3
adjusting ts comments
LukeHagar Feb 2, 2025
a0c54ab
adjusting lib for Generic error
LukeHagar Feb 3, 2025
c9457a4
adjusting ts version for Generic error
LukeHagar Feb 3, 2025
51d4729
updating lockfile
LukeHagar Feb 3, 2025
04b011d
updating generated types
LukeHagar Feb 3, 2025
2ab789f
downgrade typescript and address some types issues
benmccann Feb 3, 2025
4a6c8b3
upgrade @types/node to fix remaining types error
benmccann Feb 3, 2025
9bdfc04
adjusting tests for updated test app
LukeHagar Feb 3, 2025
894f38b
adjusting tests for updated test app
LukeHagar Feb 3, 2025
e7726a6
Update packages/kit/types/index.d.ts
LukeHagar Feb 3, 2025
8de07d1
Update packages/kit/src/exports/index.js
LukeHagar Feb 3, 2025
c18b4e8
Update packages/adapter-node/package.json
LukeHagar Feb 3, 2025
ddc9bc1
Update packages/adapter-cloudflare/package.json
LukeHagar Feb 3, 2025
80e14fe
Update packages/adapter-cloudflare-workers/package.json
LukeHagar Feb 3, 2025
3e58143
Update packages/adapter-node/src/index.js
LukeHagar Feb 3, 2025
7563cb3
Update packages/adapter-node/src/index.js
LukeHagar Feb 3, 2025
fd5b98b
Update packages/kit/src/exports/index.js
LukeHagar Feb 3, 2025
e79716c
updating lockfile
LukeHagar Feb 3, 2025
3f884b1
updating generated types
LukeHagar Feb 3, 2025
dea0952
re-export crossws Hooks type as Socket
eltigerchino Feb 3, 2025
25f039a
oopsie this should be +server.js instead of +page.server.js
eltigerchino Feb 3, 2025
4072369
Update 15-websockets.md
LukeHagar Feb 3, 2025
875536b
re-export Peer and Message types
eltigerchino Feb 3, 2025
84a1aa1
de-duplicate test id
eltigerchino Feb 3, 2025
93d40b2
revert server initialisation timing during dev
eltigerchino Feb 4, 2025
24f3b52
Update packages/kit/src/runtime/server/resolve.js
LukeHagar Feb 4, 2025
8c10aa4
Update packages/kit/src/runtime/server/resolve.js
eltigerchino Feb 4, 2025
52d607a
Update packages/kit/src/runtime/server/resolve.js
eltigerchino Feb 4, 2025
1ac7ccf
Update packages/kit/src/runtime/server/resolve.js
eltigerchino Feb 4, 2025
d9c4b1f
moving on call to after listen
LukeHagar Feb 4, 2025
6a3581b
restoring server options back to private
LukeHagar Feb 4, 2025
e762693
adjusting exports for node adapter
LukeHagar Feb 4, 2025
5c1f334
Update documentation/docs/30-advanced/15-websockets.md
eltigerchino Feb 5, 2025
8f98d61
revert typescript changes
eltigerchino Feb 5, 2025
ac788fb
Merge branch 'main' into pr/LukeHagar/12973
eltigerchino Feb 5, 2025
0a160fd
add Socket type to test app
eltigerchino Feb 5, 2025
d6f4ee5
spruce up docs
eltigerchino Feb 5, 2025
5e07cba
re-generate types
eltigerchino Feb 5, 2025
a0629ba
bump TS to 5.7
eltigerchino Feb 5, 2025
fef9dbe
add comment
eltigerchino Feb 5, 2025
940eb3d
follow mdn recommendation
eltigerchino Feb 5, 2025
e6caf6c
socket closes by itself if we navigate away
eltigerchino Feb 5, 2025
d437299
emphasise all websocket hooks are required
eltigerchino Feb 5, 2025
f203b8d
handle protocol upgrade to websocket
eltigerchino Feb 5, 2025
e6fed10
add ws to vite preview
eltigerchino Feb 5, 2025
f13af3b
i'm dumb
eltigerchino Feb 6, 2025
278c283
clarify
eltigerchino Feb 6, 2025
a458ff3
document node adapter upgradeHandler for custom servers
eltigerchino Feb 6, 2025
b766e06
formatting pass
LukeHagar Feb 6, 2025
3dc373c
tigthen up types
eltigerchino Feb 6, 2025
9597c7f
remove accept helper
eltigerchino Feb 6, 2025
9a839b5
de-duplicate respond logic
eltigerchino Feb 6, 2025
183117f
format
eltigerchino Feb 6, 2025
a9a3f9b
dynamically resolve hooks
eltigerchino Feb 6, 2025
e201b3b
comment
eltigerchino Feb 6, 2025
74937fd
remove cast and ensure headers are added to response
eltigerchino Feb 7, 2025
68bedce
move ws test pages from options-2 to basics
eltigerchino Feb 7, 2025
ec630b8
Update documentation/docs/30-advanced/15-websockets.md
LukeHagar Feb 8, 2025
19f273b
Update documentation/docs/30-advanced/15-websockets.md
eltigerchino Feb 10, 2025
8517855
Merge branch 'crossws' of https://github.com/lukehagar/kit into pr/Lu…
eltigerchino Feb 10, 2025
be4346d
add @since jsdoc
eltigerchino Feb 10, 2025
63cfe11
Merge branch 'main' into pr/LukeHagar/12973
eltigerchino Feb 10, 2025
7eb180f
revert installed typescript version
eltigerchino Feb 10, 2025
c8de055
re-generate types
eltigerchino Feb 10, 2025
6b06673
format
eltigerchino Feb 10, 2025
09c1e2a
revert typescript changes in lockfile
eltigerchino Feb 10, 2025
2fd6711
changeset
eltigerchino Feb 10, 2025
b03206d
re-generate types
eltigerchino Feb 10, 2025
d997737
add buttons to open/close websocket in test
eltigerchino Feb 10, 2025
06063f1
recursively adjusted TS Version back to 5.5.4
LukeHagar Feb 10, 2025
fef8521
Merge branch 'main' into crossws
LukeHagar Feb 10, 2025
0c1de43
updating lockfile after main merge
LukeHagar Feb 10, 2025
6411a4c
formatting run
LukeHagar Feb 10, 2025
db7f8c8
Regenerated types
LukeHagar Feb 10, 2025
23ad389
Update packages/kit/src/runtime/server/respond.js
LukeHagar Feb 10, 2025
3ffe264
removed unused hooks
LukeHagar Feb 10, 2025
367df8f
consolidating logic
LukeHagar Feb 10, 2025
3bc744d
bump crossws version
LukeHagar Feb 10, 2025
31d5617
formatting pass
LukeHagar Feb 10, 2025
fd05a21
correcting return types
LukeHagar Feb 10, 2025
bf9d9d3
restored handle_request overloads to make TS happy
LukeHagar Feb 10, 2025
ffadf9a
added overload comment
LukeHagar Feb 10, 2025
bb7aeb4
added verbatimModuleSyntax to package tsconfig
LukeHagar Feb 10, 2025
d4ca5eb
lowering TS version once more for package build errors
LukeHagar Feb 10, 2025
2b13bba
Update 15-websockets.md
LukeHagar Feb 11, 2025
427aeef
Update 15-websockets.md
LukeHagar Feb 11, 2025
2b6be27
Update 15-websockets.md
LukeHagar Feb 11, 2025
4f7b7ec
Update 15-websockets.md
LukeHagar Feb 11, 2025
f4e6c05
Update 15-websockets.md
LukeHagar Feb 11, 2025
be2a624
Update 15-websockets.md
LukeHagar Feb 11, 2025
651c15e
Update 15-websockets.md
LukeHagar Feb 11, 2025
c902fe8
Update public.d.ts
LukeHagar Feb 11, 2025
304e8a5
Update index.d.ts
LukeHagar Feb 11, 2025
63646f3
attempting to configure supports for websockets
LukeHagar Feb 11, 2025
64fff72
formatting pass
LukeHagar Feb 11, 2025
5570227
regenerated types
LukeHagar Feb 11, 2025
6e12953
adjusted supports usage
LukeHagar Feb 11, 2025
ac17702
regenerated types
LukeHagar Feb 11, 2025
6640525
rename test file from ts to js
eltigerchino Feb 12, 2025
c5c9f0a
ensure hooks call handleError when error is thrown
eltigerchino Feb 12, 2025
5ee9478
ensure dev updates work on websockets
eltigerchino Feb 12, 2025
74fcc83
dont reset test messages
eltigerchino Feb 12, 2025
2896ecf
Merge branch 'crossws' of https://github.com/lukehagar/kit into pr/Lu…
eltigerchino Feb 12, 2025
7905670
three dots instead of two
eltigerchino Feb 12, 2025
0560640
we no longer need to upgrade node types because TS is less than 5.7
eltigerchino Feb 12, 2025
a72bac6
inline getClientAddress
eltigerchino Feb 12, 2025
32981e0
only handle websocket upgrade requests
eltigerchino Feb 12, 2025
f7a88dd
clarify when kit hooks run
eltigerchino Feb 12, 2025
87c3071
remove verbatimModuleSyntax tsconfig option
eltigerchino Feb 12, 2025
5ec65b0
integrate adapter supports API
eltigerchino Feb 12, 2025
330c325
make adapter backwards compatible with older kit versions
eltigerchino Feb 12, 2025
9582975
no clue when the error hook actually runs
eltigerchino Feb 12, 2025
1c314ef
check feature when endpoint is accessed
eltigerchino Feb 12, 2025
0c497bb
clarify why we manually validate exports
eltigerchino Feb 12, 2025
51783ae
only handle upgrades if socket export exists
eltigerchino Feb 12, 2025
737d352
pass read and emulator to vite preview ws hooks resolver
eltigerchino Feb 12, 2025
fd956cb
Update documentation/docs/30-advanced/20-hooks.md
eltigerchino Feb 12, 2025
3977af6
revert blankspace removal
eltigerchino Feb 12, 2025
fbc9a8a
Merge branch 'crossws' of https://github.com/lukehagar/kit into pr/Lu…
eltigerchino Feb 12, 2025
7d0b219
better comment
eltigerchino Feb 12, 2025
448f46a
standardise node request and reject upgrade if socket doesn't exist
eltigerchino Feb 13, 2025
ba58ee7
add partial tests
eltigerchino Feb 13, 2025
fe48df9
fix handle hook returning response during upgrade
eltigerchino Feb 13, 2025
335f58c
fix vite preview server listening for upgrade
eltigerchino Feb 14, 2025
e933ea7
test unsuccessful upgrade requests
eltigerchino Feb 14, 2025
7f74b95
Merge branch 'main' into pr/LukeHagar/12973
eltigerchino Feb 14, 2025
12f7a97
format
eltigerchino Feb 14, 2025
7a6615e
fix test endpoint url
eltigerchino Feb 14, 2025
82e35ea
change response property to a getter
eltigerchino Feb 17, 2025
71cb0c5
generate types
eltigerchino Feb 17, 2025
5d65b6f
support redirect
eltigerchino Feb 18, 2025
e73415c
update error hook description
eltigerchino Feb 18, 2025
d122476
finish up tests
eltigerchino Feb 18, 2025
71376db
format
eltigerchino Feb 18, 2025
10e9274
respond with error if incorrect basepath of manifest error
eltigerchino Feb 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/tricky-drinks-develop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@sveltejs/adapter-cloudflare-workers': minor
'@sveltejs/adapter-cloudflare': minor
'@sveltejs/adapter-node': minor
'@sveltejs/kit': minor
---

feat: add support for WebSockets
5 changes: 5 additions & 0 deletions .changeset/two-islands-sleep.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/adapter-auto': patch
---

fix: better error message when exporting `socket`
11 changes: 7 additions & 4 deletions documentation/docs/25-build-and-deploy/40-adapter-node.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,12 +241,12 @@ WantedBy=sockets.target

The adapter creates two files in your build directory — `index.js` and `handler.js`. Running `index.js` — e.g. `node build`, if you use the default build directory — will start a server on the configured port.

Alternatively, you can import the `handler.js` file, which exports a handler suitable for use with [Express](https://github.com/expressjs/express), [Connect](https://github.com/senchalabs/connect) or [Polka](https://github.com/lukeed/polka) (or even just the built-in [`http.createServer`](https://nodejs.org/dist/latest/docs/api/http.html#httpcreateserveroptions-requestlistener)) and set up your own server:
Alternatively, you can import the `handler.js` file, which exports handlers suitable for use with [Express](https://github.com/expressjs/express), [Connect](https://github.com/senchalabs/connect) or [Polka](https://github.com/lukeed/polka) (or even just the built-in [`http.createServer`](https://nodejs.org/dist/latest/docs/api/http.html#httpcreateserveroptions-requestlistener)) and set up your own server:

```js
// @errors: 2307 7006
/// file: my-server.js
import { handler } from './build/handler.js';
import { handler, upgradeHandler } from './build/handler.js';
import express from 'express';

const app = express();
Expand All @@ -256,10 +256,13 @@ app.get('/healthcheck', (req, res) => {
res.end('ok');
});

// let SvelteKit handle everything else, including serving prerendered pages and static assets
// let SvelteKit handle serving prerendered pages, static assets, and SSR
app.use(handler);

app.listen(3000, () => {
const server = app.listen(3000, () => {
console.log('listening on port 3000');
});

// let SvelteKit handle protocol upgrades for WebSocket connections
server.on('upgrade', upgradeHandler);
```
7 changes: 7 additions & 0 deletions documentation/docs/25-build-and-deploy/99-writing-adapters.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ export default function (options) {
// Return `true` if the route with the given `config` can use `read`
// from `$app/server` in production, return `false` if it can't.
// Or throw a descriptive error describing how to configure the deployment
},
webSockets: () => {
// Return `true` if the production environment supports WebSockets,
// return `false` if it can't.
// Or throw a descriptive error describing how to configure the deployment
}
}
};
Expand All @@ -58,3 +63,5 @@ Within the `adapt` method, there are a number of things that an adapter should d
- Put the user's static files and the generated JS/CSS in the correct location for the target platform

Where possible, we recommend putting the adapter output under the `build/` directory with any intermediate output placed under `.svelte-kit/[adapter-name]`.

If your environment supports WebSockets, you will need to handle upgrading a HTTP request to a WebSocket connection. You can do this by listening for requests from the platform that have an `Upgrade: websocket` header, calling the `server.getWebSocketHooksResolver({ getClientAddress })` function to get the WebSocket hooks resolver and passing it to the crossws adapter `resolve` option. The [crossws Adapters section](https://crossws.unjs.io/adapters) provides examples of creating this integration within various environments.
133 changes: 133 additions & 0 deletions documentation/docs/30-advanced/15-websockets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
---
title: WebSockets
---

## The `socket` object

[WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) provide a way to open a bidirectional communication channel between a client and a server.

A `+server.js` file can export a `socket` object to handle WebSocket connections. It uses [crossws](https://crossws.unjs.io/) to provide a consistent interface across different platforms. You can define [hooks](https://crossws.unjs.io/guide/hooks), all optional, to handle the different stages of the WebSocket lifecycle.

```js
/** @type {import('@sveltejs/kit').Socket} **/
export const socket = {
LukeHagar marked this conversation as resolved.
Show resolved Hide resolved
upgrade(req) {
// ...
},

open(peer) {
// ...
},

message(peer, message) {
// ...
},

close(peer, event) {
// ...
},

error(peer, error) {
// ...
}
};
```

### upgrade

The `upgrade` hook is called before a WebSocket connection is established. It receives the [request](https://developer.mozilla.org/docs/Web/API/Request) object as a parameter.

You can use the [`error`](@sveltejs-kit#error) function imported from `@sveltejs/kit` to easily reject connections. Requests will be auto-accepted if the `upgrade` hook is not defined or does not `error`.

```js
import { error } from "@sveltejs/kit";

/** @type {import('@sveltejs/kit').Socket} **/
export const socket = {
upgrade(request) {
if (request.headers.get('origin') !== 'allowed_origin') {
// Reject the WebSocket connection by throwing an error
error(403, 'Forbidden');
}
}
};
```

### open

The `open` hook is called when a WebSocket connection is opened. It receives the [peer](https://crossws.unjs.io/guide/peer) object, to allow interacting with connected clients, as a parameter.

```js
/** @type {import('@sveltejs/kit').Socket} **/
export const socket = {
open(peer) {
// ...
}
};
```

### message

The `message` hook is called when a message is received from the client. It receives the [peer](https://crossws.unjs.io/guide/peer) object, to allow interacting with connected clients, and the [message](https://crossws.unjs.io/guide/message) object, containing data from the client, as parameters.

```js
/** @type {import('@sveltejs/kit').Socket} **/
export const socket = {
message(peer, message) {
// ...
}
};
```

### close

The `close` hook is called when a WebSocket connection is closed. It receives the [peer](https://crossws.unjs.io/guide/peer) object, to allow interacting with connected clients, and the close event object, containing the [WebSocket connection close code](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code#value) and reason, as parameters.

```js
/** @type {import('@sveltejs/kit').Socket} **/
export const socket = {
close(peer, event) {
// ...
}
};
```

### error

The `error` hook is called when a connection with a WebSocket has been closed due to an error. It receives the [peer](https://crossws.unjs.io/guide/peer) object, to allow interacting with connected clients, and the error, as parameters.

```js
/** @type {import('@sveltejs/kit').Socket} **/
export const socket = {
error(peer, error) {
// ...
}
};
```

## Connecting from the client

To connect to a WebSocket endpoint, you can use the [`WebSocket`](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/WebSocket) constructor in the browser.

```svelte
<script>
import { onMount } from 'svelte';
onMount(() => {
// To connect to src/routes/ws/+server.js
const socket = new WebSocket(`/ws`);
socket.addEventListener("open", (event) => {
socket.send("Hello Server!");
});
// ...
});
</script>
```

See [the WebSocket documentation on MDN](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) for more details.

## Compatibility

SvelteKit uses [`crossws`](https://crossws.unjs.io) to handle cross-platform WebSocket connections. Please refer to their [compatibility table](https://crossws.unjs.io/guide/peer#compatibility) for the `peer` object in different runtime environments.
eltigerchino marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 2 additions & 2 deletions documentation/docs/30-advanced/20-hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ Note that `resolve(...)` will never throw an error, it will always return a `Pro

### handleFetch

This function allows you to modify (or replace) a `fetch` request that happens inside a `load` or `action` function that runs on the server (or during pre-rendering).
This function allows you to modify (or replace) a `fetch` request that happens inside a `load`, `action`, or `handle` function that runs on the server (or during prerendering).

For example, your `load` function might make a request to a public URL like `https://api.yourapp.com` when the user performs a client-side navigation to the respective page, but during SSR it might make sense to hit the API directly (bypassing whatever proxies and load balancers sit between it and the public internet).

Expand Down Expand Up @@ -153,7 +153,7 @@ The following can be added to `src/hooks.server.js` _and_ `src/hooks.client.js`:

### handleError

If an [unexpected error](errors#Unexpected-errors) is thrown during loading or rendering, this function will be called with the `error`, `event`, `status` code and `message`. This allows for two things:
If an [unexpected error](errors#Unexpected-errors) is thrown during loading, rendering, or from an endpoint, this function will be called with the `error`, `event`, `status` code and `message`. This allows for two things:

- you can log the error
- you can generate a custom representation of the error that is safe to show to users, omitting sensitive details like messages and stack traces. The returned value, which defaults to `{ message }`, becomes the value of `$page.error`.
Expand Down
5 changes: 5 additions & 0 deletions packages/adapter-auto/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,11 @@ export default () => ({
throw new Error(
"The read function imported from $app/server only works in certain environments. Since you're using @sveltejs/adapter-auto, SvelteKit cannot determine whether it will work when your app is deployed. Please replace it with an adapter tailored to your target environment."
);
},
webSockets: () => {
throw new Error(
"The socket export that creates a WebSocket server only works in certain environments. Since you're using @sveltejs/adapter-auto, SvelteKit cannot determine whether it will work when your app is deployed. Please replace it with an adapter tailored to your target environment."
);
}
}
});
59 changes: 46 additions & 13 deletions packages/adapter-cloudflare-workers/files/entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { Server } from 'SERVER';
import { manifest, prerendered, base_path } from 'MANIFEST';
import { getAssetFromKV, mapRequestToAsset } from '@cloudflare/kv-asset-handler';
import static_asset_manifest_json from '__STATIC_CONTENT_MANIFEST';
// TODO: allow WebSocket integration with Durable Objects using crossws/adapters/cloudflare-durable
import crossws from 'crossws/adapters/cloudflare';

const static_asset_manifest = JSON.parse(static_asset_manifest_json);

const server = new Server(manifest);
Expand All @@ -11,15 +14,53 @@ const app_path = `/${manifest.appPath}`;
const immutable = `${app_path}/immutable/`;
const version_file = `${app_path}/version.json`;

/** @type {import('crossws').ResolveHooks} */
let resolve_websocket_hooks;
/** @type {import('crossws/adapters/cloudflare').CloudflareAdapter} */
let ws;

if (server.getWebSocketHooksResolver) {
ws = crossws({
resolve: (req) => resolve_websocket_hooks(req)
});
}

export default {
/**
* @param {Request} req
* @param {any} env
* @param {any} context
*/
async fetch(req, env, context) {
const options = {
platform: {
env,
context,
// lib.dom is interfering with workers-types
caches,
// req is actually a Cloudflare request not a standard request
cf: req.cf
},
getClientAddress() {
return req.headers.get('cf-connecting-ip');
}
};

await server.init({ env });

if (req.headers.get('upgrade') === 'websocket' && ws) {
resolve_websocket_hooks = server.getWebSocketHooksResolver(
// @ts-ignore
options
);
return ws.handleUpgrade(
// @ts-ignore wtf is Cloudflare doing to these types
req,
env,
context
);
}

const url = new URL(req.url);

// static assets
Expand Down Expand Up @@ -90,19 +131,11 @@ export default {
}

// dynamically-generated pages
return await server.respond(req, {
platform: {
env,
context,
// @ts-expect-error lib.dom is interfering with workers-types
caches,
// @ts-expect-error req is actually a Cloudflare request not a standard request
cf: req.cf
},
getClientAddress() {
return req.headers.get('cf-connecting-ip');
}
});
return await server.respond(
req,
// @ts-ignore
options
);
}
};

Expand Down
3 changes: 3 additions & 0 deletions packages/adapter-cloudflare-workers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@ export default function ({ config = 'wrangler.toml', platformProxy = {} } = {})
return prerender ? emulated.prerender_platform : emulated.platform;
}
};
},
supports: {
webSockets: () => true
}
};
}
Expand Down
3 changes: 2 additions & 1 deletion packages/adapter-cloudflare-workers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@
"check": "tsc --skipLibCheck"
},
"dependencies": {
"@cloudflare/workers-types": "^4.20231121.0",
"@cloudflare/workers-types": "^4.20250129.0",
"@iarna/toml": "^2.2.5",
"crossws": "^0.3.4",
"esbuild": "^0.24.0"
},
"devDependencies": {
Expand Down
3 changes: 3 additions & 0 deletions packages/adapter-cloudflare/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ export default function (options = {}) {
return prerender ? emulated.prerender_platform : emulated.platform;
}
};
},
supports: {
webSockets: () => true
}
};
}
Expand Down
1 change: 1 addition & 0 deletions packages/adapter-cloudflare/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
},
"dependencies": {
"@cloudflare/workers-types": "^4.20241106.0",
"crossws": "^0.3.4",
"esbuild": "^0.24.0",
"worktop": "0.8.0-next.18"
},
Expand Down
Loading
Loading