@dr-sentry/react 1.0.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/README.md +258 -0
- package/dist/cjs/client.d.ts +121 -0
- package/dist/cjs/client.d.ts.map +1 -0
- package/dist/cjs/client.js +483 -0
- package/dist/cjs/client.js.map +1 -0
- package/dist/cjs/context.d.ts +10 -0
- package/dist/cjs/context.d.ts.map +1 -0
- package/dist/cjs/context.js +14 -0
- package/dist/cjs/context.js.map +1 -0
- package/dist/cjs/hooks.d.ts +86 -0
- package/dist/cjs/hooks.d.ts.map +1 -0
- package/dist/cjs/hooks.js +186 -0
- package/dist/cjs/hooks.js.map +1 -0
- package/dist/cjs/index.d.ts +7 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +23 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/local-evaluator.d.ts +12 -0
- package/dist/cjs/local-evaluator.d.ts.map +1 -0
- package/dist/cjs/local-evaluator.js +44 -0
- package/dist/cjs/local-evaluator.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/provider.d.ts +24 -0
- package/dist/cjs/provider.d.ts.map +1 -0
- package/dist/cjs/provider.js +97 -0
- package/dist/cjs/provider.js.map +1 -0
- package/dist/cjs/types.d.ts +163 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +9 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/esm/client.d.ts +121 -0
- package/dist/esm/client.d.ts.map +1 -0
- package/dist/esm/client.js +479 -0
- package/dist/esm/client.js.map +1 -0
- package/dist/esm/context.d.ts +10 -0
- package/dist/esm/context.d.ts.map +1 -0
- package/dist/esm/context.js +11 -0
- package/dist/esm/context.js.map +1 -0
- package/dist/esm/hooks.d.ts +86 -0
- package/dist/esm/hooks.d.ts.map +1 -0
- package/dist/esm/hooks.js +178 -0
- package/dist/esm/hooks.js.map +1 -0
- package/dist/esm/index.d.ts +7 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +10 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/local-evaluator.d.ts +12 -0
- package/dist/esm/local-evaluator.d.ts.map +1 -0
- package/dist/esm/local-evaluator.js +41 -0
- package/dist/esm/local-evaluator.js.map +1 -0
- package/dist/esm/provider.d.ts +24 -0
- package/dist/esm/provider.d.ts.map +1 -0
- package/dist/esm/provider.js +94 -0
- package/dist/esm/provider.js.map +1 -0
- package/dist/esm/types.d.ts +163 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +8 -0
- package/dist/esm/types.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useDeploySentry = useDeploySentry;
|
|
4
|
+
exports.useFlag = useFlag;
|
|
5
|
+
exports.useFlagDetail = useFlagDetail;
|
|
6
|
+
exports.useFlagsByCategory = useFlagsByCategory;
|
|
7
|
+
exports.useDispatch = useDispatch;
|
|
8
|
+
exports.useExpiredFlags = useExpiredFlags;
|
|
9
|
+
const react_1 = require("react");
|
|
10
|
+
const context_1 = require("./context");
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Helpers
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
const EMPTY_FLAGS = [];
|
|
15
|
+
const DEFAULT_METADATA = {
|
|
16
|
+
category: 'feature',
|
|
17
|
+
purpose: '',
|
|
18
|
+
owners: [],
|
|
19
|
+
isPermanent: false,
|
|
20
|
+
expiresAt: undefined,
|
|
21
|
+
tags: [],
|
|
22
|
+
};
|
|
23
|
+
function useClient() {
|
|
24
|
+
const client = (0, react_1.useContext)(context_1.DeploySentryContext);
|
|
25
|
+
if (!client) {
|
|
26
|
+
throw new Error('DeploySentry hooks must be used within a <DeploySentryProvider>. ' +
|
|
27
|
+
'Wrap your component tree with the provider before calling any hook.');
|
|
28
|
+
}
|
|
29
|
+
return client;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Subscribe to the client's flag store via `useSyncExternalStore`.
|
|
33
|
+
*
|
|
34
|
+
* Every flag-change notification from the client (initial fetch or SSE
|
|
35
|
+
* update) will trigger a synchronous re-render of any component that
|
|
36
|
+
* consumes this hook.
|
|
37
|
+
*/
|
|
38
|
+
function useFlagSnapshot(client) {
|
|
39
|
+
const subscribe = (0, react_1.useCallback)((onStoreChange) => client.subscribe(onStoreChange), [client]);
|
|
40
|
+
const getSnapshot = (0, react_1.useCallback)(() => client.getAllFlags(), [client]);
|
|
41
|
+
// For SSR, return an empty array. Flags are fetched client-side.
|
|
42
|
+
const getServerSnapshot = (0, react_1.useCallback)(() => EMPTY_FLAGS, []);
|
|
43
|
+
return (0, react_1.useSyncExternalStore)(subscribe, getSnapshot, getServerSnapshot);
|
|
44
|
+
}
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Public hooks
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
/**
|
|
49
|
+
* Return the raw {@link DeploySentryClient} instance.
|
|
50
|
+
*
|
|
51
|
+
* Useful for advanced use-cases such as manual re-identification or
|
|
52
|
+
* subscribing to change events outside of React's lifecycle.
|
|
53
|
+
*
|
|
54
|
+
* @throws If called outside of a `<DeploySentryProvider>`.
|
|
55
|
+
*/
|
|
56
|
+
function useDeploySentry() {
|
|
57
|
+
return useClient();
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Evaluate a feature flag and return its resolved value.
|
|
61
|
+
*
|
|
62
|
+
* The component re-renders whenever the flag value changes (via SSE).
|
|
63
|
+
*
|
|
64
|
+
* @param key - The unique flag key.
|
|
65
|
+
* @param defaultValue - Value returned while the flag is loading or if the
|
|
66
|
+
* key does not exist.
|
|
67
|
+
* @returns The resolved flag value, or `defaultValue`.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```tsx
|
|
71
|
+
* const showBanner = useFlag('show-banner', false);
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
function useFlag(key, defaultValue) {
|
|
75
|
+
const client = useClient();
|
|
76
|
+
// Subscribe to the store so we re-render on updates.
|
|
77
|
+
useFlagSnapshot(client);
|
|
78
|
+
const flag = client.getFlag(key);
|
|
79
|
+
if (!flag)
|
|
80
|
+
return defaultValue;
|
|
81
|
+
return (flag.enabled ? flag.value : defaultValue);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Return detailed evaluation information for a single flag.
|
|
85
|
+
*
|
|
86
|
+
* Includes the resolved value, enabled state, full metadata, and a
|
|
87
|
+
* `loading` indicator that is `true` until the initial fetch completes.
|
|
88
|
+
*
|
|
89
|
+
* @param key - The unique flag key.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```tsx
|
|
93
|
+
* const { value, enabled, metadata, loading } = useFlagDetail('new-checkout');
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
function useFlagDetail(key) {
|
|
97
|
+
const client = useClient();
|
|
98
|
+
useFlagSnapshot(client);
|
|
99
|
+
const flag = client.getFlag(key);
|
|
100
|
+
const loading = !client.isInitialised;
|
|
101
|
+
if (!flag) {
|
|
102
|
+
return {
|
|
103
|
+
value: undefined,
|
|
104
|
+
enabled: false,
|
|
105
|
+
metadata: DEFAULT_METADATA,
|
|
106
|
+
loading,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
const metadata = {
|
|
110
|
+
category: flag.category,
|
|
111
|
+
purpose: flag.purpose,
|
|
112
|
+
owners: flag.owners,
|
|
113
|
+
isPermanent: flag.isPermanent,
|
|
114
|
+
expiresAt: flag.expiresAt,
|
|
115
|
+
tags: flag.tags,
|
|
116
|
+
};
|
|
117
|
+
return {
|
|
118
|
+
value: flag.value,
|
|
119
|
+
enabled: flag.enabled,
|
|
120
|
+
metadata,
|
|
121
|
+
loading,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Return all flags that belong to the given category.
|
|
126
|
+
*
|
|
127
|
+
* The result is referentially stable across renders as long as the
|
|
128
|
+
* underlying flag data has not changed.
|
|
129
|
+
*
|
|
130
|
+
* @param category - One of the predefined {@link FlagCategory} values.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```tsx
|
|
134
|
+
* const experiments = useFlagsByCategory('experiment');
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
function useFlagsByCategory(category) {
|
|
138
|
+
const client = useClient();
|
|
139
|
+
const allFlags = useFlagSnapshot(client);
|
|
140
|
+
return (0, react_1.useMemo)(() => allFlags.filter((f) => f.category === category), [allFlags, category]);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Return the dispatch function for the given operation name.
|
|
144
|
+
*
|
|
145
|
+
* Reads the client from context and calls {@link DeploySentryClient.dispatch},
|
|
146
|
+
* which selects the appropriate handler based on currently enabled flags.
|
|
147
|
+
*
|
|
148
|
+
* @param operation - The name of the registered operation.
|
|
149
|
+
* @returns The resolved handler function.
|
|
150
|
+
*
|
|
151
|
+
* @throws If no handlers are registered for the operation.
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```tsx
|
|
155
|
+
* const checkout = useDispatch<() => void>('checkout');
|
|
156
|
+
* checkout();
|
|
157
|
+
* ```
|
|
158
|
+
*/
|
|
159
|
+
function useDispatch(operation) {
|
|
160
|
+
const client = useDeploySentry();
|
|
161
|
+
return client.dispatch(operation);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Return all non-permanent flags whose `expiresAt` date is in the past.
|
|
165
|
+
*
|
|
166
|
+
* This is useful for building admin dashboards that surface stale flags
|
|
167
|
+
* that should be cleaned up.
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* ```tsx
|
|
171
|
+
* const expired = useExpiredFlags();
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
function useExpiredFlags() {
|
|
175
|
+
const client = useClient();
|
|
176
|
+
const allFlags = useFlagSnapshot(client);
|
|
177
|
+
return (0, react_1.useMemo)(() => {
|
|
178
|
+
const now = Date.now();
|
|
179
|
+
return allFlags.filter((f) => {
|
|
180
|
+
if (f.isPermanent || !f.expiresAt)
|
|
181
|
+
return false;
|
|
182
|
+
return new Date(f.expiresAt).getTime() <= now;
|
|
183
|
+
});
|
|
184
|
+
}, [allFlags]);
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/hooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { DeploySentryContext } from './context';
|
|
2
|
+
export { DeploySentryProvider } from './provider';
|
|
3
|
+
export { useDeploySentry, useDispatch, useExpiredFlags, useFlag, useFlagDetail, useFlagsByCategory, } from './hooks';
|
|
4
|
+
export { DeploySentryClient } from './client';
|
|
5
|
+
export { evaluateLocal } from './local-evaluator';
|
|
6
|
+
export type { ApiFlagResponse, EvaluationContext, Flag, FlagCategory, FlagConfig, FlagConfigEnvironment, FlagConfigFlag, FlagConfigRule, FlagDetail, FlagMetadata, ProviderProps, Registration, SSEFlagUpdate, UserContext, } from './types';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAGlD,OAAO,EACL,eAAe,EACf,WAAW,EACX,eAAe,EACf,OAAO,EACP,aAAa,EACb,kBAAkB,GACnB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAG9C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,IAAI,EACJ,YAAY,EACZ,UAAU,EACV,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,UAAU,EACV,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.evaluateLocal = exports.DeploySentryClient = exports.useFlagsByCategory = exports.useFlagDetail = exports.useFlag = exports.useExpiredFlags = exports.useDispatch = exports.useDeploySentry = exports.DeploySentryProvider = exports.DeploySentryContext = void 0;
|
|
4
|
+
// Context & Provider
|
|
5
|
+
var context_1 = require("./context");
|
|
6
|
+
Object.defineProperty(exports, "DeploySentryContext", { enumerable: true, get: function () { return context_1.DeploySentryContext; } });
|
|
7
|
+
var provider_1 = require("./provider");
|
|
8
|
+
Object.defineProperty(exports, "DeploySentryProvider", { enumerable: true, get: function () { return provider_1.DeploySentryProvider; } });
|
|
9
|
+
// Hooks
|
|
10
|
+
var hooks_1 = require("./hooks");
|
|
11
|
+
Object.defineProperty(exports, "useDeploySentry", { enumerable: true, get: function () { return hooks_1.useDeploySentry; } });
|
|
12
|
+
Object.defineProperty(exports, "useDispatch", { enumerable: true, get: function () { return hooks_1.useDispatch; } });
|
|
13
|
+
Object.defineProperty(exports, "useExpiredFlags", { enumerable: true, get: function () { return hooks_1.useExpiredFlags; } });
|
|
14
|
+
Object.defineProperty(exports, "useFlag", { enumerable: true, get: function () { return hooks_1.useFlag; } });
|
|
15
|
+
Object.defineProperty(exports, "useFlagDetail", { enumerable: true, get: function () { return hooks_1.useFlagDetail; } });
|
|
16
|
+
Object.defineProperty(exports, "useFlagsByCategory", { enumerable: true, get: function () { return hooks_1.useFlagsByCategory; } });
|
|
17
|
+
// Client (advanced usage)
|
|
18
|
+
var client_1 = require("./client");
|
|
19
|
+
Object.defineProperty(exports, "DeploySentryClient", { enumerable: true, get: function () { return client_1.DeploySentryClient; } });
|
|
20
|
+
// Local evaluation (file/flagData mode)
|
|
21
|
+
var local_evaluator_1 = require("./local-evaluator");
|
|
22
|
+
Object.defineProperty(exports, "evaluateLocal", { enumerable: true, get: function () { return local_evaluator_1.evaluateLocal; } });
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,qBAAqB;AACrB,qCAAgD;AAAvC,8GAAA,mBAAmB,OAAA;AAC5B,uCAAkD;AAAzC,gHAAA,oBAAoB,OAAA;AAE7B,QAAQ;AACR,iCAOiB;AANf,wGAAA,eAAe,OAAA;AACf,oGAAA,WAAW,OAAA;AACX,wGAAA,eAAe,OAAA;AACf,gGAAA,OAAO,OAAA;AACP,sGAAA,aAAa,OAAA;AACb,2GAAA,kBAAkB,OAAA;AAGpB,0BAA0B;AAC1B,mCAA8C;AAArC,4GAAA,kBAAkB,OAAA;AAE3B,wCAAwC;AACxC,qDAAkD;AAAzC,gHAAA,aAAa,OAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { EvaluationContext, FlagConfig } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Evaluate a flag locally using pre-loaded config data.
|
|
4
|
+
*
|
|
5
|
+
* This mirrors the Node SDK's local evaluator so that file/flagData mode
|
|
6
|
+
* produces consistent results across SDKs.
|
|
7
|
+
*/
|
|
8
|
+
export declare function evaluateLocal(config: FlagConfig, environment: string, key: string, context?: EvaluationContext): {
|
|
9
|
+
value: string;
|
|
10
|
+
reason: string;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=local-evaluator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-evaluator.d.ts","sourceRoot":"","sources":["../../src/local-evaluator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAkB,MAAM,SAAS,CAAC;AAE7E;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,UAAU,EAClB,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,iBAAiB,GAC1B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAgBnC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.evaluateLocal = evaluateLocal;
|
|
4
|
+
/**
|
|
5
|
+
* Evaluate a flag locally using pre-loaded config data.
|
|
6
|
+
*
|
|
7
|
+
* This mirrors the Node SDK's local evaluator so that file/flagData mode
|
|
8
|
+
* produces consistent results across SDKs.
|
|
9
|
+
*/
|
|
10
|
+
function evaluateLocal(config, environment, key, context) {
|
|
11
|
+
const flag = config.flags.find((f) => f.key === key);
|
|
12
|
+
if (!flag)
|
|
13
|
+
return { value: '', reason: 'flag_not_found' };
|
|
14
|
+
const envState = flag.environments[environment];
|
|
15
|
+
if (!envState || !envState.enabled)
|
|
16
|
+
return { value: flag.default_value, reason: 'env_disabled' };
|
|
17
|
+
if (flag.rules && context) {
|
|
18
|
+
const sorted = [...flag.rules].sort((a, b) => a.priority - b.priority);
|
|
19
|
+
for (const rule of sorted) {
|
|
20
|
+
if (!rule.environments[environment])
|
|
21
|
+
continue;
|
|
22
|
+
if (matchRule(rule, context))
|
|
23
|
+
return { value: rule.value, reason: 'rule_match' };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return { value: envState.value || flag.default_value, reason: 'default' };
|
|
27
|
+
}
|
|
28
|
+
function matchRule(rule, context) {
|
|
29
|
+
const val = context.attributes?.[rule.attribute] ?? '';
|
|
30
|
+
const targets = rule.target_values ?? [];
|
|
31
|
+
switch (rule.operator) {
|
|
32
|
+
case 'equals': return targets.length > 0 && val === targets[0];
|
|
33
|
+
case 'not_equals': return targets.length > 0 && val !== targets[0];
|
|
34
|
+
case 'in': return targets.includes(val);
|
|
35
|
+
case 'not_in': return !targets.includes(val);
|
|
36
|
+
case 'contains': return targets.length > 0 && val.includes(targets[0]);
|
|
37
|
+
case 'starts_with': return targets.length > 0 && val.startsWith(targets[0]);
|
|
38
|
+
case 'ends_with': return targets.length > 0 && val.endsWith(targets[0]);
|
|
39
|
+
case 'greater_than': return targets.length > 0 && parseFloat(val) > parseFloat(targets[0]);
|
|
40
|
+
case 'less_than': return targets.length > 0 && parseFloat(val) < parseFloat(targets[0]);
|
|
41
|
+
default: return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=local-evaluator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-evaluator.js","sourceRoot":"","sources":["../../src/local-evaluator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ProviderProps } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Provides the DeploySentry client to all descendant components.
|
|
5
|
+
*
|
|
6
|
+
* The provider creates a {@link DeploySentryClient} on mount, fetches the
|
|
7
|
+
* initial flag set, opens an SSE connection for real-time updates, and tears
|
|
8
|
+
* everything down on unmount.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```tsx
|
|
12
|
+
* <DeploySentryProvider
|
|
13
|
+
* apiKey="ds_live_abc123"
|
|
14
|
+
* baseURL="https://api.dr-sentry.com"
|
|
15
|
+
* environment="production"
|
|
16
|
+
* project="my-app"
|
|
17
|
+
* user={{ id: 'user-42' }}
|
|
18
|
+
* >
|
|
19
|
+
* <App />
|
|
20
|
+
* </DeploySentryProvider>
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function DeploySentryProvider({ apiKey, baseURL, environment, project, application, user, sessionId, mode, flagData, children, }: ProviderProps): React.ReactElement;
|
|
24
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAGpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,MAAM,EACN,OAAO,EACP,WAAW,EACX,OAAO,EACP,WAAW,EACX,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,QAAQ,EACR,QAAQ,GACT,EAAE,aAAa,GAAG,KAAK,CAAC,YAAY,CAsFpC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DeploySentryProvider = DeploySentryProvider;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const client_1 = require("./client");
|
|
7
|
+
const context_1 = require("./context");
|
|
8
|
+
/**
|
|
9
|
+
* Provides the DeploySentry client to all descendant components.
|
|
10
|
+
*
|
|
11
|
+
* The provider creates a {@link DeploySentryClient} on mount, fetches the
|
|
12
|
+
* initial flag set, opens an SSE connection for real-time updates, and tears
|
|
13
|
+
* everything down on unmount.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* <DeploySentryProvider
|
|
18
|
+
* apiKey="ds_live_abc123"
|
|
19
|
+
* baseURL="https://api.dr-sentry.com"
|
|
20
|
+
* environment="production"
|
|
21
|
+
* project="my-app"
|
|
22
|
+
* user={{ id: 'user-42' }}
|
|
23
|
+
* >
|
|
24
|
+
* <App />
|
|
25
|
+
* </DeploySentryProvider>
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
function DeploySentryProvider({ apiKey, baseURL, environment, project, application, user, sessionId, mode, flagData, children, }) {
|
|
29
|
+
const [client, setClient] = (0, react_1.useState)(null);
|
|
30
|
+
const [, setError] = (0, react_1.useState)(null);
|
|
31
|
+
// Keep a ref so the effect cleanup always targets the right instance.
|
|
32
|
+
const clientRef = (0, react_1.useRef)(null);
|
|
33
|
+
// Memoise the configuration identity so we only recreate the client when
|
|
34
|
+
// the connection parameters change, not on every render.
|
|
35
|
+
const configKey = (0, react_1.useMemo)(() => JSON.stringify({ apiKey, baseURL, environment, project, application, sessionId, mode }), [apiKey, baseURL, environment, project, application, sessionId, mode]);
|
|
36
|
+
(0, react_1.useEffect)(() => {
|
|
37
|
+
const instance = new client_1.DeploySentryClient({
|
|
38
|
+
apiKey,
|
|
39
|
+
baseURL,
|
|
40
|
+
environment,
|
|
41
|
+
project,
|
|
42
|
+
application,
|
|
43
|
+
user,
|
|
44
|
+
sessionId,
|
|
45
|
+
mode,
|
|
46
|
+
flagConfig: flagData,
|
|
47
|
+
});
|
|
48
|
+
clientRef.current = instance;
|
|
49
|
+
instance
|
|
50
|
+
.init()
|
|
51
|
+
.then(() => {
|
|
52
|
+
// Guard against the effect having been cleaned up before init resolved.
|
|
53
|
+
if (clientRef.current === instance) {
|
|
54
|
+
setClient(instance);
|
|
55
|
+
setError(null);
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
.catch((err) => {
|
|
59
|
+
if (clientRef.current === instance) {
|
|
60
|
+
setError(err instanceof Error
|
|
61
|
+
? err
|
|
62
|
+
: new Error(String(err)));
|
|
63
|
+
// Still expose the client so hooks can return defaults gracefully.
|
|
64
|
+
setClient(instance);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
return () => {
|
|
68
|
+
clientRef.current = null;
|
|
69
|
+
instance.destroy();
|
|
70
|
+
};
|
|
71
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
72
|
+
}, [configKey]);
|
|
73
|
+
// When the user context changes (but connection params stay the same),
|
|
74
|
+
// re-identify on the existing client rather than tearing it down.
|
|
75
|
+
const userKey = (0, react_1.useMemo)(() => JSON.stringify(user), [user]);
|
|
76
|
+
(0, react_1.useEffect)(() => {
|
|
77
|
+
if (!client)
|
|
78
|
+
return;
|
|
79
|
+
// The initial identify already happened inside init(), so we skip the
|
|
80
|
+
// first call by comparing refs.
|
|
81
|
+
client.identify(user).catch(() => {
|
|
82
|
+
// Swallow identify errors. The client will keep the previous state.
|
|
83
|
+
});
|
|
84
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
85
|
+
}, [userKey, client]);
|
|
86
|
+
// Delay rendering children until the client exists. Hooks like
|
|
87
|
+
// `useFlag` throw synchronously when the context value is null, which
|
|
88
|
+
// crashes the whole subtree on the first render — before `init()` has
|
|
89
|
+
// even had a chance to run. Gating children behind the client's
|
|
90
|
+
// readiness keeps the external API (a throwing hook that enforces
|
|
91
|
+
// provider presence) while preventing that race.
|
|
92
|
+
if (!client) {
|
|
93
|
+
return (0, jsx_runtime_1.jsx)(context_1.DeploySentryContext.Provider, { value: null, children: null });
|
|
94
|
+
}
|
|
95
|
+
return ((0, jsx_runtime_1.jsx)(context_1.DeploySentryContext.Provider, { value: client, children: children }));
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/provider.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeploySentry React SDK type definitions.
|
|
3
|
+
*
|
|
4
|
+
* Types are defined locally so the React SDK has zero runtime dependency on
|
|
5
|
+
* the Node SDK package. They mirror the canonical shapes from @deploysentry/sdk.
|
|
6
|
+
*/
|
|
7
|
+
/** Categories that classify the intent and lifecycle of a feature flag. */
|
|
8
|
+
export type FlagCategory = 'release' | 'feature' | 'experiment' | 'ops' | 'permission';
|
|
9
|
+
/** Rich metadata attached to every feature flag. */
|
|
10
|
+
export interface FlagMetadata {
|
|
11
|
+
/** Categorisation that drives lifecycle policies. */
|
|
12
|
+
category: FlagCategory;
|
|
13
|
+
/** Human-readable explanation of what this flag controls. */
|
|
14
|
+
purpose: string;
|
|
15
|
+
/** Team or individual owners responsible for this flag. */
|
|
16
|
+
owners: string[];
|
|
17
|
+
/** When true the flag is not expected to be removed. */
|
|
18
|
+
isPermanent: boolean;
|
|
19
|
+
/** ISO-8601 expiration timestamp. Undefined for permanent flags. */
|
|
20
|
+
expiresAt?: string;
|
|
21
|
+
/** Free-form tags for filtering and grouping. */
|
|
22
|
+
tags: string[];
|
|
23
|
+
}
|
|
24
|
+
/** A feature flag as returned by the DeploySentry API. */
|
|
25
|
+
export interface Flag {
|
|
26
|
+
/** Unique key used to reference the flag in code. */
|
|
27
|
+
key: string;
|
|
28
|
+
/** Display name of the flag. */
|
|
29
|
+
name: string;
|
|
30
|
+
/** Category classification. */
|
|
31
|
+
category: FlagCategory;
|
|
32
|
+
/** Human-readable explanation of what this flag controls. */
|
|
33
|
+
purpose: string;
|
|
34
|
+
/** Team or individual owners responsible for this flag. */
|
|
35
|
+
owners: string[];
|
|
36
|
+
/** When true the flag is not expected to be removed. */
|
|
37
|
+
isPermanent: boolean;
|
|
38
|
+
/** ISO-8601 expiration timestamp. Undefined for permanent flags. */
|
|
39
|
+
expiresAt?: string;
|
|
40
|
+
/** Whether the flag is currently enabled. */
|
|
41
|
+
enabled: boolean;
|
|
42
|
+
/** The resolved value (boolean, string, number, or JSON object). */
|
|
43
|
+
value: unknown;
|
|
44
|
+
/** Free-form tags for filtering and grouping. */
|
|
45
|
+
tags: string[];
|
|
46
|
+
}
|
|
47
|
+
/** Detailed evaluation result for a single flag. */
|
|
48
|
+
export interface FlagDetail<T = unknown> {
|
|
49
|
+
/** The resolved value after evaluation. */
|
|
50
|
+
value: T;
|
|
51
|
+
/** Whether the flag is currently enabled. */
|
|
52
|
+
enabled: boolean;
|
|
53
|
+
/** Rich metadata for the flag. */
|
|
54
|
+
metadata: FlagMetadata;
|
|
55
|
+
/** True while the initial fetch is in progress. */
|
|
56
|
+
loading: boolean;
|
|
57
|
+
}
|
|
58
|
+
/** User context sent with evaluation requests. */
|
|
59
|
+
export interface UserContext {
|
|
60
|
+
/** Unique user identifier. */
|
|
61
|
+
id: string;
|
|
62
|
+
/** Arbitrary attributes for targeting rules. */
|
|
63
|
+
attributes?: Record<string, string>;
|
|
64
|
+
}
|
|
65
|
+
/** Props accepted by {@link DeploySentryProvider}. */
|
|
66
|
+
export interface ProviderProps {
|
|
67
|
+
/** API key for authenticating with the DeploySentry service. */
|
|
68
|
+
apiKey: string;
|
|
69
|
+
/** Base URL of the DeploySentry API. */
|
|
70
|
+
baseURL: string;
|
|
71
|
+
/** Environment identifier (e.g. "production", "staging"). */
|
|
72
|
+
environment: string;
|
|
73
|
+
/** Project identifier. */
|
|
74
|
+
project: string;
|
|
75
|
+
/** Application identifier. */
|
|
76
|
+
application: string;
|
|
77
|
+
/** Optional user context for targeting. */
|
|
78
|
+
user?: UserContext;
|
|
79
|
+
/** Optional session identifier for consistent flag evaluation across requests. */
|
|
80
|
+
sessionId?: string;
|
|
81
|
+
/** SDK mode: 'server' (default), 'file' (local only), or 'server-with-fallback'. */
|
|
82
|
+
mode?: 'server' | 'file' | 'server-with-fallback';
|
|
83
|
+
/** Pre-loaded flag configuration for file/fallback mode. */
|
|
84
|
+
flagData?: FlagConfig;
|
|
85
|
+
/** React children. */
|
|
86
|
+
children: React.ReactNode;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Internal API response shape for flag evaluation.
|
|
90
|
+
* This represents the raw JSON payload from the server.
|
|
91
|
+
*/
|
|
92
|
+
export interface ApiFlagResponse {
|
|
93
|
+
key: string;
|
|
94
|
+
name?: string;
|
|
95
|
+
enabled: boolean;
|
|
96
|
+
value: unknown;
|
|
97
|
+
metadata?: {
|
|
98
|
+
category?: FlagCategory;
|
|
99
|
+
purpose?: string;
|
|
100
|
+
owners?: string[];
|
|
101
|
+
isPermanent?: boolean;
|
|
102
|
+
expiresAt?: string;
|
|
103
|
+
tags?: string[];
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/** SSE event data for real-time flag updates. */
|
|
107
|
+
export interface SSEFlagUpdate {
|
|
108
|
+
type: 'flag.updated' | 'flag.created' | 'flag.deleted';
|
|
109
|
+
flag: ApiFlagResponse;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* A registered handler entry used by {@link DeploySentryClient.register} and
|
|
113
|
+
* {@link DeploySentryClient.dispatch}.
|
|
114
|
+
*/
|
|
115
|
+
export interface Registration<T extends (...args: any[]) => any = (...args: any[]) => any> {
|
|
116
|
+
handler: T;
|
|
117
|
+
flagKey?: string;
|
|
118
|
+
}
|
|
119
|
+
/** Optional evaluation context passed to {@link DeploySentryClient.dispatch}. */
|
|
120
|
+
export interface EvaluationContext {
|
|
121
|
+
userId?: string;
|
|
122
|
+
attributes?: Record<string, string>;
|
|
123
|
+
}
|
|
124
|
+
/** Pre-loaded flag configuration for file/flagData mode. */
|
|
125
|
+
export interface FlagConfig {
|
|
126
|
+
version: number;
|
|
127
|
+
project: string;
|
|
128
|
+
application: string;
|
|
129
|
+
exported_at: string;
|
|
130
|
+
environments: FlagConfigEnvironment[];
|
|
131
|
+
flags: FlagConfigFlag[];
|
|
132
|
+
}
|
|
133
|
+
/** Environment entry in a flag config file. */
|
|
134
|
+
export interface FlagConfigEnvironment {
|
|
135
|
+
id: string;
|
|
136
|
+
name: string;
|
|
137
|
+
is_production: boolean;
|
|
138
|
+
}
|
|
139
|
+
/** Flag entry in a flag config file. */
|
|
140
|
+
export interface FlagConfigFlag {
|
|
141
|
+
key: string;
|
|
142
|
+
name: string;
|
|
143
|
+
flag_type: string;
|
|
144
|
+
category: string;
|
|
145
|
+
default_value: string;
|
|
146
|
+
is_permanent: boolean;
|
|
147
|
+
expires_at?: string;
|
|
148
|
+
environments: Record<string, {
|
|
149
|
+
enabled: boolean;
|
|
150
|
+
value: string;
|
|
151
|
+
}>;
|
|
152
|
+
rules?: FlagConfigRule[];
|
|
153
|
+
}
|
|
154
|
+
/** Targeting rule within a flag config file. */
|
|
155
|
+
export interface FlagConfigRule {
|
|
156
|
+
attribute: string;
|
|
157
|
+
operator: string;
|
|
158
|
+
target_values: string[];
|
|
159
|
+
value: string;
|
|
160
|
+
priority: number;
|
|
161
|
+
environments: Record<string, boolean>;
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* DeploySentry React SDK type definitions.
|
|
4
|
+
*
|
|
5
|
+
* Types are defined locally so the React SDK has zero runtime dependency on
|
|
6
|
+
* the Node SDK package. They mirror the canonical shapes from @deploysentry/sdk.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":";AAAA;;;;;GAKG"}
|