@reproapp/node-sdk 0.0.22 → 0.0.24

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/dist/index.js CHANGED
@@ -1525,9 +1525,10 @@ function resolveCollectionOrWarn(source, type) {
1525
1525
  function post(cfg, sessionId, body, options) {
1526
1526
  try {
1527
1527
  const entries = Array.isArray(body?.entries) ? body.entries : [];
1528
- (0, client_1.enqueueIngestEntries)(cfg, sessionId, entries, options);
1528
+ return (0, client_1.enqueueIngestEntries)(cfg, sessionId, entries, options);
1529
1529
  }
1530
1530
  catch { /* swallow in SDK */ }
1531
+ return false;
1531
1532
  }
1532
1533
  function toIngestConfig(cfg) {
1533
1534
  return {
@@ -1712,6 +1713,18 @@ const TRACE_BATCH_MAX_SERIALIZED_BYTES = (() => {
1712
1713
  return Math.trunc(env);
1713
1714
  return 512 * 1024;
1714
1715
  })();
1716
+ const TRACE_MAX_EVENTS_PER_REQUEST = (() => {
1717
+ const env = Number(process.env.REPRO_TRACE_MAX_EVENTS_PER_REQUEST);
1718
+ if (Number.isFinite(env) && env > 0)
1719
+ return Math.trunc(env);
1720
+ return 1000;
1721
+ })();
1722
+ const TRACE_MAX_BATCHES_PER_REQUEST = (() => {
1723
+ const env = Number(process.env.REPRO_TRACE_MAX_BATCHES_PER_REQUEST);
1724
+ if (Number.isFinite(env) && env > 0)
1725
+ return Math.trunc(env);
1726
+ return 8;
1727
+ })();
1715
1728
  const TRACE_FLUSH_DELAY_MS = 20;
1716
1729
  // Choose how to order trace events in payloads.
1717
1730
  // - "chronological" (default): preserve event arrival order (no reshuffle).
@@ -3766,22 +3779,31 @@ function estimateTraceBatchSerializedBytes(batch, requestRid, actionId, batchInd
3766
3779
  function chunkTraceEventsForTransport(events, requestRid, actionId) {
3767
3780
  if (!Array.isArray(events) || events.length === 0)
3768
3781
  return [];
3769
- const countBatches = chunkArray(events, TRACE_BATCH_SIZE);
3782
+ const boundedEvents = events.slice(0, TRACE_MAX_EVENTS_PER_REQUEST);
3783
+ const countBatches = chunkArray(boundedEvents, TRACE_BATCH_SIZE);
3770
3784
  const sizedBatches = [];
3771
3785
  let current = [];
3772
3786
  for (const event of countBatches.flat()) {
3787
+ if (sizedBatches.length >= TRACE_MAX_BATCHES_PER_REQUEST) {
3788
+ break;
3789
+ }
3773
3790
  const candidate = current.concat(event);
3774
3791
  const batchIndex = sizedBatches.length;
3775
3792
  const estimatedBytes = estimateTraceBatchSerializedBytes(candidate, requestRid, actionId, batchIndex);
3776
3793
  if (current.length > 0 &&
3777
3794
  estimatedBytes > TRACE_BATCH_MAX_SERIALIZED_BYTES) {
3778
3795
  sizedBatches.push(current);
3796
+ if (sizedBatches.length >= TRACE_MAX_BATCHES_PER_REQUEST) {
3797
+ current = [];
3798
+ break;
3799
+ }
3779
3800
  current = [event];
3780
3801
  continue;
3781
3802
  }
3782
3803
  current = candidate;
3783
3804
  }
3784
- if (current.length > 0) {
3805
+ if (current.length > 0 &&
3806
+ sizedBatches.length < TRACE_MAX_BATCHES_PER_REQUEST) {
3785
3807
  sizedBatches.push(current);
3786
3808
  }
3787
3809
  return sizedBatches;
@@ -4897,9 +4919,6 @@ function emitDbQuery(cfg, sid, aid, payload) {
4897
4919
  const spanContext = payload?.spanContext ?? captureSpanContextFromTracer();
4898
4920
  if (!shouldCaptureDbSpan(spanContext))
4899
4921
  return;
4900
- if (ctx.captureScope) {
4901
- ctx.captureScope.dbChangeCount += 1;
4902
- }
4903
4922
  const runCtx = {
4904
4923
  sid: ctx.sid,
4905
4924
  aid: ctx.aid,
@@ -5018,7 +5037,7 @@ async function emitDbQueryAsync(cfg, sid, aid, payload) {
5018
5037
  resultMetaMaterialization: resultMetaMaterialization.skipped,
5019
5038
  errorMaterialization: errorMaterialization.skipped,
5020
5039
  }, spanContext);
5021
- post(cfg, sid, {
5040
+ const enqueued = post(cfg, sid, {
5022
5041
  entries: [{
5023
5042
  actionId: aid ?? null,
5024
5043
  requestRid: ctx.rid ?? null,
@@ -5027,6 +5046,9 @@ async function emitDbQueryAsync(cfg, sid, aid, payload) {
5027
5046
  t: payload.t,
5028
5047
  }]
5029
5048
  });
5049
+ if (enqueued && ctx.captureScope) {
5050
+ ctx.captureScope.dbChangeCount += 1;
5051
+ }
5030
5052
  }
5031
5053
  function buildMinimalUpdate(before, after) {
5032
5054
  const set = {};
@@ -8,6 +8,6 @@ export declare const configureIngestQueueDrain: (options: {
8
8
  }) => void;
9
9
  export declare const kickIngestQueueDrain: () => void;
10
10
  export declare const postIngestEntries: (config: IngestClientConfig, sessionId: string, entries: LegacyEntry[]) => Promise<void>;
11
- export declare const enqueueIngestEntries: (config: IngestClientConfig, sessionId: string, entries: LegacyEntry[], options?: EnqueueIngestOptions) => void;
11
+ export declare const enqueueIngestEntries: (config: IngestClientConfig, sessionId: string, entries: LegacyEntry[], options?: EnqueueIngestOptions) => boolean;
12
12
  export declare const flushIngestQueue: () => Promise<void>;
13
13
  export type { IngestClientConfig, LegacyEntry } from './types';
@@ -173,7 +173,7 @@ const drainIngestQueue = async () => {
173
173
  };
174
174
  const enqueueIngestEntries = (config, sessionId, entries, options = {}) => {
175
175
  if (!sessionId || !Array.isArray(entries) || entries.length === 0) {
176
- return;
176
+ return false;
177
177
  }
178
178
  const priority = options.priority === 'high' ? 'high' : 'normal';
179
179
  const batch = {
@@ -208,6 +208,7 @@ const enqueueIngestEntries = (config, sessionId, entries, options = {}) => {
208
208
  }
209
209
  }
210
210
  scheduleDrain(shouldDeferDrain?.() ? deferDrainMs : 0);
211
+ return ingestQueue.includes(batch);
211
212
  };
212
213
  exports.enqueueIngestEntries = enqueueIngestEntries;
213
214
  const flushIngestQueue = async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reproapp/node-sdk",
3
- "version": "0.0.22",
3
+ "version": "0.0.24",
4
4
  "description": "Repro Nest SDK",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/index.ts CHANGED
@@ -1921,11 +1921,12 @@ function post(
1921
1921
  sessionId: string,
1922
1922
  body: any,
1923
1923
  options?: EnqueueIngestOptions,
1924
- ) {
1924
+ ): boolean {
1925
1925
  try {
1926
1926
  const entries = Array.isArray(body?.entries) ? (body.entries as LegacyEntry[]) : [];
1927
- enqueueIngestEntries(cfg, sessionId, entries, options);
1927
+ return enqueueIngestEntries(cfg, sessionId, entries, options);
1928
1928
  } catch { /* swallow in SDK */ }
1929
+ return false;
1929
1930
  }
1930
1931
 
1931
1932
  function toIngestConfig(cfg: IngestClientConfig): IngestClientConfig {
@@ -2116,6 +2117,16 @@ const TRACE_BATCH_MAX_SERIALIZED_BYTES = (() => {
2116
2117
  if (Number.isFinite(env) && env > 0) return Math.trunc(env);
2117
2118
  return 512 * 1024;
2118
2119
  })();
2120
+ const TRACE_MAX_EVENTS_PER_REQUEST = (() => {
2121
+ const env = Number(process.env.REPRO_TRACE_MAX_EVENTS_PER_REQUEST);
2122
+ if (Number.isFinite(env) && env > 0) return Math.trunc(env);
2123
+ return 1000;
2124
+ })();
2125
+ const TRACE_MAX_BATCHES_PER_REQUEST = (() => {
2126
+ const env = Number(process.env.REPRO_TRACE_MAX_BATCHES_PER_REQUEST);
2127
+ if (Number.isFinite(env) && env > 0) return Math.trunc(env);
2128
+ return 8;
2129
+ })();
2119
2130
  const TRACE_FLUSH_DELAY_MS = 20;
2120
2131
  // Choose how to order trace events in payloads.
2121
2132
  // - "chronological" (default): preserve event arrival order (no reshuffle).
@@ -4499,11 +4510,15 @@ function chunkTraceEventsForTransport(
4499
4510
  ): TraceEventRecord[][] {
4500
4511
  if (!Array.isArray(events) || events.length === 0) return [];
4501
4512
 
4502
- const countBatches = chunkArray(events, TRACE_BATCH_SIZE);
4513
+ const boundedEvents = events.slice(0, TRACE_MAX_EVENTS_PER_REQUEST);
4514
+ const countBatches = chunkArray(boundedEvents, TRACE_BATCH_SIZE);
4503
4515
  const sizedBatches: TraceEventRecord[][] = [];
4504
4516
  let current: TraceEventRecord[] = [];
4505
4517
 
4506
4518
  for (const event of countBatches.flat()) {
4519
+ if (sizedBatches.length >= TRACE_MAX_BATCHES_PER_REQUEST) {
4520
+ break;
4521
+ }
4507
4522
  const candidate = current.concat(event);
4508
4523
  const batchIndex = sizedBatches.length;
4509
4524
  const estimatedBytes = estimateTraceBatchSerializedBytes(
@@ -4518,6 +4533,10 @@ function chunkTraceEventsForTransport(
4518
4533
  estimatedBytes > TRACE_BATCH_MAX_SERIALIZED_BYTES
4519
4534
  ) {
4520
4535
  sizedBatches.push(current);
4536
+ if (sizedBatches.length >= TRACE_MAX_BATCHES_PER_REQUEST) {
4537
+ current = [];
4538
+ break;
4539
+ }
4521
4540
  current = [event];
4522
4541
  continue;
4523
4542
  }
@@ -4525,7 +4544,10 @@ function chunkTraceEventsForTransport(
4525
4544
  current = candidate;
4526
4545
  }
4527
4546
 
4528
- if (current.length > 0) {
4547
+ if (
4548
+ current.length > 0 &&
4549
+ sizedBatches.length < TRACE_MAX_BATCHES_PER_REQUEST
4550
+ ) {
4529
4551
  sizedBatches.push(current);
4530
4552
  }
4531
4553
 
@@ -5837,9 +5859,6 @@ function emitDbQuery(cfg: any, sid?: string, aid?: string, payload?: any) {
5837
5859
  const ctx = getCtx() as Ctx;
5838
5860
  const spanContext = payload?.spanContext ?? captureSpanContextFromTracer();
5839
5861
  if (!shouldCaptureDbSpan(spanContext)) return;
5840
- if (ctx.captureScope) {
5841
- ctx.captureScope.dbChangeCount += 1;
5842
- }
5843
5862
  const runCtx: Ctx = {
5844
5863
  sid: ctx.sid,
5845
5864
  aid: ctx.aid,
@@ -5957,7 +5976,7 @@ async function emitDbQueryAsync(cfg: any, sid?: string, aid?: string, payload?:
5957
5976
  resultMetaMaterialization: resultMetaMaterialization.skipped,
5958
5977
  errorMaterialization: errorMaterialization.skipped,
5959
5978
  }, spanContext);
5960
- post(cfg, sid, {
5979
+ const enqueued = post(cfg, sid, {
5961
5980
  entries: [{
5962
5981
  actionId: aid ?? null,
5963
5982
  requestRid: ctx.rid ?? null,
@@ -5966,6 +5985,9 @@ async function emitDbQueryAsync(cfg: any, sid?: string, aid?: string, payload?:
5966
5985
  t: payload.t,
5967
5986
  }]
5968
5987
  });
5988
+ if (enqueued && ctx.captureScope) {
5989
+ ctx.captureScope.dbChangeCount += 1;
5990
+ }
5969
5991
  }
5970
5992
 
5971
5993
  function buildMinimalUpdate(before: any, after: any) {
@@ -211,9 +211,9 @@ export const enqueueIngestEntries = (
211
211
  sessionId: string,
212
212
  entries: LegacyEntry[],
213
213
  options: EnqueueIngestOptions = {},
214
- ): void => {
214
+ ): boolean => {
215
215
  if (!sessionId || !Array.isArray(entries) || entries.length === 0) {
216
- return;
216
+ return false;
217
217
  }
218
218
  const priority = options.priority === 'high' ? 'high' : 'normal';
219
219
  const batch: QueuedIngestBatch = {
@@ -246,6 +246,7 @@ export const enqueueIngestEntries = (
246
246
  }
247
247
  }
248
248
  scheduleDrain(shouldDeferDrain?.() ? deferDrainMs : 0);
249
+ return ingestQueue.includes(batch);
249
250
  };
250
251
 
251
252
  export const flushIngestQueue = async (): Promise<void> => {
@@ -37,6 +37,10 @@ function main() {
37
37
  );
38
38
 
39
39
  assert(batches.length > 1, `expected more than one batch, got ${batches.length}`);
40
+ assert(
41
+ batches.length <= 8,
42
+ `expected trace transport to cap batches per request, got ${batches.length}`,
43
+ );
40
44
 
41
45
  batches.forEach((batch, index) => {
42
46
  const size = __reproTestHooks.estimateTraceBatchSerializedBytesForTest(
@@ -51,6 +55,18 @@ function main() {
51
55
  );
52
56
  });
53
57
 
58
+ const manyEvents = Array.from({ length: 1500 }, (_, index) => makeEvent(index, 'tiny'));
59
+ const cappedBatches = __reproTestHooks.chunkTraceEventsForTransportForTest(
60
+ manyEvents,
61
+ 'RID_test_trace_event_cap',
62
+ 'A_test_trace_event_cap',
63
+ );
64
+ const cappedEventCount = cappedBatches.reduce((sum, batch) => sum + batch.length, 0);
65
+ assert(
66
+ cappedEventCount <= 1000,
67
+ `expected trace transport to cap events per request, got ${cappedEventCount}`,
68
+ );
69
+
54
70
  // eslint-disable-next-line no-console
55
71
  console.log('trace batch size chunking OK');
56
72
  }