@fireproof/core-protocols-cloud 0.22.0-keybag → 0.23.1-dev-issue-1057

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.
@@ -1,204 +0,0 @@
1
- import { HttpHeader, Logger, Result, URI, exception2Result } from "@adviser/cement";
2
- import { SuperThis } from "@fireproof/core-types-base";
3
- import { ActiveStream, ExchangedGestalt, MsgerParamsWithEnDe, OnMsgFn, selectRandom, timeout, UnReg } from "./msger.js";
4
- import { MsgRawConnectionBase } from "./msg-raw-connection-base.js";
5
- import { ensureLogger } from "@fireproof/core-runtime";
6
- import {
7
- MsgRawConnection,
8
- MsgBase,
9
- MsgWithError,
10
- MsgIsError,
11
- RequestOpts,
12
- buildErrorMsg,
13
- } from "@fireproof/core-types-protocols-cloud";
14
-
15
- function toHttpProtocol(uri: URI): URI {
16
- const protocol = (uri.getParam("protocol") ?? uri.protocol).replace(/:$/, "");
17
- const toFix = uri.build();
18
- switch (protocol) {
19
- case "ws":
20
- case "http":
21
- toFix.protocol("http");
22
- break;
23
- case "https":
24
- case "wss":
25
- default:
26
- toFix.protocol("https");
27
- break;
28
- }
29
- return toFix.URI();
30
- }
31
-
32
- export function ensurePath(uri: URI, fp: string): string {
33
- const path = uri.pathname.replace(/\/$/, "").replace(/^\//, "");
34
- const buri = uri.build();
35
- if (path === "") {
36
- buri.appendRelative(fp);
37
- }
38
- return buri.toString();
39
- }
40
-
41
- export class HttpConnection extends MsgRawConnectionBase implements MsgRawConnection {
42
- readonly logger: Logger;
43
- readonly msgP: MsgerParamsWithEnDe;
44
-
45
- readonly baseURIs: { in: URI; cleaned: URI }[];
46
-
47
- readonly #onMsg = new Map<string, OnMsgFn>();
48
-
49
- readonly isReady = true;
50
-
51
- constructor(sthis: SuperThis, uris: URI[], msgP: MsgerParamsWithEnDe, exGestalt: ExchangedGestalt) {
52
- super(sthis, exGestalt);
53
- this.logger = ensureLogger(sthis, "HttpConnection");
54
- // this.msgParam = msgP;
55
- this.baseURIs = uris.map((uri) => ({
56
- in: uri,
57
- cleaned: toHttpProtocol(uri),
58
- }));
59
- this.msgP = msgP;
60
- }
61
-
62
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
63
- send<S extends MsgBase, Q extends MsgBase>(_msg: Q): Promise<MsgWithError<S>> {
64
- throw new Error("Method not implemented.");
65
- }
66
-
67
- async start(): Promise<Result<void>> {
68
- // if (this._qsOpen.req) {
69
- // const sOpen = await this.request(this._qsOpen.req, { waitFor: MsgIsResOpen });
70
- // if (!MsgIsResOpen(sOpen)) {
71
- // return Result.Err(this.logger.Error().Any("Err", sOpen).Msg("unexpected response").AsError());
72
- // }
73
- // this._qsOpen.res = sOpen;
74
- // }
75
- return Result.Ok(undefined);
76
- }
77
-
78
- async close(): Promise<Result<void>> {
79
- await Promise.all(Array.from(this.activeBinds.values()).map((state) => state.controller?.close()));
80
- this.#onMsg.clear();
81
- return Result.Ok(undefined);
82
- }
83
-
84
- toMsg<S extends MsgBase>(msg: MsgWithError<S>): MsgWithError<S> {
85
- this.#onMsg.forEach((fn) => fn(msg));
86
- return msg;
87
- }
88
-
89
- onMsg(fn: OnMsgFn): UnReg {
90
- const key = this.sthis.nextId().str;
91
- this.#onMsg.set(key, fn);
92
- return () => this.#onMsg.delete(key);
93
- }
94
-
95
- #poll(state: ActiveStream): void {
96
- this.request(state.bind.msg, state.bind.opts)
97
- .then((msg) => {
98
- try {
99
- state.controller?.enqueue(msg);
100
- if (MsgIsError(msg)) {
101
- state.controller?.close();
102
- } else {
103
- state.timeout = setTimeout(() => this.#poll(state), state.bind.opts.pollInterval ?? 1000);
104
- }
105
- } catch (err) {
106
- state.controller?.error(err);
107
- state.controller?.close();
108
- }
109
- })
110
- .catch((err) => {
111
- state.controller?.error(err);
112
- // state.controller?.close();
113
- });
114
- }
115
-
116
- readonly activeBinds = new Map<string, ActiveStream>();
117
- bind<Q extends MsgBase, S extends MsgBase>(req: Q, opts: RequestOpts): ReadableStream<MsgWithError<S>> {
118
- const state: ActiveStream = {
119
- id: this.sthis.nextId().str,
120
- bind: {
121
- msg: req,
122
- opts,
123
- },
124
- } satisfies ActiveStream;
125
- this.activeBinds.set(state.id, state);
126
- return new ReadableStream<MsgWithError<S>>({
127
- cancel: () => {
128
- clearTimeout(state.timeout as number);
129
- this.activeBinds.delete(state.id);
130
- },
131
- start: (controller) => {
132
- state.controller = controller;
133
- this.#poll(state);
134
- },
135
- });
136
- }
137
-
138
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
139
- async request<Q extends MsgBase, S extends MsgBase>(req: Q, _opts: RequestOpts): Promise<MsgWithError<S>> {
140
- const headers = HttpHeader.from();
141
- headers.Set("Content-Type", this.msgP.mime);
142
- headers.Set("Accept", this.msgP.mime);
143
-
144
- const rReqBody = exception2Result(() => this.msgP.ende.encode(req));
145
- if (rReqBody.isErr()) {
146
- return this.toMsg(
147
- buildErrorMsg(this, req, this.logger.Error().Err(rReqBody.Err()).Any("req", req).Msg("encode error").AsError()),
148
- );
149
- }
150
- headers.Set("Content-Length", rReqBody.Ok().byteLength.toString());
151
- const url = selectRandom(this.baseURIs);
152
- // console.log("request", url.cleaned.toString(), url.in.toString(), req);
153
- this.logger.Debug().Any(url).Any("body", req).Msg("request");
154
- const rRes = await exception2Result(() =>
155
- timeout(
156
- this.msgP.timeout,
157
- fetch(ensurePath(url.cleaned, "fp"), {
158
- method: "PUT",
159
- headers: headers.AsHeaderInit(),
160
- body: rReqBody.Ok(),
161
- }),
162
- ),
163
- );
164
- this.logger.Debug().Any(url).Any("body", rRes).Msg("response");
165
- if (rRes.isErr()) {
166
- return this.toMsg(buildErrorMsg(this, req, this.logger.Error().Err(rRes).Any(url).Msg("fetch error").AsError()));
167
- }
168
- const res = rRes.Ok();
169
- if (!res.ok) {
170
- const data = new Uint8Array(await res.arrayBuffer());
171
- const ret = await exception2Result(async () => this.msgP.ende.decode(data) as S);
172
- if (ret.isErr() || !MsgIsError(ret.Ok())) {
173
- return this.toMsg(
174
- buildErrorMsg(
175
- this,
176
- req,
177
- this.logger
178
- .Error()
179
- .Any(url)
180
- .Str("status", res.status.toString())
181
- .Str("statusText", res.statusText)
182
- .Msg("HTTP Error")
183
- .AsError(),
184
- await res.text().catch(() => "no body"),
185
- ),
186
- );
187
- }
188
- return this.toMsg(ret.Ok());
189
- }
190
- const data = new Uint8Array(await res.arrayBuffer());
191
- const ret = await exception2Result(async () => this.msgP.ende.decode(data) as S);
192
- if (ret.isErr()) {
193
- return this.toMsg(
194
- buildErrorMsg(this, req, this.logger.Error().Err(ret.Err()).Msg("decode error").AsError(), this.sthis.txt.decode(data)),
195
- );
196
- }
197
- return this.toMsg(ret.Ok());
198
- }
199
-
200
- // toOnMessage<T extends MsgBase>(msg: WithErrorMsg<T>): Result<WithErrorMsg<T>> {
201
- // this.mec.msgFn?.(msg as unknown as MessageEvent<MsgBase>);
202
- // return Result.Ok(msg);
203
- // }
204
- }
package/index.ts DELETED
@@ -1,4 +0,0 @@
1
- export * from "./http-connection.js";
2
- export * from "./msg-raw-connection-base.js";
3
- export * from "./msger.js";
4
- export * from "./ws-connection.js";
@@ -1,38 +0,0 @@
1
- import { SuperThis } from "@fireproof/core-types-base";
2
- import { MsgBase, ErrorMsg, buildErrorMsg } from "@fireproof/core-types-protocols-cloud";
3
- import { ExchangedGestalt, OnErrorFn, UnReg } from "./msger.js";
4
- import { Logger } from "@adviser/cement";
5
-
6
- export class MsgRawConnectionBase {
7
- readonly sthis: SuperThis;
8
- readonly exchangedGestalt: ExchangedGestalt;
9
-
10
- constructor(sthis: SuperThis, exGestalt: ExchangedGestalt) {
11
- this.sthis = sthis;
12
- this.exchangedGestalt = exGestalt;
13
- }
14
-
15
- readonly onErrorFns = new Map<string, OnErrorFn>();
16
- onError(fn: OnErrorFn): UnReg {
17
- const key = this.sthis.nextId().str;
18
- this.onErrorFns.set(key, fn);
19
- return () => this.onErrorFns.delete(key);
20
- }
21
-
22
- buildErrorMsg(
23
- msgCtx: {
24
- readonly logger: Logger;
25
- readonly sthis: SuperThis;
26
- },
27
- msg: Partial<MsgBase>,
28
- err: Error,
29
- ): ErrorMsg {
30
- // const logLine = this.sthis.logger.Error().Err(err).Any("msg", msg);
31
- const rmsg = Array.from(this.onErrorFns.values()).reduce((msg, fn) => {
32
- return fn(msg, err);
33
- }, msg);
34
- const emsg = buildErrorMsg(msgCtx, rmsg, err);
35
- msgCtx.logger.Error().Err(err).Any("msg", rmsg).Msg("connection error");
36
- return emsg;
37
- }
38
- }