@livestore/sync-cf 0.3.2-dev.8 → 0.4.0-dev.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.
@@ -4,37 +4,40 @@ import type { Schema } from '@livestore/utils/effect'
4
4
  import { Effect, UrlParams } from '@livestore/utils/effect'
5
5
 
6
6
  import { SearchParamsSchema } from '../common/mod.ts'
7
+
7
8
  import type { Env } from './durable-object.ts'
8
9
 
9
- // Redeclaring Response to Cloudflare Worker Response type to avoid lib.dom type clashing
10
- declare const Response: typeof CfWorker.Response
10
+ // NOTE We need to redeclare runtime types here to avoid type conflicts with the lib.dom Response type.
11
+ declare class Response extends CfWorker.Response {}
11
12
 
12
- /**
13
- * Helper type to extract DurableObject keys from Env to give consumer type safety.
14
- *
15
- * @example
16
- * ```ts
17
- * type PlatformEnv = {
18
- * DB: D1Database
19
- * ADMIN_TOKEN: string
20
- * WEBSOCKET_SERVER: DurableObjectNamespace<WebSocketServer>
21
- * }
22
- * export default makeWorker<PlatformEnv>({
23
- * durableObject: { name: "WEBSOCKET_SERVER" },
24
- * // ^ (property) name?: "WEBSOCKET_SERVER" | undefined
25
- * });
26
- */
27
- type ExtractDurableObjectKeys<TEnv = Env> = TEnv extends Env
28
- ? [keyof TEnv] extends [keyof Env]
13
+ export namespace HelperTypes {
14
+ type AnyDON = CfWorker.DurableObjectNamespace<undefined>
15
+
16
+ type DOKeys<T> = {
17
+ [K in keyof T]-?: T[K] extends AnyDON ? K : never
18
+ }[keyof T]
19
+
20
+ type NonBuiltins<T> = Omit<T, keyof Env>
21
+
22
+ /**
23
+ * Helper type to extract DurableObject keys from Env to give consumer type safety.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * type PlatformEnv = {
28
+ * DB: D1Database
29
+ * ADMIN_TOKEN: string
30
+ * WEBSOCKET_SERVER: DurableObjectNamespace<WebSocketServer>
31
+ * }
32
+ * export default makeWorker<PlatformEnv>({
33
+ * durableObject: { name: "WEBSOCKET_SERVER" },
34
+ * // ^ (property) name?: "WEBSOCKET_SERVER" | undefined
35
+ * });
36
+ */
37
+ export type ExtractDurableObjectKeys<TEnv = Env> = DOKeys<NonBuiltins<TEnv>> extends never
29
38
  ? string
30
- : keyof {
31
- [K in keyof TEnv as K extends keyof Env
32
- ? never
33
- : TEnv[K] extends CfWorker.DurableObjectNamespace<any>
34
- ? K
35
- : never]: TEnv[K]
36
- }
37
- : never
39
+ : DOKeys<NonBuiltins<TEnv>>
40
+ }
38
41
 
39
42
  // HINT: If we ever extend user's custom worker RPC, type T can help here with expected return type safety. Currently unused.
40
43
  export type CFWorker<TEnv extends Env = Env, _T extends CfWorker.Rpc.DurableObjectBranded | undefined = undefined> = {
@@ -60,7 +63,7 @@ export type MakeWorkerOptions<TEnv extends Env = Env> = {
60
63
  *
61
64
  * @default 'WEBSOCKET_SERVER'
62
65
  */
63
- name?: ExtractDurableObjectKeys<TEnv>
66
+ name?: HelperTypes.ExtractDurableObjectKeys<TEnv>
64
67
  }
65
68
  }
66
69
 
@@ -138,7 +141,8 @@ export const makeWorker = <
138
141
  * return handleWebSocket(request, env, ctx, { headers: {}, validatePayload })
139
142
  * }
140
143
  *
141
- * return new Response('Invalid path', { status: 400, headers: corsHeaders })
144
+ * return new Response('Invalid path', { status: 400 })
145
+ * return new Response('Invalid path', { status: 400 })
142
146
  * }
143
147
  * }
144
148
  * ```
@@ -157,7 +161,7 @@ export const handleWebSocket = <
157
161
  headers?: CfWorker.HeadersInit
158
162
  durableObject?: MakeWorkerOptions<TEnv>['durableObject']
159
163
  validatePayload?: (payload: Schema.JsonValue | undefined, context: { storeId: string }) => void | Promise<void>
160
- },
164
+ } = {},
161
165
  ): Promise<CfWorker.Response> =>
162
166
  Effect.gen(function* () {
163
167
  const url = new URL(request.url)
@@ -188,10 +192,13 @@ export const handleWebSocket = <
188
192
 
189
193
  const durableObjectName = options.durableObject?.name ?? 'WEBSOCKET_SERVER'
190
194
  if (!(durableObjectName in env)) {
191
- return new Response(`Failed dependency: Required Durable Object binding '${durableObjectName}' not available`, {
192
- status: 424,
193
- headers: options.headers,
194
- })
195
+ return new Response(
196
+ `Failed dependency: Required Durable Object binding '${durableObjectName as string}' not available`,
197
+ {
198
+ status: 424,
199
+ headers: options.headers,
200
+ },
201
+ )
195
202
  }
196
203
 
197
204
  const durableObjectNamespace = env[
@@ -210,5 +217,5 @@ export const handleWebSocket = <
210
217
  }
211
218
 
212
219
  // Cloudflare Durable Object type clashing with lib.dom Response type, which is why we need the casts here.
213
- return yield* Effect.promise(() => durableObject.fetch(request as any) as unknown as Promise<CfWorker.Response>)
220
+ return yield* Effect.promise(() => durableObject.fetch(request))
214
221
  }).pipe(Effect.tapCauseLogPretty, Effect.runPromise)