liminal 0.17.10 → 0.17.11

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.
Files changed (178) hide show
  1. package/Ai.ts +7 -0
  2. package/Assets.ts +21 -0
  3. package/Binding.ts +40 -0
  4. package/CHANGELOG.md +8 -1
  5. package/D1.ts +8 -0
  6. package/DoState.ts +3 -0
  7. package/Hyperdrive.ts +11 -0
  8. package/Images.ts +101 -0
  9. package/Kv.ts +65 -0
  10. package/NativeRequest.ts +3 -0
  11. package/R2.ts +7 -0
  12. package/Worker.ts +54 -0
  13. package/WorkerLoader.ts +29 -0
  14. package/{Actor.ts → actor/Actor.ts} +2 -2
  15. package/actor/ActorRegistry.ts +361 -0
  16. package/{Audition.ts → actor/Audition.ts} +1 -1
  17. package/{Client.ts → actor/Client.ts} +2 -2
  18. package/{ClientDirectory.ts → actor/ClientDirectory.ts} +3 -3
  19. package/actor/index.ts +11 -0
  20. package/asset_forwarding.ts +13 -0
  21. package/commands/sync-env.ts +30 -0
  22. package/dist/Ai.d.ts +6 -0
  23. package/dist/Ai.js +6 -0
  24. package/dist/Ai.js.map +1 -0
  25. package/dist/Assets.d.ts +11 -0
  26. package/dist/Assets.js +14 -0
  27. package/dist/Assets.js.map +1 -0
  28. package/dist/Binding.d.ts +2 -0
  29. package/dist/Binding.js +19 -0
  30. package/dist/Binding.js.map +1 -0
  31. package/dist/D1.d.ts +7 -0
  32. package/dist/D1.js +7 -0
  33. package/dist/D1.js.map +1 -0
  34. package/dist/DoState.d.ts +5 -0
  35. package/dist/DoState.js +4 -0
  36. package/dist/DoState.js.map +1 -0
  37. package/dist/Hyperdrive.d.ts +7 -0
  38. package/dist/Hyperdrive.js +7 -0
  39. package/dist/Hyperdrive.js.map +1 -0
  40. package/dist/Images.d.ts +39 -0
  41. package/dist/Images.js +60 -0
  42. package/dist/Images.js.map +1 -0
  43. package/dist/Kv.d.ts +17 -0
  44. package/dist/Kv.js +32 -0
  45. package/dist/Kv.js.map +1 -0
  46. package/dist/NativeRequest.d.ts +5 -0
  47. package/dist/NativeRequest.js +4 -0
  48. package/dist/NativeRequest.js.map +1 -0
  49. package/dist/R2.d.ts +6 -0
  50. package/dist/R2.js +6 -0
  51. package/dist/R2.js.map +1 -0
  52. package/dist/Worker.d.ts +14 -0
  53. package/dist/Worker.js +25 -0
  54. package/dist/Worker.js.map +1 -0
  55. package/dist/WorkerLoader.d.ts +9 -0
  56. package/dist/WorkerLoader.js +22 -0
  57. package/dist/WorkerLoader.js.map +1 -0
  58. package/dist/{Actor.d.ts → actor/Actor.d.ts} +1 -1
  59. package/dist/{Actor.js → actor/Actor.js} +1 -1
  60. package/dist/actor/Actor.js.map +1 -0
  61. package/dist/actor/ActorRegistry.d.ts +23 -0
  62. package/dist/actor/ActorRegistry.js +153 -0
  63. package/dist/actor/ActorRegistry.js.map +1 -0
  64. package/dist/actor/ActorTransport.js.map +1 -0
  65. package/dist/{Audition.js → actor/Audition.js} +1 -1
  66. package/dist/actor/Audition.js.map +1 -0
  67. package/dist/{Client.js → actor/Client.js} +2 -2
  68. package/dist/actor/Client.js.map +1 -0
  69. package/dist/{ClientDirectory.d.ts → actor/ClientDirectory.d.ts} +1 -1
  70. package/dist/{ClientDirectory.js → actor/ClientDirectory.js} +2 -2
  71. package/dist/actor/ClientDirectory.js.map +1 -0
  72. package/dist/actor/ClientHandle.js.map +1 -0
  73. package/dist/actor/F.js.map +1 -0
  74. package/dist/actor/Method.js.map +1 -0
  75. package/dist/actor/Protocol.js.map +1 -0
  76. package/dist/actor/errors.js.map +1 -0
  77. package/dist/actor/index.d.ts +11 -0
  78. package/dist/actor/index.js +12 -0
  79. package/dist/actor/index.js.map +1 -0
  80. package/dist/asset_forwarding.d.ts +4 -0
  81. package/dist/asset_forwarding.js +9 -0
  82. package/dist/asset_forwarding.js.map +1 -0
  83. package/dist/commands/sync-env.d.ts +8 -0
  84. package/dist/commands/sync-env.js +32 -0
  85. package/dist/commands/sync-env.js.map +1 -0
  86. package/dist/index.d.ts +12 -11
  87. package/dist/index.js +12 -11
  88. package/dist/index.js.map +1 -1
  89. package/dist/main.d.ts +2 -0
  90. package/dist/main.js +10 -0
  91. package/dist/main.js.map +1 -0
  92. package/dist/package.json +51 -0
  93. package/dist/platform/KeyValueStore.d.ts +6 -0
  94. package/dist/platform/KeyValueStore.js +96 -0
  95. package/dist/platform/KeyValueStore.js.map +1 -0
  96. package/dist/platform/index.d.ts +1 -0
  97. package/dist/platform/index.js +2 -0
  98. package/dist/platform/index.js.map +1 -0
  99. package/dist/socket_util.d.ts +4 -0
  100. package/dist/socket_util.js +18 -0
  101. package/dist/socket_util.js.map +1 -0
  102. package/dist/tsconfig.tsbuildinfo +1 -1
  103. package/dist/{Accumulator.js → util/Accumulator.js} +1 -1
  104. package/dist/util/Accumulator.js.map +1 -0
  105. package/dist/util/Diagnostic.js.map +1 -0
  106. package/dist/util/Mutex.js.map +1 -0
  107. package/dist/util/boundLayer.js.map +1 -0
  108. package/dist/util/logCause.js.map +1 -0
  109. package/dist/util/phantom.js.map +1 -0
  110. package/dist/util/schema.js.map +1 -0
  111. package/index.ts +12 -11
  112. package/main.ts +19 -0
  113. package/package.json +23 -2
  114. package/platform/KeyValueStore.ts +112 -0
  115. package/platform/index.ts +1 -0
  116. package/socket_util.ts +20 -0
  117. package/tsconfig.json +3 -2
  118. package/{Accumulator.ts → util/Accumulator.ts} +1 -1
  119. package/_constants.ts +0 -1
  120. package/dist/Accumulator.js.map +0 -1
  121. package/dist/Actor.js.map +0 -1
  122. package/dist/ActorTransport.js.map +0 -1
  123. package/dist/Audition.js.map +0 -1
  124. package/dist/Client.js.map +0 -1
  125. package/dist/ClientDirectory.js.map +0 -1
  126. package/dist/ClientHandle.js.map +0 -1
  127. package/dist/F.js.map +0 -1
  128. package/dist/Method.js.map +0 -1
  129. package/dist/Protocol.js.map +0 -1
  130. package/dist/_constants.d.ts +0 -1
  131. package/dist/_constants.js +0 -2
  132. package/dist/_constants.js.map +0 -1
  133. package/dist/_util/Diagnostic.js.map +0 -1
  134. package/dist/_util/Mutex.js.map +0 -1
  135. package/dist/_util/boundLayer.js.map +0 -1
  136. package/dist/_util/logCause.js.map +0 -1
  137. package/dist/_util/phantom.js.map +0 -1
  138. package/dist/_util/schema.js.map +0 -1
  139. package/dist/errors.js.map +0 -1
  140. /package/{ActorTransport.ts → actor/ActorTransport.ts} +0 -0
  141. /package/{ClientHandle.ts → actor/ClientHandle.ts} +0 -0
  142. /package/{F.ts → actor/F.ts} +0 -0
  143. /package/{Method.ts → actor/Method.ts} +0 -0
  144. /package/{Protocol.ts → actor/Protocol.ts} +0 -0
  145. /package/{errors.ts → actor/errors.ts} +0 -0
  146. /package/dist/{ActorTransport.d.ts → actor/ActorTransport.d.ts} +0 -0
  147. /package/dist/{ActorTransport.js → actor/ActorTransport.js} +0 -0
  148. /package/dist/{Audition.d.ts → actor/Audition.d.ts} +0 -0
  149. /package/dist/{Client.d.ts → actor/Client.d.ts} +0 -0
  150. /package/dist/{ClientHandle.d.ts → actor/ClientHandle.d.ts} +0 -0
  151. /package/dist/{ClientHandle.js → actor/ClientHandle.js} +0 -0
  152. /package/dist/{F.d.ts → actor/F.d.ts} +0 -0
  153. /package/dist/{F.js → actor/F.js} +0 -0
  154. /package/dist/{Method.d.ts → actor/Method.d.ts} +0 -0
  155. /package/dist/{Method.js → actor/Method.js} +0 -0
  156. /package/dist/{Protocol.d.ts → actor/Protocol.d.ts} +0 -0
  157. /package/dist/{Protocol.js → actor/Protocol.js} +0 -0
  158. /package/dist/{errors.d.ts → actor/errors.d.ts} +0 -0
  159. /package/dist/{errors.js → actor/errors.js} +0 -0
  160. /package/dist/{Accumulator.d.ts → util/Accumulator.d.ts} +0 -0
  161. /package/dist/{_util → util}/Diagnostic.d.ts +0 -0
  162. /package/dist/{_util → util}/Diagnostic.js +0 -0
  163. /package/dist/{_util → util}/Mutex.d.ts +0 -0
  164. /package/dist/{_util → util}/Mutex.js +0 -0
  165. /package/dist/{_util → util}/boundLayer.d.ts +0 -0
  166. /package/dist/{_util → util}/boundLayer.js +0 -0
  167. /package/dist/{_util → util}/logCause.d.ts +0 -0
  168. /package/dist/{_util → util}/logCause.js +0 -0
  169. /package/dist/{_util → util}/phantom.d.ts +0 -0
  170. /package/dist/{_util → util}/phantom.js +0 -0
  171. /package/dist/{_util → util}/schema.d.ts +0 -0
  172. /package/dist/{_util → util}/schema.js +0 -0
  173. /package/{_util → util}/Diagnostic.ts +0 -0
  174. /package/{_util → util}/Mutex.ts +0 -0
  175. /package/{_util → util}/boundLayer.ts +0 -0
  176. /package/{_util → util}/logCause.ts +0 -0
  177. /package/{_util → util}/phantom.ts +0 -0
  178. /package/{_util → util}/schema.ts +0 -0
@@ -0,0 +1,361 @@
1
+ import {
2
+ Layer,
3
+ Effect,
4
+ Scope,
5
+ Schema as S,
6
+ Context,
7
+ ManagedRuntime,
8
+ ConfigProvider,
9
+ Duration,
10
+ flow,
11
+ String,
12
+ Array,
13
+ Encoding,
14
+ Option,
15
+ } from "effect"
16
+ import { HttpServerResponse, HttpClient, FetchHttpClient } from "effect/unstable/http"
17
+
18
+ import type { ActorTransport } from "./ActorTransport.ts"
19
+ import type * as Method from "./Method.ts"
20
+ import type { ProtocolDefinition } from "./Protocol.ts"
21
+
22
+ import * as Binding from "../Binding.ts"
23
+ import * as DoState from "../DoState.ts"
24
+ import * as NativeRequest from "../NativeRequest.ts"
25
+ import { SecWebSocketProtocol, close } from "../socket_util.ts"
26
+ import { boundLayer } from "../util/boundLayer.ts"
27
+ import * as Diagnostic from "../util/Diagnostic.ts"
28
+ import { logCause } from "../util/logCause.ts"
29
+ import * as Mutex from "../util/Mutex.ts"
30
+ import { type TopFromString, encodeJsonString, decodeJsonString } from "../util/schema.ts"
31
+ import * as Actor from "./Actor.ts"
32
+ import * as ClientDirectory from "./ClientDirectory.ts"
33
+
34
+ const { debug, span } = Diagnostic.module("cloudflare.ActorRegistry")
35
+
36
+ export interface ActorRegistryDefinition<
37
+ ActorSelf,
38
+ ActorId extends string,
39
+ Name extends TopFromString,
40
+ AttachmentFields extends S.Struct.Fields,
41
+ ClientSelf,
42
+ ClientId extends string,
43
+ D extends ProtocolDefinition,
44
+ PreludeROut,
45
+ PreludeE,
46
+ RunROut,
47
+ RunE,
48
+ > {
49
+ readonly ""?: this["actor"]["definition"]["client"]["protocol"]
50
+
51
+ readonly actor: Actor.Actor<ActorSelf, ActorId, Name, AttachmentFields, ClientSelf, ClientId, D>
52
+
53
+ readonly prelude: Layer.Layer<
54
+ | PreludeROut
55
+ | NonNullable<this[""]>["F"]["Payload"]["DecodingServices"]
56
+ | NonNullable<this[""]>["F"]["Success"]["EncodingServices"]
57
+ | NonNullable<this[""]>["F"]["Failure"]["EncodingServices"]
58
+ | NonNullable<this[""]>["Event"]["EncodingServices"]
59
+ | S.Struct<AttachmentFields>["DecodingServices"]
60
+ | S.Struct<AttachmentFields>["EncodingServices"]
61
+ | Name["EncodingServices"]
62
+ | Name["DecodingServices"],
63
+ PreludeE
64
+ >
65
+
66
+ readonly runLayer: Layer.Layer<RunROut, RunE, ActorSelf | PreludeROut>
67
+
68
+ readonly handlers: Method.Handlers<
69
+ D["methods"],
70
+ ActorSelf | RunROut | HttpClient.HttpClient | PreludeROut | Scope.Scope
71
+ >
72
+
73
+ readonly onConnect: Effect.Effect<
74
+ void,
75
+ never,
76
+ ActorSelf | RunROut | HttpClient.HttpClient | PreludeROut | Scope.Scope
77
+ >
78
+
79
+ readonly hibernation?: Duration.Input | undefined
80
+ }
81
+
82
+ export interface ActorRegistry<
83
+ RegistrySelf,
84
+ RegistryId extends string,
85
+ ActorSelf,
86
+ ActorId extends string,
87
+ Name extends TopFromString,
88
+ AttachmentFields extends S.Struct.Fields,
89
+ ClientSelf,
90
+ ClientId extends string,
91
+ D extends ProtocolDefinition,
92
+ PreludeROut,
93
+ PreludeE,
94
+ RunROut,
95
+ RunE,
96
+ > extends Context.Service<RegistrySelf, DurableObjectNamespace> {
97
+ new (state: globalThis.DurableObjectState<{}>): Context.ServiceClass.Shape<RegistryId, DurableObjectNamespace>
98
+
99
+ readonly definition: ActorRegistryDefinition<
100
+ ActorSelf,
101
+ ActorId,
102
+ Name,
103
+ AttachmentFields,
104
+ ClientSelf,
105
+ ClientId,
106
+ D,
107
+ PreludeROut,
108
+ PreludeE,
109
+ RunROut,
110
+ RunE
111
+ >
112
+
113
+ readonly upgrade: (
114
+ name: Name["Type"],
115
+ attachments: S.Struct<AttachmentFields>["Type"],
116
+ ) => Effect.Effect<HttpServerResponse.HttpServerResponse, S.SchemaError, RegistrySelf | NativeRequest.NativeRequest>
117
+
118
+ readonly layer: (binding: string) => Layer.Layer<RegistrySelf, S.SchemaError, never>
119
+ }
120
+
121
+ export const Service =
122
+ <RegistrySelf>() =>
123
+ <
124
+ RegistryId extends string,
125
+ ActorSelf,
126
+ ActorId extends string,
127
+ Name extends TopFromString,
128
+ AttachmentFields extends S.Struct.Fields,
129
+ ClientSelf,
130
+ ClientId extends string,
131
+ D extends ProtocolDefinition,
132
+ PreludeROut,
133
+ PreludeE,
134
+ RunROut,
135
+ RunE,
136
+ >(
137
+ id: RegistryId,
138
+ definition: ActorRegistryDefinition<
139
+ ActorSelf,
140
+ ActorId,
141
+ Name,
142
+ AttachmentFields,
143
+ ClientSelf,
144
+ ClientId,
145
+ D,
146
+ PreludeROut,
147
+ PreludeE,
148
+ RunROut,
149
+ RunE
150
+ >,
151
+ ): ActorRegistry<
152
+ RegistrySelf,
153
+ RegistryId,
154
+ ActorSelf,
155
+ ActorId,
156
+ Name,
157
+ AttachmentFields,
158
+ ClientSelf,
159
+ ClientId,
160
+ D,
161
+ PreludeROut,
162
+ PreludeE,
163
+ RunROut,
164
+ RunE
165
+ > => {
166
+ const { hibernation, actor, prelude, runLayer, handlers, onConnect } = definition
167
+ const {
168
+ definition: {
169
+ name: Name,
170
+ client: { key: clientId, protocol: P },
171
+ attachments: AttachmentFields,
172
+ },
173
+ } = actor
174
+
175
+ const encodeName = S.encodeEffect(Name)
176
+ const decodeName = S.decodeUnknownEffect(Name)
177
+
178
+ const Attachments = S.Struct(AttachmentFields)
179
+ const encodeAttachments = S.encodeEffect(S.toCodecJson(Attachments))
180
+ const decodeAttachments = S.decodeUnknownEffect(S.toCodecJson(Attachments))
181
+ const encodeAttachmentsString = encodeJsonString(Attachments)
182
+ const decodeAttachmentsString = decodeJsonString(Attachments)
183
+
184
+ const encodeAuditionSuccess = encodeJsonString(P.Audition.Success)
185
+ const encodeAuditionFailure = encodeJsonString(P.Audition.Failure)
186
+ const decodeClientM = decodeJsonString(P.Client)
187
+ const encodeFSuccess = encodeJsonString(P.F.Success)
188
+ const encodeFFailure = encodeJsonString(P.F.Failure)
189
+
190
+ const encodeEvent = encodeJsonString(P.Event)
191
+
192
+ const transport: ActorTransport<WebSocket, AttachmentFields, D> = {
193
+ send: (socket, event) => encodeEvent(event).pipe(Effect.andThen((v) => Effect.sync(() => socket.send(v)))),
194
+ close: (socket) => Effect.sync(() => socket.close(1000)),
195
+ snapshot: (socket, attachments) =>
196
+ encodeAttachments(attachments).pipe(Effect.andThen((v) => Effect.sync(() => socket.serializeAttachment(v)))),
197
+ }
198
+
199
+ const tag = class tag extends Context.Service<RegistrySelf, DurableObjectNamespace>()(id) {
200
+ readonly runtime
201
+ readonly directory = ClientDirectory.make(actor, transport)
202
+
203
+ constructor(...args: [never]) {
204
+ super(...args)
205
+ const [state, env] = args as never as [state: globalThis.DurableObjectState<{}>, env: unknown]
206
+
207
+ if (hibernation) {
208
+ Option.andThen(
209
+ Duration.fromInput(hibernation),
210
+ flow(Duration.toMillis, state.setHibernatableWebSocketEventTimeout),
211
+ )
212
+ }
213
+
214
+ const baseLayer = Layer.mergeAll(
215
+ prelude.pipe(Layer.provideMerge(ConfigProvider.layer(ConfigProvider.fromUnknown(env)))),
216
+ FetchHttpClient.layer,
217
+ Layer.succeed(DoState.DoState, state),
218
+ Mutex.layer,
219
+ )
220
+
221
+ this.runtime = Effect.gen({ self: this }, function* () {
222
+ this.#name = yield* Effect.tryPromise(() => state.storage.get("__liminal_name")).pipe(
223
+ Effect.flatMap((v) => (typeof v === "string" ? decodeName(v) : Effect.succeed(undefined))),
224
+ )
225
+ for (const socket of state.getWebSockets()) {
226
+ const attachments = yield* decodeAttachments(socket.deserializeAttachment())
227
+ yield* this.directory.register(socket, attachments)
228
+ }
229
+ }).pipe(
230
+ Effect.tapCause(logCause),
231
+ span("make_runtime"),
232
+ Layer.effectDiscard,
233
+ Layer.provideMerge(baseLayer),
234
+ boundLayer("actor"),
235
+ ManagedRuntime.make,
236
+ )
237
+ }
238
+
239
+ #name?: Name["Type"] | undefined
240
+ fetch(request: Request): Promise<Response> {
241
+ return Effect.gen({ self: this }, function* () {
242
+ const url = new URL(request.url)
243
+ const name = yield* decodeName(url.searchParams.get("__liminal_name"))
244
+ const attachments = yield* decodeAttachmentsString(url.searchParams.get("__liminal_attachments"))
245
+ if (!this.#name) {
246
+ this.#name = name
247
+ const state = yield* DoState.DoState
248
+ const encoded = yield* S.encodeEffect(Name)(name)
249
+ yield* Effect.promise(() => state.storage.put("__liminal_name", encoded))
250
+ }
251
+ const { 0: webSocket, 1: server } = new WebSocketPair()
252
+ const state = yield* DoState.DoState
253
+ state.acceptWebSocket(server)
254
+ server.send(yield* encodeAuditionSuccess({ _tag: "Audition.Success" }))
255
+ const currentClient = yield* this.directory.register(server, attachments)
256
+ const ActorLive = Layer.succeed(actor, {
257
+ name,
258
+ clients: this.directory.handles,
259
+ currentClient,
260
+ })
261
+ yield* onConnect.pipe(
262
+ Effect.scoped,
263
+ span("onConnect"),
264
+ Effect.provide([ActorLive, runLayer.pipe(Layer.provideMerge(ActorLive))]),
265
+ )
266
+ return new Response(null, {
267
+ status: 101,
268
+ webSocket,
269
+ headers: { [SecWebSocketProtocol]: "liminal" },
270
+ })
271
+ }).pipe(Effect.scoped, Effect.tapCause(logCause), span("fetch"), this.runtime.runPromise)
272
+ }
273
+
274
+ webSocketMessage(socket: WebSocket, raw: string | ArrayBuffer) {
275
+ Effect.gen({ self: this }, function* () {
276
+ const currentClient = yield* this.directory.get(socket)
277
+ const name = yield* Effect.fromNullishOr(this.#name)
278
+ const layer = Layer.succeed(actor, {
279
+ name,
280
+ clients: this.directory.handles,
281
+ currentClient,
282
+ })
283
+ const message = yield* decodeClientM(raw instanceof ArrayBuffer ? new TextDecoder().decode(raw) : raw)
284
+ yield* debug("MessageReceived", { message })
285
+ if (message._tag === "Audition.Payload") {
286
+ return yield* Effect.die(undefined)
287
+ }
288
+ if (message._tag === "Disconnect") {
289
+ return yield* currentClient.disconnect
290
+ }
291
+ const { id, payload } = message
292
+ const { _tag, value } = payload as never
293
+ yield* handlers[_tag]!(value).pipe(
294
+ Effect.provide(runLayer.pipe(Layer.provideMerge(layer))),
295
+ Effect.matchEffect({
296
+ onSuccess: (value) =>
297
+ encodeFSuccess({
298
+ _tag: "F.Success",
299
+ id,
300
+ success: { _tag, value } as never,
301
+ }),
302
+ onFailure: (value) =>
303
+ encodeFFailure({
304
+ _tag: "F.Failure",
305
+ id,
306
+ failure: { _tag, value } as never,
307
+ }),
308
+ }),
309
+ span("handler", { attributes: { _tag } }),
310
+ Effect.andThen((v) => Effect.sync(() => socket.send(v))),
311
+ Effect.scoped,
312
+ )
313
+ }).pipe(Effect.scoped, Mutex.task, Effect.tapCause(logCause), span("webSocketMessage"), this.runtime.runFork)
314
+ }
315
+
316
+ webSocketClose(socket: WebSocket, _code: number, _reason: string, _wasClean: boolean) {
317
+ this.directory
318
+ .unregister(socket)
319
+ .pipe(Effect.tap(debug("SocketClosed")), Effect.tapCause(logCause), this.runtime.runFork)
320
+ }
321
+
322
+ webSocketError(socket: WebSocket, cause: unknown) {
323
+ Effect.gen({ self: this }, function* () {
324
+ yield* debug("SocketErrored", { cause })
325
+ yield* this.directory.unregister(socket)
326
+ }).pipe(Effect.tapCause(logCause), span("SocketErrored", { attributes: { cause } }), this.runtime.runFork)
327
+ }
328
+ }
329
+
330
+ const upgrade = Effect.fnUntraced(function* (name: Name["Type"], attachments: (typeof Attachments)["Type"]) {
331
+ yield* debug("UpgradeInitiated", { attachments })
332
+ const namespace = yield* tag
333
+ const nameEncoded = yield* encodeName(name)
334
+ const stub = namespace.getByName(nameEncoded)
335
+ const request = yield* NativeRequest.NativeRequest
336
+ const protocols = yield* Effect.fromNullishOr(request.headers.get(SecWebSocketProtocol)).pipe(
337
+ Effect.map(flow(String.split(","), Array.map(String.trim))),
338
+ )
339
+ const liminalTokenI = yield* Array.findFirstIndex(protocols, (v) => v === "liminal")
340
+ const requestClientId = yield* Effect.fromNullishOr(protocols[liminalTokenI + 1]).pipe(
341
+ Effect.flatMap((v) => Encoding.decodeBase64UrlString(v).asEffect()),
342
+ )
343
+ if (requestClientId !== clientId) {
344
+ return close(
345
+ yield* encodeAuditionFailure({
346
+ _tag: "Audition.Failure",
347
+ expected: clientId,
348
+ actual: requestClientId,
349
+ }),
350
+ )
351
+ }
352
+ const url = new URL(request.url)
353
+ url.searchParams.set("__liminal_name", nameEncoded)
354
+ url.searchParams.set("__liminal_attachments", yield* encodeAttachmentsString(attachments))
355
+ return yield* Effect.promise(() => stub.fetch(new Request(url, request))).pipe(Effect.map(HttpServerResponse.raw))
356
+ }, span("upgrade"))
357
+
358
+ const layer = Binding.layer(tag, ["getByName"])
359
+
360
+ return Object.assign(tag, { definition, upgrade, layer }) as never
361
+ }
@@ -3,7 +3,7 @@ import { Schema as S, Pipeable, Stream, Effect, Function } from "effect"
3
3
  import type { F } from "./F.ts"
4
4
  import type { ProtocolDefinition } from "./Protocol.ts"
5
5
 
6
- import * as Diagnostic from "./_util/Diagnostic.ts"
6
+ import * as Diagnostic from "../util/Diagnostic.ts"
7
7
  import * as Client from "./Client.ts"
8
8
  import { type ClientError, AuditionError } from "./errors.ts"
9
9
 
@@ -25,8 +25,8 @@ import {
25
25
  import { Socket } from "effect/unstable/socket"
26
26
  import { Worker } from "effect/unstable/workers"
27
27
 
28
- import * as Diagnostic from "./_util/Diagnostic.ts"
29
- import { decodeJsonString, encodeJsonString } from "./_util/schema.ts"
28
+ import * as Diagnostic from "../util/Diagnostic.ts"
29
+ import { decodeJsonString, encodeJsonString } from "../util/schema.ts"
30
30
  import { type ClientError, AuditionError, ConnectionError, type FError, UnresolvedError } from "./errors.ts"
31
31
  import { type F } from "./F.ts"
32
32
  import { Protocol, type ProtocolDefinition } from "./Protocol.ts"
@@ -1,12 +1,12 @@
1
1
  import { Schema as S, Effect, Cause, Ref } from "effect"
2
2
 
3
- import type { TopFromString } from "./_util/schema.ts"
3
+ import type { TopFromString } from "../util/schema.ts"
4
4
  import type { Actor } from "./Actor.ts"
5
5
  import type { ActorTransport } from "./ActorTransport.ts"
6
6
  import type { ProtocolDefinition, Disconnect, Protocol } from "./Protocol.ts"
7
7
 
8
- import * as Diagnostic from "./_util/Diagnostic.ts"
9
- import { phantom } from "./_util/phantom.ts"
8
+ import * as Diagnostic from "../util/Diagnostic.ts"
9
+ import { phantom } from "../util/phantom.ts"
10
10
  import * as ClientHandle from "./ClientHandle.ts"
11
11
 
12
12
  const { span } = Diagnostic.module("ClientDirectory")
package/actor/index.ts ADDED
@@ -0,0 +1,11 @@
1
+ export * as Actor from "./Actor.ts"
2
+ export * as ActorRegistry from "./ActorRegistry.ts"
3
+ export * as Audition from "./Audition.ts"
4
+ export * as Client from "./Client.ts"
5
+ export * as ClientDirectory from "./ClientDirectory.ts"
6
+ export * as ClientHandle from "./ClientHandle.ts"
7
+ export * as Method from "./Method.ts"
8
+ export * as Protocol from "./Protocol.ts"
9
+ export * from "./ActorTransport.ts"
10
+ export * from "./F.ts"
11
+ export * from "./errors.ts"
@@ -0,0 +1,13 @@
1
+ import { Effect, Layer } from "effect"
2
+ import { HttpServerResponse } from "effect/unstable/http"
3
+
4
+ import * as Assets from "./Assets.ts"
5
+ import * as Worker from "./Worker.ts"
6
+
7
+ export default Worker.make({
8
+ handler: Assets.forward.pipe(
9
+ Effect.provide(Assets.layer("ASSETS")),
10
+ Effect.catch(() => Effect.succeed(HttpServerResponse.empty({ status: 500 }))),
11
+ ),
12
+ prelude: Layer.empty,
13
+ })
@@ -0,0 +1,30 @@
1
+ import { Config, Effect, Path, Redacted } from "effect"
2
+ import { Argument, Command } from "effect/unstable/cli"
3
+ import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"
4
+
5
+ export const syncEnv = Command.make("sync-env", {
6
+ worker: Argument.directory("worker", { mustExist: true }),
7
+ configFile: Argument.file("config-file", { mustExist: true }),
8
+ configExport: Argument.string("config-export").pipe(Argument.withDefault("config")),
9
+ }).pipe(
10
+ Command.withHandler(
11
+ Effect.fn(function* ({ worker, configFile, configExport }) {
12
+ const path = yield* Path.Path
13
+ const spawner = yield* ChildProcessSpawner.ChildProcessSpawner
14
+ const url = yield* path.toFileUrl(path.resolve(configFile))
15
+ const module = yield* Effect.tryPromise(() => import(url.href))
16
+ const config = module[configExport] as Config.Config<Record<string, Redacted.Redacted<string>>>
17
+ const env = yield* config
18
+ for (const [name, value] of Object.entries(env)) {
19
+ yield* spawner.spawn(
20
+ ChildProcess.make({
21
+ stdout: "inherit",
22
+ stderr: "inherit",
23
+ cwd: worker,
24
+ })`pnpm wrangler secret put ${name} ${Redacted.value(value)}`,
25
+ )
26
+ yield* Effect.log(`Synced ${name} to ${worker}.`)
27
+ }
28
+ }),
29
+ ),
30
+ )
package/dist/Ai.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { Context } from "effect";
2
+ declare const Ai_base: Context.ServiceClass<Ai, "liminal/Ai", globalThis.Ai<AiModels>>;
3
+ export declare class Ai extends Ai_base {
4
+ }
5
+ export declare const layer: (binding: string) => import("effect/Layer").Layer<Ai, import("effect/Schema").SchemaError, never>;
6
+ export {};
package/dist/Ai.js ADDED
@@ -0,0 +1,6 @@
1
+ import { Context } from "effect";
2
+ import * as Binding from "./Binding.js";
3
+ export class Ai extends Context.Service()("liminal/Ai") {
4
+ }
5
+ export const layer = Binding.layer(Ai, ["run"]);
6
+ //# sourceMappingURL=Ai.js.map
package/dist/Ai.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Ai.js","sourceRoot":"","sources":["../Ai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAEhC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC,MAAM,OAAO,EAAG,SAAQ,OAAO,CAAC,OAAO,EAAqB,CAAC,YAAY,CAAC;CAAG;AAE7E,MAAM,CAAC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA"}
@@ -0,0 +1,11 @@
1
+ import { Effect, Context } from "effect";
2
+ import { HttpServerResponse } from "effect/unstable/http";
3
+ import { NativeRequest } from "./NativeRequest.ts";
4
+ declare const Assets_base: Context.ServiceClass<Assets, "liminal/Assets", {
5
+ readonly fetch: typeof fetch;
6
+ }>;
7
+ export declare class Assets extends Assets_base {
8
+ }
9
+ export declare const layer: (binding: string) => import("effect/Layer").Layer<Assets, import("effect/Schema").SchemaError, never>;
10
+ export declare const forward: Effect.Effect<HttpServerResponse.HttpServerResponse, never, Assets | NativeRequest>;
11
+ export {};
package/dist/Assets.js ADDED
@@ -0,0 +1,14 @@
1
+ import { Effect, Context } from "effect";
2
+ import { HttpServerResponse } from "effect/unstable/http";
3
+ import * as Binding from "./Binding.js";
4
+ import { NativeRequest } from "./NativeRequest.js";
5
+ export class Assets extends Context.Service()("liminal/Assets") {
6
+ }
7
+ export const layer = Binding.layer(Assets, ["fetch"]);
8
+ export const forward = Effect.gen({ self: this }, function* () {
9
+ const assets = yield* Assets;
10
+ const request = yield* NativeRequest;
11
+ const response = yield* Effect.promise(() => assets.fetch(request));
12
+ return HttpServerResponse.fromWeb(response);
13
+ });
14
+ //# sourceMappingURL=Assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Assets.js","sourceRoot":"","sources":["../Assets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAEzD,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAElD,MAAM,OAAO,MAAO,SAAQ,OAAO,CAAC,OAAO,EAKxC,CAAC,gBAAgB,CAAC;CAAG;AAExB,MAAM,CAAC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,CAAA;AAErD,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC;IACzD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAA;IAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,aAAa,CAAA;IACpC,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA;IACnE,OAAO,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;AAC7C,CAAC,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ import { Context, Layer, Schema as S } from "effect";
2
+ export declare const layer: <Self, Identifier extends string, Shape, ROut = never, E = never, RIn = never>(tag: Context.ServiceClass<Self, Identifier, Shape>, keys: ReadonlyArray<string>, derive?: (resource: Shape) => Layer.Layer<ROut, E, RIn> | undefined) => (binding: string) => Layer.Layer<ROut | Self, E | S.SchemaError, RIn>;
@@ -0,0 +1,19 @@
1
+ import { env } from "cloudflare:workers";
2
+ import { Context, Layer, Effect, Schema as S, SchemaIssue } from "effect";
3
+ export const layer = (tag, keys, derive) => (binding) => Effect.gen(function* () {
4
+ const resolved = env[binding];
5
+ if (!resolved) {
6
+ return yield* Effect.fail(new S.SchemaError(new SchemaIssue.Pointer([binding], new SchemaIssue.MissingKey({
7
+ messageMissingKey: `Missing binding "${binding}" on env`,
8
+ }))));
9
+ }
10
+ for (const key of keys) {
11
+ if (!(key in resolved)) {
12
+ return yield* Effect.fail(new S.SchemaError(new SchemaIssue.Pointer([key], new SchemaIssue.MissingKey({
13
+ messageMissingKey: `Expected key \`${key}\` on binding \`${binding}\``,
14
+ }))));
15
+ }
16
+ }
17
+ return Layer.mergeAll(Layer.succeed(tag, resolved), derive?.(resolved) ?? Layer.empty);
18
+ }).pipe(Layer.unwrap);
19
+ //# sourceMappingURL=Binding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Binding.js","sourceRoot":"","sources":["../Binding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAA;AACxC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAEzE,MAAM,CAAC,MAAM,KAAK,GAChB,CACE,GAAkD,EAClD,IAA2B,EAC3B,MAAmE,EACnE,EAAE,CACJ,CAAC,OAAe,EAAE,EAAE,CAClB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,QAAQ,GAAI,GAAa,CAAC,OAAO,CAAC,CAAA;IACxC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACvB,IAAI,CAAC,CAAC,WAAW,CACf,IAAI,WAAW,CAAC,OAAO,CACrB,CAAC,OAAO,CAAC,EACT,IAAI,WAAW,CAAC,UAAU,CAAC;YACzB,iBAAiB,EAAE,oBAAoB,OAAO,UAAU;SACzD,CAAC,CACH,CACF,CACF,CAAA;IACH,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC,CAAC,GAAG,IAAI,QAAQ,CAAC,EAAE,CAAC;YACvB,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACvB,IAAI,CAAC,CAAC,WAAW,CACf,IAAI,WAAW,CAAC,OAAO,CACrB,CAAC,GAAG,CAAC,EACL,IAAI,WAAW,CAAC,UAAU,CAAC;gBACzB,iBAAiB,EAAE,kBAAkB,GAAG,mBAAmB,OAAO,IAAI;aACvE,CAAC,CACH,CACF,CACF,CAAA;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAA;AACxF,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA"}
package/dist/D1.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { D1Client } from "@effect/sql-d1";
2
+ import { Context } from "effect";
3
+ declare const D1_base: Context.ServiceClass<D1, "liminal/D1", D1Database>;
4
+ export declare class D1 extends D1_base {
5
+ }
6
+ export declare const layer: (binding: string) => import("effect/Layer").Layer<D1 | D1Client.D1Client | import("effect/unstable/sql/SqlClient").SqlClient, import("effect/Config").ConfigError | import("effect/Schema").SchemaError, never>;
7
+ export {};
package/dist/D1.js ADDED
@@ -0,0 +1,7 @@
1
+ import { D1Client } from "@effect/sql-d1";
2
+ import { Context } from "effect";
3
+ import * as Binding from "./Binding.js";
4
+ export class D1 extends Context.Service()("liminal/D1") {
5
+ }
6
+ export const layer = Binding.layer(D1, ["exec"], (db) => D1Client.layer({ db }));
7
+ //# sourceMappingURL=D1.js.map
package/dist/D1.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"D1.js","sourceRoot":"","sources":["../D1.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAEhC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC,MAAM,OAAO,EAAG,SAAQ,OAAO,CAAC,OAAO,EAAkB,CAAC,YAAY,CAAC;CAAG;AAE1E,MAAM,CAAC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA"}
@@ -0,0 +1,5 @@
1
+ import { Context } from "effect";
2
+ declare const DoState_base: Context.ServiceClass<DoState, "liminal/DoState", DurableObjectState<{}>>;
3
+ export declare class DoState extends DoState_base {
4
+ }
5
+ export {};
@@ -0,0 +1,4 @@
1
+ import { Context } from "effect";
2
+ export class DoState extends Context.Service()("liminal/DoState") {
3
+ }
4
+ //# sourceMappingURL=DoState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DoState.js","sourceRoot":"","sources":["../DoState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAEhC,MAAM,OAAO,OAAQ,SAAQ,OAAO,CAAC,OAAO,EAA8C,CAAC,iBAAiB,CAAC;CAAG"}
@@ -0,0 +1,7 @@
1
+ import { Effect, Redacted, Context } from "effect";
2
+ declare const Hyperdrive_base: Context.ServiceClass<Hyperdrive, "liminal/Hyperdrive", globalThis.Hyperdrive>;
3
+ export declare class Hyperdrive extends Hyperdrive_base {
4
+ }
5
+ export declare const layer: (binding: string) => import("effect/Layer").Layer<Hyperdrive, import("effect/Schema").SchemaError, never>;
6
+ export declare const connectionString: Effect.Effect<Redacted.Redacted<string>, never, Hyperdrive>;
7
+ export {};
@@ -0,0 +1,7 @@
1
+ import { Effect, Redacted, Context } from "effect";
2
+ import * as Binding from "./Binding.js";
3
+ export class Hyperdrive extends Context.Service()("liminal/Hyperdrive") {
4
+ }
5
+ export const layer = Binding.layer(Hyperdrive, ["connectionString"]);
6
+ export const connectionString = Hyperdrive.asEffect().pipe(Effect.map(({ connectionString }) => Redacted.make(connectionString)));
7
+ //# sourceMappingURL=Hyperdrive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Hyperdrive.js","sourceRoot":"","sources":["../Hyperdrive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAElD,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC,MAAM,OAAO,UAAW,SAAQ,OAAO,CAAC,OAAO,EAAqC,CAAC,oBAAoB,CAAC;CAAG;AAE7G,MAAM,CAAC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAA;AAEpE,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,IAAI,CACxD,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CACtE,CAAA"}
@@ -0,0 +1,39 @@
1
+ import { Data, Context, Pipeable, Effect } from "effect";
2
+ declare const Images_base: Context.ServiceClass<Images, "liminal/ImageTransformer", ImagesBinding>;
3
+ export declare class Images extends Images_base {
4
+ }
5
+ export declare const layer: (binding: string) => import("effect/Layer").Layer<Images, import("effect/Schema").SchemaError, never>;
6
+ declare const TypeId: "~liminal/Images/Transformation";
7
+ export interface Steps extends Pipeable.Pipeable {
8
+ readonly [TypeId]: typeof TypeId;
9
+ readonly steps: ReadonlyArray<Step>;
10
+ }
11
+ export interface DrawOptions {
12
+ image: ReadableStream<Uint8Array> | ImageTransformer;
13
+ options?: ImageDrawOptions | undefined;
14
+ }
15
+ export type Step = Data.TaggedEnum<{
16
+ Transform: {
17
+ transform: ImageTransform;
18
+ };
19
+ Draw: DrawOptions;
20
+ }>;
21
+ export declare const empty: Steps;
22
+ export declare const transform: {
23
+ (transform: ImageTransform): (steps: Steps) => Steps;
24
+ (steps: Steps, transform: ImageTransform): Steps;
25
+ };
26
+ export declare const draw: {
27
+ (draw: DrawOptions): (steps: Steps) => Steps;
28
+ (steps: Steps, draw: DrawOptions): Steps;
29
+ };
30
+ export interface ProcessConfig {
31
+ readonly stream: ReadableStream<Uint8Array>;
32
+ readonly inputOptions?: ImageInputOptions | undefined;
33
+ readonly outputOptions: ImageOutputOptions;
34
+ }
35
+ export declare const process: {
36
+ (config: ProcessConfig): (steps: Steps) => Effect.Effect<ImageTransformationResult, never, Images>;
37
+ (steps: Steps, config: ProcessConfig): Effect.Effect<ImageTransformationResult, never, Images>;
38
+ };
39
+ export {};