@fncts/http 0.0.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.
Files changed (211) hide show
  1. package/Body/api.d.ts +63 -0
  2. package/Body/definition.d.ts +53 -0
  3. package/Body.d.ts +2 -0
  4. package/BodyError.d.ts +30 -0
  5. package/Headers.d.ts +42 -0
  6. package/HttpApp.d.ts +46 -0
  7. package/IncomingMessage/api.d.ts +19 -0
  8. package/IncomingMessage/definition.d.ts +21 -0
  9. package/IncomingMessage.d.ts +2 -0
  10. package/Method.d.ts +2 -0
  11. package/Middleware.d.ts +24 -0
  12. package/QueryParams.d.ts +7 -0
  13. package/RequestError.d.ts +10 -0
  14. package/ResponseError.d.ts +14 -0
  15. package/Route/api.d.ts +37 -0
  16. package/Route/definition.d.ts +35 -0
  17. package/Route/internal.d.ts +17 -0
  18. package/Route.d.ts +2 -0
  19. package/RouteNotFound.d.ts +8 -0
  20. package/Router/api.d.ts +96 -0
  21. package/Router/definition.d.ts +28 -0
  22. package/Router/internal.d.ts +26 -0
  23. package/Router.d.ts +2 -0
  24. package/Server.d.ts +53 -0
  25. package/ServerError.d.ts +9 -0
  26. package/ServerRequest/api.d.ts +6 -0
  27. package/ServerRequest/definition.d.ts +30 -0
  28. package/ServerRequest/internal.d.ts +33 -0
  29. package/ServerRequest.d.ts +2 -0
  30. package/ServerResponse/api.d.ts +69 -0
  31. package/ServerResponse/definition.d.ts +30 -0
  32. package/ServerResponse.d.ts +2 -0
  33. package/Socket.d.ts +107 -0
  34. package/UrlParams.d.ts +21 -0
  35. package/_cjs/Body/api.cjs +93 -0
  36. package/_cjs/Body/api.cjs.map +1 -0
  37. package/_cjs/Body/definition.cjs +71 -0
  38. package/_cjs/Body/definition.cjs.map +1 -0
  39. package/_cjs/Body.cjs +28 -0
  40. package/_cjs/Body.cjs.map +1 -0
  41. package/_cjs/BodyError.cjs +43 -0
  42. package/_cjs/BodyError.cjs.map +1 -0
  43. package/_cjs/Headers.cjs +87 -0
  44. package/_cjs/Headers.cjs.map +1 -0
  45. package/_cjs/HttpApp.cjs +109 -0
  46. package/_cjs/HttpApp.cjs.map +1 -0
  47. package/_cjs/IncomingMessage/api.cjs +35 -0
  48. package/_cjs/IncomingMessage/api.cjs.map +1 -0
  49. package/_cjs/IncomingMessage/definition.cjs +20 -0
  50. package/_cjs/IncomingMessage/definition.cjs.map +1 -0
  51. package/_cjs/IncomingMessage.cjs +28 -0
  52. package/_cjs/IncomingMessage.cjs.map +1 -0
  53. package/_cjs/Method.cjs +10 -0
  54. package/_cjs/Method.cjs.map +1 -0
  55. package/_cjs/Middleware.cjs +16 -0
  56. package/_cjs/Middleware.cjs.map +1 -0
  57. package/_cjs/QueryParams.cjs +6 -0
  58. package/_cjs/QueryParams.cjs.map +1 -0
  59. package/_cjs/RequestError.cjs +19 -0
  60. package/_cjs/RequestError.cjs.map +1 -0
  61. package/_cjs/ResponseError.cjs +27 -0
  62. package/_cjs/ResponseError.cjs.map +1 -0
  63. package/_cjs/Route/api.cjs +61 -0
  64. package/_cjs/Route/api.cjs.map +1 -0
  65. package/_cjs/Route/definition.cjs +35 -0
  66. package/_cjs/Route/definition.cjs.map +1 -0
  67. package/_cjs/Route/internal.cjs +31 -0
  68. package/_cjs/Route/internal.cjs.map +1 -0
  69. package/_cjs/Route.cjs +28 -0
  70. package/_cjs/Route.cjs.map +1 -0
  71. package/_cjs/RouteNotFound.cjs +18 -0
  72. package/_cjs/RouteNotFound.cjs.map +1 -0
  73. package/_cjs/Router/api.cjs +141 -0
  74. package/_cjs/Router/api.cjs.map +1 -0
  75. package/_cjs/Router/definition.cjs +22 -0
  76. package/_cjs/Router/definition.cjs.map +1 -0
  77. package/_cjs/Router/internal.cjs +85 -0
  78. package/_cjs/Router/internal.cjs.map +1 -0
  79. package/_cjs/Router.cjs +28 -0
  80. package/_cjs/Router.cjs.map +1 -0
  81. package/_cjs/Server.cjs +53 -0
  82. package/_cjs/Server.cjs.map +1 -0
  83. package/_cjs/ServerError.cjs +21 -0
  84. package/_cjs/ServerError.cjs.map +1 -0
  85. package/_cjs/ServerRequest/api.cjs +14 -0
  86. package/_cjs/ServerRequest/api.cjs.map +1 -0
  87. package/_cjs/ServerRequest/definition.cjs +29 -0
  88. package/_cjs/ServerRequest/definition.cjs.map +1 -0
  89. package/_cjs/ServerRequest/internal.cjs +77 -0
  90. package/_cjs/ServerRequest/internal.cjs.map +1 -0
  91. package/_cjs/ServerRequest.cjs +28 -0
  92. package/_cjs/ServerRequest.cjs.map +1 -0
  93. package/_cjs/ServerResponse/api.cjs +157 -0
  94. package/_cjs/ServerResponse/api.cjs.map +1 -0
  95. package/_cjs/ServerResponse/definition.cjs +44 -0
  96. package/_cjs/ServerResponse/definition.cjs.map +1 -0
  97. package/_cjs/ServerResponse.cjs +28 -0
  98. package/_cjs/ServerResponse.cjs.map +1 -0
  99. package/_cjs/Socket.cjs +221 -0
  100. package/_cjs/Socket.cjs.map +1 -0
  101. package/_cjs/UrlParams.cjs +34 -0
  102. package/_cjs/UrlParams.cjs.map +1 -0
  103. package/_cjs/global.cjs +6 -0
  104. package/_cjs/global.cjs.map +1 -0
  105. package/_mjs/Body/api.mjs +78 -0
  106. package/_mjs/Body/api.mjs.map +1 -0
  107. package/_mjs/Body/definition.mjs +58 -0
  108. package/_mjs/Body/definition.mjs.map +1 -0
  109. package/_mjs/Body.mjs +5 -0
  110. package/_mjs/Body.mjs.map +1 -0
  111. package/_mjs/BodyError.mjs +33 -0
  112. package/_mjs/BodyError.mjs.map +1 -0
  113. package/_mjs/Headers.mjs +75 -0
  114. package/_mjs/Headers.mjs.map +1 -0
  115. package/_mjs/HttpApp.mjs +96 -0
  116. package/_mjs/HttpApp.mjs.map +1 -0
  117. package/_mjs/IncomingMessage/api.mjs +25 -0
  118. package/_mjs/IncomingMessage/api.mjs.map +1 -0
  119. package/_mjs/IncomingMessage/definition.mjs +13 -0
  120. package/_mjs/IncomingMessage/definition.mjs.map +1 -0
  121. package/_mjs/IncomingMessage.mjs +5 -0
  122. package/_mjs/IncomingMessage.mjs.map +1 -0
  123. package/_mjs/Method.mjs +4 -0
  124. package/_mjs/Method.mjs.map +1 -0
  125. package/_mjs/Middleware.mjs +9 -0
  126. package/_mjs/Middleware.mjs.map +1 -0
  127. package/_mjs/QueryParams.mjs +2 -0
  128. package/_mjs/QueryParams.mjs.map +1 -0
  129. package/_mjs/RequestError.mjs +12 -0
  130. package/_mjs/RequestError.mjs.map +1 -0
  131. package/_mjs/ResponseError.mjs +20 -0
  132. package/_mjs/ResponseError.mjs.map +1 -0
  133. package/_mjs/Route/api.mjs +48 -0
  134. package/_mjs/Route/api.mjs.map +1 -0
  135. package/_mjs/Route/definition.mjs +25 -0
  136. package/_mjs/Route/definition.mjs.map +1 -0
  137. package/_mjs/Route/internal.mjs +21 -0
  138. package/_mjs/Route/internal.mjs.map +1 -0
  139. package/_mjs/Route.mjs +5 -0
  140. package/_mjs/Route.mjs.map +1 -0
  141. package/_mjs/RouteNotFound.mjs +11 -0
  142. package/_mjs/RouteNotFound.mjs.map +1 -0
  143. package/_mjs/Router/api.mjs +123 -0
  144. package/_mjs/Router/api.mjs.map +1 -0
  145. package/_mjs/Router/definition.mjs +15 -0
  146. package/_mjs/Router/definition.mjs.map +1 -0
  147. package/_mjs/Router/internal.mjs +76 -0
  148. package/_mjs/Router/internal.mjs.map +1 -0
  149. package/_mjs/Router.mjs +5 -0
  150. package/_mjs/Router.mjs.map +1 -0
  151. package/_mjs/Server.mjs +41 -0
  152. package/_mjs/Server.mjs.map +1 -0
  153. package/_mjs/ServerError.mjs +14 -0
  154. package/_mjs/ServerError.mjs.map +1 -0
  155. package/_mjs/ServerRequest/api.mjs +8 -0
  156. package/_mjs/ServerRequest/api.mjs.map +1 -0
  157. package/_mjs/ServerRequest/definition.mjs +20 -0
  158. package/_mjs/ServerRequest/definition.mjs.map +1 -0
  159. package/_mjs/ServerRequest/internal.mjs +68 -0
  160. package/_mjs/ServerRequest/internal.mjs.map +1 -0
  161. package/_mjs/ServerRequest.mjs +5 -0
  162. package/_mjs/ServerRequest.mjs.map +1 -0
  163. package/_mjs/ServerResponse/api.mjs +138 -0
  164. package/_mjs/ServerResponse/api.mjs.map +1 -0
  165. package/_mjs/ServerResponse/definition.mjs +34 -0
  166. package/_mjs/ServerResponse/definition.mjs.map +1 -0
  167. package/_mjs/ServerResponse.mjs +5 -0
  168. package/_mjs/ServerResponse.mjs.map +1 -0
  169. package/_mjs/Socket.mjs +202 -0
  170. package/_mjs/Socket.mjs.map +1 -0
  171. package/_mjs/UrlParams.mjs +25 -0
  172. package/_mjs/UrlParams.mjs.map +1 -0
  173. package/_mjs/global.mjs +2 -0
  174. package/_mjs/global.mjs.map +1 -0
  175. package/_src/Body/api.ts +106 -0
  176. package/_src/Body/definition.ts +74 -0
  177. package/_src/Body.ts +5 -0
  178. package/_src/BodyError.ts +38 -0
  179. package/_src/Headers.ts +84 -0
  180. package/_src/HttpApp.ts +129 -0
  181. package/_src/IncomingMessage/api.ts +25 -0
  182. package/_src/IncomingMessage/definition.ts +20 -0
  183. package/_src/IncomingMessage.ts +5 -0
  184. package/_src/Method.ts +5 -0
  185. package/_src/Middleware.ts +29 -0
  186. package/_src/QueryParams.ts +7 -0
  187. package/_src/RequestError.ts +13 -0
  188. package/_src/ResponseError.ts +25 -0
  189. package/_src/Route/api.ts +53 -0
  190. package/_src/Route/definition.ts +40 -0
  191. package/_src/Route/internal.ts +25 -0
  192. package/_src/Route.ts +5 -0
  193. package/_src/RouteNotFound.ts +14 -0
  194. package/_src/Router/api.ts +161 -0
  195. package/_src/Router/definition.ts +29 -0
  196. package/_src/Router/internal.ts +95 -0
  197. package/_src/Router.ts +5 -0
  198. package/_src/Server.ts +88 -0
  199. package/_src/ServerError.ts +14 -0
  200. package/_src/ServerRequest/api.ts +10 -0
  201. package/_src/ServerRequest/definition.ts +33 -0
  202. package/_src/ServerRequest/internal.ts +106 -0
  203. package/_src/ServerRequest.ts +5 -0
  204. package/_src/ServerResponse/api.ts +177 -0
  205. package/_src/ServerResponse/definition.ts +51 -0
  206. package/_src/ServerResponse.ts +5 -0
  207. package/_src/Socket.ts +294 -0
  208. package/_src/UrlParams.ts +28 -0
  209. package/_src/global.ts +2 -0
  210. package/global.d.ts +1 -0
  211. package/package.json +27 -0
package/_src/Socket.ts ADDED
@@ -0,0 +1,294 @@
1
+ import type { AsyncInputProducer } from "@fncts/io/Channel/internal/AsyncInputProducer";
2
+
3
+ import { CauseTag } from "@fncts/base/data/Cause";
4
+ import { WebSocket as IsoWs } from "isows";
5
+
6
+ export const SocketTypeId = Symbol.for("fncts.http.Socket");
7
+ export type SocketTypeId = typeof SocketTypeId;
8
+
9
+ /**
10
+ * @tsplus type fncts.http.Socket
11
+ * @tsplus companion fncts.http.SocketOps
12
+ */
13
+ export abstract class Socket {
14
+ readonly [SocketTypeId]: SocketTypeId = SocketTypeId;
15
+ abstract run<R, E, A>(handler: (_: Uint8Array) => IO<R, E, A>): IO<R, E | SocketError, void>;
16
+ abstract writer: IO<Scope, never, (chunk: Uint8Array | CloseEvent) => UIO<void>>;
17
+ }
18
+
19
+ /**
20
+ * @tsplus static fncts.http.SocketOps Tag
21
+ */
22
+ export const SocketTag = Tag<Socket>();
23
+
24
+ export const SocketGenericErrorTypeId = Symbol.for("fncts.http.Socket.SocketGenericError");
25
+ export type SocketGenericErrorTypeId = typeof SocketGenericErrorTypeId;
26
+
27
+ export class SocketGenericError extends Error {
28
+ readonly [SocketGenericErrorTypeId]: SocketGenericErrorTypeId = SocketGenericErrorTypeId;
29
+ constructor(
30
+ readonly reason: "Write" | "Read" | "Open" | "OpenTimeout",
31
+ readonly error: unknown,
32
+ ) {
33
+ super();
34
+ }
35
+ }
36
+
37
+ export const SocketCloseErrorTypeId = Symbol.for("fncts.http.Socket.SocketCloseError");
38
+ export type SocketCloseErrorTypeId = typeof SocketCloseErrorTypeId;
39
+
40
+ export class SocketCloseError extends Error {
41
+ readonly [SocketCloseErrorTypeId]: SocketCloseErrorTypeId = SocketCloseErrorTypeId;
42
+ constructor(
43
+ readonly reason: "Close",
44
+ readonly code: number,
45
+ readonly closeReason: string | undefined,
46
+ readonly error: unknown,
47
+ ) {
48
+ super();
49
+ }
50
+
51
+ static isClean(isClean: (code: number) => boolean) {
52
+ return (u: unknown): u is SocketCloseError => {
53
+ return isSocketCloseError(u) && isClean(u.code);
54
+ };
55
+ }
56
+ }
57
+
58
+ export function isSocketCloseError(u: unknown): u is SocketCloseError {
59
+ return isObject(u) && SocketCloseErrorTypeId in u;
60
+ }
61
+
62
+ export type SocketError = SocketGenericError | SocketCloseError;
63
+
64
+ export const CloseEventTypeId = Symbol.for("fncts.http.Socket.CloseEvent");
65
+ export type CloseEventTypeId = typeof CloseEventTypeId;
66
+
67
+ export class CloseEvent {
68
+ readonly [CloseEventTypeId]: CloseEventTypeId = CloseEventTypeId;
69
+ constructor(
70
+ readonly code = 1000,
71
+ readonly reason?: string,
72
+ ) {}
73
+ }
74
+
75
+ export function isCloseEvent(u: unknown): u is CloseEvent {
76
+ return isObject(u) && CloseEventTypeId in u;
77
+ }
78
+
79
+ /**
80
+ * @tsplus fluent fncts.http.Socket toChannel
81
+ */
82
+ export function toChannel<IE>(
83
+ self: Socket,
84
+ ): Channel<never, IE, Conc<Uint8Array | CloseEvent>, unknown, SocketError | IE, Conc<Uint8Array>, void> {
85
+ return Channel.unwrap(
86
+ Do((Δ) => {
87
+ const writeScope = Δ(Scope.make);
88
+ const write = Δ(writeScope.extend(self.writer));
89
+ const exitQueue = Δ(Queue.makeUnbounded<Exit<SocketError | IE, Conc<Uint8Array>>>());
90
+
91
+ const input: AsyncInputProducer<IE, Conc<Uint8Array | CloseEvent>, unknown> = {
92
+ awaitRead: IO.unit,
93
+ emit(chunk) {
94
+ return IO.foreachDiscard(chunk, write).catchAllCause((cause) => exitQueue.offer(Exit.failCause(cause)));
95
+ },
96
+ error(error) {
97
+ return writeScope.close(Exit.unit) > exitQueue.offer(Exit.failCause(error));
98
+ },
99
+ done() {
100
+ return writeScope.close(Exit.unit);
101
+ },
102
+ };
103
+
104
+ Δ(
105
+ self
106
+ .run((data) => exitQueue.offer(Exit.succeed(Conc.single(data))))
107
+ .zipRight(IO.failCauseNow(Cause.empty<IE | SocketError>()))
108
+ .result.tap((exit) => exitQueue.offer(exit)).fork.interruptible,
109
+ );
110
+
111
+ const loop: Channel<never, unknown, unknown, unknown, SocketError | IE, Conc<Uint8Array>, void> = Channel.fromIO(
112
+ exitQueue.take,
113
+ ).flatMap((exit) =>
114
+ exit.match(
115
+ (cause) => (cause._tag === CauseTag.Empty ? Channel.unit : Channel.failCause(cause)),
116
+ (chunk) => Channel.write(chunk) > loop,
117
+ ),
118
+ );
119
+
120
+ return loop.embedInput(input);
121
+ }),
122
+ );
123
+ }
124
+
125
+ /**
126
+ * @tsplus fluent fncts.http.Socket toChannelWith
127
+ */
128
+ export function toChannelWith<IE = never>(
129
+ self: Socket,
130
+ ): Channel<never, IE, Conc<Uint8Array | CloseEvent>, unknown, SocketError | IE, Conc<Uint8Array>, void> {
131
+ return self.toChannel<IE>();
132
+ }
133
+
134
+ /**
135
+ * @tsplus companion fncts.http.WebSocketOps
136
+ */
137
+ export interface WebSocket {
138
+ readonly _: unique symbol;
139
+ }
140
+
141
+ /**
142
+ * @tsplus static fncts.http.WebSocketOps Tag
143
+ */
144
+ export const WebSocketTag = Tag<WebSocket>();
145
+
146
+ /**
147
+ * @tsplus static fncts.http.SocketOps makeWebSocket
148
+ * @tsplus static fncts.http.WebSocketOps __call
149
+ */
150
+ export function makeWebSocket(
151
+ url: string,
152
+ options?: {
153
+ readonly closeCodeIsError?: (code: number) => boolean;
154
+ readonly openTimeout?: Duration;
155
+ },
156
+ ): UIO<Socket> {
157
+ return Socket.fromWebSocket(
158
+ IO.acquireRelease(
159
+ IO(() => {
160
+ if ("WebSocket" in globalThis) {
161
+ return new globalThis.WebSocket(url);
162
+ }
163
+ return new IsoWs(url);
164
+ }),
165
+ (ws) => IO(ws.close()),
166
+ ),
167
+ options,
168
+ );
169
+ }
170
+
171
+ /**
172
+ * @tsplus static fncts.http.SocketOps fromWebSocket
173
+ */
174
+ export function fromWebSocket(
175
+ acquire: IO<Scope, SocketError, globalThis.WebSocket>,
176
+ options?: {
177
+ readonly closeCodeIsError?: (code: number) => boolean;
178
+ readonly openTimeout?: Duration;
179
+ },
180
+ ): UIO<Socket> {
181
+ return Do((Δ) => {
182
+ const closeCodeIsError = options?.closeCodeIsError ?? ((code) => code !== 1000 && code !== 1006);
183
+ const sendQueue = Δ(Queue.makeUnbounded<Uint8Array | CloseEvent>());
184
+ const run = <R, E>(handler: (_: Uint8Array) => IO<R, E, any>) =>
185
+ Do((Δ) => {
186
+ const ws = Δ(acquire);
187
+ const encoder = new TextEncoder();
188
+ const fiberSet = Δ(FiberSet.make<E | SocketError, any>());
189
+ const run = Δ(
190
+ fiberSet.runtime<E | SocketError, any, R>().provideSomeService(ws as unknown as WebSocket, WebSocket.Tag),
191
+ );
192
+ let open = false;
193
+ ws.onmessage = (event) => {
194
+ run(
195
+ handler(
196
+ event.data instanceof Uint8Array
197
+ ? event.data
198
+ : typeof event.data === "string"
199
+ ? encoder.encode(event.data)
200
+ : new Uint8Array(event.data),
201
+ ),
202
+ );
203
+ };
204
+
205
+ ws.onclose = (event) => {
206
+ fiberSet.future.unsafeDone(IO.fail(new SocketCloseError("Close", event.code, event.reason, undefined)));
207
+ };
208
+
209
+ ws.onerror = (error) => {
210
+ fiberSet.future.unsafeDone(IO.fail(new SocketGenericError(open ? "Read" : "Open", error)));
211
+ };
212
+
213
+ Δ(
214
+ IO.defer(() => {
215
+ if (ws.readyState !== 1) {
216
+ return IO.async<never, SocketError, void>((resume) => {
217
+ ws.onopen = () => {
218
+ resume(IO.unit);
219
+ };
220
+ })
221
+ .timeoutFail(
222
+ options?.openTimeout ?? (10).seconds,
223
+ new SocketGenericError("OpenTimeout", 'timeout waiting for "open"'),
224
+ )
225
+ .raceFirst(fiberSet.join);
226
+ }
227
+
228
+ return IO.unit;
229
+ }),
230
+ );
231
+
232
+ Δ(IO((open = true)));
233
+
234
+ Δ(
235
+ fiberSet.run(
236
+ sendQueue.take.tap((chunk) => {
237
+ if (isCloseEvent(chunk)) {
238
+ return IO.fail(() => {
239
+ ws.close(chunk.code, chunk.reason);
240
+ return new SocketCloseError("Close", chunk.code, chunk.reason, chunk);
241
+ });
242
+ } else {
243
+ return IO.tryCatch(ws.send(chunk), (error) => new SocketGenericError("Write", error));
244
+ }
245
+ }).forever,
246
+ ),
247
+ );
248
+
249
+ Δ(
250
+ fiberSet.join.catchJust(
251
+ Maybe.partial(
252
+ (miss) => (error) =>
253
+ SocketCloseError.isClean((code) => !closeCodeIsError(code))(error) ? IO.unit : miss(),
254
+ ),
255
+ ),
256
+ );
257
+ }).scoped.interruptible;
258
+
259
+ const write = (chunk: Uint8Array | CloseEvent) => sendQueue.offer(chunk);
260
+
261
+ const writer = IO(() => write);
262
+
263
+ return new (class extends Socket {
264
+ writer = writer;
265
+ run = run;
266
+ })();
267
+ });
268
+ }
269
+
270
+ /**
271
+ * @tsplus static fncts.http.SocketOps makeWebSocketChannel
272
+ * @tsplus static fncts.http.WebSocketOps makeChannel
273
+ */
274
+ export function makeWebSocketChannel<IE = never>(
275
+ url: string,
276
+ options?: {
277
+ readonly closeCodeIsError?: (code: number) => boolean;
278
+ },
279
+ ): Channel<never, IE, Conc<Uint8Array>, unknown, IE | SocketError, Conc<Uint8Array | string | CloseEvent>, void> {
280
+ return Channel.unwrap(makeWebSocket(url, options).map((socket) => socket.toChannel<IE>()));
281
+ }
282
+
283
+ /**
284
+ * @tsplus static fncts.http.SocketOps liveWebSocket
285
+ * @tsplus static fncts.http.WebSocketOps live
286
+ */
287
+ export function live(
288
+ url: string,
289
+ options?: {
290
+ readonly closeCodeIsError?: (code: number) => boolean;
291
+ },
292
+ ): Layer<never, never, Socket> {
293
+ return Layer.scoped(WebSocket(url, options), Socket.Tag);
294
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @tsplus type fncts.http.UrlParams
3
+ * @tsplus type fncts.http.UrlParamsOps
4
+ */
5
+ export class UrlParams {
6
+ constructor(readonly backing: ReadonlyArray<readonly [string, string]>) {}
7
+ }
8
+
9
+ export declare module UrlParams {
10
+ export type Input = Readonly<Record<string, string>> | Iterable<readonly [string, string]> | URLSearchParams;
11
+ }
12
+
13
+ /**
14
+ * @tsplus static fncts.http.UrlParamsOps __call
15
+ */
16
+ export function make(input: UrlParams.Input): UrlParams {
17
+ if (Symbol.iterator in input) {
18
+ return new UrlParams(Array.from(input));
19
+ }
20
+ return new UrlParams(Array.from(Object.entries(input)));
21
+ }
22
+
23
+ /**
24
+ * @tsplus fluent fncts.http.UrlParams toString
25
+ */
26
+ export function toString(self: UrlParams): string {
27
+ return new URLSearchParams(self.backing as Array<[string, string]>).toString();
28
+ }
package/_src/global.ts ADDED
@@ -0,0 +1,2 @@
1
+ import type {} from "@fncts/io/global";
2
+ import type {} from "@fncts/schema/global";
package/global.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@fncts/http",
3
+ "version": "0.0.0",
4
+ "dependencies": {
5
+ "@fncts/base": "0.0.33",
6
+ "@fncts/io": "0.0.41",
7
+ "@fncts/schema": "0.0.13",
8
+ "@fncts/typelevel": "0.0.16",
9
+ "find-my-way": "^8.1.0",
10
+ "find-my-way-ts": "^0.1.1",
11
+ "isows": "^1.0.4",
12
+ "uuid": "^9.0.1"
13
+ },
14
+ "exports": {
15
+ "./*": {
16
+ "import": "./_mjs/*.mjs",
17
+ "require": "./_cjs/*.cjs"
18
+ },
19
+ ".": {
20
+ "import": "./_mjs/index.mjs",
21
+ "require": "./_cjs/index.cjs"
22
+ }
23
+ },
24
+ "publishConfig": {
25
+ "access": "public"
26
+ }
27
+ }