@effect-atom/atom 0.1.1 → 0.1.3
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/AtomRpc/package.json +6 -0
- package/dist/cjs/Atom.js +19 -13
- package/dist/cjs/Atom.js.map +1 -1
- package/dist/cjs/AtomRpc.js +97 -0
- package/dist/cjs/AtomRpc.js.map +1 -0
- package/dist/cjs/index.js +3 -1
- package/dist/dts/Atom.d.ts +14 -5
- package/dist/dts/Atom.d.ts.map +1 -1
- package/dist/dts/AtomRpc.d.ts +38 -0
- package/dist/dts/AtomRpc.d.ts.map +1 -0
- package/dist/dts/index.d.ts +4 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/esm/Atom.js +18 -12
- package/dist/esm/Atom.js.map +1 -1
- package/dist/esm/AtomRpc.js +69 -0
- package/dist/esm/AtomRpc.js.map +1 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -1
- package/package.json +10 -1
- package/src/Atom.ts +38 -25
- package/src/AtomRpc.ts +198 -0
- package/src/index.ts +5 -0
package/src/AtomRpc.ts
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since 1.0.0
|
|
3
|
+
*/
|
|
4
|
+
import * as Reactivity from "@effect/experimental/Reactivity"
|
|
5
|
+
import * as Headers from "@effect/platform/Headers"
|
|
6
|
+
import type * as Rpc from "@effect/rpc/Rpc"
|
|
7
|
+
import * as RpcClient from "@effect/rpc/RpcClient"
|
|
8
|
+
import type { RpcClientError } from "@effect/rpc/RpcClientError"
|
|
9
|
+
import type * as RpcGroup from "@effect/rpc/RpcGroup"
|
|
10
|
+
import type { RequestId } from "@effect/rpc/RpcMessage"
|
|
11
|
+
import * as RpcSchema from "@effect/rpc/RpcSchema"
|
|
12
|
+
import * as Data from "effect/Data"
|
|
13
|
+
import * as Effect from "effect/Effect"
|
|
14
|
+
import * as Equal from "effect/Equal"
|
|
15
|
+
import { pipe } from "effect/Function"
|
|
16
|
+
import * as Hash from "effect/Hash"
|
|
17
|
+
import type { ReadonlyRecord } from "effect/Record"
|
|
18
|
+
import * as Stream from "effect/Stream"
|
|
19
|
+
import * as Atom from "./Atom.js"
|
|
20
|
+
import type * as Result from "./Result.js"
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @since 1.0.0
|
|
24
|
+
* @category Models
|
|
25
|
+
*/
|
|
26
|
+
export interface AtomRpcClient<Rpcs extends Rpc.Any, E> {
|
|
27
|
+
readonly client: Atom.Atom<
|
|
28
|
+
Result.Result<RpcClient.RpcClient.Flat<Rpcs, RpcClientError>, E>
|
|
29
|
+
>
|
|
30
|
+
|
|
31
|
+
readonly mutation: <Tag extends Rpc.Tag<Rpcs>>(
|
|
32
|
+
arg: Tag
|
|
33
|
+
) => Rpc.ExtractTag<Rpcs, Tag> extends Rpc.Rpc<
|
|
34
|
+
infer _Tag,
|
|
35
|
+
infer _Payload,
|
|
36
|
+
infer _Success,
|
|
37
|
+
infer _Error,
|
|
38
|
+
infer _Middleware
|
|
39
|
+
> ? [_Success] extends [RpcSchema.Stream<infer _A, infer _E>] ? never
|
|
40
|
+
: Atom.AtomResultFn<
|
|
41
|
+
{
|
|
42
|
+
readonly payload: Rpc.PayloadConstructor<Rpc.ExtractTag<Rpcs, Tag>>
|
|
43
|
+
readonly reactivityKeys?:
|
|
44
|
+
| ReadonlyRecord<string, ReadonlyArray<unknown>>
|
|
45
|
+
| undefined
|
|
46
|
+
readonly headers?: Headers.Input | undefined
|
|
47
|
+
},
|
|
48
|
+
_Success["Type"],
|
|
49
|
+
_Error["Type"] | E | _Middleware["failure"]["Type"]
|
|
50
|
+
>
|
|
51
|
+
: never
|
|
52
|
+
|
|
53
|
+
readonly query: <Tag extends Rpc.Tag<Rpcs>>(
|
|
54
|
+
tag: Tag,
|
|
55
|
+
payload: Rpc.PayloadConstructor<Rpc.ExtractTag<Rpcs, Tag>>,
|
|
56
|
+
options?: {
|
|
57
|
+
readonly headers?: Headers.Input | undefined
|
|
58
|
+
readonly reactivityKeys?:
|
|
59
|
+
| ReadonlyArray<unknown>
|
|
60
|
+
| ReadonlyRecord<string, ReadonlyArray<unknown>>
|
|
61
|
+
| undefined
|
|
62
|
+
}
|
|
63
|
+
) => Rpc.ExtractTag<Rpcs, Tag> extends Rpc.Rpc<
|
|
64
|
+
infer _Tag,
|
|
65
|
+
infer _Payload,
|
|
66
|
+
infer _Success,
|
|
67
|
+
infer _Error,
|
|
68
|
+
infer _Middleware
|
|
69
|
+
> ? [_Success] extends [RpcSchema.Stream<infer _A, infer _E>] ? Atom.Writable<
|
|
70
|
+
Atom.PullResult<
|
|
71
|
+
_A,
|
|
72
|
+
_E | _Error["Type"] | E | _Middleware["failure"]["Type"]
|
|
73
|
+
>,
|
|
74
|
+
void
|
|
75
|
+
>
|
|
76
|
+
: Atom.Atom<
|
|
77
|
+
Result.Result<
|
|
78
|
+
_Success["Type"],
|
|
79
|
+
_Error["Type"] | E | _Middleware["failure"]["Type"]
|
|
80
|
+
>
|
|
81
|
+
>
|
|
82
|
+
: never
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @since 1.0.0
|
|
87
|
+
* @category Constructors
|
|
88
|
+
*/
|
|
89
|
+
export const make = <Rpcs extends Rpc.Any, ER>(
|
|
90
|
+
group: RpcGroup.RpcGroup<Rpcs>,
|
|
91
|
+
options: {
|
|
92
|
+
readonly runtime: Atom.AtomRuntime<
|
|
93
|
+
RpcClient.Protocol | Rpc.MiddlewareClient<Rpcs> | Rpc.Context<Rpcs>,
|
|
94
|
+
ER
|
|
95
|
+
>
|
|
96
|
+
readonly spanPrefix?: string | undefined
|
|
97
|
+
readonly spanAttributes?: Record<string, unknown> | undefined
|
|
98
|
+
readonly generateRequestId?: (() => RequestId) | undefined
|
|
99
|
+
readonly disableTracing?: boolean | undefined
|
|
100
|
+
}
|
|
101
|
+
): AtomRpcClient<Rpcs, ER> => {
|
|
102
|
+
const client = options.runtime.atom(
|
|
103
|
+
RpcClient.make(group, {
|
|
104
|
+
...options,
|
|
105
|
+
flatten: true
|
|
106
|
+
})
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
const mutation = Atom.family(<Tag extends Rpc.Tag<Rpcs>>(tag: Tag) =>
|
|
110
|
+
options.runtime.fn<{
|
|
111
|
+
readonly payload: Rpc.PayloadConstructor<Rpc.ExtractTag<Rpcs, Tag>>
|
|
112
|
+
readonly reactivityKeys?:
|
|
113
|
+
| ReadonlyArray<unknown>
|
|
114
|
+
| ReadonlyRecord<string, ReadonlyArray<unknown>>
|
|
115
|
+
| undefined
|
|
116
|
+
readonly headers?: Headers.Input | undefined
|
|
117
|
+
}>()(
|
|
118
|
+
Effect.fnUntraced(function*({ headers, payload, reactivityKeys }, get) {
|
|
119
|
+
const c = yield* get.result(client)
|
|
120
|
+
const effect = c(tag, payload, { headers } as any)
|
|
121
|
+
return yield* reactivityKeys
|
|
122
|
+
? Reactivity.mutation(effect, reactivityKeys)
|
|
123
|
+
: effect
|
|
124
|
+
})
|
|
125
|
+
)
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
const queryFamily = Atom.family(({ headers, payload, reactivityKeys, tag }: QueryKey) => {
|
|
129
|
+
const rpc = group.requests.get(tag)! as any as Rpc.AnyWithProps
|
|
130
|
+
const atom = RpcSchema.isStreamSchema(rpc.successSchema)
|
|
131
|
+
? Atom.pull((get) =>
|
|
132
|
+
get.result(client).pipe(
|
|
133
|
+
Effect.map((client) => client(tag, payload, { headers } as any)),
|
|
134
|
+
Stream.unwrap
|
|
135
|
+
)
|
|
136
|
+
)
|
|
137
|
+
: Atom.make((get) =>
|
|
138
|
+
get
|
|
139
|
+
.result(client)
|
|
140
|
+
.pipe(
|
|
141
|
+
Effect.flatMap((client) => client(tag, payload, { headers } as any))
|
|
142
|
+
)
|
|
143
|
+
)
|
|
144
|
+
return reactivityKeys ? options.runtime.factory.withReactivity(reactivityKeys)(atom) : atom
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
const query = <Tag extends Rpc.Tag<Rpcs>>(
|
|
148
|
+
tag: Tag,
|
|
149
|
+
payload: Rpc.PayloadConstructor<Rpc.ExtractTag<Rpcs, Tag>>,
|
|
150
|
+
options?: {
|
|
151
|
+
readonly headers?: Headers.Input | undefined
|
|
152
|
+
readonly reactivityKeys?: ReadonlyArray<unknown> | undefined
|
|
153
|
+
}
|
|
154
|
+
) =>
|
|
155
|
+
queryFamily(
|
|
156
|
+
new QueryKey({
|
|
157
|
+
tag,
|
|
158
|
+
payload: Data.struct(payload),
|
|
159
|
+
headers: options?.headers
|
|
160
|
+
? Data.unsafeStruct(Headers.fromInput(options.headers))
|
|
161
|
+
: undefined,
|
|
162
|
+
reactivityKeys: options?.reactivityKeys
|
|
163
|
+
? Data.array(options.reactivityKeys)
|
|
164
|
+
: undefined
|
|
165
|
+
})
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
client,
|
|
170
|
+
mutation,
|
|
171
|
+
query
|
|
172
|
+
} as any
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
class QueryKey extends Data.Class<{
|
|
176
|
+
tag: string
|
|
177
|
+
payload: any
|
|
178
|
+
headers?: Headers.Headers | undefined
|
|
179
|
+
reactivityKeys?: ReadonlyArray<unknown> | undefined
|
|
180
|
+
}> {
|
|
181
|
+
[Equal.symbol](that: QueryKey) {
|
|
182
|
+
return (
|
|
183
|
+
this.tag === that.tag &&
|
|
184
|
+
Equal.equals(this.payload, that.payload) &&
|
|
185
|
+
Equal.equals(this.headers, that.headers) &&
|
|
186
|
+
Equal.equals(this.reactivityKeys, that.reactivityKeys)
|
|
187
|
+
)
|
|
188
|
+
}
|
|
189
|
+
[Hash.symbol]() {
|
|
190
|
+
return pipe(
|
|
191
|
+
Hash.string(this.tag),
|
|
192
|
+
Hash.combine(Hash.hash(this.payload)),
|
|
193
|
+
Hash.combine(Hash.hash(this.headers)),
|
|
194
|
+
Hash.combine(Hash.hash(this.reactivityKeys)),
|
|
195
|
+
Hash.cached(this)
|
|
196
|
+
)
|
|
197
|
+
}
|
|
198
|
+
}
|