@effect-atom/atom 0.1.7 → 0.1.9

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/src/AtomRpc.ts CHANGED
@@ -9,14 +9,17 @@ import type { RpcClientError } from "@effect/rpc/RpcClientError"
9
9
  import type * as RpcGroup from "@effect/rpc/RpcGroup"
10
10
  import type { RequestId } from "@effect/rpc/RpcMessage"
11
11
  import * as RpcSchema from "@effect/rpc/RpcSchema"
12
+ import * as Context from "effect/Context"
12
13
  import * as Data from "effect/Data"
13
14
  import * as Duration from "effect/Duration"
14
15
  import * as Effect from "effect/Effect"
15
16
  import * as Equal from "effect/Equal"
16
17
  import { pipe } from "effect/Function"
17
18
  import * as Hash from "effect/Hash"
19
+ import * as Layer from "effect/Layer"
18
20
  import type { ReadonlyRecord } from "effect/Record"
19
21
  import * as Stream from "effect/Stream"
22
+ import type { Mutable, NoInfer } from "effect/Types"
20
23
  import * as Atom from "./Atom.js"
21
24
  import type * as Result from "./Result.js"
22
25
 
@@ -24,10 +27,15 @@ import type * as Result from "./Result.js"
24
27
  * @since 1.0.0
25
28
  * @category Models
26
29
  */
27
- export interface AtomRpcClient<Rpcs extends Rpc.Any, E> {
28
- readonly client: Atom.Atom<
29
- Result.Result<RpcClient.RpcClient.Flat<Rpcs, RpcClientError>, E>
30
- >
30
+ export interface AtomRpcClient<Self, Id extends string, Rpcs extends Rpc.Any, E>
31
+ extends Context.Tag<Self, RpcClient.RpcClient.Flat<Rpcs, RpcClientError>>
32
+ {
33
+ new(
34
+ _: never
35
+ ): Context.TagClassShape<Id, RpcClient.RpcClient.Flat<Rpcs, RpcClientError>>
36
+
37
+ readonly layer: Layer.Layer<Self, E>
38
+ readonly runtime: Atom.AtomRuntime<Self, E>
31
39
 
32
40
  readonly mutation: <Tag extends Rpc.Tag<Rpcs>>(
33
41
  arg: Tag
@@ -42,6 +50,7 @@ export interface AtomRpcClient<Rpcs extends Rpc.Any, E> {
42
50
  {
43
51
  readonly payload: Rpc.PayloadConstructor<Rpc.ExtractTag<Rpcs, Tag>>
44
52
  readonly reactivityKeys?:
53
+ | ReadonlyArray<unknown>
45
54
  | ReadonlyRecord<string, ReadonlyArray<unknown>>
46
55
  | undefined
47
56
  readonly headers?: Headers.Input | undefined
@@ -56,10 +65,7 @@ export interface AtomRpcClient<Rpcs extends Rpc.Any, E> {
56
65
  payload: Rpc.PayloadConstructor<Rpc.ExtractTag<Rpcs, Tag>>,
57
66
  options?: {
58
67
  readonly headers?: Headers.Input | undefined
59
- readonly reactivityKeys?:
60
- | ReadonlyArray<unknown>
61
- | ReadonlyRecord<string, ReadonlyArray<unknown>>
62
- | undefined
68
+ readonly reactivityKeys?: ReadonlyArray<unknown> | undefined
63
69
  readonly timeToLive?: Duration.DurationInput | undefined
64
70
  }
65
71
  ) => Rpc.ExtractTag<Rpcs, Tag> extends Rpc.Rpc<
@@ -84,15 +90,25 @@ export interface AtomRpcClient<Rpcs extends Rpc.Any, E> {
84
90
  : never
85
91
  }
86
92
 
93
+ declare global {
94
+ interface ErrorConstructor {
95
+ stackTraceLimit: number
96
+ }
97
+ }
98
+
87
99
  /**
88
100
  * @since 1.0.0
89
101
  * @category Constructors
90
102
  */
91
- export const make = <Rpcs extends Rpc.Any, ER>(
92
- group: RpcGroup.RpcGroup<Rpcs>,
103
+ export const Tag = <Self>() =>
104
+ <const Id extends string, Rpcs extends Rpc.Any, ER>(
105
+ id: Id,
93
106
  options: {
94
- readonly runtime: Atom.AtomRuntime<
95
- RpcClient.Protocol | Rpc.MiddlewareClient<Rpcs> | Rpc.Context<Rpcs>,
107
+ readonly group: RpcGroup.RpcGroup<Rpcs>
108
+ readonly protocol: Layer.Layer<
109
+ | RpcClient.Protocol
110
+ | Rpc.MiddlewareClient<NoInfer<Rpcs>>
111
+ | Rpc.Context<NoInfer<Rpcs>>,
96
112
  ER
97
113
  >
98
114
  readonly spanPrefix?: string | undefined
@@ -100,16 +116,23 @@ export const make = <Rpcs extends Rpc.Any, ER>(
100
116
  readonly generateRequestId?: (() => RequestId) | undefined
101
117
  readonly disableTracing?: boolean | undefined
102
118
  }
103
- ): AtomRpcClient<Rpcs, ER> => {
104
- const client = options.runtime.atom(
105
- RpcClient.make(group, {
119
+ ): AtomRpcClient<Self, Id, Rpcs, ER> => {
120
+ const self: Mutable<AtomRpcClient<Self, Id, Rpcs, ER>> = Context.Tag(id)<
121
+ Self,
122
+ RpcClient.RpcClient.Flat<Rpcs, RpcClientError>
123
+ >() as any
124
+
125
+ self.layer = Layer.scoped(
126
+ self,
127
+ RpcClient.make(options.group, {
106
128
  ...options,
107
129
  flatten: true
108
130
  })
109
- )
131
+ ).pipe(Layer.provide(options.protocol)) as Layer.Layer<Self, ER>
132
+ self.runtime = Atom.runtime(self.layer)
110
133
 
111
- const mutation = Atom.family(<Tag extends Rpc.Tag<Rpcs>>(tag: Tag) =>
112
- options.runtime.fn<{
134
+ self.mutation = Atom.family(<Tag extends Rpc.Tag<Rpcs>>(tag: Tag) =>
135
+ self.runtime.fn<{
113
136
  readonly payload: Rpc.PayloadConstructor<Rpc.ExtractTag<Rpcs, Tag>>
114
137
  readonly reactivityKeys?:
115
138
  | ReadonlyArray<unknown>
@@ -117,39 +140,41 @@ export const make = <Rpcs extends Rpc.Any, ER>(
117
140
  | undefined
118
141
  readonly headers?: Headers.Input | undefined
119
142
  }>()(
120
- Effect.fnUntraced(function*({ headers, payload, reactivityKeys }, get) {
121
- const c = yield* get.result(client)
122
- const effect = c(tag, payload, { headers } as any)
143
+ Effect.fnUntraced(function*({ headers, payload, reactivityKeys }) {
144
+ const client = yield* self
145
+ const effect = client(tag, payload, { headers } as any)
123
146
  return yield* reactivityKeys
124
147
  ? Reactivity.mutation(effect, reactivityKeys)
125
148
  : effect
126
149
  })
127
150
  )
128
- )
151
+ ) as any
129
152
 
130
- const queryFamily = Atom.family(({ headers, payload, reactivityKeys, tag, timeToLive }: QueryKey) => {
131
- const rpc = group.requests.get(tag)! as any as Rpc.AnyWithProps
132
- let atom = RpcSchema.isStreamSchema(rpc.successSchema)
133
- ? Atom.pull((get) =>
134
- get.result(client).pipe(
135
- Effect.map((client) => client(tag, payload, { headers } as any)),
136
- Stream.unwrap
137
- )
138
- )
139
- : Atom.make((get) =>
140
- get
141
- .result(client)
142
- .pipe(
143
- Effect.flatMap((client) => client(tag, payload, { headers } as any))
153
+ const queryFamily = Atom.family(
154
+ ({ headers, payload, reactivityKeys, tag, timeToLive }: QueryKey) => {
155
+ const rpc = options.group.requests.get(tag)! as any as Rpc.AnyWithProps
156
+ let atom = RpcSchema.isStreamSchema(rpc.successSchema)
157
+ ? self.runtime.pull(
158
+ self.pipe(
159
+ Effect.map((client) => client(tag, payload, { headers } as any)),
160
+ Stream.unwrap
144
161
  )
145
- )
146
- if (timeToLive) {
147
- atom = Duration.isFinite(timeToLive) ? Atom.setIdleTTL(atom, timeToLive) : Atom.keepAlive(atom)
162
+ )
163
+ : self.runtime.atom(
164
+ Effect.flatMap(self, (client) => client(tag, payload, { headers } as any))
165
+ )
166
+ if (timeToLive) {
167
+ atom = Duration.isFinite(timeToLive)
168
+ ? Atom.setIdleTTL(atom, timeToLive)
169
+ : Atom.keepAlive(atom)
170
+ }
171
+ return reactivityKeys
172
+ ? self.runtime.factory.withReactivity(reactivityKeys)(atom)
173
+ : atom
148
174
  }
149
- return reactivityKeys ? options.runtime.factory.withReactivity(reactivityKeys)(atom) : atom
150
- })
175
+ )
151
176
 
152
- const query = <Tag extends Rpc.Tag<Rpcs>>(
177
+ self.query = <Tag extends Rpc.Tag<Rpcs>>(
153
178
  tag: Tag,
154
179
  payload: Rpc.PayloadConstructor<Rpc.ExtractTag<Rpcs, Tag>>,
155
180
  options?: {
@@ -168,15 +193,13 @@ export const make = <Rpcs extends Rpc.Any, ER>(
168
193
  reactivityKeys: options?.reactivityKeys
169
194
  ? Data.array(options.reactivityKeys)
170
195
  : undefined,
171
- timeToLive: options?.timeToLive ? Duration.decode(options.timeToLive) : undefined
196
+ timeToLive: options?.timeToLive
197
+ ? Duration.decode(options.timeToLive)
198
+ : undefined
172
199
  })
173
- )
200
+ ) as any
174
201
 
175
- return {
176
- client,
177
- mutation,
178
- query
179
- } as any
202
+ return self as AtomRpcClient<Self, Id, Rpcs, ER>
180
203
  }
181
204
 
182
205
  class QueryKey extends Data.Class<{