@effect-app/infra 1.19.0 → 1.20.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @effect-app/infra
2
2
 
3
+ ## 1.20.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 71cef1a: add SSE middleware
8
+
3
9
  ## 1.19.0
4
10
 
5
11
  ### Minor Changes
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.makeSSE = void 0;
7
+ var _setupRequest = require("@effect-app/infra/api/setupRequest");
8
+ var _errorReporter = require("@effect-app/infra/errorReporter");
9
+ var _effectApp = require("effect-app");
10
+ var _http = require("effect-app/http");
11
+ // Tell the client to retry every 10 seconds if connectivity is lost
12
+ const setRetry = _effectApp.Stream.succeed("retry: 10000");
13
+ const keepAlive = _effectApp.Stream.schedule(_effectApp.Effect.succeed(":keep-alive"), _effectApp.Schedule.fixed(_effectApp.Duration.seconds(15)));
14
+ const makeSSE = (events, schema) => _effectApp.Effect.gen(function* () {
15
+ yield* _effectApp.Effect.logInfo("$ start listening to events");
16
+ const enc = new TextEncoder();
17
+ const eventStream = _effectApp.Stream.map(events, _ => `id: ${_.evt.id}\ndata: ${JSON.stringify(_effectApp.S.encodeSync(schema)(_.evt))}`);
18
+ const stream = (0, _effectApp.pipe)(setRetry, _effectApp.Stream.merge(keepAlive), _effectApp.Stream.merge(eventStream), _effectApp.Stream.map(_ => enc.encode(_ + "\n\n")));
19
+ const ctx = yield* _effectApp.Effect.context();
20
+ const res = _http.HttpServerResponse.stream(stream.pipe(_effectApp.Stream.tapErrorCause((0, _errorReporter.reportError)("Request")), _effectApp.Stream.provideContext(ctx)), {
21
+ contentType: "text/event-stream",
22
+ headers: _http.HttpHeaders.fromInput({
23
+ "content-type": "text/event-stream",
24
+ "cache-control": "no-cache",
25
+ "x-accel-buffering": "no",
26
+ "connection": "keep-alive" // if (req.httpVersion !== "2.0")
27
+ })
28
+ });
29
+ return res;
30
+ }).pipe(_effectApp.Effect.tapErrorCause((0, _errorReporter.reportError)("Request")), _ => (0, _setupRequest.setupRequestContext)(_, "events"));
31
+ exports.makeSSE = makeSSE;
32
+ //# sourceMappingURL=events.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.cjs","names":["_setupRequest","require","_errorReporter","_effectApp","_http","setRetry","Stream","succeed","keepAlive","schedule","Effect","Schedule","fixed","Duration","seconds","makeSSE","events","schema","gen","logInfo","enc","TextEncoder","eventStream","map","_","evt","id","JSON","stringify","S","encodeSync","stream","pipe","merge","encode","ctx","context","res","HttpServerResponse","tapErrorCause","reportError","provideContext","contentType","headers","HttpHeaders","fromInput","setupRequestContext","exports"],"sources":["../../../src/api/internal/events.ts"],"sourcesContent":[null],"mappings":";;;;;;AAAA,IAAAA,aAAA,GAAAC,OAAA;AACA,IAAAC,cAAA,GAAAD,OAAA;AACA,IAAAE,UAAA,GAAAF,OAAA;AACA,IAAAG,KAAA,GAAAH,OAAA;AAEA;AACA,MAAMI,QAAQ,GAAGC,iBAAM,CAACC,OAAO,CAAC,cAAc,CAAC;AAC/C,MAAMC,SAAS,GAAGF,iBAAM,CAACG,QAAQ,CAACC,iBAAM,CAACH,OAAO,CAAC,aAAa,CAAC,EAAEI,mBAAQ,CAACC,KAAK,CAACC,mBAAQ,CAACC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;AAE/F,MAAMC,OAAO,GAAGA,CAAiCC,MAAyD,EAAEC,MAAuB,KAAKP,iBAAM,CAClJQ,GAAG,CAAC,aAAS;EACZ,OAAOR,iBAAM,CAACS,OAAO,CAAC,6BAA6B,CAAC;EAEpD,MAAMC,GAAG,GAAG,IAAIC,WAAW,EAAE;EAE7B,MAAMC,WAAW,GAAGhB,iBAAM,CAACiB,GAAG,CAC5BP,MAAM,EACLQ,CAAC,IAAK,OAAOA,CAAC,CAACC,GAAG,CAACC,EAAE,WAAWC,IAAI,CAACC,SAAS,CAACC,YAAC,CAACC,UAAU,CAACb,MAAM,CAAC,CAACO,CAAC,CAACC,GAAG,CAAC,CAAC,EAAE,CAC/E;EAED,MAAMM,MAAM,GAAG,IAAAC,eAAI,EACjB3B,QAAQ,EACRC,iBAAM,CAAC2B,KAAK,CAACzB,SAAS,CAAC,EACvBF,iBAAM,CAAC2B,KAAK,CAACX,WAAW,CAAC,EACzBhB,iBAAM,CAACiB,GAAG,CAAEC,CAAC,IAAKJ,GAAG,CAACc,MAAM,CAACV,CAAC,GAAG,MAAM,CAAC,CAAC,CAC1C;EAED,MAAMW,GAAG,GAAG,OAAOzB,iBAAM,CAAC0B,OAAO,EAAK;EACtC,MAAMC,GAAG,GAAGC,wBAAkB,CAACP,MAAM,CACnCA,MAAM,CACHC,IAAI,CACH1B,iBAAM,CAACiC,aAAa,CAAC,IAAAC,0BAAW,EAAC,SAAS,CAAC,CAAC,EAC5ClC,iBAAM,CAACmC,cAAc,CAACN,GAAG,CAAC,CAC3B,EACH;IACEO,WAAW,EAAE,mBAAmB;IAChCC,OAAO,EAAEC,iBAAW,CAACC,SAAS,CAAC;MAC7B,cAAc,EAAE,mBAAmB;MACnC,eAAe,EAAE,UAAU;MAC3B,mBAAmB,EAAE,IAAI;MACzB,YAAY,EAAE,YAAY,CAAC;KAC5B;GACF,CACF;EACD,OAAOR,GAAG;AACZ,CAAC,CAAC,CACDL,IAAI,CAACtB,iBAAM,CAAC6B,aAAa,CAAC,IAAAC,0BAAW,EAAC,SAAS,CAAC,CAAC,EAAGhB,CAAC,IAAK,IAAAsB,iCAAmB,EAACtB,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAAuB,OAAA,CAAAhC,OAAA,GAAAA,OAAA","ignoreList":[]}
@@ -3,8 +3,28 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ var _exportNames = {
7
+ accessLog: true,
8
+ uuidLogAnnotation: true,
9
+ endpointCallsMetric: true,
10
+ errorLog: true,
11
+ basicAuth: true,
12
+ cors: true
13
+ };
6
14
  exports.uuidLogAnnotation = exports.errorLog = exports.endpointCallsMetric = exports.cors = exports.basicAuth = exports.accessLog = void 0;
7
15
  var internal = _interopRequireWildcard(require("./internal/middlewares.cjs"));
16
+ var _events = require("./internal/events.cjs");
17
+ Object.keys(_events).forEach(function (key) {
18
+ if (key === "default" || key === "__esModule") return;
19
+ if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
20
+ if (key in exports && exports[key] === _events[key]) return;
21
+ Object.defineProperty(exports, key, {
22
+ enumerable: true,
23
+ get: function () {
24
+ return _events[key];
25
+ }
26
+ });
27
+ });
8
28
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
9
29
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
10
30
  /**
@@ -56,4 +76,4 @@ const basicAuth = exports.basicAuth = internal.basicAuth;
56
76
  * @since 1.0.0
57
77
  */
58
78
  const cors = exports.cors = internal.cors;
59
- //# sourceMappingURL=Middlewares.cjs.map
79
+ //# sourceMappingURL=middlewares.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middlewares.cjs","names":["internal","_interopRequireWildcard","require","_events","Object","keys","forEach","key","prototype","hasOwnProperty","call","_exportNames","exports","defineProperty","enumerable","get","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","n","__proto__","a","getOwnPropertyDescriptor","u","i","set","accessLog","uuidLogAnnotation","endpointCallsMetric","errorLog","basicAuth","cors"],"sources":["../../src/api/middlewares.ts"],"sourcesContent":[null],"mappings":";;;;;;;;;;;;;;AAQA,IAAAA,QAAA,GAAAC,uBAAA,CAAAC,OAAA;AAEA,IAAAC,OAAA,GAAAD,OAAA;AAAAE,MAAA,CAAAC,IAAA,CAAAF,OAAA,EAAAG,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAH,MAAA,CAAAI,SAAA,CAAAC,cAAA,CAAAC,IAAA,CAAAC,YAAA,EAAAJ,GAAA;EAAA,IAAAA,GAAA,IAAAK,OAAA,IAAAA,OAAA,CAAAL,GAAA,MAAAJ,OAAA,CAAAI,GAAA;EAAAH,MAAA,CAAAS,cAAA,CAAAD,OAAA,EAAAL,GAAA;IAAAO,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAZ,OAAA,CAAAI,GAAA;IAAA;EAAA;AAAA;AAAoC,SAAAS,yBAAAC,CAAA,6BAAAC,OAAA,mBAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAF,wBAAA,YAAAA,CAAAC,CAAA,WAAAA,CAAA,GAAAG,CAAA,GAAAD,CAAA,KAAAF,CAAA;AAAA,SAAAhB,wBAAAgB,CAAA,EAAAE,CAAA,SAAAA,CAAA,IAAAF,CAAA,IAAAA,CAAA,CAAAI,UAAA,SAAAJ,CAAA,eAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,WAAAK,OAAA,EAAAL,CAAA,QAAAG,CAAA,GAAAJ,wBAAA,CAAAG,CAAA,OAAAC,CAAA,IAAAA,CAAA,CAAAG,GAAA,CAAAN,CAAA,UAAAG,CAAA,CAAAL,GAAA,CAAAE,CAAA,OAAAO,CAAA,KAAAC,SAAA,UAAAC,CAAA,GAAAtB,MAAA,CAAAS,cAAA,IAAAT,MAAA,CAAAuB,wBAAA,WAAAC,CAAA,IAAAX,CAAA,oBAAAW,CAAA,OAAAnB,cAAA,CAAAC,IAAA,CAAAO,CAAA,EAAAW,CAAA,SAAAC,CAAA,GAAAH,CAAA,GAAAtB,MAAA,CAAAuB,wBAAA,CAAAV,CAAA,EAAAW,CAAA,UAAAC,CAAA,KAAAA,CAAA,CAAAd,GAAA,IAAAc,CAAA,CAAAC,GAAA,IAAA1B,MAAA,CAAAS,cAAA,CAAAW,CAAA,EAAAI,CAAA,EAAAC,CAAA,IAAAL,CAAA,CAAAI,CAAA,IAAAX,CAAA,CAAAW,CAAA,YAAAJ,CAAA,CAAAF,OAAA,GAAAL,CAAA,EAAAG,CAAA,IAAAA,CAAA,CAAAU,GAAA,CAAAb,CAAA,EAAAO,CAAA,GAAAA,CAAA;AAEpC;;;;;;;;AAQO,MAAMO,SAAS,GAAAnB,OAAA,CAAAmB,SAAA,GAEqC/B,QAAQ,CAAC+B,SAAS;AAE7E;;;;;;;;;;AAUO,MAAMC,iBAAiB,GAAApB,OAAA,CAAAoB,iBAAA,GAE6BhC,QAAQ,CAACgC,iBAAiB;AAErF;;;;;;;AAOO,MAAMC,mBAAmB,GAAArB,OAAA,CAAAqB,mBAAA,GAEPjC,QAAQ,CAACiC,mBAAmB;AAErD;;;;;;AAMO,MAAMC,QAAQ,GAAAtB,OAAA,CAAAsB,QAAA,GAAwDlC,QAAQ,CAACkC,QAAQ;AAW9F;;;;;;AAMO,MAAMC,SAAS,GAAAvB,OAAA,CAAAuB,SAAA,GAQ6CnC,QAAQ,CAACmC,SAAS;AAerF;;;;;;AAMO,MAAMC,IAAI,GAAAxB,OAAA,CAAAwB,IAAA,GAE0CpC,QAAQ,CAACoC,IAAI","ignoreList":[]}
@@ -0,0 +1,9 @@
1
+ import { Effect, S, Stream } from "effect-app";
2
+ import { HttpServerResponse } from "effect-app/http";
3
+ export declare const makeSSE: <A extends {
4
+ id: any;
5
+ }, E, R, SI>(events: Stream.Stream<{
6
+ evt: A;
7
+ namespace: string;
8
+ }, E, R>, schema: S.Schema<A, SI>) => Effect.Effect<HttpServerResponse.HttpServerResponse, never, import("../../services/RequestContextContainer.js").RequestContextContainer | import("../../services/Store/ContextMapContainer.js").ContextMapContainer | Exclude<Exclude<R, import("effect/Tracer").ParentSpan>, never>>;
9
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/api/internal/events.ts"],"names":[],"mappings":"AAEA,OAAO,EAAY,MAAM,EAAQ,CAAC,EAAY,MAAM,EAAE,MAAM,YAAY,CAAA;AACxE,OAAO,EAAe,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAMjE,eAAO,MAAM,OAAO,GAAI,CAAC,SAAS;IAAE,EAAE,EAAE,GAAG,CAAA;CAAE,EAAE,CAAC,EAAC,CAAC,EAAE,EAAE,UAAU,MAAM,CAAC,MAAM,CAAC;IAAE,GAAG,EAAE,CAAC,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,0RAqC5C,CAAA"}
@@ -0,0 +1,28 @@
1
+ import { setupRequestContext } from "@effect-app/infra/api/setupRequest";
2
+ import { reportError } from "@effect-app/infra/errorReporter";
3
+ import { Duration, Effect, pipe, S, Schedule, Stream } from "effect-app";
4
+ import { HttpHeaders, HttpServerResponse } from "effect-app/http";
5
+ // Tell the client to retry every 10 seconds if connectivity is lost
6
+ const setRetry = Stream.succeed("retry: 10000");
7
+ const keepAlive = Stream.schedule(Effect.succeed(":keep-alive"), Schedule.fixed(Duration.seconds(15)));
8
+ export const makeSSE = (events, schema) => Effect
9
+ .gen(function* () {
10
+ yield* Effect.logInfo("$ start listening to events");
11
+ const enc = new TextEncoder();
12
+ const eventStream = Stream.map(events, (_) => `id: ${_.evt.id}\ndata: ${JSON.stringify(S.encodeSync(schema)(_.evt))}`);
13
+ const stream = pipe(setRetry, Stream.merge(keepAlive), Stream.merge(eventStream), Stream.map((_) => enc.encode(_ + "\n\n")));
14
+ const ctx = yield* Effect.context();
15
+ const res = HttpServerResponse.stream(stream
16
+ .pipe(Stream.tapErrorCause(reportError("Request")), Stream.provideContext(ctx)), {
17
+ contentType: "text/event-stream",
18
+ headers: HttpHeaders.fromInput({
19
+ "content-type": "text/event-stream",
20
+ "cache-control": "no-cache",
21
+ "x-accel-buffering": "no",
22
+ "connection": "keep-alive" // if (req.httpVersion !== "2.0")
23
+ })
24
+ });
25
+ return res;
26
+ })
27
+ .pipe(Effect.tapErrorCause(reportError("Request")), (_) => setupRequestContext(_, "events"));
28
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwaS9pbnRlcm5hbC9ldmVudHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sb0NBQW9DLENBQUE7QUFDeEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGlDQUFpQyxDQUFBO0FBQzdELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUN4RSxPQUFPLEVBQUUsV0FBVyxFQUFFLGtCQUFrQixFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFFakUsb0VBQW9FO0FBQ3BFLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUE7QUFDL0MsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUE7QUFFdEcsTUFBTSxDQUFDLE1BQU0sT0FBTyxHQUFHLENBQWlDLE1BQXlELEVBQUUsTUFBdUIsRUFBRSxFQUFFLENBQUMsTUFBTTtLQUNsSixHQUFHLENBQUMsUUFBUSxDQUFDO0lBQ1osS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyw2QkFBNkIsQ0FBQyxDQUFBO0lBRXBELE1BQU0sR0FBRyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUE7SUFFN0IsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FDNUIsTUFBTSxFQUNOLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxXQUFXLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUMvRSxDQUFBO0lBRUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUNqQixRQUFRLEVBQ1IsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsRUFDdkIsTUFBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsRUFDekIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FDMUMsQ0FBQTtJQUVELE1BQU0sR0FBRyxHQUFHLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUssQ0FBQTtJQUN0QyxNQUFNLEdBQUcsR0FBRyxrQkFBa0IsQ0FBQyxNQUFNLENBQ25DLE1BQU07U0FDSCxJQUFJLENBQ0gsTUFBTSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUMsRUFDNUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FDM0IsRUFDSDtRQUNFLFdBQVcsRUFBRSxtQkFBbUI7UUFDaEMsT0FBTyxFQUFFLFdBQVcsQ0FBQyxTQUFTLENBQUM7WUFDN0IsY0FBYyxFQUFFLG1CQUFtQjtZQUNuQyxlQUFlLEVBQUUsVUFBVTtZQUMzQixtQkFBbUIsRUFBRSxJQUFJO1lBQ3pCLFlBQVksRUFBRSxZQUFZLENBQUMsaUNBQWlDO1NBQzdELENBQUM7S0FDSCxDQUNGLENBQUE7SUFDRCxPQUFPLEdBQUcsQ0FBQTtBQUNaLENBQUMsQ0FBQztLQUNELElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQSJ9
@@ -6,6 +6,7 @@
6
6
  import type * as App from "@effect/platform/HttpApp";
7
7
  import type { Effect } from "effect-app";
8
8
  import type { NotLoggedInError } from "../errors.js";
9
+ export * from "./internal/events.js";
9
10
  /**
10
11
  * Add access logs for handled requests. The log runs before each request.
11
12
  * Optionally configure log level using the first argument. The default log level
@@ -78,4 +79,4 @@ export interface CorsOptions {
78
79
  * @since 1.0.0
79
80
  */
80
81
  export declare const cors: (options?: Partial<CorsOptions>) => <R, E>(app: App.Default<R, E>) => App.Default<R, E>;
81
- //# sourceMappingURL=Middlewares.d.ts.map
82
+ //# sourceMappingURL=middlewares.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middlewares.d.ts","sourceRoot":"","sources":["../../src/api/middlewares.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,KAAK,GAAG,MAAM,0BAA0B,CAAA;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AACxC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAGpD,cAAc,sBAAsB,CAAA;AAEpC;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,EAAE,CACtB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,KACjC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAsB,CAAA;AAE7E;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,EAAE,CAC9B,gBAAgB,CAAC,EAAE,MAAM,KACtB,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAA8B,CAAA;AAErF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAC3C,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,KACnB,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAgC,CAAA;AAErD;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAqB,CAAA;AAE9F;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;;GAKG;AACH,eAAO,MAAM,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC,EAC5B,gBAAgB,EAAE,CAChB,WAAW,EAAE,oBAAoB,KAC9B,MAAM,CAAC,CAAC,EAAE,gBAAgB,EAAE,EAAE,CAAC,EACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;CAC7B,CAAC,KACC,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,CAAsB,CAAA;AAErF;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,OAAO,CAAA;CACrB;AAED;;;;;GAKG;AACH,eAAO,MAAM,IAAI,EAAE,CACjB,OAAO,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,KAC3B,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAiB,CAAA"}
@@ -1,4 +1,5 @@
1
1
  import * as internal from "./internal/middlewares.js";
2
+ export * from "./internal/events.js";
2
3
  /**
3
4
  * Add access logs for handled requests. The log runs before each request.
4
5
  * Optionally configure log level using the first argument. The default log level
@@ -48,4 +49,4 @@ export const basicAuth = internal.basicAuth;
48
49
  * @since 1.0.0
49
50
  */
50
51
  export const cors = internal.cors;
51
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWlkZGxld2FyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL01pZGRsZXdhcmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVFBLE9BQU8sS0FBSyxRQUFRLE1BQU0sMkJBQTJCLENBQUE7QUFFckQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sQ0FBQyxNQUFNLFNBQVMsR0FFcUMsUUFBUSxDQUFDLFNBQVMsQ0FBQTtBQUU3RTs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FFNkIsUUFBUSxDQUFDLGlCQUFpQixDQUFBO0FBRXJGOzs7Ozs7R0FNRztBQUNILE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUVQLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQTtBQUVyRDs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLFFBQVEsR0FBd0QsUUFBUSxDQUFDLFFBQVEsQ0FBQTtBQVc5Rjs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLFNBQVMsR0FRNkMsUUFBUSxDQUFDLFNBQVMsQ0FBQTtBQWVyRjs7Ozs7R0FLRztBQUNILE1BQU0sQ0FBQyxNQUFNLElBQUksR0FFMEMsUUFBUSxDQUFDLElBQUksQ0FBQSJ9
52
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlkZGxld2FyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYXBpL21pZGRsZXdhcmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVFBLE9BQU8sS0FBSyxRQUFRLE1BQU0sMkJBQTJCLENBQUE7QUFFckQsY0FBYyxzQkFBc0IsQ0FBQTtBQUVwQzs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUVxQyxRQUFRLENBQUMsU0FBUyxDQUFBO0FBRTdFOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUU2QixRQUFRLENBQUMsaUJBQWlCLENBQUE7QUFFckY7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBRVAsUUFBUSxDQUFDLG1CQUFtQixDQUFBO0FBRXJEOzs7OztHQUtHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sUUFBUSxHQUF3RCxRQUFRLENBQUMsUUFBUSxDQUFBO0FBVzlGOzs7OztHQUtHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQVE2QyxRQUFRLENBQUMsU0FBUyxDQUFBO0FBZXJGOzs7OztHQUtHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sSUFBSSxHQUUwQyxRQUFRLENBQUMsSUFBSSxDQUFBIn0=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect-app/infra",
3
- "version": "1.19.0",
3
+ "version": "1.20.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "dependencies": {
@@ -18,10 +18,10 @@
18
18
  "proper-lockfile": "^4.1.2",
19
19
  "pure-rand": "6.1.0",
20
20
  "redlock": "^4.2.0",
21
- "@effect-app/core": "1.10.1",
22
21
  "@effect-app/infra-adapters": "1.11.3",
23
22
  "@effect-app/schema": "1.12.1",
24
- "effect-app": "1.17.1"
23
+ "effect-app": "1.17.1",
24
+ "@effect-app/core": "1.10.1"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@babel/cli": "^7.25.6",
@@ -0,0 +1,47 @@
1
+ import { setupRequestContext } from "@effect-app/infra/api/setupRequest"
2
+ import { reportError } from "@effect-app/infra/errorReporter"
3
+ import { Duration, Effect, pipe, S, Schedule, Stream } from "effect-app"
4
+ import { HttpHeaders, HttpServerResponse } from "effect-app/http"
5
+
6
+ // Tell the client to retry every 10 seconds if connectivity is lost
7
+ const setRetry = Stream.succeed("retry: 10000")
8
+ const keepAlive = Stream.schedule(Effect.succeed(":keep-alive"), Schedule.fixed(Duration.seconds(15)))
9
+
10
+ export const makeSSE = <A extends { id: any }, E,R, SI>(events: Stream.Stream<{ evt: A, namespace: string}, E, R>, schema: S.Schema<A, SI>) => Effect
11
+ .gen(function*() {
12
+ yield* Effect.logInfo("$ start listening to events")
13
+
14
+ const enc = new TextEncoder()
15
+
16
+ const eventStream = Stream.map(
17
+ events,
18
+ (_) => `id: ${_.evt.id}\ndata: ${JSON.stringify(S.encodeSync(schema)(_.evt))}`
19
+ )
20
+
21
+ const stream = pipe(
22
+ setRetry,
23
+ Stream.merge(keepAlive),
24
+ Stream.merge(eventStream),
25
+ Stream.map((_) => enc.encode(_ + "\n\n"))
26
+ )
27
+
28
+ const ctx = yield* Effect.context<R>()
29
+ const res = HttpServerResponse.stream(
30
+ stream
31
+ .pipe(
32
+ Stream.tapErrorCause(reportError("Request")),
33
+ Stream.provideContext(ctx)
34
+ ),
35
+ {
36
+ contentType: "text/event-stream",
37
+ headers: HttpHeaders.fromInput({
38
+ "content-type": "text/event-stream",
39
+ "cache-control": "no-cache",
40
+ "x-accel-buffering": "no",
41
+ "connection": "keep-alive" // if (req.httpVersion !== "2.0")
42
+ })
43
+ }
44
+ )
45
+ return res
46
+ })
47
+ .pipe(Effect.tapErrorCause(reportError("Request")), (_) => setupRequestContext(_, "events"))
@@ -8,6 +8,8 @@ import type { Effect } from "effect-app"
8
8
  import type { NotLoggedInError } from "../errors.js"
9
9
  import * as internal from "./internal/middlewares.js"
10
10
 
11
+ export * from "./internal/events.js"
12
+
11
13
  /**
12
14
  * Add access logs for handled requests. The log runs before each request.
13
15
  * Optionally configure log level using the first argument. The default log level
@@ -1 +0,0 @@
1
- {"version":3,"file":"Middlewares.cjs","names":["internal","_interopRequireWildcard","require","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","hasOwnProperty","call","i","set","accessLog","exports","uuidLogAnnotation","endpointCallsMetric","errorLog","basicAuth","cors"],"sources":["../../src/api/Middlewares.ts"],"sourcesContent":[null],"mappings":";;;;;;AAQA,IAAAA,QAAA,GAAAC,uBAAA,CAAAC,OAAA;AAAqD,SAAAC,yBAAAC,CAAA,6BAAAC,OAAA,mBAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAF,wBAAA,YAAAA,CAAAC,CAAA,WAAAA,CAAA,GAAAG,CAAA,GAAAD,CAAA,KAAAF,CAAA;AAAA,SAAAH,wBAAAG,CAAA,EAAAE,CAAA,SAAAA,CAAA,IAAAF,CAAA,IAAAA,CAAA,CAAAI,UAAA,SAAAJ,CAAA,eAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,WAAAK,OAAA,EAAAL,CAAA,QAAAG,CAAA,GAAAJ,wBAAA,CAAAG,CAAA,OAAAC,CAAA,IAAAA,CAAA,CAAAG,GAAA,CAAAN,CAAA,UAAAG,CAAA,CAAAI,GAAA,CAAAP,CAAA,OAAAQ,CAAA,KAAAC,SAAA,UAAAC,CAAA,GAAAC,MAAA,CAAAC,cAAA,IAAAD,MAAA,CAAAE,wBAAA,WAAAC,CAAA,IAAAd,CAAA,oBAAAc,CAAA,OAAAC,cAAA,CAAAC,IAAA,CAAAhB,CAAA,EAAAc,CAAA,SAAAG,CAAA,GAAAP,CAAA,GAAAC,MAAA,CAAAE,wBAAA,CAAAb,CAAA,EAAAc,CAAA,UAAAG,CAAA,KAAAA,CAAA,CAAAV,GAAA,IAAAU,CAAA,CAAAC,GAAA,IAAAP,MAAA,CAAAC,cAAA,CAAAJ,CAAA,EAAAM,CAAA,EAAAG,CAAA,IAAAT,CAAA,CAAAM,CAAA,IAAAd,CAAA,CAAAc,CAAA,YAAAN,CAAA,CAAAH,OAAA,GAAAL,CAAA,EAAAG,CAAA,IAAAA,CAAA,CAAAe,GAAA,CAAAlB,CAAA,EAAAQ,CAAA,GAAAA,CAAA;AAErD;;;;;;;;AAQO,MAAMW,SAAS,GAAAC,OAAA,CAAAD,SAAA,GAEqCvB,QAAQ,CAACuB,SAAS;AAE7E;;;;;;;;;;AAUO,MAAME,iBAAiB,GAAAD,OAAA,CAAAC,iBAAA,GAE6BzB,QAAQ,CAACyB,iBAAiB;AAErF;;;;;;;AAOO,MAAMC,mBAAmB,GAAAF,OAAA,CAAAE,mBAAA,GAEP1B,QAAQ,CAAC0B,mBAAmB;AAErD;;;;;;AAMO,MAAMC,QAAQ,GAAAH,OAAA,CAAAG,QAAA,GAAwD3B,QAAQ,CAAC2B,QAAQ;AAW9F;;;;;;AAMO,MAAMC,SAAS,GAAAJ,OAAA,CAAAI,SAAA,GAQ6C5B,QAAQ,CAAC4B,SAAS;AAerF;;;;;;AAMO,MAAMC,IAAI,GAAAL,OAAA,CAAAK,IAAA,GAE0C7B,QAAQ,CAAC6B,IAAI","ignoreList":[]}
@@ -1 +0,0 @@
1
- {"version":3,"file":"middlewares.d.ts","sourceRoot":"","sources":["../../src/api/middlewares.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,KAAK,GAAG,MAAM,0BAA0B,CAAA;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AACxC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAGpD;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,EAAE,CACtB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,KACjC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAsB,CAAA;AAE7E;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,EAAE,CAC9B,gBAAgB,CAAC,EAAE,MAAM,KACtB,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAA8B,CAAA;AAErF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,EAC3C,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,KACnB,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAgC,CAAA;AAErD;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAqB,CAAA;AAE9F;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;;GAKG;AACH,eAAO,MAAM,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC,EAC5B,gBAAgB,EAAE,CAChB,WAAW,EAAE,oBAAoB,KAC9B,MAAM,CAAC,CAAC,EAAE,gBAAgB,EAAE,EAAE,CAAC,EACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;CAC7B,CAAC,KACC,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,CAAsB,CAAA;AAErF;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,cAAc,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,OAAO,CAAA;CACrB;AAED;;;;;GAKG;AACH,eAAO,MAAM,IAAI,EAAE,CACjB,OAAO,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,KAC3B,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAiB,CAAA"}