@ops-ai/react-router-toggly 1.2.1 → 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/CHANGELOG.md +33 -0
- package/dist/client.cjs +106 -14
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +5 -2
- package/dist/client.d.ts +5 -2
- package/dist/client.js +108 -16
- package/dist/client.js.map +1 -1
- package/dist/server.cjs +50 -4
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +1 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +42 -4
- package/dist/server.js.map +1 -1
- package/dist/telemetry/grpc.cjs +1 -1
- package/dist/telemetry/grpc.cjs.map +1 -1
- package/dist/telemetry/grpc.js +1 -1
- package/dist/telemetry/grpc.js.map +1 -1
- package/package.json +4 -3
- package/proto/usage.proto +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
|
+
## 1.5.1
|
|
2
|
+
|
|
3
|
+
2026-10-15
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- After `dispose()`, `use()` and `captureCheck()` no longer create an
|
|
7
|
+
unmanaged reporter or attach leftover lifecycle listeners [OPS-1758].
|
|
8
|
+
|
|
9
|
+
## 1.5.0
|
|
10
|
+
|
|
11
|
+
2026-10-11
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- `use()` for timed feature usage scopes (attempt, duration, errors) via `@ops-ai/toggly-client-telemetry` [OPS-1758].
|
|
15
|
+
|
|
1
16
|
# Changelog
|
|
2
17
|
|
|
18
|
+
## [1.4.0] - 2026-10-11
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- Usage scope metrics on `VariantStats` (`errorCount`, `durationSumMs`,
|
|
22
|
+
`errorDurationSumMs`) and batcher APIs `recordUsageError`, `recordUsageDuration`,
|
|
23
|
+
`recordUsageScopeOutcome` (proto fields 5–7).
|
|
24
|
+
|
|
25
|
+
## [1.3.1] - 2026-10-11
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
- Only call `useRouteLoaderData` when `routeId` is set and use `useInRouterContext` so SSR and non-data-router apps hydrate from `fallbackContext` / `TogglyScript` without invoking data-router hooks [OPS-1756].
|
|
29
|
+
|
|
30
|
+
## [1.3.0] - 2026-10-04
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
- Server export of `createSegmentMembershipClient` for Backend-key targeting-list updates.
|
|
34
|
+
|
|
35
|
+
|
|
3
36
|
## [1.2.1] - 2026-09-27
|
|
4
37
|
|
|
5
38
|
### Fixed
|
package/dist/client.cjs
CHANGED
|
@@ -186,6 +186,7 @@ function createBrowserTelemetry(config) {
|
|
|
186
186
|
}
|
|
187
187
|
};
|
|
188
188
|
const getReporter = () => {
|
|
189
|
+
if (disposed) return void 0;
|
|
189
190
|
if (!reporter) {
|
|
190
191
|
reporter = togglyClientTelemetry.createTelemetryReporter({
|
|
191
192
|
appKey: config.appKey,
|
|
@@ -207,6 +208,7 @@ function createBrowserTelemetry(config) {
|
|
|
207
208
|
};
|
|
208
209
|
function replay(entry) {
|
|
209
210
|
const target = getReporter();
|
|
211
|
+
if (!target) return;
|
|
210
212
|
target.setContext(entry.context);
|
|
211
213
|
if (entry.kind === "feature") {
|
|
212
214
|
const methods = ["recordCheck", "recordUsage", "recordView"];
|
|
@@ -274,6 +276,28 @@ function createBrowserTelemetry(config) {
|
|
|
274
276
|
}
|
|
275
277
|
const api = {
|
|
276
278
|
recordUsage: (key, variant = "enabled") => feature(key, variant, 1),
|
|
279
|
+
use: (key, fn, variant = "enabled") => {
|
|
280
|
+
if (!usage || disposed) {
|
|
281
|
+
return togglyClientTelemetry.runFeatureUsageScope(
|
|
282
|
+
{ recordAttempt: () => {
|
|
283
|
+
}, recordSuccessDuration: () => {
|
|
284
|
+
}, recordFailure: () => {
|
|
285
|
+
} },
|
|
286
|
+
fn
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
const target = getReporter();
|
|
290
|
+
if (!target) {
|
|
291
|
+
return togglyClientTelemetry.runFeatureUsageScope(
|
|
292
|
+
{ recordAttempt: () => {
|
|
293
|
+
}, recordSuccessDuration: () => {
|
|
294
|
+
}, recordFailure: () => {
|
|
295
|
+
} },
|
|
296
|
+
fn
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
return target.use(key, fn, variant);
|
|
300
|
+
},
|
|
277
301
|
recordView: (key, variant = "enabled") => feature(key, variant, 2),
|
|
278
302
|
incrementCounter: (key, value = 1) => event({ partition, context, key, kind: "counter", values: [value] }),
|
|
279
303
|
setGauge: (key, value) => event({ partition, context, key, kind: "gauge", values: [value] }),
|
|
@@ -293,7 +317,10 @@ function createBrowserTelemetry(config) {
|
|
|
293
317
|
if (disposed || !usage) return () => {
|
|
294
318
|
};
|
|
295
319
|
if (active) {
|
|
296
|
-
const
|
|
320
|
+
const target = getReporter();
|
|
321
|
+
if (!target) return () => {
|
|
322
|
+
};
|
|
323
|
+
const record = target.captureCheck();
|
|
297
324
|
return (key, result) => record(key, checkVariantLabel(result));
|
|
298
325
|
}
|
|
299
326
|
const attribution = context;
|
|
@@ -320,7 +347,7 @@ function createBrowserTelemetry(config) {
|
|
|
320
347
|
|
|
321
348
|
// src/client/sdk-identity.ts
|
|
322
349
|
var SDK_ID = "react-router";
|
|
323
|
-
var SDK_VERSION = "1.
|
|
350
|
+
var SDK_VERSION = "1.5.0";
|
|
324
351
|
function appendSdkQueryParams(params) {
|
|
325
352
|
params.set("sdk", SDK_ID);
|
|
326
353
|
params.set("sdkVersion", SDK_VERSION);
|
|
@@ -1053,32 +1080,97 @@ function FeatureGate({
|
|
|
1053
1080
|
const enabled = useFeatureGate(featureKeys, requirement, negate, context, contextKind);
|
|
1054
1081
|
return enabled ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children }) : null;
|
|
1055
1082
|
}
|
|
1056
|
-
function
|
|
1083
|
+
function resolveServerContext(data, fallbackContext) {
|
|
1084
|
+
const serverContext = data?.[TOGGLY_LOADER_KEY];
|
|
1085
|
+
return serverContext ?? fallbackContext;
|
|
1086
|
+
}
|
|
1087
|
+
function buildMergedConfig(config, serverContext) {
|
|
1088
|
+
return config ?? (serverContext ? {
|
|
1089
|
+
appKey: serverContext.appKey,
|
|
1090
|
+
environment: serverContext.environment
|
|
1091
|
+
} : void 0);
|
|
1092
|
+
}
|
|
1093
|
+
function RouterTogglyProviderInner({
|
|
1094
|
+
children,
|
|
1095
|
+
serverContext,
|
|
1096
|
+
config,
|
|
1097
|
+
...props
|
|
1098
|
+
}) {
|
|
1099
|
+
const mergedConfig = buildMergedConfig(config, serverContext);
|
|
1100
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TogglyProvider, { serverContext, config: mergedConfig, ...props, children });
|
|
1101
|
+
}
|
|
1102
|
+
function RouterTogglyProviderWithData({
|
|
1103
|
+
children,
|
|
1104
|
+
data,
|
|
1105
|
+
fallbackContext,
|
|
1106
|
+
config,
|
|
1107
|
+
...props
|
|
1108
|
+
}) {
|
|
1109
|
+
const serverContext = resolveServerContext(data, fallbackContext);
|
|
1110
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RouterTogglyProviderInner, { serverContext, config, ...props, children });
|
|
1111
|
+
}
|
|
1112
|
+
function RouterTogglyProviderFromRoute({
|
|
1057
1113
|
children,
|
|
1058
1114
|
routeId,
|
|
1059
1115
|
fallbackContext,
|
|
1060
1116
|
config,
|
|
1061
1117
|
...props
|
|
1062
1118
|
}) {
|
|
1063
|
-
const routeData = reactRouter.useRouteLoaderData(routeId
|
|
1119
|
+
const routeData = reactRouter.useRouteLoaderData(routeId);
|
|
1120
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1121
|
+
RouterTogglyProviderWithData,
|
|
1122
|
+
{
|
|
1123
|
+
data: routeData,
|
|
1124
|
+
fallbackContext,
|
|
1125
|
+
config,
|
|
1126
|
+
...props,
|
|
1127
|
+
children
|
|
1128
|
+
}
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
function RouterTogglyProviderFromLoader({
|
|
1132
|
+
children,
|
|
1133
|
+
fallbackContext,
|
|
1134
|
+
config,
|
|
1135
|
+
...props
|
|
1136
|
+
}) {
|
|
1064
1137
|
const loaderData = reactRouter.useLoaderData();
|
|
1065
|
-
const data = routeId ? routeData : loaderData;
|
|
1066
|
-
const serverContext = data?.[TOGGLY_LOADER_KEY];
|
|
1067
|
-
const resolvedServerContext = serverContext ?? fallbackContext;
|
|
1068
|
-
const mergedConfig = config ?? (resolvedServerContext ? {
|
|
1069
|
-
appKey: resolvedServerContext.appKey,
|
|
1070
|
-
environment: resolvedServerContext.environment
|
|
1071
|
-
} : void 0);
|
|
1072
1138
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1073
|
-
|
|
1139
|
+
RouterTogglyProviderWithData,
|
|
1074
1140
|
{
|
|
1075
|
-
|
|
1076
|
-
|
|
1141
|
+
data: loaderData,
|
|
1142
|
+
fallbackContext,
|
|
1143
|
+
config,
|
|
1077
1144
|
...props,
|
|
1078
1145
|
children
|
|
1079
1146
|
}
|
|
1080
1147
|
);
|
|
1081
1148
|
}
|
|
1149
|
+
function RouterTogglyProviderStatic({
|
|
1150
|
+
children,
|
|
1151
|
+
fallbackContext,
|
|
1152
|
+
config,
|
|
1153
|
+
...props
|
|
1154
|
+
}) {
|
|
1155
|
+
const serverContext = fallbackContext ?? getWindowTogglyData();
|
|
1156
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RouterTogglyProviderInner, { serverContext, config, ...props, children });
|
|
1157
|
+
}
|
|
1158
|
+
function RouterTogglyProvider({
|
|
1159
|
+
children,
|
|
1160
|
+
routeId,
|
|
1161
|
+
fallbackContext,
|
|
1162
|
+
config,
|
|
1163
|
+
...props
|
|
1164
|
+
}) {
|
|
1165
|
+
const inRouter = reactRouter.useInRouterContext();
|
|
1166
|
+
if (routeId && inRouter) {
|
|
1167
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RouterTogglyProviderFromRoute, { routeId, fallbackContext, config, ...props, children });
|
|
1168
|
+
}
|
|
1169
|
+
if (inRouter) {
|
|
1170
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RouterTogglyProviderFromLoader, { fallbackContext, config, ...props, children });
|
|
1171
|
+
}
|
|
1172
|
+
return /* @__PURE__ */ jsxRuntime.jsx(RouterTogglyProviderStatic, { fallbackContext, config, ...props, children });
|
|
1173
|
+
}
|
|
1082
1174
|
function useTogglyLoaderData() {
|
|
1083
1175
|
const loaderData = reactRouter.useLoaderData();
|
|
1084
1176
|
return {
|