@effect/platform 0.79.3 → 0.80.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ChannelSchema/package.json +6 -0
- package/MsgPack/package.json +6 -0
- package/Ndjson/package.json +6 -0
- package/SocketServer/package.json +6 -0
- package/dist/cjs/ChannelSchema.js +69 -0
- package/dist/cjs/ChannelSchema.js.map +1 -0
- package/dist/cjs/Headers.js +1 -1
- package/dist/cjs/Headers.js.map +1 -1
- package/dist/cjs/HttpApiClient.js +1 -1
- package/dist/cjs/HttpApiClient.js.map +1 -1
- package/dist/cjs/HttpApiEndpoint.js +11 -1
- package/dist/cjs/HttpApiEndpoint.js.map +1 -1
- package/dist/cjs/HttpBody.js.map +1 -1
- package/dist/cjs/HttpRouter.js.map +1 -1
- package/dist/cjs/MsgPack.js +148 -0
- package/dist/cjs/MsgPack.js.map +1 -0
- package/dist/cjs/Ndjson.js +152 -0
- package/dist/cjs/Ndjson.js.map +1 -0
- package/dist/cjs/SocketServer.js +43 -0
- package/dist/cjs/SocketServer.js.map +1 -0
- package/dist/cjs/Transferable.js +6 -5
- package/dist/cjs/Transferable.js.map +1 -1
- package/dist/cjs/Url.js.map +1 -1
- package/dist/cjs/UrlParams.js +19 -1
- package/dist/cjs/UrlParams.js.map +1 -1
- package/dist/cjs/WorkerRunner.js.map +1 -1
- package/dist/cjs/index.js +9 -1
- package/dist/cjs/internal/httpRouter.js +2 -0
- package/dist/cjs/internal/httpRouter.js.map +1 -1
- package/dist/cjs/internal/worker.js +1 -1
- package/dist/cjs/internal/worker.js.map +1 -1
- package/dist/dts/ChannelSchema.d.ts +69 -0
- package/dist/dts/ChannelSchema.d.ts.map +1 -0
- package/dist/dts/Headers.d.ts +1 -1
- package/dist/dts/Headers.d.ts.map +1 -1
- package/dist/dts/HttpApiClient.d.ts +3 -3
- package/dist/dts/HttpApiClient.d.ts.map +1 -1
- package/dist/dts/HttpApiEndpoint.d.ts +32 -0
- package/dist/dts/HttpApiEndpoint.d.ts.map +1 -1
- package/dist/dts/HttpBody.d.ts +1 -1
- package/dist/dts/HttpBody.d.ts.map +1 -1
- package/dist/dts/HttpRouter.d.ts +3 -0
- package/dist/dts/HttpRouter.d.ts.map +1 -1
- package/dist/dts/MsgPack.d.ts +103 -0
- package/dist/dts/MsgPack.d.ts.map +1 -0
- package/dist/dts/Ndjson.d.ts +169 -0
- package/dist/dts/Ndjson.d.ts.map +1 -0
- package/dist/dts/SocketServer.d.ts +70 -0
- package/dist/dts/SocketServer.d.ts.map +1 -0
- package/dist/dts/Transferable.d.ts +2 -2
- package/dist/dts/Transferable.d.ts.map +1 -1
- package/dist/dts/Url.d.ts +2 -2
- package/dist/dts/Url.d.ts.map +1 -1
- package/dist/dts/UrlParams.d.ts +8 -1
- package/dist/dts/UrlParams.d.ts.map +1 -1
- package/dist/dts/WorkerRunner.d.ts +3 -1
- package/dist/dts/WorkerRunner.d.ts.map +1 -1
- package/dist/dts/index.d.ts +16 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/httpRouter.d.ts.map +1 -1
- package/dist/esm/ChannelSchema.js +59 -0
- package/dist/esm/ChannelSchema.js.map +1 -0
- package/dist/esm/Headers.js +1 -1
- package/dist/esm/Headers.js.map +1 -1
- package/dist/esm/HttpApiClient.js +1 -1
- package/dist/esm/HttpApiClient.js.map +1 -1
- package/dist/esm/HttpApiEndpoint.js +10 -0
- package/dist/esm/HttpApiEndpoint.js.map +1 -1
- package/dist/esm/HttpBody.js.map +1 -1
- package/dist/esm/HttpRouter.js.map +1 -1
- package/dist/esm/MsgPack.js +137 -0
- package/dist/esm/MsgPack.js.map +1 -0
- package/dist/esm/Ndjson.js +134 -0
- package/dist/esm/Ndjson.js.map +1 -0
- package/dist/esm/SocketServer.js +32 -0
- package/dist/esm/SocketServer.js.map +1 -0
- package/dist/esm/Transferable.js +6 -5
- package/dist/esm/Transferable.js.map +1 -1
- package/dist/esm/Url.js.map +1 -1
- package/dist/esm/UrlParams.js +18 -0
- package/dist/esm/UrlParams.js.map +1 -1
- package/dist/esm/WorkerRunner.js.map +1 -1
- package/dist/esm/index.js +16 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/httpRouter.js +2 -0
- package/dist/esm/internal/httpRouter.js.map +1 -1
- package/dist/esm/internal/worker.js +1 -1
- package/dist/esm/internal/worker.js.map +1 -1
- package/package.json +35 -2
- package/src/ChannelSchema.ts +267 -0
- package/src/Headers.ts +2 -2
- package/src/HttpApiClient.ts +9 -5
- package/src/HttpApiEndpoint.ts +36 -6
- package/src/HttpBody.ts +1 -1
- package/src/HttpRouter.ts +9 -0
- package/src/MsgPack.ts +372 -0
- package/src/Ndjson.ts +493 -0
- package/src/SocketServer.ts +79 -0
- package/src/Transferable.ts +9 -8
- package/src/Url.ts +5 -5
- package/src/UrlParams.ts +29 -2
- package/src/WorkerRunner.ts +3 -1
- package/src/index.ts +20 -0
- package/src/internal/httpRouter.ts +2 -0
- package/src/internal/worker.ts +1 -1
package/src/Ndjson.ts
ADDED
|
@@ -0,0 +1,493 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since 1.0.0
|
|
3
|
+
*/
|
|
4
|
+
import { TypeIdError } from "@effect/platform/Error"
|
|
5
|
+
import type * as Cause from "effect/Cause"
|
|
6
|
+
import * as Channel from "effect/Channel"
|
|
7
|
+
import * as Chunk from "effect/Chunk"
|
|
8
|
+
import * as Effect from "effect/Effect"
|
|
9
|
+
import { dual, identity } from "effect/Function"
|
|
10
|
+
import type { ParseError } from "effect/ParseResult"
|
|
11
|
+
import type * as Schema from "effect/Schema"
|
|
12
|
+
import * as ChannelSchema from "./ChannelSchema.js"
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @since 1.0.0
|
|
16
|
+
* @category type ids
|
|
17
|
+
*/
|
|
18
|
+
export const ErrorTypeId: unique symbol = Symbol.for("@effect/platform/Ndjson/NdjsonError")
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @since 1.0.0
|
|
22
|
+
* @category type ids
|
|
23
|
+
*/
|
|
24
|
+
export type NdjsonErrorTypeId = typeof ErrorTypeId
|
|
25
|
+
|
|
26
|
+
const encoder = new TextEncoder()
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @since 1.0.0
|
|
30
|
+
* @category errors
|
|
31
|
+
*/
|
|
32
|
+
export class NdjsonError extends TypeIdError(ErrorTypeId, "NdjsonError")<{
|
|
33
|
+
readonly reason: "Pack" | "Unpack"
|
|
34
|
+
readonly cause: unknown
|
|
35
|
+
}> {
|
|
36
|
+
get message() {
|
|
37
|
+
return this.reason
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Represents a set of options which can be used to control how the newline
|
|
43
|
+
* delimited JSON is handled.
|
|
44
|
+
*
|
|
45
|
+
* @since 1.0.0
|
|
46
|
+
* @category models
|
|
47
|
+
*/
|
|
48
|
+
export interface NdjsonOptions {
|
|
49
|
+
/**
|
|
50
|
+
* Whether or not the newline delimited JSON parser should ignore empty lines.
|
|
51
|
+
*
|
|
52
|
+
* Defaults to `false`.
|
|
53
|
+
*
|
|
54
|
+
* From the [newline delimited JSON spec](https://github.com/ndjson/ndjson-spec):
|
|
55
|
+
* ```text
|
|
56
|
+
* The parser MAY silently ignore empty lines, e.g. \n\n. This behavior MUST
|
|
57
|
+
* be documented and SHOULD be configurable by the user of the parser.
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @since 1.0.0
|
|
61
|
+
*/
|
|
62
|
+
readonly ignoreEmptyLines?: boolean
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @since 1.0.0
|
|
67
|
+
* @category constructors
|
|
68
|
+
*/
|
|
69
|
+
export const packString = <IE = never, Done = unknown>(): Channel.Channel<
|
|
70
|
+
Chunk.Chunk<string>,
|
|
71
|
+
Chunk.Chunk<unknown>,
|
|
72
|
+
IE | NdjsonError,
|
|
73
|
+
IE,
|
|
74
|
+
Done,
|
|
75
|
+
Done
|
|
76
|
+
> => {
|
|
77
|
+
const loop: Channel.Channel<
|
|
78
|
+
Chunk.Chunk<string>,
|
|
79
|
+
Chunk.Chunk<unknown>,
|
|
80
|
+
IE | NdjsonError,
|
|
81
|
+
IE,
|
|
82
|
+
Done,
|
|
83
|
+
Done
|
|
84
|
+
> = Channel.readWithCause({
|
|
85
|
+
onInput: (input: Chunk.Chunk<unknown>) =>
|
|
86
|
+
Channel.zipRight(
|
|
87
|
+
Channel.flatMap(
|
|
88
|
+
Effect.try({
|
|
89
|
+
try: () => Chunk.of(Chunk.toReadonlyArray(input).map((_) => JSON.stringify(_)).join("\n") + "\n"),
|
|
90
|
+
catch: (cause) => new NdjsonError({ reason: "Pack", cause })
|
|
91
|
+
}),
|
|
92
|
+
Channel.write
|
|
93
|
+
),
|
|
94
|
+
loop
|
|
95
|
+
),
|
|
96
|
+
onFailure: Channel.failCause,
|
|
97
|
+
onDone: Channel.succeed
|
|
98
|
+
})
|
|
99
|
+
return loop
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @since 1.0.0
|
|
104
|
+
* @category constructors
|
|
105
|
+
*/
|
|
106
|
+
export const pack = <IE = never, Done = unknown>(): Channel.Channel<
|
|
107
|
+
Chunk.Chunk<Uint8Array>,
|
|
108
|
+
Chunk.Chunk<unknown>,
|
|
109
|
+
IE | NdjsonError,
|
|
110
|
+
IE,
|
|
111
|
+
Done,
|
|
112
|
+
Done
|
|
113
|
+
> => Channel.mapOut(packString(), Chunk.map((_) => encoder.encode(_)))
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @since 1.0.0
|
|
117
|
+
* @category constructors
|
|
118
|
+
*/
|
|
119
|
+
export const packSchema = <A, I, R>(
|
|
120
|
+
schema: Schema.Schema<A, I, R>
|
|
121
|
+
) =>
|
|
122
|
+
<IE = never, Done = unknown>(): Channel.Channel<
|
|
123
|
+
Chunk.Chunk<Uint8Array>,
|
|
124
|
+
Chunk.Chunk<A>,
|
|
125
|
+
IE | NdjsonError | ParseError,
|
|
126
|
+
IE,
|
|
127
|
+
Done,
|
|
128
|
+
Done,
|
|
129
|
+
R
|
|
130
|
+
> => Channel.pipeTo(ChannelSchema.encode(schema)(), pack())
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* @since 1.0.0
|
|
134
|
+
* @category constructors
|
|
135
|
+
*/
|
|
136
|
+
export const packSchemaString = <A, I, R>(
|
|
137
|
+
schema: Schema.Schema<A, I, R>
|
|
138
|
+
) =>
|
|
139
|
+
<IE = never, Done = unknown>(): Channel.Channel<
|
|
140
|
+
Chunk.Chunk<string>,
|
|
141
|
+
Chunk.Chunk<A>,
|
|
142
|
+
IE | NdjsonError | ParseError,
|
|
143
|
+
IE,
|
|
144
|
+
Done,
|
|
145
|
+
Done,
|
|
146
|
+
R
|
|
147
|
+
> => Channel.pipeTo(ChannelSchema.encode(schema)(), packString())
|
|
148
|
+
|
|
149
|
+
const filterEmpty = Chunk.filter<string>((line) => line.length > 0)
|
|
150
|
+
const filterEmptyChannel = <IE, Done>() => {
|
|
151
|
+
const loop: Channel.Channel<
|
|
152
|
+
Chunk.Chunk<string>,
|
|
153
|
+
Chunk.Chunk<string>,
|
|
154
|
+
IE,
|
|
155
|
+
IE,
|
|
156
|
+
Done,
|
|
157
|
+
Done,
|
|
158
|
+
never
|
|
159
|
+
> = Channel.readWithCause({
|
|
160
|
+
onInput(input: Chunk.Chunk<string>) {
|
|
161
|
+
const filtered = filterEmpty(input)
|
|
162
|
+
return Channel.zipRight(Chunk.isEmpty(filtered) ? Channel.void : Channel.write(filtered), loop)
|
|
163
|
+
},
|
|
164
|
+
onFailure(cause: Cause.Cause<IE>) {
|
|
165
|
+
return Channel.failCause(cause)
|
|
166
|
+
},
|
|
167
|
+
onDone(done: Done) {
|
|
168
|
+
return Channel.succeed(done)
|
|
169
|
+
}
|
|
170
|
+
})
|
|
171
|
+
return loop
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* @since 1.0.0
|
|
176
|
+
* @category constructors
|
|
177
|
+
*/
|
|
178
|
+
export const unpackString = <IE = never, Done = unknown>(options?: NdjsonOptions): Channel.Channel<
|
|
179
|
+
Chunk.Chunk<unknown>,
|
|
180
|
+
Chunk.Chunk<string>,
|
|
181
|
+
IE | NdjsonError,
|
|
182
|
+
IE,
|
|
183
|
+
Done,
|
|
184
|
+
Done
|
|
185
|
+
> => {
|
|
186
|
+
const lines = Channel.splitLines<IE, Done>().pipe(
|
|
187
|
+
options?.ignoreEmptyLines === true ?
|
|
188
|
+
Channel.pipeTo(filterEmptyChannel()) :
|
|
189
|
+
identity
|
|
190
|
+
)
|
|
191
|
+
return Channel.mapOutEffect(lines, (chunk) =>
|
|
192
|
+
Effect.try({
|
|
193
|
+
try: () => Chunk.map(chunk, (_) => JSON.parse(_)),
|
|
194
|
+
catch: (cause) => new NdjsonError({ reason: "Unpack", cause })
|
|
195
|
+
}))
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const decodeString = <IE, Done>() => {
|
|
199
|
+
const decoder = new TextDecoder()
|
|
200
|
+
const loop: Channel.Channel<
|
|
201
|
+
Chunk.Chunk<string>,
|
|
202
|
+
Chunk.Chunk<Uint8Array>,
|
|
203
|
+
IE,
|
|
204
|
+
IE,
|
|
205
|
+
Done,
|
|
206
|
+
Done,
|
|
207
|
+
never
|
|
208
|
+
> = Channel.readWithCause({
|
|
209
|
+
onInput: (input) =>
|
|
210
|
+
Channel.zipRight(
|
|
211
|
+
Channel.write(Chunk.map(input, (_) => decoder.decode(_))),
|
|
212
|
+
loop
|
|
213
|
+
),
|
|
214
|
+
onFailure: Channel.failCause,
|
|
215
|
+
onDone: Channel.succeed
|
|
216
|
+
})
|
|
217
|
+
return loop
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* @since 1.0.0
|
|
222
|
+
* @category constructors
|
|
223
|
+
*/
|
|
224
|
+
export const unpack = <IE = never, Done = unknown>(options?: NdjsonOptions): Channel.Channel<
|
|
225
|
+
Chunk.Chunk<unknown>,
|
|
226
|
+
Chunk.Chunk<Uint8Array>,
|
|
227
|
+
IE | NdjsonError,
|
|
228
|
+
IE,
|
|
229
|
+
Done,
|
|
230
|
+
Done
|
|
231
|
+
> => {
|
|
232
|
+
return Channel.pipeTo(decodeString(), unpackString(options))
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* @since 1.0.0
|
|
237
|
+
* @category constructors
|
|
238
|
+
*/
|
|
239
|
+
export const unpackSchema = <A, I, R>(
|
|
240
|
+
schema: Schema.Schema<A, I, R>
|
|
241
|
+
) =>
|
|
242
|
+
<IE = never, Done = unknown>(options?: NdjsonOptions): Channel.Channel<
|
|
243
|
+
Chunk.Chunk<A>,
|
|
244
|
+
Chunk.Chunk<Uint8Array>,
|
|
245
|
+
NdjsonError | ParseError | IE,
|
|
246
|
+
IE,
|
|
247
|
+
Done,
|
|
248
|
+
Done,
|
|
249
|
+
R
|
|
250
|
+
> => Channel.pipeTo(unpack(options), ChannelSchema.decodeUnknown(schema)())
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* @since 1.0.0
|
|
254
|
+
* @category constructors
|
|
255
|
+
*/
|
|
256
|
+
export const unpackSchemaString = <A, I, R>(
|
|
257
|
+
schema: Schema.Schema<A, I, R>
|
|
258
|
+
) =>
|
|
259
|
+
<IE = never, Done = unknown>(options?: NdjsonOptions): Channel.Channel<
|
|
260
|
+
Chunk.Chunk<A>,
|
|
261
|
+
Chunk.Chunk<string>,
|
|
262
|
+
NdjsonError | ParseError | IE,
|
|
263
|
+
IE,
|
|
264
|
+
Done,
|
|
265
|
+
Done,
|
|
266
|
+
R
|
|
267
|
+
> => Channel.pipeTo(unpackString(options), ChannelSchema.decodeUnknown(schema)())
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* @since 1.0.0
|
|
271
|
+
* @category combinators
|
|
272
|
+
*/
|
|
273
|
+
export const duplex: {
|
|
274
|
+
/**
|
|
275
|
+
* @since 1.0.0
|
|
276
|
+
* @category combinators
|
|
277
|
+
*/
|
|
278
|
+
(options?: NdjsonOptions): <R, IE, OE, OutDone, InDone>(
|
|
279
|
+
self: Channel.Channel<Chunk.Chunk<Uint8Array>, Chunk.Chunk<Uint8Array>, OE, IE | NdjsonError, OutDone, InDone, R>
|
|
280
|
+
) => Channel.Channel<Chunk.Chunk<unknown>, Chunk.Chunk<unknown>, NdjsonError | OE, IE, OutDone, InDone, R>
|
|
281
|
+
/**
|
|
282
|
+
* @since 1.0.0
|
|
283
|
+
* @category combinators
|
|
284
|
+
*/
|
|
285
|
+
<R, IE, OE, OutDone, InDone>(
|
|
286
|
+
self: Channel.Channel<Chunk.Chunk<Uint8Array>, Chunk.Chunk<Uint8Array>, OE, IE | NdjsonError, OutDone, InDone, R>,
|
|
287
|
+
options?: NdjsonOptions
|
|
288
|
+
): Channel.Channel<Chunk.Chunk<unknown>, Chunk.Chunk<unknown>, NdjsonError | OE, IE, OutDone, InDone, R>
|
|
289
|
+
} = dual((args) => Channel.isChannel(args[0]), <R, IE, OE, OutDone, InDone>(
|
|
290
|
+
self: Channel.Channel<Chunk.Chunk<Uint8Array>, Chunk.Chunk<Uint8Array>, OE, IE | NdjsonError, OutDone, InDone, R>,
|
|
291
|
+
options?: NdjsonOptions
|
|
292
|
+
): Channel.Channel<Chunk.Chunk<unknown>, Chunk.Chunk<unknown>, NdjsonError | OE, IE, OutDone, InDone, R> =>
|
|
293
|
+
Channel.pipeTo(
|
|
294
|
+
Channel.pipeTo(pack(), self),
|
|
295
|
+
unpack(options)
|
|
296
|
+
))
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* @since 1.0.0
|
|
300
|
+
* @category combinators
|
|
301
|
+
*/
|
|
302
|
+
export const duplexString: {
|
|
303
|
+
/**
|
|
304
|
+
* @since 1.0.0
|
|
305
|
+
* @category combinators
|
|
306
|
+
*/
|
|
307
|
+
(options?: NdjsonOptions): <R, IE, OE, OutDone, InDone>(
|
|
308
|
+
self: Channel.Channel<Chunk.Chunk<string>, Chunk.Chunk<string>, OE, IE | NdjsonError, OutDone, InDone, R>
|
|
309
|
+
) => Channel.Channel<Chunk.Chunk<unknown>, Chunk.Chunk<unknown>, NdjsonError | OE, IE, OutDone, InDone, R>
|
|
310
|
+
/**
|
|
311
|
+
* @since 1.0.0
|
|
312
|
+
* @category combinators
|
|
313
|
+
*/
|
|
314
|
+
<R, IE, OE, OutDone, InDone>(
|
|
315
|
+
self: Channel.Channel<Chunk.Chunk<string>, Chunk.Chunk<string>, OE, IE | NdjsonError, OutDone, InDone, R>,
|
|
316
|
+
options?: NdjsonOptions
|
|
317
|
+
): Channel.Channel<Chunk.Chunk<unknown>, Chunk.Chunk<unknown>, NdjsonError | OE, IE, OutDone, InDone, R>
|
|
318
|
+
} = dual((args) => Channel.isChannel(args[0]), <R, IE, OE, OutDone, InDone>(
|
|
319
|
+
self: Channel.Channel<Chunk.Chunk<string>, Chunk.Chunk<string>, OE, IE | NdjsonError, OutDone, InDone, R>,
|
|
320
|
+
options?: NdjsonOptions
|
|
321
|
+
): Channel.Channel<Chunk.Chunk<unknown>, Chunk.Chunk<unknown>, NdjsonError | OE, IE, OutDone, InDone, R> =>
|
|
322
|
+
Channel.pipeTo(
|
|
323
|
+
Channel.pipeTo(packString(), self),
|
|
324
|
+
unpackString(options)
|
|
325
|
+
))
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* @since 1.0.0
|
|
329
|
+
* @category combinators
|
|
330
|
+
*/
|
|
331
|
+
export const duplexSchema: {
|
|
332
|
+
/**
|
|
333
|
+
* @since 1.0.0
|
|
334
|
+
* @category combinators
|
|
335
|
+
*/
|
|
336
|
+
<IA, II, IR, OA, OI, OR>(
|
|
337
|
+
options: Partial<NdjsonOptions> & {
|
|
338
|
+
readonly inputSchema: Schema.Schema<IA, II, IR>
|
|
339
|
+
readonly outputSchema: Schema.Schema<OA, OI, OR>
|
|
340
|
+
}
|
|
341
|
+
): <R, InErr, OutErr, OutDone, InDone>(
|
|
342
|
+
self: Channel.Channel<
|
|
343
|
+
Chunk.Chunk<Uint8Array>,
|
|
344
|
+
Chunk.Chunk<Uint8Array>,
|
|
345
|
+
OutErr,
|
|
346
|
+
NdjsonError | ParseError | InErr,
|
|
347
|
+
OutDone,
|
|
348
|
+
InDone,
|
|
349
|
+
R
|
|
350
|
+
>
|
|
351
|
+
) => Channel.Channel<
|
|
352
|
+
Chunk.Chunk<OA>,
|
|
353
|
+
Chunk.Chunk<IA>,
|
|
354
|
+
NdjsonError | ParseError | OutErr,
|
|
355
|
+
InErr,
|
|
356
|
+
OutDone,
|
|
357
|
+
InDone,
|
|
358
|
+
R | IR | OR
|
|
359
|
+
>
|
|
360
|
+
/**
|
|
361
|
+
* @since 1.0.0
|
|
362
|
+
* @category combinators
|
|
363
|
+
*/
|
|
364
|
+
<R, InErr, OutErr, OutDone, InDone, IA, II, IR, OA, OI, OR>(
|
|
365
|
+
self: Channel.Channel<
|
|
366
|
+
Chunk.Chunk<Uint8Array>,
|
|
367
|
+
Chunk.Chunk<Uint8Array>,
|
|
368
|
+
OutErr,
|
|
369
|
+
NdjsonError | ParseError | InErr,
|
|
370
|
+
OutDone,
|
|
371
|
+
InDone,
|
|
372
|
+
R
|
|
373
|
+
>,
|
|
374
|
+
options: Partial<NdjsonOptions> & {
|
|
375
|
+
readonly inputSchema: Schema.Schema<IA, II, IR>
|
|
376
|
+
readonly outputSchema: Schema.Schema<OA, OI, OR>
|
|
377
|
+
}
|
|
378
|
+
): Channel.Channel<
|
|
379
|
+
Chunk.Chunk<OA>,
|
|
380
|
+
Chunk.Chunk<IA>,
|
|
381
|
+
NdjsonError | ParseError | OutErr,
|
|
382
|
+
InErr,
|
|
383
|
+
OutDone,
|
|
384
|
+
InDone,
|
|
385
|
+
R | IR | OR
|
|
386
|
+
>
|
|
387
|
+
} = dual(2, <R, InErr, OutErr, OutDone, InDone, IA, II, IR, OA, OI, OR>(
|
|
388
|
+
self: Channel.Channel<
|
|
389
|
+
Chunk.Chunk<Uint8Array>,
|
|
390
|
+
Chunk.Chunk<Uint8Array>,
|
|
391
|
+
OutErr,
|
|
392
|
+
NdjsonError | ParseError | InErr,
|
|
393
|
+
OutDone,
|
|
394
|
+
InDone,
|
|
395
|
+
R
|
|
396
|
+
>,
|
|
397
|
+
options: Partial<NdjsonOptions> & {
|
|
398
|
+
readonly inputSchema: Schema.Schema<IA, II, IR>
|
|
399
|
+
readonly outputSchema: Schema.Schema<OA, OI, OR>
|
|
400
|
+
}
|
|
401
|
+
): Channel.Channel<
|
|
402
|
+
Chunk.Chunk<OA>,
|
|
403
|
+
Chunk.Chunk<IA>,
|
|
404
|
+
NdjsonError | ParseError | OutErr,
|
|
405
|
+
InErr,
|
|
406
|
+
OutDone,
|
|
407
|
+
InDone,
|
|
408
|
+
R | IR | OR
|
|
409
|
+
> => ChannelSchema.duplexUnknown(duplex(self, options), options))
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* @since 1.0.0
|
|
413
|
+
* @category combinators
|
|
414
|
+
*/
|
|
415
|
+
export const duplexSchemaString: {
|
|
416
|
+
/**
|
|
417
|
+
* @since 1.0.0
|
|
418
|
+
* @category combinators
|
|
419
|
+
*/
|
|
420
|
+
<IA, II, IR, OA, OI, OR>(
|
|
421
|
+
options: Partial<NdjsonOptions> & {
|
|
422
|
+
readonly inputSchema: Schema.Schema<IA, II, IR>
|
|
423
|
+
readonly outputSchema: Schema.Schema<OA, OI, OR>
|
|
424
|
+
}
|
|
425
|
+
): <R, InErr, OutErr, OutDone, InDone>(
|
|
426
|
+
self: Channel.Channel<
|
|
427
|
+
Chunk.Chunk<string>,
|
|
428
|
+
Chunk.Chunk<string>,
|
|
429
|
+
OutErr,
|
|
430
|
+
NdjsonError | ParseError | InErr,
|
|
431
|
+
OutDone,
|
|
432
|
+
InDone,
|
|
433
|
+
R
|
|
434
|
+
>
|
|
435
|
+
) => Channel.Channel<
|
|
436
|
+
Chunk.Chunk<OA>,
|
|
437
|
+
Chunk.Chunk<IA>,
|
|
438
|
+
NdjsonError | ParseError | OutErr,
|
|
439
|
+
InErr,
|
|
440
|
+
OutDone,
|
|
441
|
+
InDone,
|
|
442
|
+
R | IR | OR
|
|
443
|
+
>
|
|
444
|
+
/**
|
|
445
|
+
* @since 1.0.0
|
|
446
|
+
* @category combinators
|
|
447
|
+
*/
|
|
448
|
+
<R, InErr, OutErr, OutDone, InDone, IA, II, IR, OA, OI, OR>(
|
|
449
|
+
self: Channel.Channel<
|
|
450
|
+
Chunk.Chunk<string>,
|
|
451
|
+
Chunk.Chunk<string>,
|
|
452
|
+
OutErr,
|
|
453
|
+
NdjsonError | ParseError | InErr,
|
|
454
|
+
OutDone,
|
|
455
|
+
InDone,
|
|
456
|
+
R
|
|
457
|
+
>,
|
|
458
|
+
options: Partial<NdjsonOptions> & {
|
|
459
|
+
readonly inputSchema: Schema.Schema<IA, II, IR>
|
|
460
|
+
readonly outputSchema: Schema.Schema<OA, OI, OR>
|
|
461
|
+
}
|
|
462
|
+
): Channel.Channel<
|
|
463
|
+
Chunk.Chunk<OA>,
|
|
464
|
+
Chunk.Chunk<IA>,
|
|
465
|
+
NdjsonError | ParseError | OutErr,
|
|
466
|
+
InErr,
|
|
467
|
+
OutDone,
|
|
468
|
+
InDone,
|
|
469
|
+
R | IR | OR
|
|
470
|
+
>
|
|
471
|
+
} = dual(2, <R, InErr, OutErr, OutDone, InDone, IA, II, IR, OA, OI, OR>(
|
|
472
|
+
self: Channel.Channel<
|
|
473
|
+
Chunk.Chunk<string>,
|
|
474
|
+
Chunk.Chunk<string>,
|
|
475
|
+
OutErr,
|
|
476
|
+
NdjsonError | ParseError | InErr,
|
|
477
|
+
OutDone,
|
|
478
|
+
InDone,
|
|
479
|
+
R
|
|
480
|
+
>,
|
|
481
|
+
options: Partial<NdjsonOptions> & {
|
|
482
|
+
readonly inputSchema: Schema.Schema<IA, II, IR>
|
|
483
|
+
readonly outputSchema: Schema.Schema<OA, OI, OR>
|
|
484
|
+
}
|
|
485
|
+
): Channel.Channel<
|
|
486
|
+
Chunk.Chunk<OA>,
|
|
487
|
+
Chunk.Chunk<IA>,
|
|
488
|
+
NdjsonError | ParseError | OutErr,
|
|
489
|
+
InErr,
|
|
490
|
+
OutDone,
|
|
491
|
+
InDone,
|
|
492
|
+
R | IR | OR
|
|
493
|
+
> => ChannelSchema.duplexUnknown(duplexString(self, options), options))
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since 1.0.0
|
|
3
|
+
*/
|
|
4
|
+
import * as Context from "effect/Context"
|
|
5
|
+
import * as Data from "effect/Data"
|
|
6
|
+
import type * as Effect from "effect/Effect"
|
|
7
|
+
import type * as Socket from "./Socket.js"
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @since 1.0.0
|
|
11
|
+
* @category tags
|
|
12
|
+
*/
|
|
13
|
+
export class SocketServer extends Context.Tag("@effect/platform/SocketServer")<
|
|
14
|
+
SocketServer,
|
|
15
|
+
{
|
|
16
|
+
readonly address: Address
|
|
17
|
+
readonly run: <R, E, _>(
|
|
18
|
+
handler: (socket: Socket.Socket) => Effect.Effect<_, E, R>
|
|
19
|
+
) => Effect.Effect<never, SocketServerError, R>
|
|
20
|
+
}
|
|
21
|
+
>() {}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @since 1.0.0
|
|
25
|
+
* @category errors
|
|
26
|
+
*/
|
|
27
|
+
export const ErrorTypeId: unique symbol = Symbol.for("@effect/platform/SocketServer/SocketServerError")
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @since 1.0.0
|
|
31
|
+
* @category errors
|
|
32
|
+
*/
|
|
33
|
+
export type ErrorTypeId = typeof ErrorTypeId
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @since 1.0.0
|
|
37
|
+
* @category errors
|
|
38
|
+
*/
|
|
39
|
+
export class SocketServerError extends Data.TaggedError("SocketServerError")<{
|
|
40
|
+
readonly reason: "Open" | "Unknown"
|
|
41
|
+
readonly cause: unknown
|
|
42
|
+
}> {
|
|
43
|
+
/**
|
|
44
|
+
* @since 1.0.0
|
|
45
|
+
*/
|
|
46
|
+
readonly [ErrorTypeId]: ErrorTypeId = ErrorTypeId
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @since 1.0.0
|
|
50
|
+
*/
|
|
51
|
+
get message(): string {
|
|
52
|
+
return this.reason
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @since 1.0.0
|
|
58
|
+
* @category models
|
|
59
|
+
*/
|
|
60
|
+
export type Address = UnixAddress | TcpAddress
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @since 1.0.0
|
|
64
|
+
* @category models
|
|
65
|
+
*/
|
|
66
|
+
export interface TcpAddress {
|
|
67
|
+
readonly _tag: "TcpAddress"
|
|
68
|
+
readonly hostname: string
|
|
69
|
+
readonly port: number
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @since 1.0.0
|
|
74
|
+
* @category models
|
|
75
|
+
*/
|
|
76
|
+
export interface UnixAddress {
|
|
77
|
+
readonly _tag: "UnixAddress"
|
|
78
|
+
readonly path: string
|
|
79
|
+
}
|
package/src/Transferable.ts
CHANGED
|
@@ -17,8 +17,8 @@ export interface CollectorService {
|
|
|
17
17
|
readonly unsafeAddAll: (_: Iterable<globalThis.Transferable>) => void
|
|
18
18
|
readonly read: Effect.Effect<Array<globalThis.Transferable>>
|
|
19
19
|
readonly unsafeRead: () => Array<globalThis.Transferable>
|
|
20
|
-
readonly unsafeClear: () =>
|
|
21
|
-
readonly clear: Effect.Effect<
|
|
20
|
+
readonly unsafeClear: () => Array<globalThis.Transferable>
|
|
21
|
+
readonly clear: Effect.Effect<Array<globalThis.Transferable>>
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
/**
|
|
@@ -35,15 +35,16 @@ export class Collector extends Context.Tag("@effect/platform/Transferable/Collec
|
|
|
35
35
|
* @category constructors
|
|
36
36
|
*/
|
|
37
37
|
export const unsafeMakeCollector = (): CollectorService => {
|
|
38
|
-
|
|
38
|
+
let tranferables: Array<globalThis.Transferable> = []
|
|
39
39
|
const unsafeAddAll = (transfers: Iterable<globalThis.Transferable>): void => {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
40
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
41
|
+
tranferables.push(...transfers)
|
|
43
42
|
}
|
|
44
43
|
const unsafeRead = (): Array<globalThis.Transferable> => tranferables
|
|
45
|
-
const unsafeClear = ():
|
|
46
|
-
|
|
44
|
+
const unsafeClear = (): Array<globalThis.Transferable> => {
|
|
45
|
+
const prev = tranferables
|
|
46
|
+
tranferables = []
|
|
47
|
+
return prev
|
|
47
48
|
}
|
|
48
49
|
return Collector.of({
|
|
49
50
|
unsafeAddAll,
|
package/src/Url.ts
CHANGED
|
@@ -194,9 +194,9 @@ export const mutate: {
|
|
|
194
194
|
})
|
|
195
195
|
|
|
196
196
|
/** @internal */
|
|
197
|
-
const immutableURLSetter = <P extends keyof URL>(property: P): {
|
|
198
|
-
(value: URL[P]): (url: URL) => URL
|
|
199
|
-
(url: URL, value: URL[P]): URL
|
|
197
|
+
const immutableURLSetter = <P extends keyof URL, A = never>(property: P): {
|
|
198
|
+
(value: URL[P] | A): (url: URL) => URL
|
|
199
|
+
(url: URL, value: URL[P] | A): URL
|
|
200
200
|
} =>
|
|
201
201
|
dual(2, (url: URL, value: URL[P]) =>
|
|
202
202
|
mutate(url, (url) => {
|
|
@@ -354,14 +354,14 @@ export const setPort: {
|
|
|
354
354
|
* @since 1.0.0
|
|
355
355
|
* @category Setters
|
|
356
356
|
*/
|
|
357
|
-
(port: string): (url: URL) => URL
|
|
357
|
+
(port: string | number): (url: URL) => URL
|
|
358
358
|
/**
|
|
359
359
|
* Updates the port of the URL.
|
|
360
360
|
*
|
|
361
361
|
* @since 1.0.0
|
|
362
362
|
* @category Setters
|
|
363
363
|
*/
|
|
364
|
-
(url: URL, port: string): URL
|
|
364
|
+
(url: URL, port: string | number): URL
|
|
365
365
|
} = immutableURLSetter("port")
|
|
366
366
|
|
|
367
367
|
/**
|
package/src/UrlParams.ts
CHANGED
|
@@ -21,7 +21,7 @@ export interface UrlParams extends ReadonlyArray<readonly [string, string]> {}
|
|
|
21
21
|
* @category models
|
|
22
22
|
*/
|
|
23
23
|
export type Input =
|
|
24
|
-
|
|
|
24
|
+
| CoercibleRecord
|
|
25
25
|
| Iterable<readonly [string, Coercible]>
|
|
26
26
|
| URLSearchParams
|
|
27
27
|
|
|
@@ -31,13 +31,35 @@ export type Input =
|
|
|
31
31
|
*/
|
|
32
32
|
export type Coercible = string | number | bigint | boolean | null | undefined
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* @since 1.0.0
|
|
36
|
+
* @category models
|
|
37
|
+
*/
|
|
38
|
+
export interface CoercibleRecord {
|
|
39
|
+
readonly [key: string]: Coercible | ReadonlyArray<Coercible> | CoercibleRecord
|
|
40
|
+
}
|
|
41
|
+
|
|
34
42
|
/**
|
|
35
43
|
* @since 1.0.0
|
|
36
44
|
* @category constructors
|
|
37
45
|
*/
|
|
38
46
|
export const fromInput = (input: Input): UrlParams => {
|
|
47
|
+
const parsed = fromInputNested(input)
|
|
48
|
+
const out: Array<[string, string]> = []
|
|
49
|
+
for (let i = 0; i < parsed.length; i++) {
|
|
50
|
+
if (Array.isArray(parsed[i][0])) {
|
|
51
|
+
const [keys, value] = parsed[i] as [Array<string>, string]
|
|
52
|
+
out.push([`${keys[0]}[${keys.slice(1).join("][")}]`, value])
|
|
53
|
+
} else {
|
|
54
|
+
out.push(parsed[i] as [string, string])
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return out
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const fromInputNested = (input: Input): Array<[string | Array<string>, any]> => {
|
|
39
61
|
const entries = Symbol.iterator in input ? Arr.fromIterable(input) : Object.entries(input)
|
|
40
|
-
const out: Array<
|
|
62
|
+
const out: Array<[string | Array<string>, string]> = []
|
|
41
63
|
for (const [key, value] of entries) {
|
|
42
64
|
if (Array.isArray(value)) {
|
|
43
65
|
for (let i = 0; i < value.length; i++) {
|
|
@@ -45,6 +67,11 @@ export const fromInput = (input: Input): UrlParams => {
|
|
|
45
67
|
out.push([key, String(value[i])])
|
|
46
68
|
}
|
|
47
69
|
}
|
|
70
|
+
} else if (typeof value === "object") {
|
|
71
|
+
const nested = fromInputNested(value as CoercibleRecord)
|
|
72
|
+
for (const [k, v] of nested) {
|
|
73
|
+
out.push([[key, ...(typeof k === "string" ? [k] : k)], v])
|
|
74
|
+
}
|
|
48
75
|
} else if (value !== undefined) {
|
|
49
76
|
out.push([key, String(value)])
|
|
50
77
|
}
|