@ops-ai/react-router-toggly 1.2.0 → 1.5.1

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/server.d.cts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { LocalGate } from '@ops-ai/toggly-local-gates';
2
2
  import { EvaluatedDefinitions, TogglyEntityContext } from '@ops-ai/toggly-hooks-types';
3
3
  export { fromHttpRequest } from '@ops-ai/toggly-eval';
4
+ export { SegmentMembershipError, createSegmentMembershipClient } from '@ops-ai/toggly-segments';
4
5
 
5
6
  interface MetricsFeatureOptions {
6
7
  /** Optional feature key for experiment-style subcounts. */
package/dist/server.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { LocalGate } from '@ops-ai/toggly-local-gates';
2
2
  import { EvaluatedDefinitions, TogglyEntityContext } from '@ops-ai/toggly-hooks-types';
3
3
  export { fromHttpRequest } from '@ops-ai/toggly-eval';
4
+ export { SegmentMembershipError, createSegmentMembershipClient } from '@ops-ai/toggly-segments';
4
5
 
5
6
  interface MetricsFeatureOptions {
6
7
  /** Optional feature key for experiment-style subcounts. */
package/dist/server.js CHANGED
@@ -10,6 +10,7 @@ import fs from 'fs';
10
10
  import path from 'path';
11
11
  import { fileURLToPath } from 'url';
12
12
  import { redirect } from 'react-router';
13
+ export { SegmentMembershipError, createSegmentMembershipClient } from '@ops-ai/toggly-segments';
13
14
 
14
15
  // src/core/index.ts
15
16
 
@@ -204,7 +205,15 @@ var MAX_UNIQUE_USER_HASHES_PER_FEATURE = 1e4;
204
205
  var MAX_APPLICATION_UNIQUE_USER_HASHES = 1e4;
205
206
  var MAX_FEATURES_PER_BATCH = 500;
206
207
  function emptyVariant() {
207
- return { checkCount: 0, requestCount: 0, usedCount: 0, viewedCount: 0 };
208
+ return {
209
+ checkCount: 0,
210
+ requestCount: 0,
211
+ usedCount: 0,
212
+ viewedCount: 0,
213
+ errorCount: 0,
214
+ durationSumMs: 0,
215
+ errorDurationSumMs: 0
216
+ };
208
217
  }
209
218
  function emptyFeature() {
210
219
  return {
@@ -316,6 +325,32 @@ var UsageBatcher = class {
316
325
  this.addHashCapped(agg.uniqueViewedUserHashes, hash, this.maxUniqueHashesPerFeature);
317
326
  }
318
327
  }
328
+ recordUsageError(feature, _identity, variant = "enabled", count = 1) {
329
+ if (count <= 0) return;
330
+ const agg = this.get(feature);
331
+ if (!agg) return;
332
+ this.getVariant(agg, variant).errorCount += count;
333
+ }
334
+ recordUsageDuration(feature, durationMs, _identity, variant = "enabled", failed = false) {
335
+ if (!Number.isFinite(durationMs) || durationMs <= 0) return;
336
+ const ms = Math.floor(durationMs);
337
+ const agg = this.get(feature);
338
+ if (!agg) return;
339
+ const stats = this.getVariant(agg, variant);
340
+ if (failed) stats.errorDurationSumMs += ms;
341
+ else stats.durationSumMs += ms;
342
+ }
343
+ recordUsageScopeOutcome(feature, outcome, identity, variant = "enabled") {
344
+ if (outcome.cancelled) return;
345
+ if (outcome.failed) {
346
+ this.recordUsageError(feature, identity, variant);
347
+ if (outcome.durationMs != null) {
348
+ this.recordUsageDuration(feature, outcome.durationMs, identity, variant, true);
349
+ }
350
+ } else if (outcome.durationMs != null) {
351
+ this.recordUsageDuration(feature, outcome.durationMs, identity, variant, false);
352
+ }
353
+ }
319
354
  isEmpty() {
320
355
  return this.perFeature.size === 0 && this.appUnique.size === 0 && this.definitionCacheHits === 0 && this.definitionCacheMisses === 0;
321
356
  }
@@ -325,10 +360,7 @@ var UsageBatcher = class {
325
360
  featureCount() {
326
361
  return this.perFeature.size;
327
362
  }
328
- buildAndReset() {
329
- if (this.isEmpty()) {
330
- return null;
331
- }
363
+ buildPayload() {
332
364
  const payload = {
333
365
  appKey: this.appKey,
334
366
  environment: this.environment,
@@ -338,57 +370,60 @@ var UsageBatcher = class {
338
370
  uniqueUserHashes: [...this.appUnique],
339
371
  processStartTime: toProtobufTimestamp(this.processStartTime)
340
372
  };
341
- if (this.instanceName) {
342
- payload.instanceName = this.instanceName;
343
- }
344
- if (this.appVersion) {
345
- payload.appVersion = this.appVersion;
346
- }
347
- if (this.definitionCacheHits > 0) {
348
- payload.definitionCacheHits = this.definitionCacheHits;
349
- }
350
- if (this.definitionCacheMisses > 0) {
351
- payload.definitionCacheMisses = this.definitionCacheMisses;
373
+ if (this.instanceName) payload.instanceName = this.instanceName;
374
+ if (this.appVersion) payload.appVersion = this.appVersion;
375
+ if (this.definitionCacheHits > 0) payload.definitionCacheHits = this.definitionCacheHits;
376
+ if (this.definitionCacheMisses > 0) payload.definitionCacheMisses = this.definitionCacheMisses;
377
+ return payload;
378
+ }
379
+ appendFeatureStat(payload, snapshots, feature, agg) {
380
+ const variantStats = {};
381
+ for (const [name, stats] of agg.variantStats) {
382
+ if (stats.checkCount > 0 || stats.requestCount > 0 || stats.usedCount > 0 || stats.viewedCount > 0 || stats.errorCount > 0 || stats.durationSumMs > 0 || stats.errorDurationSumMs > 0) {
383
+ variantStats[name] = { ...stats };
384
+ }
352
385
  }
353
- const uniqueUsersEnabled = {};
354
- const uniqueUsersDisabled = {};
355
- const uniqueUsersUsed = {};
386
+ if (agg.uniqueUsersEnabled.size > 0) snapshots.uniqueUsersEnabled[feature] = [...agg.uniqueUsersEnabled];
387
+ if (agg.uniqueUsersDisabled.size > 0) snapshots.uniqueUsersDisabled[feature] = [...agg.uniqueUsersDisabled];
388
+ if (agg.uniqueUsersUsed.size > 0) snapshots.uniqueUsersUsed[feature] = [...agg.uniqueUsersUsed];
389
+ payload.stats.push({
390
+ feature,
391
+ uniqueContextIdentifierEnabledCount: agg.uniqueUsersEnabled.size,
392
+ uniqueContextIdentifierDisabledCount: agg.uniqueUsersDisabled.size,
393
+ uniqueUsersUsedCount: agg.uniqueUsersUsed.size,
394
+ uniqueUserHashes: [...agg.uniqueUserHashes],
395
+ uniqueViewedUserHashes: [...agg.uniqueViewedUserHashes],
396
+ variantStats
397
+ });
398
+ }
399
+ buildIdentitySnapshots(payload) {
400
+ const snapshots = {
401
+ uniqueUsersEnabled: {},
402
+ uniqueUsersDisabled: {},
403
+ uniqueUsersUsed: {}
404
+ };
356
405
  for (const [feature, agg] of this.perFeature) {
357
- const variantStats = {};
358
- for (const [name, stats] of agg.variantStats) {
359
- if (stats.checkCount > 0 || stats.requestCount > 0 || stats.usedCount > 0 || stats.viewedCount > 0) {
360
- variantStats[name] = { ...stats };
361
- }
362
- }
363
- if (agg.uniqueUsersEnabled.size > 0) {
364
- uniqueUsersEnabled[feature] = [...agg.uniqueUsersEnabled];
365
- }
366
- if (agg.uniqueUsersDisabled.size > 0) {
367
- uniqueUsersDisabled[feature] = [...agg.uniqueUsersDisabled];
368
- }
369
- if (agg.uniqueUsersUsed.size > 0) {
370
- uniqueUsersUsed[feature] = [...agg.uniqueUsersUsed];
371
- }
372
- payload.stats.push({
373
- feature,
374
- uniqueContextIdentifierEnabledCount: agg.uniqueUsersEnabled.size,
375
- uniqueContextIdentifierDisabledCount: agg.uniqueUsersDisabled.size,
376
- uniqueUsersUsedCount: agg.uniqueUsersUsed.size,
377
- uniqueUserHashes: [...agg.uniqueUserHashes],
378
- uniqueViewedUserHashes: [...agg.uniqueViewedUserHashes],
379
- variantStats
380
- });
406
+ this.appendFeatureStat(payload, snapshots, feature, agg);
381
407
  }
408
+ return snapshots;
409
+ }
410
+ reset() {
382
411
  this.perFeature = /* @__PURE__ */ new Map();
383
412
  this.appUnique = /* @__PURE__ */ new Set();
384
413
  this.droppedFeatures = false;
385
414
  this.definitionCacheHits = 0;
386
415
  this.definitionCacheMisses = 0;
416
+ }
417
+ buildAndReset() {
418
+ if (this.isEmpty()) {
419
+ return null;
420
+ }
421
+ const payload = this.buildPayload();
422
+ const snapshots = this.buildIdentitySnapshots(payload);
423
+ this.reset();
387
424
  return {
388
425
  payload,
389
- uniqueUsersEnabled,
390
- uniqueUsersDisabled,
391
- uniqueUsersUsed
426
+ ...snapshots
392
427
  };
393
428
  }
394
429
  restoreFromBundle(bundle) {
@@ -409,6 +444,9 @@ var UsageBatcher = class {
409
444
  target.requestCount += vs.requestCount ?? 0;
410
445
  target.usedCount += vs.usedCount ?? 0;
411
446
  target.viewedCount += vs.viewedCount ?? 0;
447
+ target.errorCount += vs.errorCount ?? 0;
448
+ target.durationSumMs += vs.durationSumMs ?? 0;
449
+ target.errorDurationSumMs += vs.errorDurationSumMs ?? 0;
412
450
  }
413
451
  for (const hash of stat.uniqueUserHashes ?? []) {
414
452
  this.addHashCapped(agg.uniqueUserHashes, hash, this.maxUniqueHashesPerFeature);
@@ -579,7 +617,7 @@ var MetricsBatcher = class {
579
617
 
580
618
  // src/core/sdk-identity.ts
581
619
  var SDK_ID = "react-router";
582
- var SDK_VERSION = "1.2.0";
620
+ var SDK_VERSION = "1.5.0";
583
621
  function sdkUserAgent() {
584
622
  return `toggly-${SDK_ID}/${SDK_VERSION}`;
585
623
  }
@@ -1099,7 +1137,7 @@ async function extractEvalContext(request, providers = {}) {
1099
1137
 
1100
1138
  // src/server/sdk-identity.ts
1101
1139
  var SDK_ID2 = "react-router";
1102
- var SDK_VERSION2 = "1.2.0";
1140
+ var SDK_VERSION2 = "1.5.0";
1103
1141
  var SDK_HEADER_ID = "X-Toggly-Sdk";
1104
1142
  var SDK_HEADER_VERSION = "X-Toggly-Sdk-Version";
1105
1143
  function sdkUserAgent2() {