@equinor/fusion-framework-module-http 6.2.5 → 6.3.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,27 @@
1
1
  # Change Log
2
2
 
3
+ ## 6.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#3038](https://github.com/equinor/fusion-framework/pull/3038) [`7a0a510`](https://github.com/equinor/fusion-framework/commit/7a0a510e0af1f0769c596e1b9aaa391250efd95d) Thanks [@odinr](https://github.com/odinr)! - ### Added
8
+
9
+ - Introduced support for Server-Sent Events (SSE) in the HTTP module.
10
+ - Added `sse# Change Log method to `HttpClient` for subscribing to SSE streams.
11
+ - Added `sseMap` operator for handling SSE in RxJS pipelines.
12
+ - Added `createSseSelector` for transforming SSE responses into observables.
13
+ - Enhanced error handling with `ServerSentEventResponseError`.
14
+
15
+ ### Documentation
16
+
17
+ - Updated README with examples and usage details for SSE support.
18
+
19
+ ### Patch Changes
20
+
21
+ - Updated dependencies [[`efd70a3`](https://github.com/equinor/fusion-framework/commit/efd70a34f734e0c155d3440e35ce4fa11a7abc42)]:
22
+ - @equinor/fusion-framework-module@4.4.0
23
+ - @equinor/fusion-framework-module-msal@4.0.4
24
+
3
25
  ## 6.2.5
4
26
 
5
27
  ### Patch Changes
package/README.md CHANGED
@@ -18,13 +18,13 @@ Whether you're building a simple application or a complex portal, the Fusion Fra
18
18
 
19
19
  ## Package
20
20
 
21
- | Namespace | Description |
22
- |-----------|-------------|
23
- | `@equinor/fusion-framework-module-http` | http module
24
- | `@equinor/fusion-framework-module-http/client` | http clients
25
- | `@equinor/fusion-framework-module-http/selectors` | http selectors
26
- | `@equinor/fusion-framework-module-http/operators` | http client operators
27
- | `@equinor/fusion-framework-module-http/errors` | http client errors
21
+ | Namespace | Description |
22
+ | ------------------------------------------------- | --------------------- |
23
+ | `@equinor/fusion-framework-module-http` | http module |
24
+ | `@equinor/fusion-framework-module-http/client` | http clients |
25
+ | `@equinor/fusion-framework-module-http/selectors` | http selectors |
26
+ | `@equinor/fusion-framework-module-http/operators` | http client operators |
27
+ | `@equinor/fusion-framework-module-http/errors` | http client errors |
28
28
 
29
29
  ## Usage
30
30
  Working with Fusion Framework, HTTP clients are defined during the configuration phase. The configuration is called by the Framework during initialization, ensuring that the HTTP clients are ready to be used. This approach allows for centralized and optimized client configuration, promoting consistency, performance, and security in HTTP communication within the Fusion Framework ecosystem.
@@ -179,15 +179,15 @@ By following this approach, you can enhance the efficiency, consistency, securit
179
179
 
180
180
  When configuring an HTTP client in the Fusion Framework, you can specify various settings to customize its behavior. The following options are available for configuring an HTTP client:
181
181
 
182
- | Property | Description |
183
- |----------|-------------|
184
- | `baseUri` | The base URI for the API endpoint. |
185
- | `defaultScopes` | The default scopes for MSAL authentication. |
186
- | `selector` | The response selector for processing the response. |
187
- | `onCreate` | A callback function to execute when the client is created. |
188
- | `requestHandler` | The request operators for processing outgoing requests. |
189
- | `responseHandler` | The response operators for processing incoming responses. |
190
- | `ctor` | The constructor function for a custom client. |
182
+ | Property | Description |
183
+ | ----------------- | ---------------------------------------------------------- |
184
+ | `baseUri` | The base URI for the API endpoint. |
185
+ | `defaultScopes` | The default scopes for MSAL authentication. |
186
+ | `selector` | The response selector for processing the response. |
187
+ | `onCreate` | A callback function to execute when the client is created. |
188
+ | `requestHandler` | The request operators for processing outgoing requests. |
189
+ | `responseHandler` | The response operators for processing incoming responses. |
190
+ | `ctor` | The constructor function for a custom client. |
191
191
 
192
192
 
193
193
  ### Basic configuration
@@ -807,6 +807,12 @@ client.blob('/image.jpg').then(
807
807
  }
808
808
  );
809
809
 
810
+ /** example of Server Sent Events */
811
+ client.sse$('/chatbot', {
812
+ method: 'POST',
813
+ body: { prompt: 'Tell me a joke' }
814
+ })
815
+
810
816
  /** Example of executing named function */
811
817
  client.execute<Users>('json', '/users'); // same as client.json<Users>('/users');
812
818
 
@@ -826,4 +832,163 @@ client.request$.subscribe(request => {
826
832
  client.response$.subscribe(response => {
827
833
  console.log('Incoming response:', response);
828
834
  });
829
- ```
835
+ ```
836
+
837
+ ### Server-Sent Events (SSE)
838
+
839
+ The HTTP client supports Server-Sent Events (SSE) through the `sse$` method. While this feature is versatile and can be used for various real-time communication scenarios, such as notifications, dashboards, or collaborative tools, it was primarily developed to facilitate streaming responses from chatbots.
840
+
841
+ Key benefits of SSE:
842
+ - Ideal for live updates, such as chatbot interactions, notifications, or collaborative tools.
843
+ - Provides an efficient way to handle server-driven data updates.
844
+ - Simplifies real-time communication with minimal setup.
845
+
846
+ The `sse$` method enables you to subscribe to a continuous stream of events sent by the server, making it particularly useful for applications requiring dynamic, real-time interactions, such as conversational AI or chatbot systems. This functionality ensures seamless and efficient communication between the client and server, enhancing the user experience in scenarios where immediate feedback or updates are critical.
847
+
848
+ #### Usage
849
+
850
+ The `sse$` method returns an observable that emits events as they are received from the server. It uses `client.fetch$` under the hood, abstracting common boilerplate code such as setting headers, configuring the request, and handling the response stream.
851
+
852
+ ```typescript
853
+ /** Example of using the sse$ method to subscribe to server-sent events */
854
+ const eventStream$ = client.sse$<{ message: string }>('/events');
855
+
856
+ const subscription = eventStream$.subscribe({
857
+ next: (event) => console.log('Received event:', event),
858
+ error: (error) => console.error('An error occurred:', error),
859
+ complete: () => console.log('Event stream completed'),
860
+ });
861
+
862
+ // To stop listening to events, unsubscribe from the observable
863
+ subscription.unsubscribe();
864
+ ```
865
+
866
+ #### Options
867
+
868
+ | Option | Description |
869
+ | ---------------- | ------------------------------------------------------------------------------------ |
870
+ | `dataParser` | A function to parse the raw event data into a desired format. |
871
+ | `skipHeartbeats` | A boolean indicating whether to skip heartbeat events (default: `false`). |
872
+ | `eventFilter` | An array of event types to filter. Only events matching these types will be emitted. |
873
+
874
+ #### Customizing SSE Behavior
875
+
876
+ You can customize the behavior of the SSE stream by providing options to the `sse$` method. For example, you can specify a custom data parser or handle reconnection logic.
877
+
878
+ ```typescript
879
+ /** Example of customizing SSE behavior with options */
880
+ const customEventStream$ = client.sse$<MyEventData & { timestamp: Date }>(
881
+ '/custom-events',
882
+ { method: 'POST', body: 'tell me a joke' },
883
+ {
884
+ dataParser: (data) => {
885
+ const parsedData = JSON.parse(data) as MyEventData;
886
+ return { ...parsedData, timestamp: new Date() };
887
+ },
888
+ }
889
+ );
890
+
891
+ customEventStream$.subscribe({
892
+ next: (event) => console.log('Custom event received:', event),
893
+ error: (error) => console.error('An error occurred:', error),
894
+ complete: () => console.log('Custom event stream completed'),
895
+ });
896
+ ```
897
+
898
+ #### Aborting SSE Requests
899
+
900
+ You can abort an SSE request by using the `abort` method of the HTTP client or by unsubscribing from the observable.
901
+
902
+ ```typescript
903
+ /** Example of aborting an SSE request */
904
+ const abortController = new AbortController();
905
+
906
+ const abortableEventStream$ = client.sse$<{ message: string }>('/abortable-events', {
907
+ signal: abortController.signal,
908
+ });
909
+
910
+ const subscription = abortableEventStream$.subscribe({
911
+ next: (event) => console.log('Received event:', event),
912
+ error: (error) => console.error('An error occurred:', error),
913
+ complete: () => console.log('Event stream completed'),
914
+ });
915
+
916
+ // Abort the request
917
+ abortController.abort();
918
+ ```
919
+
920
+ > [!NOTE]
921
+ > Unsubscribing from the observable will also abort the SSE request automatically.
922
+
923
+ #### Using `sseSelector` with `httpClient.fetch`
924
+
925
+ If you need to create an SSE call from scratch without using the `sse$` method, you can use the `sseSelector` directly with the `httpClient.fetch` method. Here's an example:
926
+
927
+ ```typescript
928
+ import { createSseSelector } from '@equinor/fusion-framework-module-http/selectors';
929
+
930
+ /** Example of using sseSelector with httpClient.fetch */
931
+ const sseSelector = createSseSelector<{ message: string }>({
932
+ dataParser: (data) => JSON.parse(data),
933
+ skipHeartbeats: true,
934
+ eventFilter: ['message', 'update'],
935
+ });
936
+
937
+ const headers = new Headers({
938
+ 'Accept': 'text/event-stream',
939
+ 'Cache-Control': 'no-cache',
940
+ 'Connection': 'keep-alive',
941
+ });
942
+
943
+ const sseStream$ = client.fetch('/events', {
944
+ selector: sseSelector,
945
+ headers,
946
+ method: 'GET', // SSE calls typically use GET
947
+ });
948
+
949
+ const subscription = sseStream$.subscribe({
950
+ next: (event) => console.log('Received event:', event),
951
+ error: (error) => console.error('An error occurred:', error),
952
+ complete: () => console.log('Event stream completed'),
953
+ });
954
+
955
+ // To stop listening to events, unsubscribe from the observable
956
+ subscription.unsubscribe();
957
+ ```
958
+
959
+ #### Using `sseMap` with `client.fetch$`
960
+
961
+ The `sseMap` operator can be used with `client.fetch$` to process Server-Sent Events (SSE) in a declarative manner. This approach allows you to handle SSE streams while leveraging the flexibility of RxJS.
962
+
963
+ ```typescript
964
+ import { sseMap } from '@equinor/fusion-framework-module-http/operators';
965
+
966
+ /** Example of using sseMap with client.fetch$ */
967
+ const sseStream$ = client.fetch$('/events', {
968
+ method: 'GET',
969
+ headers: {
970
+ 'Accept': 'text/event-stream',
971
+ 'Cache-Control': 'no-cache',
972
+ 'Connection': 'keep-alive',
973
+ },
974
+ }).pipe(
975
+ sseMap<{ message: string }>({
976
+ dataParser: (data) => JSON.parse(data),
977
+ skipHeartbeats: true,
978
+ eventFilter: ['message', 'update'],
979
+ }),
980
+ );
981
+
982
+ const subscription = sseStream$.subscribe({
983
+ next: (event) => console.log('Received event:', event),
984
+ error: (error) => console.error('An error occurred:', error),
985
+ complete: () => console.log('SSE stream completed'),
986
+ });
987
+
988
+ // To stop listening to events, unsubscribe from the observable
989
+ subscription.unsubscribe();
990
+ ```
991
+
992
+ This example demonstrates how to use `sseMap` with `client.fetch$` to process SSE data efficiently.
993
+
994
+ This approach provides more flexibility for customizing the SSE behavior while still leveraging the `httpClient.fetch` method. However, for most use cases, `client.sse$` is recommended as it simplifies the process by abstracting common boilerplate code.
@@ -33,4 +33,26 @@ export class HttpJsonResponseError extends HttpResponseError {
33
33
  this.data = options?.data;
34
34
  }
35
35
  }
36
+ /**
37
+ * Represents an error that occurs when handling a server-sent event (SSE) HTTP response.
38
+ *
39
+ * @template TType - The type of additional data associated with the error.
40
+ * @template TResponse - The type of the HTTP response object.
41
+ *
42
+ * @extends HttpResponseError<TResponse>
43
+ */
44
+ export class ServerSentEventResponseError extends HttpResponseError {
45
+ static Name = 'ServerSentEventResponseError';
46
+ /**
47
+ * Creates a new instance of the error.
48
+ *
49
+ * @param message - The error message describing the cause of the error.
50
+ * @param response - The HTTP response associated with the error.
51
+ * @param options - Optional error options, which may include additional data of type `TType`.
52
+ */
53
+ constructor(message, response, options) {
54
+ super(message, response, options);
55
+ this.name = ServerSentEventResponseError.Name;
56
+ }
57
+ }
36
58
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,iBAAwC,SAAQ,KAAK;IAI9C;IAHlB,MAAM,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,YACE,OAAe,EACC,QAAmB,EACnC,OAAsB;QAEtB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAHR,aAAQ,GAAR,QAAQ,CAAW;IAIrC,CAAC;;AAGH;;;;;;GAMG;AACH,MAAM,OAAO,qBAGX,SAAQ,iBAA4B;IACpC,MAAM,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACtB,IAAI,CAAS;IAE7B;;;;;;OAMG;IACH,YAAY,OAAe,EAAE,QAAmB,EAAE,OAAyC;QACzF,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC,IAAI,CAAC;QACvC,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,CAAC;IAC5B,CAAC"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,OAAO,iBAAwC,SAAQ,KAAK;IAI9C;IAHlB,MAAM,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,YACE,OAAe,EACC,QAAmB,EACnC,OAAsB;QAEtB,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAHR,aAAQ,GAAR,QAAQ,CAAW;IAIrC,CAAC;;AAGH;;;;;;GAMG;AACH,MAAM,OAAO,qBAGX,SAAQ,iBAA4B;IACpC,MAAM,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACtB,IAAI,CAAS;IAE7B;;;;;;OAMG;IACH,YAAY,OAAe,EAAE,QAAmB,EAAE,OAAyC;QACzF,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC,IAAI,CAAC;QACvC,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,CAAC;IAC5B,CAAC;;AAGH;;;;;;;GAOG;AACH,MAAM,OAAO,4BAGX,SAAQ,iBAA4B;IACpC,MAAM,CAAC,IAAI,GAAG,8BAA8B,CAAC;IAE7C;;;;;;OAMG;IACH,YAAY,OAAe,EAAE,QAAmB,EAAE,OAAyC;QACzF,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC,IAAI,CAAC;IAChD,CAAC"}
@@ -4,6 +4,7 @@ import { fromFetch } from 'rxjs/fetch';
4
4
  import { HttpRequestHandler, HttpResponseHandler } from '../operators';
5
5
  import { blobSelector, jsonSelector } from '../selectors';
6
6
  import { HttpResponseError } from '../../errors';
7
+ import { createSseSelector, } from '../selectors/sse-selector';
7
8
  /** Base http client for executing requests */
8
9
  export class HttpClient {
9
10
  uri;
@@ -147,6 +148,40 @@ export class HttpClient {
147
148
  blob(path, args) {
148
149
  return firstValueFrom(this.blob$(path, args));
149
150
  }
151
+ /**
152
+ * Initiates a Server-Sent Events (SSE) stream request to the specified path and returns a stream of events.
153
+ *
154
+ * @template T - The type of the event data expected from the SSE stream.
155
+ * @param path - The endpoint path to connect to for the SSE stream.
156
+ * @param args - Optional fetch request initialization options, including headers and abort signal.
157
+ * @param options - Optional selector options for customizing the SSE stream, excluding the abort signal.
158
+ *
159
+ * @returns A `StreamResponse` that emits `ServerSentEvent<T>` objects as they are received from the server.
160
+ *
161
+ * @example
162
+ * const sse$ = httpClient.sse(
163
+ * '/events',
164
+ * { method: 'POST', body: JSON.stringify({ prompt: 'tell me a joke' }) },
165
+ * { eventFilter: ['message'] }
166
+ * );
167
+ * sse$.subscribe({
168
+ * next: (event) => console.log(event),
169
+ * error: (err) => console.error(err),
170
+ * complete: () => console.log('Completed'),
171
+ * });
172
+ */
173
+ sse$(path, args, options) {
174
+ // Setup default common headers for SSE
175
+ const headers = new Headers(args?.headers);
176
+ headers.append('Accept', 'text/event-stream');
177
+ headers.append('Content-Type', 'text/event-stream');
178
+ headers.append('Cache-Control', 'no-cache');
179
+ headers.append('Connection', 'keep-alive');
180
+ // Create the selector using the provided options and the abort signal from args
181
+ const selector = createSseSelector({ ...options, abortSignal: args?.signal });
182
+ // Call the fetch$ method with the provided path and the constructed init object
183
+ return this._fetch$(path, { selector, ...args, headers });
184
+ }
150
185
  /** @deprecated */
151
186
  jsonAsync(path, args) {
152
187
  return this.json(path, args);
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../src/lib/client/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../../src/lib/client/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { switchMap } from 'rxjs/operators';
2
+ import { createSseSelector, } from '../selectors/sse-selector';
3
+ /**
4
+ * An operator function for handling Server-Sent Events (SSE) in an RxJS pipeline.
5
+ *
6
+ * @template R - The type of the parsed data from the SSE.
7
+ * @template T - The type of the input `Response` object, defaults to `Response`.
8
+ *
9
+ * @param options - Configuration options for the SSE selector.
10
+ *
11
+ * @returns An `OperatorFunction` that transforms a stream of `Response` objects
12
+ * into a stream of `ServerSentEvent` objects containing parsed data of type `R`.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import { sseMap } from '@equinor/fusion-framework-module-http/operators';
17
+ * import { fromFetch } from 'rxjs/fetch';
18
+ *
19
+ * const response$ = fromFetch('https://example.com/sse', {
20
+ * method: 'GET',
21
+ * headers: {
22
+ * 'Accept': 'text/event-stream',
23
+ * },
24
+ * }).pipe(
25
+ * sseMap( { /* SSE selector options *\/ })
26
+ * ).subscribe((event) => {
27
+ * console.log(event.data); // Process the parsed SSE data
28
+ * });
29
+ * ```
30
+ */
31
+ export const sseMap = (options) => (source) => source.pipe(switchMap(createSseSelector(options)));
32
+ export default sseMap;
33
+ //# sourceMappingURL=sse.operator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.operator.js","sourceRoot":"","sources":["../../../../src/lib/operators/sse.operator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EACL,iBAAiB,GAGlB,MAAM,2BAA2B,CAAC;AAEnC;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,CAAC,MAAM,MAAM,GACjB,CACE,OAA+B,EACU,EAAE,CAC7C,CAAC,MAAM,EAAE,EAAE,CACT,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAO,OAAO,CAAC,CAAC,CAAC,CAAC;AAE7D,eAAe,MAAM,CAAC"}
@@ -0,0 +1,164 @@
1
+ import { EMPTY, from, fromEvent } from 'rxjs';
2
+ import { finalize, takeUntil } from 'rxjs/operators';
3
+ import { ServerSentEventResponseError } from '../../errors.js';
4
+ const defaultDataParser = (data) => {
5
+ try {
6
+ return JSON.parse(data);
7
+ }
8
+ catch {
9
+ return data;
10
+ }
11
+ };
12
+ /**
13
+ * Parses a string containing Server-Sent Events (SSE) data into individual event objects.
14
+ *
15
+ * @template TData - The type of the parsed `data` field in the event.
16
+ * @param text - The raw SSE data as a string, where events are separated by double newlines.
17
+ * @param options - Optional configuration for parsing the events.
18
+ * @param options.dataParser - A custom parser function for the `data` field. Defaults to JSON parsing,
19
+ * falling back to returning the raw string if parsing fails.
20
+ *
21
+ * @returns A generator that yields `ServerSentEvent` objects parsed from the input string.
22
+ *
23
+ * @remarks
24
+ * - Empty lines and events with no fields are ignored.
25
+ * - If the `data` field cannot be parsed as JSON, it is returned as a plain string.
26
+ * - Fields other than `data` are stored as strings in the resulting `ServerSentEvent` object.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * const sseData = `
31
+ * id: 1
32
+ * event: message
33
+ * data: {"key":"value"}
34
+ *
35
+ * id: 2
36
+ * event: update
37
+ * data: plain text
38
+ * `;
39
+ *
40
+ * for (const event of parseEvents(sseData)) {
41
+ * console.log(event);
42
+ * }
43
+ * // Output:
44
+ * // { id: "1", event: "message", data: { key: "value" } }
45
+ * // { id: "2", event: "update", data: "plain text" }
46
+ * ```
47
+ */
48
+ function* parseEvents(text, options) {
49
+ // Split the input string into individual event strings using double newline as separator
50
+ const eventStrings = text.split('\n\n');
51
+ const dataParser = options?.dataParser || defaultDataParser;
52
+ // Iterate through each event string
53
+ for (const eventStr of eventStrings) {
54
+ // Skip empty event strings (after trimming whitespace)
55
+ if (!eventStr.trim())
56
+ continue;
57
+ // Split the event string into lines (fields) using single newline
58
+ const lines = eventStr.split('\n');
59
+ // Use reduce to process each line in the event string
60
+ const event = lines.reduce((event, line) => {
61
+ // Skip empty lines
62
+ if (!line)
63
+ return event;
64
+ // Find the index of the first colon, which separates field name and value
65
+ const colonIndex = line.indexOf(':');
66
+ // Skip lines without a colon (invalid format)
67
+ if (colonIndex === -1)
68
+ return event;
69
+ // Extract the field name (before colon) and trim whitespace
70
+ const field = line.slice(0, colonIndex).trim();
71
+ // Extract the field value (after colon) and trim whitespace
72
+ const value = line.slice(colonIndex + 1).trim();
73
+ // Handle the 'data' field specially, attempting JSON parsing
74
+ if (field === 'data') {
75
+ event.data = dataParser(value);
76
+ }
77
+ else {
78
+ // For non-data fields, assign the value as a string to the event object
79
+ event[field] = value;
80
+ }
81
+ return event;
82
+ }, {});
83
+ // Only emit the event to the results if it has at least one field
84
+ if (Object.keys(event).length) {
85
+ yield event;
86
+ }
87
+ }
88
+ }
89
+ async function* readStream(reader, options) {
90
+ const skipHeartbeats = !!options?.skipHeartbeats;
91
+ const eventFilter = options?.eventFilter
92
+ ? Array.isArray(options.eventFilter)
93
+ ? options.eventFilter
94
+ : [options.eventFilter]
95
+ : null;
96
+ const decoder = new TextDecoder();
97
+ while (true) {
98
+ const { done, value } = await reader.read();
99
+ if (done) {
100
+ break;
101
+ }
102
+ const text = decoder.decode(value, { stream: true });
103
+ const events = parseEvents(text, { dataParser: options?.dataParser });
104
+ for (const event of events) {
105
+ if (event.retry) {
106
+ await new Promise((resolve) => setTimeout(resolve, Number.parseInt(event.retry ?? '300', 10)));
107
+ continue;
108
+ }
109
+ if (skipHeartbeats) {
110
+ // Skip comment-based heartbeats (no event, data, or id)
111
+ if (!event.event && !event.data && !event.id) {
112
+ continue;
113
+ }
114
+ // Skip named heartbeat events (e.g., event: heartbeat or event: ping)
115
+ if (event.event && ['heartbeat', 'ping'].includes(event.event)) {
116
+ continue;
117
+ }
118
+ }
119
+ if (!eventFilter || (event.event && eventFilter.includes(event.event))) {
120
+ yield event;
121
+ }
122
+ }
123
+ }
124
+ }
125
+ /**
126
+ * Transforms an SSE response into an Observable stream of parsed events.
127
+ * @param response - The HTTP response with Content-Type: text/event-stream.
128
+ * @param options - Optional configuration for event filtering and heartbeat handling.
129
+ * @param options.eventFilter - Filter events by type (single string or array).
130
+ * @param options.skipHeartbeats - Skip empty/heartbeat events if true.
131
+ * @param options.dataParser - Custom parser for the data field.
132
+ * @param options.abortSignal - Abort signal to cancel the stream.
133
+ * @returns An Observable emitting parsed ServerSentEvent objects.
134
+ * @throws ServerSentEventResponseError if response is invalid or stream fails.
135
+ */
136
+ export const createSseSelector = (options) => {
137
+ return (response) => {
138
+ if (!response.ok) {
139
+ throw new ServerSentEventResponseError(`HTTP error! Status: ${response.status}`, response);
140
+ }
141
+ if (!response.body) {
142
+ throw new ServerSentEventResponseError('Response body is not readable', response);
143
+ }
144
+ if (!response.headers.get('Content-Type')?.includes('text/event-stream')) {
145
+ throw new ServerSentEventResponseError('Response is not a text/event-stream', response);
146
+ }
147
+ const reader = response.body.getReader();
148
+ return from(readStream(reader, {
149
+ dataParser: options?.dataParser,
150
+ skipHeartbeats: options?.skipHeartbeats,
151
+ eventFilter: options?.eventFilter,
152
+ })).pipe(
153
+ // Stop reading if the abort signal is triggered
154
+ takeUntil(options?.abortSignal ? fromEvent(options.abortSignal, 'abort') : EMPTY), finalize(async () => {
155
+ // cancel just in case of a pre-mature exit
156
+ await reader.cancel().catch(() => {
157
+ /** ignore cancellation errors */
158
+ });
159
+ reader.releaseLock();
160
+ }));
161
+ };
162
+ };
163
+ export default createSseSelector;
164
+ //# sourceMappingURL=sse-selector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse-selector.js","sourceRoot":"","sources":["../../../../src/lib/selectors/sse-selector.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,3 @@
1
1
  // Generated by genversion.
2
- export const version = '6.2.5';
2
+ export const version = '6.3.0';
3
3
  //# sourceMappingURL=version.js.map