@pluv/platform-cloudflare 0.17.3 → 0.19.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.
@@ -1,18 +1,18 @@
1
1
 
2
- > @pluv/platform-cloudflare@0.17.3 build /home/runner/work/pluv/pluv/packages/platform-cloudflare
2
+ > @pluv/platform-cloudflare@0.19.0 build /home/runner/work/pluv/pluv/packages/platform-cloudflare
3
3
  > tsup src/index.ts --format esm,cjs --dts
4
4
 
5
- CLI Building entry: src/index.ts
6
- CLI Using tsconfig: tsconfig.json
7
- CLI tsup v8.0.2
8
- CLI Target: es6
9
- ESM Build start
10
- CJS Build start
11
- ESM dist/index.mjs 5.81 KB
12
- ESM ⚡️ Build success in 92ms
13
- CJS dist/index.js 6.94 KB
14
- CJS ⚡️ Build success in 91ms
15
- DTS Build start
16
- DTS ⚡️ Build success in 3182ms
17
- DTS dist/index.d.mts 2.94 KB
18
- DTS dist/index.d.ts 2.94 KB
5
+ CLI Building entry: src/index.ts
6
+ CLI Using tsconfig: tsconfig.json
7
+ CLI tsup v8.1.0
8
+ CLI Target: es6
9
+ ESM Build start
10
+ CJS Build start
11
+ CJS dist/index.js 6.86 KB
12
+ CJS ⚡️ Build success in 91ms
13
+ ESM dist/index.mjs 5.73 KB
14
+ ESM ⚡️ Build success in 92ms
15
+ DTS Build start
16
+ DTS ⚡️ Build success in 2530ms
17
+ DTS dist/index.d.mts 3.02 KB
18
+ DTS dist/index.d.ts 3.02 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,116 @@
1
1
  # @pluv/platform-cloudflare
2
2
 
3
+ ## 0.19.0
4
+
5
+ ### Patch Changes
6
+
7
+ - @pluv/io@0.19.0
8
+ - @pluv/types@0.19.0
9
+
10
+ ## 0.18.0
11
+
12
+ ### Minor Changes
13
+
14
+ - 99b5ca9: ## Breaking Changes
15
+
16
+ - `@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.
17
+
18
+ ### Before:
19
+
20
+ ```ts
21
+ // backend/io.ts
22
+
23
+ import { createIO } from "@pluv/io";
24
+ import { createPluvHandler, platformNode } from "@pluv/platform-node";
25
+ import { z } from "zod";
26
+
27
+ export const io = createIO({
28
+ platform: platformNode(),
29
+ })
30
+ .event("SEND_MESSAGE", {
31
+ input: z.object({ message: z.string() }),
32
+ resolver: ({ message }) => ({ RECEIVE_MESSAGE: { message } }),
33
+ })
34
+ .event("DOUBLE_VALUE", {
35
+ input: z.object({ value: z.number() }),
36
+ resolver: ({ value }) => ({ VALUE_DOUBLED: { value: value * 2 } }),
37
+ });
38
+
39
+ const Pluv = createPluvHandler({
40
+ io,
41
+ /* ... */
42
+ });
43
+ ```
44
+
45
+ ```ts
46
+ // frontend/pluv.ts
47
+
48
+ import { createClient } from "@pluv/react";
49
+ import type { io } from "../backend/io";
50
+
51
+ const client = createClient<typeof io>({
52
+ /* ... */
53
+ });
54
+ ```
55
+
56
+ ### Now:
57
+
58
+ ```ts
59
+ import { createIO } from "@pluv/io";
60
+ import { createPluvHandler, platformNode } from "@pluv/platform-node";
61
+ import { z } from "zod";
62
+
63
+ const io = createIO({
64
+ platform: platformNode(),
65
+ });
66
+
67
+ const router = io.router({
68
+ SEND_MESSAGE: io.procedure
69
+ .input(z.object({ message: z.string() }))
70
+ .broadcast(({ message }) => ({
71
+ RECEIVE_MESSAGE: { message },
72
+ })),
73
+ DOUBLE_VALUE: io.procedure
74
+ .input(z.object({ value: z.number() }))
75
+ .broadcast(({ value }) => ({
76
+ VALUE_DOUBLED: { value: value * 2 },
77
+ })),
78
+ });
79
+
80
+ export const ioServer = io.server({ router });
81
+
82
+ const Pluv = createPluvHandler({
83
+ io: ioServer, // <- This uses the PluvServer now
84
+ /* ... */
85
+ });
86
+ ```
87
+
88
+ ```ts
89
+ // frontend/pluv.ts
90
+
91
+ import { createClient } from "@pluv/react";
92
+ import type { ioServer } from "../backend/io";
93
+
94
+ // This users the PluvServer type now
95
+ const client = createClient<typeof ioServer>({
96
+ /* ... */
97
+ });
98
+ ```
99
+
100
+ - `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:
101
+
102
+ ```ts
103
+ const router = io.mergeRouters(router1, router2);
104
+ ```
105
+
106
+ ### Patch Changes
107
+
108
+ - Updated dependencies [428c21c]
109
+ - Updated dependencies [329dbcd]
110
+ - Updated dependencies [99b5ca9]
111
+ - @pluv/io@0.18.0
112
+ - @pluv/types@0.18.0
113
+
3
114
  ## 0.17.3
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
- platform: platformCloudflare(),
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
- await io.register(server);
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, PluvIO } from '@pluv/io';
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<TPluv extends PluvIO<CloudflarePlatform>> = (ctx: AuthorizeFunctionContext) => MaybePromise<Maybe<InferIOAuthorizeUser<InferIOAuthorize<TPluv>>>>;
31
- type CreatePluvHandlerConfig<TPluv extends PluvIO<CloudflarePlatform>, TEnv extends Record<string, any>> = {
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: TPluv;
36
- } & (InferIOAuthorizeRequired<InferIOAuthorize<TPluv>> extends true ? {
37
- authorize: AuthorizeFunction<TPluv>;
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<TPluv extends PluvIO<CloudflarePlatform, any, any, any, any, any, any>> = TPluv extends PluvIO<CloudflarePlatform<infer IEnv>, any, any, any, any, any, any> ? IEnv : {};
50
- declare const createPluvHandler: <TPluv extends PluvIO<CloudflarePlatform<{}>, any, any, any, any, any, any>>(config: CreatePluvHandlerConfig<TPluv, Id<InferCloudflarePluvHandlerEnv<TPluv>>>) => CreatePluvHandlerResult<Id<InferCloudflarePluvHandlerEnv<TPluv>>>;
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, PluvIO } from '@pluv/io';
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<TPluv extends PluvIO<CloudflarePlatform>> = (ctx: AuthorizeFunctionContext) => MaybePromise<Maybe<InferIOAuthorizeUser<InferIOAuthorize<TPluv>>>>;
31
- type CreatePluvHandlerConfig<TPluv extends PluvIO<CloudflarePlatform>, TEnv extends Record<string, any>> = {
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: TPluv;
36
- } & (InferIOAuthorizeRequired<InferIOAuthorize<TPluv>> extends true ? {
37
- authorize: AuthorizeFunction<TPluv>;
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<TPluv extends PluvIO<CloudflarePlatform, any, any, any, any, any, any>> = TPluv extends PluvIO<CloudflarePlatform<infer IEnv>, any, any, any, any, any, any> ? IEnv : {};
50
- declare const createPluvHandler: <TPluv extends PluvIO<CloudflarePlatform<{}>, any, any, any, any, any, any>>(config: CreatePluvHandlerConfig<TPluv, Id<InferCloudflarePluvHandlerEnv<TPluv>>>) => CreatePluvHandlerResult<Id<InferCloudflarePluvHandlerEnv<TPluv>>>;
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
@@ -85,13 +85,11 @@ var createPluvHandler = (config) => {
85
85
  return namespace;
86
86
  };
87
87
  const authHandler = (request, env) => __async(void 0, null, function* () {
88
- if (!authorize)
89
- return null;
88
+ if (!authorize) return null;
90
89
  const { pathname, searchParams } = new URL(request.url);
91
90
  const matcher = (0, import_path_to_regexp.match)(`${endpoint}/authorize`);
92
91
  const matched = matcher(pathname);
93
- if (!matched)
94
- return null;
92
+ if (!matched) return null;
95
93
  const roomId = searchParams.get("room");
96
94
  if (!roomId) {
97
95
  return new Response("Not found", {
@@ -101,8 +99,7 @@ var createPluvHandler = (config) => {
101
99
  }
102
100
  try {
103
101
  const user = yield authorize({ request, roomId });
104
- if (!user)
105
- throw new Error();
102
+ if (!user) throw new Error();
106
103
  const namespace = getDurableObjectNamespace(env);
107
104
  const durableObjectId = namespace.idFromName(roomId);
108
105
  const token = yield io.createToken({
@@ -115,21 +112,17 @@ var createPluvHandler = (config) => {
115
112
  status: 200
116
113
  });
117
114
  } catch (err) {
118
- return new Response(
119
- err instanceof Error ? err.message : "Unauthorized",
120
- {
121
- headers: { "Content-Type": "text/plain" },
122
- status: 403
123
- }
124
- );
115
+ return new Response(err instanceof Error ? err.message : "Unauthorized", {
116
+ headers: { "Content-Type": "text/plain" },
117
+ status: 403
118
+ });
125
119
  }
126
120
  });
127
121
  const roomHandler = (request, env) => __async(void 0, null, function* () {
128
122
  const { pathname } = new URL(request.url);
129
123
  const matcher = (0, import_path_to_regexp.match)(`${endpoint}/room/:roomId`);
130
124
  const matched = matcher(pathname);
131
- if (!matched)
132
- return null;
125
+ if (!matched) return null;
133
126
  const { roomId } = matched.params;
134
127
  if (!roomId) {
135
128
  return new Response("Not found", {
@@ -178,11 +171,8 @@ var CloudflareWebSocket = class extends import_io.AbstractWebSocket {
178
171
  this.webSocket.addEventListener(type, handler);
179
172
  }
180
173
  close(code, reason) {
181
- const canClose = [this.CONNECTING, this.OPEN].some(
182
- (readyState) => readyState === this.readyState
183
- );
184
- if (!canClose)
185
- return;
174
+ const canClose = [this.CONNECTING, this.OPEN].some((readyState) => readyState === this.readyState);
175
+ if (!canClose) return;
186
176
  this.webSocket.close(code, reason);
187
177
  }
188
178
  initialize() {
@@ -190,8 +180,7 @@ var CloudflareWebSocket = class extends import_io.AbstractWebSocket {
190
180
  return Promise.resolve(() => void 0);
191
181
  }
192
182
  send(message) {
193
- if (this.readyState !== this.OPEN)
194
- return;
183
+ if (this.readyState !== this.OPEN) return;
195
184
  this.webSocket.send(message);
196
185
  }
197
186
  terminate() {
@@ -205,8 +194,7 @@ var CloudflarePlatform = class extends import_io2.AbstractPlatform {
205
194
  return new CloudflareWebSocket(webSocket, config);
206
195
  }
207
196
  parseData(data) {
208
- if (typeof data === "string")
209
- return JSON.parse(data);
197
+ if (typeof data === "string") return JSON.parse(data);
210
198
  const decoder = new TextDecoder("utf8");
211
199
  return JSON.parse(decoder.decode(data));
212
200
  }
package/dist/index.mjs CHANGED
@@ -59,13 +59,11 @@ var createPluvHandler = (config) => {
59
59
  return namespace;
60
60
  };
61
61
  const authHandler = (request, env) => __async(void 0, null, function* () {
62
- if (!authorize)
63
- return null;
62
+ if (!authorize) return null;
64
63
  const { pathname, searchParams } = new URL(request.url);
65
64
  const matcher = match(`${endpoint}/authorize`);
66
65
  const matched = matcher(pathname);
67
- if (!matched)
68
- return null;
66
+ if (!matched) return null;
69
67
  const roomId = searchParams.get("room");
70
68
  if (!roomId) {
71
69
  return new Response("Not found", {
@@ -75,8 +73,7 @@ var createPluvHandler = (config) => {
75
73
  }
76
74
  try {
77
75
  const user = yield authorize({ request, roomId });
78
- if (!user)
79
- throw new Error();
76
+ if (!user) throw new Error();
80
77
  const namespace = getDurableObjectNamespace(env);
81
78
  const durableObjectId = namespace.idFromName(roomId);
82
79
  const token = yield io.createToken({
@@ -89,21 +86,17 @@ var createPluvHandler = (config) => {
89
86
  status: 200
90
87
  });
91
88
  } catch (err) {
92
- return new Response(
93
- err instanceof Error ? err.message : "Unauthorized",
94
- {
95
- headers: { "Content-Type": "text/plain" },
96
- status: 403
97
- }
98
- );
89
+ return new Response(err instanceof Error ? err.message : "Unauthorized", {
90
+ headers: { "Content-Type": "text/plain" },
91
+ status: 403
92
+ });
99
93
  }
100
94
  });
101
95
  const roomHandler = (request, env) => __async(void 0, null, function* () {
102
96
  const { pathname } = new URL(request.url);
103
97
  const matcher = match(`${endpoint}/room/:roomId`);
104
98
  const matched = matcher(pathname);
105
- if (!matched)
106
- return null;
99
+ if (!matched) return null;
107
100
  const { roomId } = matched.params;
108
101
  if (!roomId) {
109
102
  return new Response("Not found", {
@@ -138,9 +131,7 @@ var createPluvHandler = (config) => {
138
131
  import { AbstractPlatform } from "@pluv/io";
139
132
 
140
133
  // src/CloudflareWebSocket.ts
141
- import {
142
- AbstractWebSocket
143
- } from "@pluv/io";
134
+ import { AbstractWebSocket } from "@pluv/io";
144
135
  var CloudflareWebSocket = class extends AbstractWebSocket {
145
136
  get readyState() {
146
137
  return this.webSocket.readyState;
@@ -154,11 +145,8 @@ var CloudflareWebSocket = class extends AbstractWebSocket {
154
145
  this.webSocket.addEventListener(type, handler);
155
146
  }
156
147
  close(code, reason) {
157
- const canClose = [this.CONNECTING, this.OPEN].some(
158
- (readyState) => readyState === this.readyState
159
- );
160
- if (!canClose)
161
- return;
148
+ const canClose = [this.CONNECTING, this.OPEN].some((readyState) => readyState === this.readyState);
149
+ if (!canClose) return;
162
150
  this.webSocket.close(code, reason);
163
151
  }
164
152
  initialize() {
@@ -166,8 +154,7 @@ var CloudflareWebSocket = class extends AbstractWebSocket {
166
154
  return Promise.resolve(() => void 0);
167
155
  }
168
156
  send(message) {
169
- if (this.readyState !== this.OPEN)
170
- return;
157
+ if (this.readyState !== this.OPEN) return;
171
158
  this.webSocket.send(message);
172
159
  }
173
160
  terminate() {
@@ -181,8 +168,7 @@ var CloudflarePlatform = class extends AbstractPlatform {
181
168
  return new CloudflareWebSocket(webSocket, config);
182
169
  }
183
170
  parseData(data) {
184
- if (typeof data === "string")
185
- return JSON.parse(data);
171
+ if (typeof data === "string") return JSON.parse(data);
186
172
  const decoder = new TextDecoder("utf8");
187
173
  return JSON.parse(decoder.decode(data));
188
174
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pluv/platform-cloudflare",
3
- "version": "0.17.3",
3
+ "version": "0.19.0",
4
4
  "description": "@pluv/io adapter for cloudflare workers",
5
5
  "author": "leedavidcs",
6
6
  "license": "MIT",
@@ -17,17 +17,17 @@
17
17
  "access": "public"
18
18
  },
19
19
  "dependencies": {
20
- "path-to-regexp": "^6.2.2",
21
- "@pluv/io": "^0.17.3",
22
- "@pluv/types": "^0.17.3"
20
+ "path-to-regexp": "^7.0.0",
21
+ "@pluv/io": "^0.19.0",
22
+ "@pluv/types": "^0.19.0"
23
23
  },
24
24
  "devDependencies": {
25
- "@cloudflare/workers-types": "^4.20240405.0",
25
+ "@cloudflare/workers-types": "^4.20240620.0",
26
26
  "eslint": "^8.57.0",
27
- "tsup": "^8.0.2",
27
+ "tsup": "^8.1.0",
28
28
  "typescript": "^5.4.5",
29
- "@pluv/tsconfig": "^0.17.3",
30
- "eslint-config-pluv": "^0.17.3"
29
+ "@pluv/tsconfig": "^0.19.0",
30
+ "eslint-config-pluv": "^0.19.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
- TEnv extends Record<string, any> = {},
7
- > extends AbstractPlatform<WebSocket, { env: TEnv }, { request: Request }> {
8
- public convertWebSocket(
9
- webSocket: WebSocket,
10
- config: ConvertWebSocketConfig,
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
 
@@ -1,5 +1,5 @@
1
- import { IORoom, PluvIO } from "@pluv/io";
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<TPluv extends PluvIO<CloudflarePlatform>> = (
17
+ export type AuthorizeFunction<TPluvServer extends PluvServer<CloudflarePlatform, any, any, any>> = (
18
18
  ctx: AuthorizeFunctionContext,
19
- ) => MaybePromise<Maybe<InferIOAuthorizeUser<InferIOAuthorize<TPluv>>>>;
19
+ ) => MaybePromise<Maybe<InferIOAuthorizeUser<InferIOAuthorize<TPluvServer>>>>;
20
20
 
21
21
  export type CreatePluvHandlerConfig<
22
- TPluv extends PluvIO<CloudflarePlatform>,
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
- request: Request,
29
- response: Response,
30
- env: TEnv,
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
- TPluv extends PluvIO<CloudflarePlatform, any, any, any, any, any, any>,
54
- > =
55
- TPluv extends PluvIO<
56
- CloudflarePlatform<infer IEnv>,
57
- any,
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<TPluv>>;
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: Id<InferCloudflarePluvHandlerEnv<TPluv>>,
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
- err instanceof Error ? err.message : "Unauthorized",
181
- {
182
- headers: { "Content-Type": "text/plain" },
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<TPluv>>> = {
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
  };