http-request-manager 18.12.4 → 18.12.8

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,7 +1,7 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { inject, Injectable, APP_ID, Inject, InjectionToken, isDevMode, signal, effect, computed, Injector, Optional, EventEmitter, Input, Output, ViewEncapsulation, Component, NgModule, ViewChild } from '@angular/core';
3
3
  import { ComponentStore } from '@ngrx/component-store';
4
- import { map, catchError, filter, tap, finalize, takeWhile, retry, startWith, mergeMap, takeUntil, concatMap, toArray, withLatestFrom, switchMap, delay, take, scan, distinctUntilChanged } from 'rxjs/operators';
4
+ import { map, catchError, filter, finalize, tap, scan, takeWhile, retry, startWith, mergeMap, takeUntil, concatMap, toArray, withLatestFrom, switchMap, delay, take, distinctUntilChanged } from 'rxjs/operators';
5
5
  import { HttpClient, HttpHeaders, HttpEventType, HttpHeaderResponse, HttpErrorResponse, HTTP_INTERCEPTORS } from '@angular/common/http';
6
6
  import * as CryptoJS from 'crypto-js';
7
7
  import { from, BehaviorSubject, EMPTY, throwError, defer, interval, timer, Subject, of, Observable, merge, Subscription, take as take$1, catchError as catchError$1, map as map$1, tap as tap$1, switchMap as switchMap$1, startWith as startWith$1, distinctUntilChanged as distinctUntilChanged$1, combineLatest, filter as filter$1, takeUntil as takeUntil$1, ReplaySubject } from 'rxjs';
@@ -884,6 +884,7 @@ class StreamingProcessor {
884
884
  this.contentType = '';
885
885
  this.maxBufferSize = 10 * 1024 * 1024; // 10MB limit
886
886
  this.lastParsedLength = 0; // Track parsed position to avoid duplicates
887
+ this.lastParsedLineEnd = 0; // Track end of last-parsed complete line for NDJSON incremental parsing
887
888
  this.streamConfig = config || { streamType: StreamType.AI_STREAMING };
888
889
  }
889
890
  /**
@@ -906,18 +907,26 @@ class StreamingProcessor {
906
907
  return null;
907
908
  case HttpEventType.DownloadProgress:
908
909
  if (event.partialText) {
909
- this.appendToBuffer(event.partialText);
910
+ // partialText is cumulative, so replace the buffer instead of appending
911
+ this.buffer = event.partialText;
910
912
  const parsedData = this.parseBuffer();
911
- // Only return NEW items since last parse (progressive updates)
912
- const newItems = parsedData.slice(this.lastParsedLength);
913
- // received = cumulative total for display, newItems.length = new this chunk
914
- const received = newItems.length; // Changed from lastParsedLength
915
- this.lastParsedLength = parsedData.length;
913
+ // For NDJSON incremental parsing, parsedData already contains only new items.
914
+ // For other formats, parsedData is cumulative so slice from lastParsedLength.
915
+ const isIncremental = this.streamConfig.streamType === StreamType.NDJSON;
916
+ const newItems = isIncremental ? parsedData : parsedData.slice(this.lastParsedLength);
917
+ // received = cumulative total for progress display
918
+ const received = isIncremental
919
+ ? this.lastParsedLength + parsedData.length
920
+ : parsedData.length;
921
+ this.lastParsedLength = received;
922
+ // Return null when no new items — prevents empty array emissions
923
+ if (newItems.length === 0) {
924
+ return null;
925
+ }
916
926
  const total = this.totalFromHeader;
917
927
  const percent = total
918
928
  ? Math.min(100, Math.round((received / total) * 100))
919
929
  : 0;
920
- // console.log('[STREAM] progress:', percent, 'received:', received, 'total:', total, 'bufferLen:', this.buffer.length, 'parsedCount:', parsedData.length);
921
930
  const progress = {
922
931
  received,
923
932
  total,
@@ -925,19 +934,24 @@ class StreamingProcessor {
925
934
  stage: 'streaming'
926
935
  };
927
936
  return {
928
- data: newItems.length > 0 ? newItems : [],
937
+ data: newItems,
929
938
  progress
930
939
  };
931
940
  }
932
941
  return null;
933
942
  case HttpEventType.Response:
934
943
  if (event.body) {
935
- this.appendToBuffer(event.body);
944
+ // event.body is the complete response, replace the buffer
945
+ this.buffer = event.body;
936
946
  const parsedData = this.parseBuffer();
937
- // Only return items not already returned via progress events
938
- const remaining = parsedData.slice(this.lastParsedLength);
939
- this.lastParsedLength = parsedData.length;
940
- const received = parsedData.length;
947
+ // For NDJSON incremental parsing, parsedData already contains only new items.
948
+ // For other formats, parsedData is cumulative so slice from lastParsedLength.
949
+ const isIncremental = this.streamConfig.streamType === StreamType.NDJSON;
950
+ const remaining = isIncremental ? parsedData : parsedData.slice(this.lastParsedLength);
951
+ const received = isIncremental
952
+ ? this.lastParsedLength + parsedData.length
953
+ : parsedData.length;
954
+ this.lastParsedLength = received;
941
955
  const total = this.totalFromHeader;
942
956
  const percent = total
943
957
  ? Math.min(100, Math.round((received / total) * 100))
@@ -966,6 +980,7 @@ class StreamingProcessor {
966
980
  // Implement sliding window if buffer gets too large
967
981
  if (this.buffer.length > this.maxBufferSize) {
968
982
  this.buffer = this.buffer.slice(-this.maxBufferSize / 2);
983
+ this.lastParsedLineEnd = 0;
969
984
  }
970
985
  }
971
986
  /**
@@ -976,11 +991,25 @@ class StreamingProcessor {
976
991
  return [];
977
992
  }
978
993
  try {
994
+ if (this.streamConfig.streamType === StreamType.NDJSON) {
995
+ // For NDJSON, only parse complete lines since the last parse.
996
+ // Find the last newline in the buffer — everything after it is an incomplete line.
997
+ const lastNewlineIndex = this.buffer.lastIndexOf('\n');
998
+ if (lastNewlineIndex === -1) {
999
+ // No complete lines yet
1000
+ return [];
1001
+ }
1002
+ // Parse only the content from lastParsedLineEnd up to (and including) the last newline
1003
+ const bufferToParse = this.buffer.substring(this.lastParsedLineEnd, lastNewlineIndex + 1);
1004
+ this.lastParsedLineEnd = lastNewlineIndex + 1;
1005
+ const result = parseStreamData(bufferToParse, this.contentType, this.streamConfig);
1006
+ return result;
1007
+ }
979
1008
  const result = parseStreamData(this.buffer, this.contentType, this.streamConfig);
980
1009
  return result;
981
1010
  }
982
1011
  catch (error) {
983
- console.warn('Failed to parse streaming data:', error);
1012
+ // console.warn('Failed to parse streaming data:', error);
984
1013
  return [];
985
1014
  }
986
1015
  }
@@ -991,6 +1020,7 @@ class StreamingProcessor {
991
1020
  this.buffer = '';
992
1021
  this.contentType = '';
993
1022
  this.lastParsedLength = 0;
1023
+ this.lastParsedLineEnd = 0;
994
1024
  this.totalFromHeader = undefined;
995
1025
  }
996
1026
  /**
@@ -2891,7 +2921,9 @@ class RequestService extends WebsocketService {
2891
2921
  observe: 'events',
2892
2922
  responseType: 'text',
2893
2923
  reportProgress: true
2894
- }).pipe(tap(data => console.log('STREAM DATA', data)), requestStreaming({
2924
+ }).pipe(
2925
+ // tap(data => console.log('STREAM DATA', data)),
2926
+ requestStreaming({
2895
2927
  streamType: options.streamType || StreamType.AI_STREAMING,
2896
2928
  totalHeader: options.totalHeader
2897
2929
  }), this.requestStreaming(options), finalize(() => {
@@ -2981,19 +3013,19 @@ class RequestService extends WebsocketService {
2981
3013
  requestStreaming(options) {
2982
3014
  return (source$) => {
2983
3015
  return source$.pipe(tap(output => {
2984
- // Update progress from stream output
2985
3016
  this.progress.next(output.progress.percent);
2986
3017
  this.streamProgress.next(output.progress);
2987
- }), map(output => {
2988
- const data = output.data;
2989
- if (!data || (Array.isArray(data) && data.length === 0)) {
2990
- return data;
2991
- }
3018
+ }), scan((acc, output) => {
3019
+ // Accumulate data from each emission
3020
+ const newData = output.data;
2992
3021
  if (options?.adapter) {
2993
- return data.map((item) => options.adapter(item));
3022
+ const adaptedData = newData.map((item) => options.adapter(item));
3023
+ return [...acc, ...adaptedData];
2994
3024
  }
2995
- return data;
2996
- }));
3025
+ else {
3026
+ return [...acc, ...newData];
3027
+ }
3028
+ }, []));
2997
3029
  };
2998
3030
  }
2999
3031
  downloadFileRequest(options) {
@@ -4170,7 +4202,7 @@ class HTTPManagerService extends RequestService {
4170
4202
  }
4171
4203
  handleSequentialError(request, error, index, options) {
4172
4204
  if (options.logErrors !== false) {
4173
- console.error(`Batch request ${index} failed:`, error);
4205
+ // console.error(`Batch request ${index} failed:`, error);
4174
4206
  }
4175
4207
  if (options.stopOnError) {
4176
4208
  return throwError(() => error);
@@ -4182,7 +4214,7 @@ class HTTPManagerService extends RequestService {
4182
4214
  }
4183
4215
  handleParallelError(request, error, index, options) {
4184
4216
  if (options.logErrors !== false) {
4185
- console.error(`Batch request ${index} failed:`, error);
4217
+ // console.error(`Batch request ${index} failed:`, error);
4186
4218
  }
4187
4219
  if (options.ignoreErrors) {
4188
4220
  return of(undefined);
@@ -4277,17 +4309,17 @@ class RequestSignalsService extends WebsocketService {
4277
4309
  * - Streams are protected - non-stream requests wait for active streams
4278
4310
  */
4279
4311
  queueRequest(request$, method, isStream = false) {
4280
- console.log(`[Queue] ${method} queued (isStream=${isStream})`, {
4281
- activeMethod: this.activeMethod,
4282
- activeStreamMethod: this.activeStreamMethod,
4283
- queueLength: this.requestQueue.length
4284
- });
4312
+ // console.log(`[Queue] ${method} queued (isStream=${isStream})`, {
4313
+ // activeMethod: this.activeMethod,
4314
+ // activeStreamMethod: this.activeStreamMethod,
4315
+ // queueLength: this.requestQueue.length
4316
+ // });
4285
4317
  return new Observable((observer) => {
4286
- console.log(`[Queue] ${method} observer created, checking conditions...`, {
4287
- activeMethod: this.activeMethod,
4288
- activeStreamMethod: this.activeStreamMethod,
4289
- isStream
4290
- });
4318
+ // console.log(`[Queue] ${method} observer created, checking conditions...`, {
4319
+ // activeMethod: this.activeMethod,
4320
+ // activeStreamMethod: this.activeStreamMethod,
4321
+ // isStream
4322
+ // });
4291
4323
  const queuedRequest = {
4292
4324
  observable: request$,
4293
4325
  resolve: (value) => observer.next(value),
@@ -4297,7 +4329,7 @@ class RequestSignalsService extends WebsocketService {
4297
4329
  };
4298
4330
  // If a stream is currently active, non-stream requests must wait
4299
4331
  if (this.activeStreamMethod && !isStream) {
4300
- console.log(`[Queue] ${method} queued (1), waiting for stream ${this.activeStreamMethod}`);
4332
+ // console.log(`[Queue] ${method} queued (1), waiting for stream ${this.activeStreamMethod}`);
4301
4333
  this.requestQueue.push(queuedRequest);
4302
4334
  return () => {
4303
4335
  const idx = this.requestQueue.findIndex(q => q === queuedRequest);
@@ -4307,7 +4339,7 @@ class RequestSignalsService extends WebsocketService {
4307
4339
  }
4308
4340
  // If a request is already running, queue this one (FIFO)
4309
4341
  if (this.activeMethod) {
4310
- console.log(`[Queue] ${method} queued (2), waiting for ${this.activeMethod}`);
4342
+ // console.log(`[Queue] ${method} queued (2), waiting for ${this.activeMethod}`);
4311
4343
  this.requestQueue.push(queuedRequest);
4312
4344
  return () => {
4313
4345
  const idx = this.requestQueue.findIndex(q => q === queuedRequest);
@@ -4316,7 +4348,7 @@ class RequestSignalsService extends WebsocketService {
4316
4348
  };
4317
4349
  }
4318
4350
  // No active request - start immediately
4319
- console.log(`[Queue] ${method} starting immediately`);
4351
+ // console.log(`[Queue] ${method} starting immediately`);
4320
4352
  this.startRequest(queuedRequest, observer);
4321
4353
  return () => {
4322
4354
  const idx = this.requestQueue.findIndex(q => q === queuedRequest);
@@ -4334,23 +4366,23 @@ class RequestSignalsService extends WebsocketService {
4334
4366
  this.activeStreamMethod = queuedRequest.method;
4335
4367
  }
4336
4368
  this._activeRequestCount.update(c => c + 1);
4337
- console.log(`[Queue] Starting ${queuedRequest.method}${queuedRequest.isStream ? ' (STREAM)' : ''}`, {
4338
- activeMethod: this.activeMethod,
4339
- activeStreamMethod: this.activeStreamMethod,
4340
- queueLength: this.requestQueue.length
4341
- });
4369
+ // console.log(`[Queue] Starting ${queuedRequest.method}${queuedRequest.isStream ? ' (STREAM)' : ''}`, {
4370
+ // activeMethod: this.activeMethod,
4371
+ // activeStreamMethod: this.activeStreamMethod,
4372
+ // queueLength: this.requestQueue.length
4373
+ // });
4342
4374
  const sub = queuedRequest.observable.subscribe({
4343
4375
  next: (value) => {
4344
- console.log(`[Queue] ${queuedRequest.method} received value, isStream=${queuedRequest.isStream}`);
4376
+ // console.log(`[Queue] ${queuedRequest.method} received value, isStream=${queuedRequest.isStream}`);
4345
4377
  observer.next(value);
4346
4378
  },
4347
4379
  error: (error) => {
4348
- console.log(`[Queue] ${queuedRequest.method} error:`, error);
4380
+ // console.log(`[Queue] ${queuedRequest.method} error:`, error);
4349
4381
  observer.error(error);
4350
4382
  this.cleanupAndProcessNext(queuedRequest.method, !!queuedRequest.isStream);
4351
4383
  },
4352
4384
  complete: () => {
4353
- console.log(`[Queue] ${queuedRequest.method} complete, isStream=${queuedRequest.isStream}`);
4385
+ // console.log(`[Queue] ${queuedRequest.method} complete, isStream=${queuedRequest.isStream}`);
4354
4386
  observer.complete();
4355
4387
  this.cleanupAndProcessNext(queuedRequest.method, !!queuedRequest.isStream);
4356
4388
  }
@@ -4361,35 +4393,29 @@ class RequestSignalsService extends WebsocketService {
4361
4393
  * Clean up completed request and process next in queue
4362
4394
  */
4363
4395
  cleanupAndProcessNext(method, wasStream) {
4364
- console.log(`[Queue] cleanupAndProcessNext called: method=${method}, wasStream=${wasStream}`, {
4365
- activeMethod: this.activeMethod,
4366
- activeStreamMethod: this.activeStreamMethod,
4367
- queueLength: this.requestQueue.length
4368
- });
4396
+ // console.log(`[Queue] cleanupAndProcessNext called: method=${method}, wasStream=${wasStream}`, {
4397
+ // activeMethod: this.activeMethod,
4398
+ // activeStreamMethod: this.activeStreamMethod,
4399
+ // queueLength: this.requestQueue.length
4400
+ // });
4369
4401
  this.activeRequests.delete(method);
4370
4402
  this.activeMethod = null;
4371
4403
  if (wasStream) {
4372
4404
  this.activeStreamMethod = null;
4373
4405
  }
4374
- this._activeRequestCount.update(c => {
4375
- const newCount = Math.max(0, c - 1);
4376
- if (newCount === 0) {
4377
- this.progress.set(0);
4378
- }
4379
- return newCount;
4380
- });
4381
- console.log(`[Queue] After cleanup:`, {
4382
- activeMethod: this.activeMethod,
4383
- activeStreamMethod: this.activeStreamMethod,
4384
- queueLength: this.requestQueue.length
4385
- });
4406
+ this._activeRequestCount.update(c => Math.max(0, c - 1));
4407
+ // console.log(`[Queue] After cleanup:`, {
4408
+ // activeMethod: this.activeMethod,
4409
+ // activeStreamMethod: this.activeStreamMethod,
4410
+ // queueLength: this.requestQueue.length
4411
+ // });
4386
4412
  // Process next request in queue
4387
4413
  if (this.requestQueue.length > 0) {
4388
4414
  const next = this.requestQueue.shift();
4389
- console.log(`[Queue] Processing next from queue: ${next.method}`, {
4390
- isStream: next.isStream,
4391
- queueLength: this.requestQueue.length
4392
- });
4415
+ // console.log(`[Queue] Processing next from queue: ${next.method}`, {
4416
+ // isStream: next.isStream,
4417
+ // queueLength: this.requestQueue.length
4418
+ // });
4393
4419
  this.startRequest(next, {
4394
4420
  next: (value) => next.resolve(value),
4395
4421
  error: (error) => next.reject(error),
@@ -8467,7 +8493,7 @@ class RequestManagerBasicDemoComponent {
8467
8493
  // Update displayed columns when data changes
8468
8494
  updateDisplayedColumns(data) {
8469
8495
  this.displayedColumns = this.getColumnsFromData(data);
8470
- console.log('[DEMO] Updated columns:', this.displayedColumns);
8496
+ // console.log('[DEMO] Updated columns:', this.displayedColumns)
8471
8497
  }
8472
8498
  // Helper to check if value is an object
8473
8499
  isObject(value) {
@@ -8727,7 +8753,7 @@ class RequestManagerBasicDemoComponent {
8727
8753
  this.requestParams.GET = reqParams.apiOptions;
8728
8754
  this.STREAM$ = this.httpManagerService.getRequest(reqParams.apiOptions, reqParams.path)
8729
8755
  .pipe(tap((data) => {
8730
- console.log("API STREAM response", data);
8756
+ // console.log("API STREAM response", data)
8731
8757
  if (data && data.length > 0) {
8732
8758
  this.updateDisplayedColumns(data);
8733
8759
  }
@@ -9032,7 +9058,7 @@ class RequestManagerStateDemoComponent {
9032
9058
  this.stateManagerDemoService.data$.pipe(tap$1((data) => console.log("API STREAM_AI response", data)));
9033
9059
  this.error$.pipe(tap$1((data) => {
9034
9060
  debugger;
9035
- console.log("API STREAM response", data);
9061
+ // console.log("API STREAM response", data)
9036
9062
  }), catchError$1(error => {
9037
9063
  return throwError(() => this.errorHandling(error, 'STREAM'));
9038
9064
  }));
@@ -9208,7 +9234,7 @@ class RequestManagerDemoComponent {
9208
9234
  // Update displayed columns when data changes
9209
9235
  updateDisplayedColumns(data) {
9210
9236
  this.displayedColumns = this.getColumnsFromData(data);
9211
- console.log('[DEMO] Updated columns:', this.displayedColumns);
9237
+ // console.log('[DEMO] Updated columns:', this.displayedColumns)
9212
9238
  }
9213
9239
  // Helper to check if value is an object
9214
9240
  isObject(value) {
@@ -9492,7 +9518,7 @@ class RequestManagerDemoComponent {
9492
9518
  this.STREAM_error$.next('');
9493
9519
  this.STREAM$ = this.httpManagerService.getRequest(reqParams.apiOptions, reqParams.path)
9494
9520
  .pipe(tap((data) => {
9495
- console.log("API STREAM response", data);
9521
+ // console.log("API STREAM response", data)
9496
9522
  if (data && data.length > 0) {
9497
9523
  this.updateDisplayedColumns(data);
9498
9524
  }