effect-cf 0.2.0 → 0.3.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/CHANGELOG.md +6 -0
- package/README.md +12 -1
- package/dist/index.d.mts +7 -7
- package/dist/index.mjs +7 -7
- package/package.json +1 -1
- package/src/DurableObject.ts +9 -6
- package/src/DurableObjectWebSocket.ts +4 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# effect-cf
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#10](https://github.com/danieljvdm/effect-cf/pull/10) [`a0e3f43`](https://github.com/danieljvdm/effect-cf/commit/a0e3f436df695b8ea3908fbb7813efea099ccd13) Thanks [@danieljvdm](https://github.com/danieljvdm)! - Type Durable Object websocket lifecycle handlers with `DurableWebSocket` instead of raw `WebSocket`, so handlers can use the Effect-native durable socket API without manually wrapping Cloudflare sockets.
|
|
8
|
+
|
|
3
9
|
## 0.2.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -144,7 +144,7 @@ Durable Object application sockets should use the hibernation-compatible state A
|
|
|
144
144
|
|
|
145
145
|
```ts
|
|
146
146
|
import { Effect, Schema as S } from "effect";
|
|
147
|
-
import { DurableObjectState, DurableObjectWebSocket, Worker } from "effect-cf";
|
|
147
|
+
import { DurableObject, DurableObjectState, DurableObjectWebSocket, Worker } from "effect-cf";
|
|
148
148
|
|
|
149
149
|
const ConnectionAttachment = S.Struct({
|
|
150
150
|
id: S.String,
|
|
@@ -173,6 +173,17 @@ export const fetch = Effect.gen(function* () {
|
|
|
173
173
|
|
|
174
174
|
`DurableWebSocket` keeps the native socket available as `socket.raw`, while `send`, `close`, `serializeAttachment`, and `deserializeAttachment` return typed `Effect` failures. Use `state.getWebSockets(tag)` to retrieve wrapped sockets for broadcast and rehydration.
|
|
175
175
|
|
|
176
|
+
`DurableObject.make` lifecycle handlers receive wrapped sockets automatically:
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
export const RoomLive = DurableObject.make(layer, {
|
|
180
|
+
webSocketMessage: (socket, message) =>
|
|
181
|
+
Effect.gen(function* () {
|
|
182
|
+
yield* socket.send(message);
|
|
183
|
+
}),
|
|
184
|
+
});
|
|
185
|
+
```
|
|
186
|
+
|
|
176
187
|
Schema-backed attachments can rehydrate hibernated sockets:
|
|
177
188
|
|
|
178
189
|
```ts
|
package/dist/index.d.mts
CHANGED
|
@@ -468,11 +468,11 @@ interface DurableWebSocketHandlers<R = never, E = unknown> {
|
|
|
468
468
|
readonly close?: (socket: DurableWebSocket, code: number, reason: string, wasClean: boolean) => Effect.Effect<void, E, R>;
|
|
469
469
|
readonly error?: (socket: DurableWebSocket, error: unknown) => Effect.Effect<void, E, R>;
|
|
470
470
|
}
|
|
471
|
-
/**
|
|
471
|
+
/** Maps compact websocket lifecycle handler names to `DurableObject.make` options. */
|
|
472
472
|
declare const handlers: <R = never, E = unknown>(options: DurableWebSocketHandlers<R, E>) => {
|
|
473
|
-
webSocketMessage: ((socket:
|
|
474
|
-
webSocketClose: ((socket:
|
|
475
|
-
webSocketError: ((socket:
|
|
473
|
+
webSocketMessage: ((socket: DurableWebSocket, message: string | ArrayBuffer) => Effect.Effect<void, E, R>) | undefined;
|
|
474
|
+
webSocketClose: ((socket: DurableWebSocket, code: number, reason: string, wasClean: boolean) => Effect.Effect<void, E, R>) | undefined;
|
|
475
|
+
webSocketError: ((socket: DurableWebSocket, error: unknown) => Effect.Effect<void, E, R>) | undefined;
|
|
476
476
|
};
|
|
477
477
|
declare namespace DurableObjectState_d_exports {
|
|
478
478
|
export { DurableObjectState, DurableObjectStateService, fromDurableObjectState };
|
|
@@ -1457,9 +1457,9 @@ interface DurableObjectOptions<ROut, Rpc extends DurableObjectRpc<ROut>> {
|
|
|
1457
1457
|
*/
|
|
1458
1458
|
readonly alarms?: Effect.Effect<unknown, unknown, HandlerContext<ROut>>;
|
|
1459
1459
|
readonly alarm?: (alarmInfo?: globalThis.AlarmInvocationInfo) => Effect.Effect<void, unknown, HandlerContext<ROut>>;
|
|
1460
|
-
readonly webSocketMessage?: (socket:
|
|
1461
|
-
readonly webSocketClose?: (socket:
|
|
1462
|
-
readonly webSocketError?: (socket:
|
|
1460
|
+
readonly webSocketMessage?: (socket: DurableWebSocket, message: string | ArrayBuffer) => Effect.Effect<void, unknown, HandlerContext<ROut>>;
|
|
1461
|
+
readonly webSocketClose?: (socket: DurableWebSocket, code: number, reason: string, wasClean: boolean) => Effect.Effect<void, unknown, HandlerContext<ROut>>;
|
|
1462
|
+
readonly webSocketError?: (socket: DurableWebSocket, error: unknown) => Effect.Effect<void, unknown, HandlerContext<ROut>>;
|
|
1463
1463
|
}
|
|
1464
1464
|
/**
|
|
1465
1465
|
* Cloudflare `DurableObject` constructor produced by {@link make}.
|
package/dist/index.mjs
CHANGED
|
@@ -923,11 +923,11 @@ const attachment = (schema) => {
|
|
|
923
923
|
schema
|
|
924
924
|
};
|
|
925
925
|
};
|
|
926
|
-
/**
|
|
926
|
+
/** Maps compact websocket lifecycle handler names to `DurableObject.make` options. */
|
|
927
927
|
const handlers = (options) => ({
|
|
928
|
-
webSocketMessage: options.message
|
|
929
|
-
webSocketClose: options.close
|
|
930
|
-
webSocketError: options.error
|
|
928
|
+
webSocketMessage: options.message,
|
|
929
|
+
webSocketClose: options.close,
|
|
930
|
+
webSocketError: options.error
|
|
931
931
|
});
|
|
932
932
|
//#endregion
|
|
933
933
|
//#region src/DurableObjectState.ts
|
|
@@ -1230,13 +1230,13 @@ const make$4 = (layer, options = {}) => {
|
|
|
1230
1230
|
if (rawAlarm !== void 0) return this[RunSymbol](rawAlarm);
|
|
1231
1231
|
}
|
|
1232
1232
|
webSocketMessage(socket, message) {
|
|
1233
|
-
if (options.webSocketMessage !== void 0) return this[RunSymbol](options.webSocketMessage(socket, message));
|
|
1233
|
+
if (options.webSocketMessage !== void 0) return this[RunSymbol](options.webSocketMessage(fromWebSocket(socket), message));
|
|
1234
1234
|
}
|
|
1235
1235
|
webSocketClose(socket, code, reason, wasClean) {
|
|
1236
|
-
if (options.webSocketClose !== void 0) return this[RunSymbol](options.webSocketClose(socket, code, reason, wasClean));
|
|
1236
|
+
if (options.webSocketClose !== void 0) return this[RunSymbol](options.webSocketClose(fromWebSocket(socket), code, reason, wasClean));
|
|
1237
1237
|
}
|
|
1238
1238
|
webSocketError(socket, error) {
|
|
1239
|
-
if (options.webSocketError !== void 0) return this[RunSymbol](options.webSocketError(socket, error));
|
|
1239
|
+
if (options.webSocketError !== void 0) return this[RunSymbol](options.webSocketError(fromWebSocket(socket), error));
|
|
1240
1240
|
}
|
|
1241
1241
|
}
|
|
1242
1242
|
defineEntrypointRpcMethods("Durable Object", EffectDurableObject.prototype, options.rpc, reservedMethodNames, (self, effect) => self[RunSymbol](effect));
|
package/package.json
CHANGED
package/src/DurableObject.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { Effect, Layer, ManagedRuntime, type Scope } from "effect";
|
|
|
4
4
|
import { NativeRequest } from "./Worker";
|
|
5
5
|
import { WorkerEnvironment, type WorkerEnv } from "./Environment";
|
|
6
6
|
import { DurableObjectState, fromDurableObjectState } from "./DurableObjectState";
|
|
7
|
+
import { fromWebSocket, type DurableWebSocket } from "./DurableObjectWebSocket";
|
|
7
8
|
import * as DurableObjectDefinition from "./DurableObjectDefinition";
|
|
8
9
|
import * as Entrypoint from "./internal/Entrypoint";
|
|
9
10
|
|
|
@@ -84,17 +85,17 @@ export interface DurableObjectOptions<ROut, Rpc extends DurableObjectRpc<ROut>>
|
|
|
84
85
|
alarmInfo?: globalThis.AlarmInvocationInfo,
|
|
85
86
|
) => Effect.Effect<void, unknown, HandlerContext<ROut>>;
|
|
86
87
|
readonly webSocketMessage?: (
|
|
87
|
-
socket:
|
|
88
|
+
socket: DurableWebSocket,
|
|
88
89
|
message: string | ArrayBuffer,
|
|
89
90
|
) => Effect.Effect<void, unknown, HandlerContext<ROut>>;
|
|
90
91
|
readonly webSocketClose?: (
|
|
91
|
-
socket:
|
|
92
|
+
socket: DurableWebSocket,
|
|
92
93
|
code: number,
|
|
93
94
|
reason: string,
|
|
94
95
|
wasClean: boolean,
|
|
95
96
|
) => Effect.Effect<void, unknown, HandlerContext<ROut>>;
|
|
96
97
|
readonly webSocketError?: (
|
|
97
|
-
socket:
|
|
98
|
+
socket: DurableWebSocket,
|
|
98
99
|
error: unknown,
|
|
99
100
|
) => Effect.Effect<void, unknown, HandlerContext<ROut>>;
|
|
100
101
|
}
|
|
@@ -172,7 +173,7 @@ export const make = <
|
|
|
172
173
|
|
|
173
174
|
webSocketMessage(socket: WebSocket, message: string | ArrayBuffer): Promise<void> | void {
|
|
174
175
|
if (options.webSocketMessage !== undefined) {
|
|
175
|
-
return this[RunSymbol](options.webSocketMessage(socket, message));
|
|
176
|
+
return this[RunSymbol](options.webSocketMessage(fromWebSocket(socket), message));
|
|
176
177
|
}
|
|
177
178
|
}
|
|
178
179
|
|
|
@@ -183,13 +184,15 @@ export const make = <
|
|
|
183
184
|
wasClean: boolean,
|
|
184
185
|
): Promise<void> | void {
|
|
185
186
|
if (options.webSocketClose !== undefined) {
|
|
186
|
-
return this[RunSymbol](
|
|
187
|
+
return this[RunSymbol](
|
|
188
|
+
options.webSocketClose(fromWebSocket(socket), code, reason, wasClean),
|
|
189
|
+
);
|
|
187
190
|
}
|
|
188
191
|
}
|
|
189
192
|
|
|
190
193
|
webSocketError(socket: WebSocket, error: unknown): Promise<void> | void {
|
|
191
194
|
if (options.webSocketError !== undefined) {
|
|
192
|
-
return this[RunSymbol](options.webSocketError(socket, error));
|
|
195
|
+
return this[RunSymbol](options.webSocketError(fromWebSocket(socket), error));
|
|
193
196
|
}
|
|
194
197
|
}
|
|
195
198
|
}
|
|
@@ -251,21 +251,9 @@ export interface DurableWebSocketHandlers<R = never, E = unknown> {
|
|
|
251
251
|
readonly error?: (socket: DurableWebSocket, error: unknown) => Effect.Effect<void, E, R>;
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
-
/**
|
|
254
|
+
/** Maps compact websocket lifecycle handler names to `DurableObject.make` options. */
|
|
255
255
|
export const handlers = <R = never, E = unknown>(options: DurableWebSocketHandlers<R, E>) => ({
|
|
256
|
-
webSocketMessage:
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
: (socket: WebSocket, message: string | ArrayBuffer) =>
|
|
260
|
-
options.message?.(fromWebSocket(socket), message) ?? Effect.void,
|
|
261
|
-
webSocketClose:
|
|
262
|
-
options.close === undefined
|
|
263
|
-
? undefined
|
|
264
|
-
: (socket: WebSocket, code: number, reason: string, wasClean: boolean) =>
|
|
265
|
-
options.close?.(fromWebSocket(socket), code, reason, wasClean) ?? Effect.void,
|
|
266
|
-
webSocketError:
|
|
267
|
-
options.error === undefined
|
|
268
|
-
? undefined
|
|
269
|
-
: (socket: WebSocket, error: unknown) =>
|
|
270
|
-
options.error?.(fromWebSocket(socket), error) ?? Effect.void,
|
|
256
|
+
webSocketMessage: options.message,
|
|
257
|
+
webSocketClose: options.close,
|
|
258
|
+
webSocketError: options.error,
|
|
271
259
|
});
|