@pluv/platform-cloudflare 0.17.2 → 0.18.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.
- package/.turbo/turbo-build.log +8 -8
- package/CHANGELOG.md +111 -0
- package/README.md +5 -4
- package/dist/index.d.mts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +5 -10
- package/dist/index.mjs +6 -13
- package/package.json +6 -6
- package/src/CloudflarePlatform.ts +6 -7
- package/src/CloudflareWebSocket.ts +3 -13
- package/src/createPluvHandler.ts +31 -80
- package/src/platformCloudflare.ts +1 -3
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @pluv/platform-cloudflare@0.
|
|
2
|
+
> @pluv/platform-cloudflare@0.18.0 build /home/runner/work/pluv/pluv/packages/platform-cloudflare
|
|
3
3
|
> tsup src/index.ts --format esm,cjs --dts
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
[34mCLI[39m Target: es6
|
|
9
9
|
[34mESM[39m Build start
|
|
10
10
|
[34mCJS[39m Build start
|
|
11
|
-
[32mCJS[39m [1mdist/index.js [22m[32m6.
|
|
12
|
-
[32mCJS[39m ⚡️ Build success in
|
|
13
|
-
[32mESM[39m [1mdist/index.mjs [22m[32m5.
|
|
14
|
-
[32mESM[39m ⚡️ Build success in
|
|
11
|
+
[32mCJS[39m [1mdist/index.js [22m[32m6.90 KB[39m
|
|
12
|
+
[32mCJS[39m ⚡️ Build success in 87ms
|
|
13
|
+
[32mESM[39m [1mdist/index.mjs [22m[32m5.77 KB[39m
|
|
14
|
+
[32mESM[39m ⚡️ Build success in 88ms
|
|
15
15
|
[34mDTS[39m Build start
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
17
|
-
[32mDTS[39m [1mdist/index.d.mts [22m[
|
|
18
|
-
[32mDTS[39m [1mdist/index.d.ts [22m[
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 2209ms
|
|
17
|
+
[32mDTS[39m [1mdist/index.d.mts [22m[32m3.02 KB[39m
|
|
18
|
+
[32mDTS[39m [1mdist/index.d.ts [22m[32m3.02 KB[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,116 @@
|
|
|
1
1
|
# @pluv/platform-cloudflare
|
|
2
2
|
|
|
3
|
+
## 0.18.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 99b5ca9: ## Breaking Changes
|
|
8
|
+
|
|
9
|
+
- `@pluv/io` has been updated to introduce `PluvProcedure`, `PluvRouter` and `PluvServer`. This change is intended to improve the ergonomics of declaring events and simplifying inferences of event types.
|
|
10
|
+
|
|
11
|
+
### Before:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
// backend/io.ts
|
|
15
|
+
|
|
16
|
+
import { createIO } from "@pluv/io";
|
|
17
|
+
import { createPluvHandler, platformNode } from "@pluv/platform-node";
|
|
18
|
+
import { z } from "zod";
|
|
19
|
+
|
|
20
|
+
export const io = createIO({
|
|
21
|
+
platform: platformNode(),
|
|
22
|
+
})
|
|
23
|
+
.event("SEND_MESSAGE", {
|
|
24
|
+
input: z.object({ message: z.string() }),
|
|
25
|
+
resolver: ({ message }) => ({ RECEIVE_MESSAGE: { message } }),
|
|
26
|
+
})
|
|
27
|
+
.event("DOUBLE_VALUE", {
|
|
28
|
+
input: z.object({ value: z.number() }),
|
|
29
|
+
resolver: ({ value }) => ({ VALUE_DOUBLED: { value: value * 2 } }),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const Pluv = createPluvHandler({
|
|
33
|
+
io,
|
|
34
|
+
/* ... */
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
// frontend/pluv.ts
|
|
40
|
+
|
|
41
|
+
import { createClient } from "@pluv/react";
|
|
42
|
+
import type { io } from "../backend/io";
|
|
43
|
+
|
|
44
|
+
const client = createClient<typeof io>({
|
|
45
|
+
/* ... */
|
|
46
|
+
});
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Now:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import { createIO } from "@pluv/io";
|
|
53
|
+
import { createPluvHandler, platformNode } from "@pluv/platform-node";
|
|
54
|
+
import { z } from "zod";
|
|
55
|
+
|
|
56
|
+
const io = createIO({
|
|
57
|
+
platform: platformNode(),
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const router = io.router({
|
|
61
|
+
SEND_MESSAGE: io.procedure
|
|
62
|
+
.input(z.object({ message: z.string() }))
|
|
63
|
+
.broadcast(({ message }) => ({
|
|
64
|
+
RECEIVE_MESSAGE: { message },
|
|
65
|
+
})),
|
|
66
|
+
DOUBLE_VALUE: io.procedure
|
|
67
|
+
.input(z.object({ value: z.number() }))
|
|
68
|
+
.broadcast(({ value }) => ({
|
|
69
|
+
VALUE_DOUBLED: { value: value * 2 },
|
|
70
|
+
})),
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
export const ioServer = io.server({ router });
|
|
74
|
+
|
|
75
|
+
const Pluv = createPluvHandler({
|
|
76
|
+
io: ioServer, // <- This uses the PluvServer now
|
|
77
|
+
/* ... */
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
// frontend/pluv.ts
|
|
83
|
+
|
|
84
|
+
import { createClient } from "@pluv/react";
|
|
85
|
+
import type { ioServer } from "../backend/io";
|
|
86
|
+
|
|
87
|
+
// This users the PluvServer type now
|
|
88
|
+
const client = createClient<typeof ioServer>({
|
|
89
|
+
/* ... */
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
- `PluvRouter` instances can also be merged via the `mergeRouters` method, which effectively performs an `Object.assign` of the events object and returns a new `PluvRouter` with the correct types:
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
const router = io.mergeRouters(router1, router2);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Patch Changes
|
|
100
|
+
|
|
101
|
+
- Updated dependencies [428c21c]
|
|
102
|
+
- Updated dependencies [329dbcd]
|
|
103
|
+
- Updated dependencies [99b5ca9]
|
|
104
|
+
- @pluv/io@0.18.0
|
|
105
|
+
- @pluv/types@0.18.0
|
|
106
|
+
|
|
107
|
+
## 0.17.3
|
|
108
|
+
|
|
109
|
+
### Patch Changes
|
|
110
|
+
|
|
111
|
+
- @pluv/io@0.17.3
|
|
112
|
+
- @pluv/types@0.17.3
|
|
113
|
+
|
|
3
114
|
## 0.17.2
|
|
4
115
|
|
|
5
116
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -50,14 +50,15 @@ pnpm add @pluv/platform-cloudflare
|
|
|
50
50
|
import { createIO } from "@pluv/io";
|
|
51
51
|
import { platformCloudflare } from "@pluv/platform-cloudflare";
|
|
52
52
|
|
|
53
|
-
export const io = createIO({
|
|
54
|
-
|
|
55
|
-
});
|
|
53
|
+
export const io = createIO({ platform: platformCloudflare() });
|
|
54
|
+
export const ioServer = io.server();
|
|
56
55
|
|
|
57
56
|
/* Somewhere in a Cloudflare worker durable object */
|
|
58
57
|
const { 0: client, 1: server } = new WebSocketPair();
|
|
59
58
|
|
|
60
|
-
|
|
59
|
+
const room = ioServer.getRoom(state.id.toString(), { env });
|
|
60
|
+
|
|
61
|
+
await room.register(server);
|
|
61
62
|
|
|
62
63
|
return new Response(null, { status: 101, webSocket: client });
|
|
63
64
|
```
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbstractWebSocket, AbstractEventMap, AbstractListener, AbstractWebSocketConfig, AbstractPlatform, ConvertWebSocketConfig,
|
|
1
|
+
import { AbstractWebSocket, AbstractEventMap, AbstractListener, AbstractWebSocketConfig, AbstractPlatform, ConvertWebSocketConfig, PluvServer } from '@pluv/io';
|
|
2
2
|
import { MaybePromise, Maybe, InferIOAuthorizeUser, InferIOAuthorize, InferIOAuthorizeRequired, Id } from '@pluv/types';
|
|
3
3
|
|
|
4
4
|
type CloudflareWebSocketConfig = AbstractWebSocketConfig;
|
|
@@ -27,14 +27,14 @@ interface AuthorizeFunctionContext {
|
|
|
27
27
|
request: Request<any, CfProperties<any>>;
|
|
28
28
|
roomId: string;
|
|
29
29
|
}
|
|
30
|
-
type AuthorizeFunction<
|
|
31
|
-
type CreatePluvHandlerConfig<
|
|
30
|
+
type AuthorizeFunction<TPluvServer extends PluvServer<CloudflarePlatform, any, any, any>> = (ctx: AuthorizeFunctionContext) => MaybePromise<Maybe<InferIOAuthorizeUser<InferIOAuthorize<TPluvServer>>>>;
|
|
31
|
+
type CreatePluvHandlerConfig<TPluvServer extends PluvServer<CloudflarePlatform, any, any, any>, TEnv extends Record<string, any>> = {
|
|
32
32
|
binding: string;
|
|
33
33
|
endpoint?: string;
|
|
34
34
|
modify?: (request: Request, response: Response, env: TEnv) => MaybePromise<Response>;
|
|
35
|
-
io:
|
|
36
|
-
} & (InferIOAuthorizeRequired<InferIOAuthorize<
|
|
37
|
-
authorize: AuthorizeFunction<
|
|
35
|
+
io: TPluvServer;
|
|
36
|
+
} & (InferIOAuthorizeRequired<InferIOAuthorize<TPluvServer>> extends true ? {
|
|
37
|
+
authorize: AuthorizeFunction<TPluvServer>;
|
|
38
38
|
} : {
|
|
39
39
|
authorize?: undefined;
|
|
40
40
|
});
|
|
@@ -46,8 +46,8 @@ interface CreatePluvHandlerResult<TEnv extends Record<string, any> = {}> {
|
|
|
46
46
|
fetch: PluvHandlerFetch<TEnv>;
|
|
47
47
|
handler: ExportedHandler<TEnv>;
|
|
48
48
|
}
|
|
49
|
-
type InferCloudflarePluvHandlerEnv<
|
|
50
|
-
declare const createPluvHandler: <
|
|
49
|
+
type InferCloudflarePluvHandlerEnv<TPluvServer extends PluvServer<CloudflarePlatform, any, any, any>> = TPluvServer extends PluvServer<CloudflarePlatform<infer IEnv>, any, any, any> ? IEnv : {};
|
|
50
|
+
declare const createPluvHandler: <TPluvServer extends PluvServer<CloudflarePlatform<{}>, any, any, any>>(config: CreatePluvHandlerConfig<TPluvServer, Id<InferCloudflarePluvHandlerEnv<TPluvServer>>>) => CreatePluvHandlerResult<Id<InferCloudflarePluvHandlerEnv<TPluvServer>>>;
|
|
51
51
|
|
|
52
52
|
declare const platformCloudflare: <TEnv extends Record<string, any> = {}>() => CloudflarePlatform<TEnv>;
|
|
53
53
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbstractWebSocket, AbstractEventMap, AbstractListener, AbstractWebSocketConfig, AbstractPlatform, ConvertWebSocketConfig,
|
|
1
|
+
import { AbstractWebSocket, AbstractEventMap, AbstractListener, AbstractWebSocketConfig, AbstractPlatform, ConvertWebSocketConfig, PluvServer } from '@pluv/io';
|
|
2
2
|
import { MaybePromise, Maybe, InferIOAuthorizeUser, InferIOAuthorize, InferIOAuthorizeRequired, Id } from '@pluv/types';
|
|
3
3
|
|
|
4
4
|
type CloudflareWebSocketConfig = AbstractWebSocketConfig;
|
|
@@ -27,14 +27,14 @@ interface AuthorizeFunctionContext {
|
|
|
27
27
|
request: Request<any, CfProperties<any>>;
|
|
28
28
|
roomId: string;
|
|
29
29
|
}
|
|
30
|
-
type AuthorizeFunction<
|
|
31
|
-
type CreatePluvHandlerConfig<
|
|
30
|
+
type AuthorizeFunction<TPluvServer extends PluvServer<CloudflarePlatform, any, any, any>> = (ctx: AuthorizeFunctionContext) => MaybePromise<Maybe<InferIOAuthorizeUser<InferIOAuthorize<TPluvServer>>>>;
|
|
31
|
+
type CreatePluvHandlerConfig<TPluvServer extends PluvServer<CloudflarePlatform, any, any, any>, TEnv extends Record<string, any>> = {
|
|
32
32
|
binding: string;
|
|
33
33
|
endpoint?: string;
|
|
34
34
|
modify?: (request: Request, response: Response, env: TEnv) => MaybePromise<Response>;
|
|
35
|
-
io:
|
|
36
|
-
} & (InferIOAuthorizeRequired<InferIOAuthorize<
|
|
37
|
-
authorize: AuthorizeFunction<
|
|
35
|
+
io: TPluvServer;
|
|
36
|
+
} & (InferIOAuthorizeRequired<InferIOAuthorize<TPluvServer>> extends true ? {
|
|
37
|
+
authorize: AuthorizeFunction<TPluvServer>;
|
|
38
38
|
} : {
|
|
39
39
|
authorize?: undefined;
|
|
40
40
|
});
|
|
@@ -46,8 +46,8 @@ interface CreatePluvHandlerResult<TEnv extends Record<string, any> = {}> {
|
|
|
46
46
|
fetch: PluvHandlerFetch<TEnv>;
|
|
47
47
|
handler: ExportedHandler<TEnv>;
|
|
48
48
|
}
|
|
49
|
-
type InferCloudflarePluvHandlerEnv<
|
|
50
|
-
declare const createPluvHandler: <
|
|
49
|
+
type InferCloudflarePluvHandlerEnv<TPluvServer extends PluvServer<CloudflarePlatform, any, any, any>> = TPluvServer extends PluvServer<CloudflarePlatform<infer IEnv>, any, any, any> ? IEnv : {};
|
|
50
|
+
declare const createPluvHandler: <TPluvServer extends PluvServer<CloudflarePlatform<{}>, any, any, any>>(config: CreatePluvHandlerConfig<TPluvServer, Id<InferCloudflarePluvHandlerEnv<TPluvServer>>>) => CreatePluvHandlerResult<Id<InferCloudflarePluvHandlerEnv<TPluvServer>>>;
|
|
51
51
|
|
|
52
52
|
declare const platformCloudflare: <TEnv extends Record<string, any> = {}>() => CloudflarePlatform<TEnv>;
|
|
53
53
|
|
package/dist/index.js
CHANGED
|
@@ -115,13 +115,10 @@ var createPluvHandler = (config) => {
|
|
|
115
115
|
status: 200
|
|
116
116
|
});
|
|
117
117
|
} catch (err) {
|
|
118
|
-
return new Response(
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
status: 403
|
|
123
|
-
}
|
|
124
|
-
);
|
|
118
|
+
return new Response(err instanceof Error ? err.message : "Unauthorized", {
|
|
119
|
+
headers: { "Content-Type": "text/plain" },
|
|
120
|
+
status: 403
|
|
121
|
+
});
|
|
125
122
|
}
|
|
126
123
|
});
|
|
127
124
|
const roomHandler = (request, env) => __async(void 0, null, function* () {
|
|
@@ -178,9 +175,7 @@ var CloudflareWebSocket = class extends import_io.AbstractWebSocket {
|
|
|
178
175
|
this.webSocket.addEventListener(type, handler);
|
|
179
176
|
}
|
|
180
177
|
close(code, reason) {
|
|
181
|
-
const canClose = [this.CONNECTING, this.OPEN].some(
|
|
182
|
-
(readyState) => readyState === this.readyState
|
|
183
|
-
);
|
|
178
|
+
const canClose = [this.CONNECTING, this.OPEN].some((readyState) => readyState === this.readyState);
|
|
184
179
|
if (!canClose)
|
|
185
180
|
return;
|
|
186
181
|
this.webSocket.close(code, reason);
|
package/dist/index.mjs
CHANGED
|
@@ -89,13 +89,10 @@ var createPluvHandler = (config) => {
|
|
|
89
89
|
status: 200
|
|
90
90
|
});
|
|
91
91
|
} catch (err) {
|
|
92
|
-
return new Response(
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
status: 403
|
|
97
|
-
}
|
|
98
|
-
);
|
|
92
|
+
return new Response(err instanceof Error ? err.message : "Unauthorized", {
|
|
93
|
+
headers: { "Content-Type": "text/plain" },
|
|
94
|
+
status: 403
|
|
95
|
+
});
|
|
99
96
|
}
|
|
100
97
|
});
|
|
101
98
|
const roomHandler = (request, env) => __async(void 0, null, function* () {
|
|
@@ -138,9 +135,7 @@ var createPluvHandler = (config) => {
|
|
|
138
135
|
import { AbstractPlatform } from "@pluv/io";
|
|
139
136
|
|
|
140
137
|
// src/CloudflareWebSocket.ts
|
|
141
|
-
import {
|
|
142
|
-
AbstractWebSocket
|
|
143
|
-
} from "@pluv/io";
|
|
138
|
+
import { AbstractWebSocket } from "@pluv/io";
|
|
144
139
|
var CloudflareWebSocket = class extends AbstractWebSocket {
|
|
145
140
|
get readyState() {
|
|
146
141
|
return this.webSocket.readyState;
|
|
@@ -154,9 +149,7 @@ var CloudflareWebSocket = class extends AbstractWebSocket {
|
|
|
154
149
|
this.webSocket.addEventListener(type, handler);
|
|
155
150
|
}
|
|
156
151
|
close(code, reason) {
|
|
157
|
-
const canClose = [this.CONNECTING, this.OPEN].some(
|
|
158
|
-
(readyState) => readyState === this.readyState
|
|
159
|
-
);
|
|
152
|
+
const canClose = [this.CONNECTING, this.OPEN].some((readyState) => readyState === this.readyState);
|
|
160
153
|
if (!canClose)
|
|
161
154
|
return;
|
|
162
155
|
this.webSocket.close(code, reason);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pluv/platform-cloudflare",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "@pluv/io adapter for cloudflare workers",
|
|
5
5
|
"author": "leedavidcs",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,16 +18,16 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"path-to-regexp": "^6.2.2",
|
|
21
|
-
"@pluv/io": "^0.
|
|
22
|
-
"@pluv/types": "^0.
|
|
21
|
+
"@pluv/io": "^0.18.0",
|
|
22
|
+
"@pluv/types": "^0.18.0"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@cloudflare/workers-types": "^4.
|
|
25
|
+
"@cloudflare/workers-types": "^4.20240529.0",
|
|
26
26
|
"eslint": "^8.57.0",
|
|
27
27
|
"tsup": "^8.0.2",
|
|
28
28
|
"typescript": "^5.4.5",
|
|
29
|
-
"@pluv/tsconfig": "^0.
|
|
30
|
-
"eslint-config-pluv": "^0.
|
|
29
|
+
"@pluv/tsconfig": "^0.18.0",
|
|
30
|
+
"eslint-config-pluv": "^0.18.0"
|
|
31
31
|
},
|
|
32
32
|
"scripts": {
|
|
33
33
|
"build": "tsup src/index.ts --format esm,cjs --dts",
|
|
@@ -2,13 +2,12 @@ import type { ConvertWebSocketConfig } from "@pluv/io";
|
|
|
2
2
|
import { AbstractPlatform } from "@pluv/io";
|
|
3
3
|
import { CloudflareWebSocket } from "./CloudflareWebSocket";
|
|
4
4
|
|
|
5
|
-
export class CloudflarePlatform<
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
): CloudflareWebSocket {
|
|
5
|
+
export class CloudflarePlatform<TEnv extends Record<string, any> = {}> extends AbstractPlatform<
|
|
6
|
+
WebSocket,
|
|
7
|
+
{ env: TEnv },
|
|
8
|
+
{ request: Request }
|
|
9
|
+
> {
|
|
10
|
+
public convertWebSocket(webSocket: WebSocket, config: ConvertWebSocketConfig): CloudflareWebSocket {
|
|
12
11
|
return new CloudflareWebSocket(webSocket, config);
|
|
13
12
|
}
|
|
14
13
|
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AbstractEventMap,
|
|
3
|
-
AbstractListener,
|
|
4
|
-
AbstractWebSocket,
|
|
5
|
-
AbstractWebSocketConfig,
|
|
6
|
-
} from "@pluv/io";
|
|
1
|
+
import { AbstractEventMap, AbstractListener, AbstractWebSocket, AbstractWebSocketConfig } from "@pluv/io";
|
|
7
2
|
|
|
8
3
|
export interface CloudflareWebSocketEventMap {
|
|
9
4
|
close: CloseEvent;
|
|
@@ -29,17 +24,12 @@ export class CloudflareWebSocket extends AbstractWebSocket {
|
|
|
29
24
|
this.webSocket = webSocket;
|
|
30
25
|
}
|
|
31
26
|
|
|
32
|
-
public addEventListener<TType extends keyof AbstractEventMap>(
|
|
33
|
-
type: TType,
|
|
34
|
-
handler: AbstractListener<TType>,
|
|
35
|
-
) {
|
|
27
|
+
public addEventListener<TType extends keyof AbstractEventMap>(type: TType, handler: AbstractListener<TType>) {
|
|
36
28
|
this.webSocket.addEventListener(type, handler as any);
|
|
37
29
|
}
|
|
38
30
|
|
|
39
31
|
public close(code?: number | undefined, reason?: string | undefined): void {
|
|
40
|
-
const canClose = [this.CONNECTING, this.OPEN].some(
|
|
41
|
-
(readyState) => readyState === this.readyState,
|
|
42
|
-
);
|
|
32
|
+
const canClose = [this.CONNECTING, this.OPEN].some((readyState) => readyState === this.readyState);
|
|
43
33
|
|
|
44
34
|
if (!canClose) return;
|
|
45
35
|
|
package/src/createPluvHandler.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IORoom,
|
|
2
|
-
import {
|
|
1
|
+
import type { IORoom, PluvServer } from "@pluv/io";
|
|
2
|
+
import type {
|
|
3
3
|
Id,
|
|
4
4
|
InferIOAuthorize,
|
|
5
5
|
InferIOAuthorizeRequired,
|
|
@@ -14,24 +14,20 @@ export interface AuthorizeFunctionContext {
|
|
|
14
14
|
request: Request<any, CfProperties<any>>;
|
|
15
15
|
roomId: string;
|
|
16
16
|
}
|
|
17
|
-
export type AuthorizeFunction<
|
|
17
|
+
export type AuthorizeFunction<TPluvServer extends PluvServer<CloudflarePlatform, any, any, any>> = (
|
|
18
18
|
ctx: AuthorizeFunctionContext,
|
|
19
|
-
) => MaybePromise<Maybe<InferIOAuthorizeUser<InferIOAuthorize<
|
|
19
|
+
) => MaybePromise<Maybe<InferIOAuthorizeUser<InferIOAuthorize<TPluvServer>>>>;
|
|
20
20
|
|
|
21
21
|
export type CreatePluvHandlerConfig<
|
|
22
|
-
|
|
22
|
+
TPluvServer extends PluvServer<CloudflarePlatform, any, any, any>,
|
|
23
23
|
TEnv extends Record<string, any>,
|
|
24
24
|
> = {
|
|
25
25
|
binding: string;
|
|
26
26
|
endpoint?: string;
|
|
27
|
-
modify?: (
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
) => MaybePromise<Response>;
|
|
32
|
-
io: TPluv;
|
|
33
|
-
} & (InferIOAuthorizeRequired<InferIOAuthorize<TPluv>> extends true
|
|
34
|
-
? { authorize: AuthorizeFunction<TPluv> }
|
|
27
|
+
modify?: (request: Request, response: Response, env: TEnv) => MaybePromise<Response>;
|
|
28
|
+
io: TPluvServer;
|
|
29
|
+
} & (InferIOAuthorizeRequired<InferIOAuthorize<TPluvServer>> extends true
|
|
30
|
+
? { authorize: AuthorizeFunction<TPluvServer> }
|
|
35
31
|
: { authorize?: undefined });
|
|
36
32
|
|
|
37
33
|
export type PluvHandlerFetch<TEnv extends Record<string, any> = {}> = (
|
|
@@ -39,9 +35,7 @@ export type PluvHandlerFetch<TEnv extends Record<string, any> = {}> = (
|
|
|
39
35
|
env: TEnv,
|
|
40
36
|
) => Promise<Response | null>;
|
|
41
37
|
|
|
42
|
-
export interface CreatePluvHandlerResult<
|
|
43
|
-
TEnv extends Record<string, any> = {},
|
|
44
|
-
> {
|
|
38
|
+
export interface CreatePluvHandlerResult<TEnv extends Record<string, any> = {}> {
|
|
45
39
|
DurableObject: {
|
|
46
40
|
new (state: DurableObjectState, env: TEnv): DurableObject;
|
|
47
41
|
};
|
|
@@ -49,60 +43,30 @@ export interface CreatePluvHandlerResult<
|
|
|
49
43
|
handler: ExportedHandler<TEnv>;
|
|
50
44
|
}
|
|
51
45
|
|
|
52
|
-
type InferCloudflarePluvHandlerEnv<
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
any,
|
|
59
|
-
any,
|
|
60
|
-
any,
|
|
61
|
-
any,
|
|
62
|
-
any
|
|
63
|
-
>
|
|
64
|
-
? IEnv
|
|
65
|
-
: {};
|
|
66
|
-
|
|
67
|
-
export const createPluvHandler = <
|
|
68
|
-
TPluv extends PluvIO<CloudflarePlatform, any, any, any, any, any, any>,
|
|
69
|
-
>(
|
|
70
|
-
config: CreatePluvHandlerConfig<
|
|
71
|
-
TPluv,
|
|
72
|
-
Id<InferCloudflarePluvHandlerEnv<TPluv>>
|
|
73
|
-
>,
|
|
74
|
-
): CreatePluvHandlerResult<Id<InferCloudflarePluvHandlerEnv<TPluv>>> => {
|
|
46
|
+
type InferCloudflarePluvHandlerEnv<TPluvServer extends PluvServer<CloudflarePlatform, any, any, any>> =
|
|
47
|
+
TPluvServer extends PluvServer<CloudflarePlatform<infer IEnv>, any, any, any> ? IEnv : {};
|
|
48
|
+
|
|
49
|
+
export const createPluvHandler = <TPluvServer extends PluvServer<CloudflarePlatform, any, any, any>>(
|
|
50
|
+
config: CreatePluvHandlerConfig<TPluvServer, Id<InferCloudflarePluvHandlerEnv<TPluvServer>>>,
|
|
51
|
+
): CreatePluvHandlerResult<Id<InferCloudflarePluvHandlerEnv<TPluvServer>>> => {
|
|
75
52
|
const { authorize, binding, endpoint = "/api/pluv", modify, io } = config;
|
|
76
53
|
|
|
77
54
|
const DurableObject = class implements DurableObject {
|
|
78
|
-
private _env: Id<InferCloudflarePluvHandlerEnv<
|
|
55
|
+
private _env: Id<InferCloudflarePluvHandlerEnv<TPluvServer>>;
|
|
79
56
|
private _io: IORoom<CloudflarePlatform>;
|
|
80
57
|
|
|
81
|
-
constructor(
|
|
82
|
-
state: DurableObjectState,
|
|
83
|
-
env: Id<InferCloudflarePluvHandlerEnv<TPluv>>,
|
|
84
|
-
) {
|
|
58
|
+
constructor(state: DurableObjectState, env: Id<InferCloudflarePluvHandlerEnv<TPluvServer>>) {
|
|
85
59
|
this._env = env;
|
|
86
60
|
this._io = io.getRoom(state.id.toString(), { env });
|
|
87
61
|
}
|
|
88
62
|
|
|
89
|
-
webSocketClose(
|
|
90
|
-
ws: WebSocket,
|
|
91
|
-
code: number,
|
|
92
|
-
reason: string,
|
|
93
|
-
wasClean: boolean,
|
|
94
|
-
): void | Promise<void> {}
|
|
63
|
+
webSocketClose(ws: WebSocket, code: number, reason: string, wasClean: boolean): void | Promise<void> {}
|
|
95
64
|
|
|
96
65
|
webSocketError(ws: WebSocket, error: unknown): void | Promise<void> {}
|
|
97
66
|
|
|
98
|
-
webSocketMessage(
|
|
99
|
-
ws: WebSocket,
|
|
100
|
-
message: string | ArrayBuffer,
|
|
101
|
-
): void | Promise<void> {}
|
|
67
|
+
webSocketMessage(ws: WebSocket, message: string | ArrayBuffer): void | Promise<void> {}
|
|
102
68
|
|
|
103
|
-
async fetch(
|
|
104
|
-
request: Request<any, CfProperties<any>>,
|
|
105
|
-
): Promise<Response> {
|
|
69
|
+
async fetch(request: Request<any, CfProperties<any>>): Promise<Response> {
|
|
106
70
|
const isWSRequest = request.headers.get("Upgrade") === "websocket";
|
|
107
71
|
|
|
108
72
|
if (!isWSRequest) {
|
|
@@ -123,12 +87,8 @@ export const createPluvHandler = <
|
|
|
123
87
|
}
|
|
124
88
|
};
|
|
125
89
|
|
|
126
|
-
const getDurableObjectNamespace = (
|
|
127
|
-
env
|
|
128
|
-
): DurableObjectNamespace => {
|
|
129
|
-
const namespace = env[
|
|
130
|
-
binding as keyof typeof env
|
|
131
|
-
] as DurableObjectNamespace;
|
|
90
|
+
const getDurableObjectNamespace = (env: Id<InferCloudflarePluvHandlerEnv<TPluvServer>>): DurableObjectNamespace => {
|
|
91
|
+
const namespace = env[binding as keyof typeof env] as DurableObjectNamespace;
|
|
132
92
|
|
|
133
93
|
if (!namespace) {
|
|
134
94
|
throw new Error(`Could not find DurableObject binding: ${binding}`);
|
|
@@ -137,9 +97,7 @@ export const createPluvHandler = <
|
|
|
137
97
|
return namespace;
|
|
138
98
|
};
|
|
139
99
|
|
|
140
|
-
const authHandler: PluvHandlerFetch<
|
|
141
|
-
Id<InferCloudflarePluvHandlerEnv<TPluv>>
|
|
142
|
-
> = async (request, env) => {
|
|
100
|
+
const authHandler: PluvHandlerFetch<Id<InferCloudflarePluvHandlerEnv<TPluvServer>>> = async (request, env) => {
|
|
143
101
|
if (!authorize) return null;
|
|
144
102
|
|
|
145
103
|
const { pathname, searchParams } = new URL(request.url);
|
|
@@ -176,19 +134,14 @@ export const createPluvHandler = <
|
|
|
176
134
|
status: 200,
|
|
177
135
|
});
|
|
178
136
|
} catch (err) {
|
|
179
|
-
return new Response(
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
status: 403,
|
|
184
|
-
},
|
|
185
|
-
);
|
|
137
|
+
return new Response(err instanceof Error ? err.message : "Unauthorized", {
|
|
138
|
+
headers: { "Content-Type": "text/plain" },
|
|
139
|
+
status: 403,
|
|
140
|
+
});
|
|
186
141
|
}
|
|
187
142
|
};
|
|
188
143
|
|
|
189
|
-
const roomHandler: PluvHandlerFetch<
|
|
190
|
-
Id<InferCloudflarePluvHandlerEnv<TPluv>>
|
|
191
|
-
> = async (request, env) => {
|
|
144
|
+
const roomHandler: PluvHandlerFetch<Id<InferCloudflarePluvHandlerEnv<TPluvServer>>> = async (request, env) => {
|
|
192
145
|
const { pathname } = new URL(request.url);
|
|
193
146
|
const matcher = match<{ roomId: string }>(`${endpoint}/room/:roomId`);
|
|
194
147
|
const matched = matcher(pathname);
|
|
@@ -211,15 +164,13 @@ export const createPluvHandler = <
|
|
|
211
164
|
return room.fetch(request);
|
|
212
165
|
};
|
|
213
166
|
|
|
214
|
-
const fetch: PluvHandlerFetch<
|
|
215
|
-
Id<InferCloudflarePluvHandlerEnv<TPluv>>
|
|
216
|
-
> = async (request, env) => {
|
|
167
|
+
const fetch: PluvHandlerFetch<Id<InferCloudflarePluvHandlerEnv<TPluvServer>>> = async (request, env) => {
|
|
217
168
|
return [authHandler, roomHandler].reduce((promise, current) => {
|
|
218
169
|
return promise.then((value) => value ?? current(request, env));
|
|
219
170
|
}, Promise.resolve<Response | null>(null));
|
|
220
171
|
};
|
|
221
172
|
|
|
222
|
-
const handler: ExportedHandler<Id<InferCloudflarePluvHandlerEnv<
|
|
173
|
+
const handler: ExportedHandler<Id<InferCloudflarePluvHandlerEnv<TPluvServer>>> = {
|
|
223
174
|
fetch: async (request, env) => {
|
|
224
175
|
const response =
|
|
225
176
|
(await fetch(request, env)) ??
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { CloudflarePlatform } from "./CloudflarePlatform";
|
|
2
2
|
|
|
3
|
-
export const platformCloudflare = <
|
|
4
|
-
TEnv extends Record<string, any> = {},
|
|
5
|
-
>(): CloudflarePlatform<TEnv> => {
|
|
3
|
+
export const platformCloudflare = <TEnv extends Record<string, any> = {}>(): CloudflarePlatform<TEnv> => {
|
|
6
4
|
return new CloudflarePlatform<TEnv>();
|
|
7
5
|
};
|