liminal 0.17.15 → 0.17.17

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 (81) hide show
  1. package/Actor.ts +22 -33
  2. package/{workerd/ActorHandle.ts → ActorHandle.ts} +7 -2
  3. package/{workerd/WorkerdActorNamespace.ts → ActorNamespace.ts} +46 -32
  4. package/{workerd/WorkerdActorRuntime.ts → ActorRuntime.ts} +71 -44
  5. package/ActorTransport.ts +2 -2
  6. package/Audition.ts +1 -1
  7. package/BrowserActorNamespace.ts +257 -0
  8. package/CHANGELOG.md +28 -0
  9. package/Client.ts +127 -76
  10. package/ClientDirectory.ts +40 -32
  11. package/ClientHandle.ts +9 -7
  12. package/Fn.ts +39 -0
  13. package/Tracing.ts +11 -3
  14. package/dist/Actor.d.ts +3 -5
  15. package/dist/Actor.js +5 -9
  16. package/dist/Actor.js.map +1 -1
  17. package/dist/{workerd/ActorHandle.d.ts → ActorHandle.d.ts} +6 -3
  18. package/dist/ActorHandle.js.map +1 -0
  19. package/dist/{workerd/WorkerdActorNamespace.d.ts → ActorNamespace.d.ts} +12 -10
  20. package/dist/{workerd/WorkerdActorNamespace.js → ActorNamespace.js} +16 -10
  21. package/dist/ActorNamespace.js.map +1 -0
  22. package/dist/{workerd/WorkerdActorRuntime.d.ts → ActorRuntime.d.ts} +10 -9
  23. package/dist/{workerd/WorkerdActorRuntime.js → ActorRuntime.js} +40 -34
  24. package/dist/ActorRuntime.js.map +1 -0
  25. package/dist/ActorTransport.d.ts +2 -2
  26. package/dist/Audition.js +1 -1
  27. package/dist/Audition.js.map +1 -1
  28. package/dist/BrowserActorNamespace.d.ts +39 -0
  29. package/dist/BrowserActorNamespace.js +134 -0
  30. package/dist/BrowserActorNamespace.js.map +1 -0
  31. package/dist/Client.d.ts +7 -4
  32. package/dist/Client.js +78 -48
  33. package/dist/Client.js.map +1 -1
  34. package/dist/ClientDirectory.d.ts +1 -1
  35. package/dist/ClientDirectory.js +11 -5
  36. package/dist/ClientDirectory.js.map +1 -1
  37. package/dist/ClientHandle.d.ts +5 -4
  38. package/dist/Fn.d.ts +8 -0
  39. package/dist/Tracing.js +6 -2
  40. package/dist/Tracing.js.map +1 -1
  41. package/dist/experimental/L/append.js +1 -1
  42. package/dist/experimental/L/append.js.map +1 -1
  43. package/dist/experimental/L/history.js +1 -1
  44. package/dist/experimental/L/history.js.map +1 -1
  45. package/dist/index.common.d.ts +12 -0
  46. package/dist/index.common.js +13 -0
  47. package/dist/index.common.js.map +1 -0
  48. package/dist/index.d.ts +4 -11
  49. package/dist/index.js +4 -11
  50. package/dist/index.js.map +1 -1
  51. package/dist/index.non-workerd.d.ts +1 -0
  52. package/dist/index.non-workerd.js +2 -0
  53. package/dist/index.non-workerd.js.map +1 -0
  54. package/dist/package.json +13 -7
  55. package/dist/tsconfig.tsbuildinfo +1 -1
  56. package/experimental/L/append.ts +1 -1
  57. package/experimental/L/history.ts +1 -1
  58. package/index.common.ts +12 -0
  59. package/index.non-workerd.ts +1 -0
  60. package/index.ts +4 -11
  61. package/package.json +12 -9
  62. package/_util/schema.ts +0 -7
  63. package/browser/BrowserActorNamespace.ts +0 -248
  64. package/browser/index.ts +0 -1
  65. package/dist/_util/schema.d.ts +0 -4
  66. package/dist/_util/schema.js +0 -5
  67. package/dist/_util/schema.js.map +0 -1
  68. package/dist/browser/BrowserActorNamespace.d.ts +0 -16
  69. package/dist/browser/BrowserActorNamespace.js +0 -133
  70. package/dist/browser/BrowserActorNamespace.js.map +0 -1
  71. package/dist/browser/index.d.ts +0 -1
  72. package/dist/browser/index.js +0 -2
  73. package/dist/browser/index.js.map +0 -1
  74. package/dist/workerd/ActorHandle.js.map +0 -1
  75. package/dist/workerd/WorkerdActorNamespace.js.map +0 -1
  76. package/dist/workerd/WorkerdActorRuntime.js.map +0 -1
  77. package/dist/workerd/index.d.ts +0 -3
  78. package/dist/workerd/index.js +0 -4
  79. package/dist/workerd/index.js.map +0 -1
  80. package/workerd/index.ts +0 -3
  81. /package/dist/{workerd/ActorHandle.js → ActorHandle.js} +0 -0
@@ -1,15 +1,13 @@
1
1
  import { Schema as S, Effect, Cause, Ref } from "effect"
2
- import * as Spanner from "liminal-util/Spanner"
2
+ import * as Boundary from "liminal-util/Boundary"
3
+ import type { TopFromString } from "liminal-util/schema"
3
4
 
4
5
  import { phantom } from "./_util/phantom.ts"
5
- import type { TopFromString } from "./_util/schema.ts"
6
6
  import type { Actor } from "./Actor.ts"
7
7
  import type { ActorTransport } from "./ActorTransport.ts"
8
8
  import * as ClientHandle from "./ClientHandle.ts"
9
9
  import type { ProtocolDefinition, Disconnect, Protocol } from "./Protocol.ts"
10
10
 
11
- const span = Spanner.make(import.meta.url)
12
-
13
11
  export interface ClientEntry<Client, Handle> {
14
12
  readonly client: Client
15
13
 
@@ -86,33 +84,43 @@ export const make = <
86
84
  entries.delete(key)
87
85
  handles.delete(current.handle)
88
86
  }
89
- }).pipe(span("unregister"))
90
-
91
- const register = Effect.fnUntraced(function* (client: Client, attachments: S.Struct<AttachmentFields>["Type"]) {
92
- const clientKey = key(client)
93
- yield* snapshot(client, attachments)
94
- const attachmentsRef = yield* Ref.make(attachments)
95
- const handle: Handle = {
96
- attachments: Ref.get(attachmentsRef),
97
- save: Effect.fnUntraced(function* (attachments) {
98
- yield* Ref.set(attachmentsRef, attachments)
99
- yield* snapshot(client, attachments)
100
- }),
101
- send: (_tag, payload) =>
102
- send(client, {
103
- _tag: "Event",
104
- event: { _tag, ...payload } as never,
87
+ }).pipe(Boundary.span("unregister", import.meta.url))
88
+
89
+ const register = Effect.fnUntraced(
90
+ function* (client: Client, attachments: S.Struct<AttachmentFields>["Type"]) {
91
+ const clientKey = key(client)
92
+ yield* snapshot(client, attachments)
93
+ const attachmentsRef = yield* Ref.make(attachments)
94
+ const handle: Handle = {
95
+ attachments: Ref.get(attachmentsRef),
96
+ save: Effect.fnUntraced(function* (attachments) {
97
+ yield* Ref.set(attachmentsRef, attachments)
98
+ yield* snapshot(client, attachments)
105
99
  }),
106
- disconnect: close(client).pipe(Effect.andThen(unregister(clientKey)), Effect.asVoid),
107
- }
108
- const previous = entries.get(clientKey)
109
- if (previous) {
110
- handles.delete(previous.handle)
111
- }
112
- entries.set(clientKey, { client, handle })
113
- handles.add(handle)
114
- return handle
115
- }, span("register"))
116
-
117
- return { ...phantom, handles, register, get, entry, unregister }
100
+ send: (_tag, payload) =>
101
+ send(client, {
102
+ _tag: "Event",
103
+ event: { _tag, ...payload } as never,
104
+ }),
105
+ disconnect: close(client).pipe(Effect.andThen(unregister(clientKey)), Effect.asVoid),
106
+ }
107
+ const previous = entries.get(clientKey)
108
+ if (previous) {
109
+ handles.delete(previous.handle)
110
+ }
111
+ entries.set(clientKey, { client, handle })
112
+ handles.add(handle)
113
+ return handle
114
+ },
115
+ Boundary.span("register", import.meta.url),
116
+ )
117
+
118
+ return {
119
+ ...phantom,
120
+ handles,
121
+ register,
122
+ get,
123
+ entry,
124
+ unregister,
125
+ }
118
126
  }
package/ClientHandle.ts CHANGED
@@ -2,20 +2,22 @@ import { Schema as S, Effect } from "effect"
2
2
 
3
3
  import type { ProtocolDefinition } from "./Protocol.ts"
4
4
 
5
- export interface Sender<ActorSelf, D extends ProtocolDefinition> {
6
- readonly send: <K extends keyof D["events"]>(
7
- tag: K,
8
- payload: S.Struct<D["events"][K]>["Type"],
9
- ) => Effect.Effect<void, S.SchemaError, ActorSelf | ReturnType<typeof S.TaggedUnion<D["events"]>>["EncodingServices"]>
5
+ export type Send<D extends ProtocolDefinition, RIn> = <K extends keyof D["events"]>(
6
+ tag: K,
7
+ payload: S.Struct<D["events"][K]>["Type"],
8
+ ) => Effect.Effect<void, never, RIn | ReturnType<typeof S.TaggedUnion<D["events"]>>["EncodingServices"]>
10
9
 
11
- readonly disconnect: Effect.Effect<void, never, ActorSelf>
10
+ export interface Sender<D extends ProtocolDefinition, R> {
11
+ readonly send: Send<D, R>
12
+
13
+ readonly disconnect: Effect.Effect<void, never, R>
12
14
  }
13
15
 
14
16
  export interface ClientHandle<
15
17
  ActorSelf,
16
18
  AttachmentFields extends S.Struct.Fields,
17
19
  D extends ProtocolDefinition,
18
- > extends Sender<ActorSelf, D> {
20
+ > extends Sender<D, ActorSelf> {
19
21
  readonly attachments: Effect.Effect<S.Struct<AttachmentFields>["Type"]>
20
22
 
21
23
  readonly save: (
package/Fn.ts CHANGED
@@ -53,3 +53,42 @@ export interface Fn<Self, Internal extends Methods> {
53
53
  e: (value: D, payload: FnPayload<Internal, K>) => E,
54
54
  ): (payload: FnPayload<Internal, K>) => E
55
55
  }
56
+
57
+ export interface FnNoSelf<Internal extends Methods> {
58
+ <K extends keyof Internal>(tag: K): (payload: FnPayload<Internal, K>) => FnEffect<never, Internal, K>
59
+
60
+ <K extends keyof Internal, A>(
61
+ tag: K,
62
+ a: (effect: FnEffect<never, Internal, K>, payload: FnPayload<Internal, K>) => A,
63
+ ): (payload: FnPayload<Internal, K>) => A
64
+
65
+ <K extends keyof Internal, A, B>(
66
+ tag: K,
67
+ a: (effect: FnEffect<never, Internal, K>, payload: FnPayload<Internal, K>) => A,
68
+ b: (value: A, payload: FnPayload<Internal, K>) => B,
69
+ ): (payload: FnPayload<Internal, K>) => B
70
+
71
+ <K extends keyof Internal, A, B, C>(
72
+ tag: K,
73
+ a: (effect: FnEffect<never, Internal, K>, payload: FnPayload<Internal, K>) => A,
74
+ b: (value: A, payload: FnPayload<Internal, K>) => B,
75
+ c: (value: B, payload: FnPayload<Internal, K>) => C,
76
+ ): (payload: FnPayload<Internal, K>) => C
77
+
78
+ <K extends keyof Internal, A, B, C, D>(
79
+ tag: K,
80
+ a: (effect: FnEffect<never, Internal, K>, payload: FnPayload<Internal, K>) => A,
81
+ b: (value: A, payload: FnPayload<Internal, K>) => B,
82
+ c: (value: B, payload: FnPayload<Internal, K>) => C,
83
+ d: (value: C, payload: FnPayload<Internal, K>) => D,
84
+ ): (payload: FnPayload<Internal, K>) => D
85
+
86
+ <K extends keyof Internal, A, B, C, D, E>(
87
+ tag: K,
88
+ a: (effect: FnEffect<never, Internal, K>, payload: FnPayload<Internal, K>) => A,
89
+ b: (value: A, payload: FnPayload<Internal, K>) => B,
90
+ c: (value: B, payload: FnPayload<Internal, K>) => C,
91
+ d: (value: C, payload: FnPayload<Internal, K>) => D,
92
+ e: (value: D, payload: FnPayload<Internal, K>) => E,
93
+ ): (payload: FnPayload<Internal, K>) => E
94
+ }
package/Tracing.ts CHANGED
@@ -19,9 +19,17 @@ export const Session = S.Struct({
19
19
  trace: TraceEnvelope,
20
20
  })
21
21
 
22
- export const parent = Effect.currentParentSpan.pipe(Effect.catchTag("NoSuchElementError", () => Effect.undefined))
23
-
24
- export const current = Effect.currentSpan.pipe(Effect.catchTag("NoSuchElementError", () => Effect.undefined))
22
+ export const parent = Effect.currentParentSpan.pipe(
23
+ Effect.catchTags({
24
+ NoSuchElementError: () => Effect.undefined,
25
+ }),
26
+ )
27
+
28
+ export const current = Effect.currentSpan.pipe(
29
+ Effect.catchTags({
30
+ NoSuchElementError: () => Effect.undefined,
31
+ }),
32
+ )
25
33
 
26
34
  export const currentTrace = current.pipe(Effect.map((span) => (span ? toTraceEnvelope(span) : undefined)))
27
35
 
package/dist/Actor.d.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  import { Context, Schema as S } from "effect";
2
- import type { TopFromString } from "./_util/schema.ts";
2
+ import type { TopFromString } from "liminal-util/schema";
3
3
  import type * as ActorClient from "./Client.ts";
4
4
  import type { ClientHandle, Sender } from "./ClientHandle.ts";
5
- import * as Method from "./Method.ts";
6
5
  import { type ProtocolDefinition } from "./Protocol.ts";
7
6
  export declare const TypeId: "~liminal/Actor";
8
7
  export interface Service<ActorSelf, Name extends TopFromString, AttachmentFields extends S.Struct.Fields, D extends ProtocolDefinition> {
@@ -19,8 +18,7 @@ export interface Actor<ActorSelf, ActorId extends string, Name extends TopFromSt
19
18
  new (_: never): Context.ServiceClass.Shape<ActorId, Service<ActorSelf, Name, AttachmentFields, D>>;
20
19
  readonly [TypeId]: typeof TypeId;
21
20
  readonly definition: ActorDefinition<Name, AttachmentFields, ActorClientSelf, ActorClientId, D>;
22
- readonly all: Sender<ActorSelf, D>;
23
- readonly others: Sender<ActorSelf, D>;
24
- readonly handler: <K extends keyof D["external"], R>(tag: K, f: Method.Handler<D["external"][K], R>) => Method.Handler<D["external"][K], R>;
21
+ readonly all: Sender<D, ActorSelf>;
22
+ readonly others: Sender<D, ActorSelf>;
25
23
  }
26
24
  export declare const Service: <ActorSelf>() => <ActorId extends string, Name extends TopFromString, D extends ProtocolDefinition, AttachmentFields extends S.Struct.Fields, ClientSelf, ClientId extends string>(id: ActorId, definition: ActorDefinition<Name, AttachmentFields, ClientSelf, ClientId, D>) => Actor<ActorSelf, ActorId, Name, AttachmentFields, ClientSelf, ClientId, D>;
package/dist/Actor.js CHANGED
@@ -1,32 +1,28 @@
1
1
  import { Context, Schema as S, Effect } from "effect";
2
- import * as Spanner from "liminal-util/Spanner";
3
- import * as Method from "./Method.js";
2
+ import * as Boundary from "liminal-util/Boundary";
4
3
  import {} from "./Protocol.js";
5
- const span = Spanner.make(import.meta.url);
6
4
  export const TypeId = "~liminal/Actor";
7
5
  export const Service = () => (id, definition) => {
8
6
  const tag = Context.Service()(id);
9
7
  const all = {
10
- send: (key, payload) => tag.asEffect().pipe(Effect.flatMap(({ clients }) => Effect.forEach(clients, (client) => client.send(key, payload), { concurrency: "unbounded" })), span("send-all")),
11
- disconnect: tag.asEffect().pipe(Effect.flatMap(({ clients }) => Effect.forEach(clients, ({ disconnect }) => disconnect)), span("disconnect-all")),
8
+ send: (key, payload) => tag.pipe(Effect.flatMap(({ clients }) => Effect.forEach(clients, (client) => client.send(key, payload), { concurrency: "unbounded" })), Boundary.span("send-all", import.meta.url)),
9
+ disconnect: tag.pipe(Effect.flatMap(({ clients }) => Effect.forEach(clients, ({ disconnect }) => disconnect)), Boundary.span("disconnect-all", import.meta.url)),
12
10
  };
13
11
  const others = {
14
12
  send: Effect.fnUntraced(function* (key, payload) {
15
13
  const { clients, currentClient } = yield* tag;
16
14
  yield* Effect.forEach(clients, (client) => (client === currentClient ? Effect.void : client.send(key, payload)), { concurrency: "unbounded" });
17
- }, span("send-others")),
15
+ }, Boundary.span("send-others", import.meta.url)),
18
16
  disconnect: Effect.gen(function* () {
19
17
  const { clients, currentClient } = yield* tag;
20
18
  yield* Effect.forEach(clients, (client) => (client === currentClient ? Effect.void : client.disconnect));
21
- }).pipe(span("disconnect-others")),
19
+ }).pipe(Boundary.span("disconnect-others", import.meta.url)),
22
20
  };
23
- const handler = (_tag, f) => f;
24
21
  return Object.assign(tag, {
25
22
  [TypeId]: TypeId,
26
23
  definition,
27
24
  all,
28
25
  others,
29
- handler,
30
26
  });
31
27
  };
32
28
  //# sourceMappingURL=Actor.js.map
package/dist/Actor.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Actor.js","sourceRoot":"","sources":["../Actor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACrD,OAAO,KAAK,OAAO,MAAM,sBAAsB,CAAA;AAK/C,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,EAA2B,MAAM,eAAe,CAAA;AAEvD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAE1C,MAAM,CAAC,MAAM,MAAM,GAAG,gBAAyB,CAAA;AAsD/C,MAAM,CAAC,MAAM,OAAO,GAClB,GAAc,EAAE,CAChB,CAQE,EAAW,EACX,UAA4E,EACA,EAAE;IAC9E,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,EAA4D,CAAC,EAAE,CAAC,CAAA;IAE3F,MAAM,GAAG,GAAyB;QAChC,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,CACrB,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,CACjB,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAC7B,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAC7F,EACD,IAAI,CAAC,UAAU,CAAC,CACjB;QACH,UAAU,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,CAC7B,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EACxF,IAAI,CAAC,gBAAgB,CAAC,CACvB;KACF,CAAA;IAED,MAAM,MAAM,GAAyB;QACnC,IAAI,EAAE,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,GAAG,EAAE,OAAO;YAC7C,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,CAAA;YAC7C,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CACnB,OAAO,EACP,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,EAChF,EAAE,WAAW,EAAE,WAAW,EAAE,CAC7B,CAAA;QACH,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QACvB,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC9B,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,CAAA;YAC7C,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAA;QAC1G,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;KACnC,CAAA;IAED,MAAM,OAAO,GAAG,CACd,IAAO,EACP,CAAsC,EACD,EAAE,CAAC,CAAC,CAAA;IAE3C,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE;QACxB,CAAC,MAAM,CAAC,EAAE,MAAM;QAChB,UAAU;QACV,GAAG;QACH,MAAM;QACN,OAAO;KACR,CAAC,CAAA;AACJ,CAAC,CAAA"}
1
+ {"version":3,"file":"Actor.js","sourceRoot":"","sources":["../Actor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACrD,OAAO,KAAK,QAAQ,MAAM,uBAAuB,CAAA;AAKjD,OAAO,EAA2B,MAAM,eAAe,CAAA;AAEvD,MAAM,CAAC,MAAM,MAAM,GAAG,gBAAyB,CAAA;AAiD/C,MAAM,CAAC,MAAM,OAAO,GAClB,GAAc,EAAE,CAChB,CAQE,EAAW,EACX,UAA4E,EACA,EAAE;IAC9E,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,EAA4D,CAAC,EAAE,CAAC,CAAA;IAE3F,MAAM,GAAG,GAAyB;QAChC,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,CACrB,GAAG,CAAC,IAAI,CACN,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAC7B,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAC7F,EACD,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAC3C;QACH,UAAU,EAAE,GAAG,CAAC,IAAI,CAClB,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EACxF,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CACjD;KACF,CAAA;IAED,MAAM,MAAM,GAAyB;QACnC,IAAI,EAAE,MAAM,CAAC,UAAU,CACrB,QAAQ,CAAC,EAAE,GAAG,EAAE,OAAO;YACrB,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,CAAA;YAC7C,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CACnB,OAAO,EACP,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,EAChF,EAAE,WAAW,EAAE,WAAW,EAAE,CAC7B,CAAA;QACH,CAAC,EACD,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAC9C;QACD,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC9B,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,CAAA;YAC7C,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAA;QAC1G,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;KAC7D,CAAA;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE;QACxB,CAAC,MAAM,CAAC,EAAE,MAAM;QAChB,UAAU;QACV,GAAG;QACH,MAAM;KACP,CAAC,CAAA;AACJ,CAAC,CAAA"}
@@ -1,9 +1,12 @@
1
1
  import { Schema as S, Effect, Cause, Encoding } from "effect";
2
2
  import { NativeRequest } from "effect-workerd";
3
3
  import { HttpServerResponse } from "effect/unstable/http";
4
- import type { TopFromString } from "../_util/schema.ts";
5
- import type { Methods } from "../Method.ts";
6
- export interface ActorHandle<NamespaceSelf, Internal extends Methods, Name extends TopFromString, AttachmentFields extends S.Struct.Fields> {
4
+ import type { TopFromString } from "liminal-util/schema";
5
+ import type { Send } from "./ClientHandle.ts";
6
+ import type { Methods } from "./Method.ts";
7
+ import type { ProtocolDefinition } from "./Protocol.ts";
8
+ export interface ActorHandle<NamespaceSelf, Internal extends Methods, Name extends TopFromString, AttachmentFields extends S.Struct.Fields, D extends ProtocolDefinition> {
7
9
  readonly upgrade: (attachments: S.Struct<AttachmentFields>["Type"]) => Effect.Effect<HttpServerResponse.HttpServerResponse, S.SchemaError | Encoding.EncodingError | Cause.NoSuchElementError, NamespaceSelf | NativeRequest.NativeRequest | Name["EncodingServices"] | S.Struct<AttachmentFields>["EncodingServices"]>;
8
10
  readonly call: <K extends keyof Internal, M extends Internal[K]>(method: K, payload: M["payload"]["Type"]) => Effect.Effect<M["success"]["Type"], M["failure"]["Type"], NamespaceSelf>;
11
+ readonly proxySendAll: Send<D, NamespaceSelf>;
9
12
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActorHandle.js","sourceRoot":"","sources":["../ActorHandle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA"}
@@ -1,23 +1,25 @@
1
1
  import { Layer, Schema as S, Context, Exit } from "effect";
2
- import { type TopFromString } from "../_util/schema.ts";
3
- import type { Actor } from "../Actor.ts";
4
- import type { Methods } from "../Method.ts";
5
- import type { ProtocolDefinition } from "../Protocol.ts";
2
+ import { Env } from "effect-workerd";
3
+ import { type TopFromString } from "liminal-util/schema";
4
+ import type { Actor } from "./Actor.ts";
6
5
  import type { ActorHandle } from "./ActorHandle.ts";
6
+ import type { Methods } from "./Method.ts";
7
+ import type { ProtocolDefinition } from "./Protocol.ts";
7
8
  export interface ActorNamespaceDefinition<Internal extends Methods, ActorSelf, ActorId extends string, Name extends TopFromString, AttachmentFields extends S.Struct.Fields, ClientSelf, ClientId extends string, D extends ProtocolDefinition> {
8
9
  readonly binding: string;
9
10
  readonly internal: Internal;
10
11
  readonly actor: Actor<ActorSelf, ActorId, Name, AttachmentFields, ClientSelf, ClientId, D>;
11
12
  }
12
13
  export interface ActorNamespace<NamespaceSelf, NamespaceId extends string, Internal extends Methods, ActorSelf, ActorId extends string, Name extends TopFromString, AttachmentFields extends S.Struct.Fields, ClientSelf, ClientId extends string, D extends ProtocolDefinition> {
13
- new (_: never): Context.ServiceClass.Shape<NamespaceId, DurableObjectNamespace<Rpc.DurableObjectBranded & WorkerdActorNamespace.MakeRpc<Internal>>>;
14
+ new (_: never): Context.ServiceClass.Shape<NamespaceId, DurableObjectNamespace<Rpc.DurableObjectBranded & ActorNamespace.MakeRpc<Internal, D>>>;
14
15
  readonly definition: ActorNamespaceDefinition<Methods, ActorSelf, ActorId, Name, AttachmentFields, ClientSelf, ClientId, D>;
15
- readonly bind: (name: Name["Type"]) => ActorHandle<NamespaceSelf, Internal, Name, AttachmentFields>;
16
- readonly layer: Layer.Layer<NamespaceSelf, S.SchemaError, never>;
16
+ readonly bind: (name: Name["Type"]) => ActorHandle<NamespaceSelf, Internal, Name, AttachmentFields, D>;
17
+ readonly layer: Layer.Layer<NamespaceSelf, S.SchemaError, Env>;
17
18
  }
18
- export declare namespace WorkerdActorNamespace {
19
- type MakeRpc<External extends Methods> = {
20
- rpc: <K extends keyof External>(method: K, payload: External[K]["payload"]["Type"]) => Promise<Exit.Exit<External[K]["success"]["Type"], External[K]["failure"]["Type"]>>;
19
+ export declare namespace ActorNamespace {
20
+ type MakeRpc<Internal extends Methods, D extends ProtocolDefinition> = {
21
+ rpc: <K extends keyof Internal>(method: K, payload: Internal[K]["payload"]["Type"]) => Promise<Exit.Exit<Internal[K]["success"]["Type"], Internal[K]["failure"]["Type"]>>;
22
+ proxySendAll<K extends keyof D["events"]>(event: K, payload: S.Struct<D["events"][K]>["Type"]): void;
21
23
  };
22
24
  }
23
25
  export declare const Service: <NamespaceSelf>() => <NamespaceId extends string, Internal extends Methods, ActorSelf, ActorId extends string, Name extends TopFromString, AttachmentFields extends S.Struct.Fields, ClientSelf, ClientId extends string, D extends ProtocolDefinition>(id: NamespaceId, definition: ActorNamespaceDefinition<Internal, ActorSelf, ActorId, Name, AttachmentFields, ClientSelf, ClientId, D>) => ActorNamespace<NamespaceSelf, NamespaceId, Internal, ActorSelf, ActorId, Name, AttachmentFields, ClientSelf, ClientId, D>;
@@ -1,10 +1,9 @@
1
1
  import { Layer, Effect, Schema as S, Context, flow, String, Array, Encoding, Exit } from "effect";
2
- import { Binding, NativeRequest } from "effect-workerd";
2
+ import { Binding, Env, NativeRequest } from "effect-workerd";
3
3
  import { SecWebSocketProtocol, close } from "effect-workerd/socket_util";
4
4
  import { HttpServerResponse, HttpTraceContext } from "effect/unstable/http";
5
- import * as Spanner from "liminal-util/Spanner";
6
- import { encodeJsonString } from "../_util/schema.js";
7
- const span = Spanner.make(import.meta.url);
5
+ import * as Boundary from "liminal-util/Boundary";
6
+ import { encodeJsonString } from "liminal-util/schema";
8
7
  export const Service = () => (id, definition) => {
9
8
  const { binding, actor } = definition;
10
9
  const { definition: { name: Name, client: { key: clientId, protocol: P }, attachments: AttachmentFields, }, } = actor;
@@ -22,8 +21,9 @@ export const Service = () => (id, definition) => {
22
21
  const upgrade = (attachments) => Effect.gen({ self: this }, function* () {
23
22
  const request = yield* NativeRequest.NativeRequest;
24
23
  const protocols = yield* Effect.fromNullishOr(request.headers.get(SecWebSocketProtocol)).pipe(Effect.map(flow(String.split(","), Array.map(String.trim))));
25
- const liminalTokenI = yield* Array.findFirstIndex(protocols, (v) => v === "liminal");
26
- const requestClientId = yield* Effect.fromNullishOr(protocols[liminalTokenI + 1]).pipe(Effect.flatMap((v) => Encoding.decodeBase64UrlString(v).asEffect()));
24
+ const liminalTokenI = yield* Array.findFirstIndex(protocols, (v) => v === "liminal").pipe(Effect.fromOption);
25
+ const liminalClientId = yield* Effect.fromNullishOr(protocols[liminalTokenI + 1]);
26
+ const requestClientId = yield* Effect.fromNullishOr(protocols[liminalTokenI + 2]).pipe(Effect.flatMap((v) => Encoding.decodeBase64UrlString(v).pipe(Effect.fromResult)));
27
27
  if (requestClientId !== clientId) {
28
28
  return close(yield* encodeAuditionFailure({
29
29
  _tag: "Audition.Failure",
@@ -33,6 +33,7 @@ export const Service = () => (id, definition) => {
33
33
  }
34
34
  const url = new URL(request.url);
35
35
  url.searchParams.set("__liminal_attachments", yield* encodeAttachmentsString(attachments));
36
+ url.searchParams.set("__liminal_client_id", liminalClientId);
36
37
  const actorRequest = new Request(url, request);
37
38
  const traceHeaders = yield* Effect.currentSpan.pipe(Effect.map(HttpTraceContext.toHeaders));
38
39
  for (const [key, value] of Object.entries(traceHeaders)) {
@@ -40,15 +41,20 @@ export const Service = () => (id, definition) => {
40
41
  }
41
42
  const stub = yield* getStub;
42
43
  return yield* Effect.promise(() => stub.fetch(actorRequest)).pipe(Effect.map(HttpServerResponse.raw));
43
- }).pipe(span("upgrade", { kind: "client" }));
44
+ }).pipe(Boundary.span("upgrade", import.meta.url, { kind: "client" }));
44
45
  const call = Effect.fnUntraced(function* (method, payload) {
45
46
  const stub = yield* getStub;
46
47
  const exit = yield* Effect.promise(() => stub.rpc(method, payload));
47
48
  return yield* exit;
48
- });
49
- return { upgrade, call };
49
+ }, Boundary.span("call", import.meta.url));
50
+ // TODO:
51
+ const proxySendAll = Effect.fnUntraced(function* (event, payload) {
52
+ const stub = yield* getStub;
53
+ yield* Effect.promise(() => stub.proxySendAll(event, payload));
54
+ }, Boundary.span("proxySendAll", import.meta.url));
55
+ return { upgrade, call, proxySendAll };
50
56
  };
51
57
  const layer = Binding.layer(tag, ["idFromName", "idFromString", "newUniqueId", "get", "getByName"])(binding);
52
58
  return Object.assign(tag, { definition, bind, layer });
53
59
  };
54
- //# sourceMappingURL=WorkerdActorNamespace.js.map
60
+ //# sourceMappingURL=ActorNamespace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActorNamespace.js","sourceRoot":"","sources":["../ActorNamespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AACjG,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC5D,OAAO,EAAE,oBAAoB,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AACxE,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAC3E,OAAO,KAAK,QAAQ,MAAM,uBAAuB,CAAA;AACjD,OAAO,EAAsB,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAsE1E,MAAM,CAAC,MAAM,OAAO,GAClB,GAAkB,EAAE,CACpB,CAWE,EAAe,EACf,UAAmH,EAYnH,EAAE;IACF,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,UAAU,CAAA;IACrC,MAAM,EACJ,UAAU,EAAE,EACV,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,EAAE,EACtC,WAAW,EAAE,gBAAgB,GAC9B,GACF,GAAG,KAAK,CAAA;IAET,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,EAGxB,CAAC,EAAE,CAAC,CAAA;IAEP,MAAM,UAAU,GAAG,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAA;IACvC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAA;IAC9C,MAAM,uBAAuB,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAA;IAC7D,MAAM,qBAAqB,GAAG,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IAElE,MAAM,IAAI,GAAG,CAAC,IAAkB,EAAmE,EAAE;QACnG,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClC,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,GAAG,CAAA;YAC5B,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;YAC3C,OAAO,SAAS,CAAC,SAAS,CAAC,WAAW,CAAC,CAAA;QACzC,CAAC,CAAC,CAAA;QAEF,MAAM,OAAO,GAAG,CAAC,WAA+C,EAAE,EAAE,CAClE,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC;YAClC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,aAAa,CAAC,aAAa,CAAA;YAClD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAC3F,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAC5D,CAAA;YACD,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;YAC5G,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAA;YACjF,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CACpF,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CACjF,CAAA;YACD,IAAI,eAAe,KAAK,QAAQ,EAAE,CAAC;gBACjC,OAAO,KAAK,CACV,KAAK,CAAC,CAAC,qBAAqB,CAAC;oBAC3B,IAAI,EAAE,kBAAkB;oBACxB,QAAQ,EAAE,QAAQ;oBAClB,MAAM,EAAE,eAAe;iBACxB,CAAC,CACH,CAAA;YACH,CAAC;YACD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAChC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC,uBAAuB,CAAC,WAAW,CAAC,CAAC,CAAA;YAC1F,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,qBAAqB,EAAE,eAAe,CAAC,CAAA;YAC5D,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;YAC9C,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAA;YAC3F,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;gBACxD,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;YACtC,CAAC;YACD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,OAAO,CAAA;YAC3B,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAA;QACvG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAA;QAExE,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAC5B,QAAQ,CAAC,EACP,MAAS,EACT,OAA6B;YAE7B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,OAAO,CAAA;YAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAe,EAAE,OAAgB,CAAC,CAAC,CAAA;YACrF,OAAO,KAAK,CAAC,CAAC,IAAW,CAAA;QAC3B,CAAC,EACD,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CACvC,CAAA;QAED,QAAQ;QACR,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU,CACpC,QAAQ,CAAC,EAA+B,KAAQ,EAAE,OAAyC;YACzF,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,OAAO,CAAA;YAC3B,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,KAAc,EAAE,OAAgB,CAAC,CAAC,CAAA;QAClF,CAAC,EACD,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CACtC,CAAA;QAEV,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,CAAA;IACxC,CAAC,CAAA;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;IAE5G,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;AACxD,CAAC,CAAA"}
@@ -1,19 +1,20 @@
1
1
  import { DurableObject } from "cloudflare:workers";
2
2
  import { Layer, Effect, Scope, Schema as S, Duration } from "effect";
3
+ import { Env } from "effect-workerd";
3
4
  import { HttpClient } from "effect/unstable/http";
4
- import { type TopFromString } from "../_util/schema.ts";
5
- import type { Handlers, Methods } from "../Method.ts";
6
- import type { ProtocolDefinition } from "../Protocol.ts";
7
- import type { ActorNamespace } from "./WorkerdActorNamespace.ts";
5
+ import { type TopFromString } from "liminal-util/schema";
6
+ import type { ActorNamespace } from "./ActorNamespace.ts";
7
+ import type { Handlers, Methods } from "./Method.ts";
8
+ import type { ProtocolDefinition } from "./Protocol.ts";
8
9
  export interface ActorRuntimeDefinition<NamespaceSelf, NamespaceId extends string, Internal extends Methods, ActorSelf, ActorId extends string, Name extends TopFromString, AttachmentFields extends S.Struct.Fields, ClientSelf, ClientId extends string, D extends ProtocolDefinition, PreludeROut, PreludeE, RunROut, RunE> {
9
10
  readonly ""?: this["namespace"]["definition"]["actor"]["definition"]["client"]["protocol"];
10
11
  readonly namespace: ActorNamespace<NamespaceSelf, NamespaceId, Internal, ActorSelf, ActorId, Name, AttachmentFields, ClientSelf, ClientId, D>;
11
- readonly prelude: Layer.Layer<PreludeROut | NonNullable<this[""]>["F"]["Payload"]["DecodingServices"] | NonNullable<this[""]>["F"]["Success"]["EncodingServices"] | NonNullable<this[""]>["F"]["Failure"]["EncodingServices"] | NonNullable<this[""]>["Event"]["EncodingServices"] | S.Struct<AttachmentFields>["DecodingServices"] | S.Struct<AttachmentFields>["EncodingServices"] | Name["EncodingServices"] | Name["DecodingServices"], PreludeE, HttpClient.HttpClient>;
12
- readonly layer: Layer.Layer<RunROut, RunE, ActorSelf | HttpClient.HttpClient | PreludeROut>;
13
- readonly external: Handlers<D["external"], ActorSelf | HttpClient.HttpClient | PreludeROut | RunROut | Scope.Scope>;
12
+ readonly prelude: Layer.Layer<PreludeROut | NonNullable<this[""]>["F"]["Payload"]["DecodingServices"] | NonNullable<this[""]>["F"]["Success"]["EncodingServices"] | NonNullable<this[""]>["F"]["Failure"]["EncodingServices"] | NonNullable<this[""]>["Event"]["EncodingServices"] | S.Struct<AttachmentFields>["DecodingServices"] | S.Struct<AttachmentFields>["EncodingServices"] | Name["EncodingServices"] | Name["DecodingServices"], PreludeE, HttpClient.HttpClient | Env>;
13
+ readonly layer: Layer.Layer<RunROut, RunE, ActorSelf | HttpClient.HttpClient | Env | PreludeROut>;
14
+ readonly external: Handlers<D["external"], ActorSelf | HttpClient.HttpClient | Env | PreludeROut | RunROut | Scope.Scope>;
14
15
  readonly internal: Handlers<Internal, ActorSelf | HttpClient.HttpClient | PreludeROut | RunROut | Scope.Scope>;
15
- readonly hydrate: Effect.Effect<S.Struct<D["state"]>["Type"], never, ActorSelf | HttpClient.HttpClient | PreludeROut | RunROut | Scope.Scope>;
16
- readonly onDisconnect: Effect.Effect<void, never, ActorSelf | HttpClient.HttpClient | PreludeROut | RunROut | Scope.Scope>;
16
+ readonly hydrate: Effect.Effect<S.Struct<D["state"]>["Type"], never, ActorSelf | HttpClient.HttpClient | Env | PreludeROut | RunROut | Scope.Scope>;
17
+ readonly onDisconnect: Effect.Effect<void, never, ActorSelf | HttpClient.HttpClient | Env | PreludeROut | RunROut | Scope.Scope>;
17
18
  readonly hibernation?: Duration.Input | undefined;
18
19
  }
19
20
  export declare const make: <NamespaceSelf, NamespaceId extends string, Internal extends Methods, ActorSelf, ActorId extends string, Name extends TopFromString, AttachmentFields extends S.Struct.Fields, ClientSelf, ClientId extends string, D extends ProtocolDefinition, PreludeROut, PreludeE, RunROut, RunE>(definition: ActorRuntimeDefinition<NamespaceSelf, NamespaceId, Internal, ActorSelf, ActorId, Name, AttachmentFields, ClientSelf, ClientId, D, PreludeROut, PreludeE, RunROut, RunE>) => new (state: DurableObjectState<{}>, env: Cloudflare.Env) => DurableObject;
@@ -1,17 +1,15 @@
1
1
  import { DurableObject } from "cloudflare:workers";
2
2
  import { Layer, Effect, Scope, Schema as S, Context, ManagedRuntime, ConfigProvider, Duration, flow, Option, Tracer, pipe, Exit, } from "effect";
3
3
  import { DoState } from "effect-workerd";
4
+ import { Env } from "effect-workerd";
4
5
  import { Clock } from "effect-workerd/platform";
5
6
  import { SecWebSocketProtocol } from "effect-workerd/socket_util";
6
7
  import { Headers, FetchHttpClient, HttpClient, HttpTraceContext } from "effect/unstable/http";
7
- import { boundLayer } from "liminal-util/boundLayer";
8
- import { logCause } from "liminal-util/logCause";
9
- import * as Spanner from "liminal-util/Spanner";
10
- import { encodeJsonString, decodeJsonString } from "../_util/schema.js";
11
- import * as ClientDirectory from "../ClientDirectory.js";
12
- import * as Tracing from "../Tracing.js";
13
- import { sessionAttributes, SessionId, sessionLink } from "../Tracing.js";
14
- const span = Spanner.make(import.meta.url);
8
+ import * as Boundary from "liminal-util/Boundary";
9
+ import { encodeJsonString, decodeJsonString } from "liminal-util/schema";
10
+ import * as ClientDirectory from "./ClientDirectory.js";
11
+ import * as Tracing from "./Tracing.js";
12
+ import { sessionAttributes, SessionId, sessionLink } from "./Tracing.js";
15
13
  export const make = (definition) => {
16
14
  const { hibernation, prelude, external, layer, hydrate, onDisconnect, internal, namespace: { definition: { actor }, }, } = definition;
17
15
  const { definition: { name: Name, client: { protocol: P }, attachments: AttachmentFields, }, } = actor;
@@ -34,26 +32,27 @@ export const make = (definition) => {
34
32
  const { _tag } = event.event;
35
33
  return Effect.gen(function* () {
36
34
  const trace = yield* Tracing.currentTrace;
37
- const encoded = yield* encodeEvent({
38
- ...event,
39
- ...(trace && { trace }),
40
- });
35
+ const encoded = yield* encodeEvent({ ...event, ...(trace && { trace }) }).pipe(Effect.catchTags({
36
+ SchemaError: Effect.die,
37
+ }));
41
38
  // @effect-diagnostics-next-line tryCatchInEffectGen:off
42
39
  try {
43
40
  socket.send(encoded);
44
41
  // oxlint-disable-next-line no-unused-vars
45
42
  }
46
43
  catch (_e) { }
47
- }).pipe(span("send", {
44
+ }).pipe(Boundary.span("send", import.meta.url, {
48
45
  attributes: { _tag, ...sessionAttributes(session) },
49
46
  kind: "producer",
50
47
  links: [sessionLink(session)],
51
48
  }));
52
49
  },
53
50
  close: ({ socket }) => Effect.sync(() => socket.close(1000)),
54
- snapshot: ({ socket, session }, attachments) => encodeSocketAttachment({ attachments, session }).pipe(Effect.andThen((v) => Effect.sync(() => socket.serializeAttachment(v)))),
51
+ snapshot: ({ socket, session }, attachments) => encodeSocketAttachment({ attachments, session }).pipe(Effect.catchTags({
52
+ SchemaError: Effect.die,
53
+ }), Effect.andThen((v) => Effect.sync(() => socket.serializeAttachment(v)))),
55
54
  };
56
- class NameDecoded extends Context.Service()("liminal/WorkerdActorNamespace/NameDecoded") {
55
+ class NameDecoded extends Context.Service()("liminal/ActorNamespace/NameDecoded") {
57
56
  }
58
57
  return class extends DurableObject {
59
58
  run;
@@ -71,7 +70,7 @@ export const make = (definition) => {
71
70
  if (hibernation) {
72
71
  Option.andThen(Duration.fromInput(hibernation), flow(Duration.toMillis, (timeout) => state.setHibernatableWebSocketEventTimeout(timeout)));
73
72
  }
74
- const Live = Layer.mergeAll(FetchHttpClient.layer, Layer.succeed(DoState.DoState, state), Layer.effect(NameDecoded, S.decodeUnknownEffect(Name)(state.id.name))).pipe(Layer.provideMerge(prelude.pipe(Layer.provideMerge(Layer.mergeAll(FetchHttpClient.layer, ConfigProvider.layer(ConfigProvider.fromUnknown(env)))))), Layer.provideMerge(Clock.layer));
73
+ const Live = Layer.mergeAll(FetchHttpClient.layer, Layer.succeed(DoState.DoState, state), Layer.succeed(Env, env), Layer.effect(NameDecoded, S.decodeUnknownEffect(Name)(state.id.name))).pipe(Layer.provideMerge(prelude.pipe(Layer.provideMerge(Layer.mergeAll(FetchHttpClient.layer, ConfigProvider.layer(ConfigProvider.fromUnknown(env)), Layer.succeed(Env, env))))), Layer.provideMerge(Clock.layer));
75
74
  const HydrateClientsLive = Effect.gen({ self: this }, function* () {
76
75
  for (const socket of state.getWebSockets()) {
77
76
  const { attachments, session } = yield* decodeSocketAttachment(socket.deserializeAttachment());
@@ -79,23 +78,24 @@ export const make = (definition) => {
79
78
  .register({ socket, session }, attachments)
80
79
  .pipe(Effect.linkSpans(Tracer.externalSpan(session.trace), sessionLink(session).attributes));
81
80
  }
82
- }).pipe(span("hydrate"), Layer.effectDiscard);
83
- const runtime = ManagedRuntime.make(HydrateClientsLive.pipe(Layer.provideMerge(Live), boundLayer("actor")));
84
- this.run = flow(Effect.tapCause(logCause), runtime.runPromise);
81
+ }).pipe(Boundary.span("hydrate", import.meta.url), Layer.effectDiscard);
82
+ const runtime = ManagedRuntime.make(HydrateClientsLive.pipe(Layer.provideMerge(Live), Boundary.layer("actor", import.meta.url)));
83
+ this.run = (effect) => Effect.onError(effect, Effect.logError).pipe(runtime.runPromise);
85
84
  }
86
85
  fetch(request) {
87
86
  return Effect.gen({ self: this }, function* () {
88
87
  const url = new URL(request.url);
89
88
  const attachments = yield* decodeAttachmentsString(url.searchParams.get("__liminal_attachments"));
89
+ const clientId = yield* Effect.fromNullishOr(url.searchParams.get("__liminal_client_id"));
90
90
  const { 0: webSocket, 1: server } = new WebSocketPair();
91
91
  const state = yield* DoState.DoState;
92
92
  const session = {
93
- id: SessionId.make(crypto.randomUUID()),
93
+ id: SessionId.make(clientId),
94
94
  trace: yield* Effect.currentSpan.pipe(Effect.map(Tracing.toTraceEnvelope)),
95
95
  };
96
96
  const currentClient = yield* this.directory.register({ socket: server, session }, attachments);
97
97
  state.acceptWebSocket(server);
98
- const initial = yield* hydrate.pipe(this.provideActor(currentClient), span("hydrate", {
98
+ const initial = yield* hydrate.pipe(this.provideActor(currentClient), Boundary.span("hydrate", import.meta.url, {
99
99
  attributes: sessionAttributes(session),
100
100
  links: [sessionLink(session)],
101
101
  }));
@@ -105,7 +105,7 @@ export const make = (definition) => {
105
105
  webSocket,
106
106
  headers: { [SecWebSocketProtocol]: "liminal" },
107
107
  });
108
- }).pipe(span("fetch", {
108
+ }).pipe(Boundary.span("fetch", import.meta.url, {
109
109
  kind: "server",
110
110
  parent: pipe(request.headers, Headers.fromInput, HttpTraceContext.fromHeaders, Option.getOrUndefined),
111
111
  }), this.run);
@@ -121,7 +121,7 @@ export const make = (definition) => {
121
121
  }
122
122
  if (message._tag === "Disconnect") {
123
123
  yield* currentClient.disconnect;
124
- return yield* onDisconnect.pipe(this.provideActor(currentClient), span("disconnect", {
124
+ return yield* onDisconnect.pipe(this.provideActor(currentClient), Boundary.span("disconnect", import.meta.url, {
125
125
  attributes: sessionAttributes(session),
126
126
  links: [sessionLink(session)],
127
127
  }));
@@ -158,47 +158,53 @@ export const make = (definition) => {
158
158
  }), Effect.andThen((v) => Effect.try({
159
159
  try: () => socket.send(v),
160
160
  catch: () => { },
161
- })), this.provideActor(currentClient), span("handler", {
161
+ })), this.provideActor(currentClient), Boundary.span("handler", import.meta.url, {
162
162
  attributes: { _tag, ...sessionAttributes(session) },
163
163
  kind: "server",
164
164
  parent,
165
165
  links,
166
166
  }));
167
- }).pipe(span("socket-message"), this.run);
167
+ }).pipe(Boundary.span("socket-message", import.meta.url), this.run);
168
168
  }
169
169
  webSocketClose(socket, _code, _reason, _wasClean) {
170
170
  Effect.gen({ self: this }, function* () {
171
- const entry = yield* this.directory
172
- .entry(socket)
173
- .pipe(Effect.catchTag("NoSuchElementError", () => Effect.undefined));
171
+ const entry = yield* this.directory.entry(socket).pipe(Effect.catchTags({
172
+ NoSuchElementError: () => Effect.undefined,
173
+ }));
174
174
  if (!entry) {
175
175
  return;
176
176
  }
177
177
  const { client: { session }, handle: currentClient, } = entry;
178
178
  yield* Effect.annotateCurrentSpan(sessionAttributes(session));
179
179
  yield* this.directory.unregister(socket);
180
- yield* onDisconnect.pipe(this.provideActor(currentClient), span("disconnect", {
180
+ yield* onDisconnect.pipe(this.provideActor(currentClient), Boundary.span("disconnect", import.meta.url, {
181
181
  attributes: sessionAttributes(session),
182
182
  links: [sessionLink(session)],
183
183
  }));
184
- }).pipe(span("socket-close"), this.run);
184
+ }).pipe(Boundary.span("socket-close", import.meta.url), this.run);
185
185
  }
186
186
  webSocketError(socket, cause) {
187
187
  Effect.gen({ self: this }, function* () {
188
188
  const { client: { session }, handle: currentClient, } = yield* this.directory.entry(socket);
189
189
  yield* Effect.annotateCurrentSpan(sessionAttributes(session));
190
190
  yield* this.directory.unregister(socket);
191
- yield* onDisconnect.pipe(this.provideActor(currentClient), span("disconnect", {
191
+ yield* onDisconnect.pipe(this.provideActor(currentClient), Boundary.span("disconnect", import.meta.url, {
192
192
  attributes: sessionAttributes(session),
193
193
  links: [sessionLink(session)],
194
194
  }));
195
195
  yield* Effect.annotateLogs(Effect.logDebug("SocketErrored"), { cause });
196
- }).pipe(span("socket-error"), this.run);
196
+ }).pipe(Boundary.span("socket-error", import.meta.url), this.run);
197
197
  }
198
198
  async rpc(method, payload) {
199
199
  const handler = internal[method];
200
- return await handler(payload).pipe(this.provideActor(null), span("fn-internal"), Effect.exit, this.run);
200
+ return await handler(payload).pipe(this.provideActor(null), Boundary.span("fn-internal", import.meta.url), Effect.exit, this.run);
201
+ }
202
+ async proxySendAll(event, payload) {
203
+ await Effect.gen(function* () {
204
+ const { clients } = yield* actor;
205
+ yield* Effect.forEach(clients, ({ send }) => send(event, payload), { concurrency: "unbounded" });
206
+ }).pipe(this.provideActor(null), Boundary.span("fn-internal", import.meta.url), this.run);
201
207
  }
202
208
  };
203
209
  };
204
- //# sourceMappingURL=WorkerdActorRuntime.js.map
210
+ //# sourceMappingURL=ActorRuntime.js.map